Merge branch 'master' of https://github.com/thomasrudin-mt/mapserver
This commit is contained in:
commit
ca7415f8cc
@ -23,7 +23,7 @@ function send_stats()
|
|||||||
local data = {
|
local data = {
|
||||||
time = minetest.get_timeofday() * 24000,
|
time = minetest.get_timeofday() * 24000,
|
||||||
uptime = minetest.get_server_uptime(),
|
uptime = minetest.get_server_uptime(),
|
||||||
max_lag = get_max_lag(),
|
max_lag = tonumber(get_max_lag()),
|
||||||
players = {}
|
players = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,11 +36,11 @@ function send_stats()
|
|||||||
velocity = player:get_player_velocity()
|
velocity = player:get_player_velocity()
|
||||||
}
|
}
|
||||||
|
|
||||||
table.insert(data.players, player)
|
table.insert(data.players, info)
|
||||||
end
|
end
|
||||||
|
|
||||||
http.fetch({
|
http.fetch({
|
||||||
url = url,
|
url = url .. "/api/minetest",
|
||||||
extra_headers = { "Content-Type: application/json", "Authorization: " .. key },
|
extra_headers = { "Content-Type: application/json", "Authorization: " .. key },
|
||||||
timeout = 1,
|
timeout = 1,
|
||||||
post_data = minetest.write_json(data)
|
post_data = minetest.write_json(data)
|
||||||
|
@ -18,7 +18,7 @@ clean:
|
|||||||
rm -rf $(OUT_DIR)
|
rm -rf $(OUT_DIR)
|
||||||
|
|
||||||
$(STATIC_VFS):
|
$(STATIC_VFS):
|
||||||
go generate
|
go run github.com/mjibson/esc -o vfs/static.go -prefix="static/" -pkg vfs static
|
||||||
|
|
||||||
build: $(STATIC_VFS) $(OUT_DIR)
|
build: $(STATIC_VFS) $(OUT_DIR)
|
||||||
# native
|
# native
|
||||||
|
@ -2,16 +2,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"mapserver/app"
|
"mapserver/app"
|
||||||
"mapserver/mapobject"
|
"mapserver/mapobject"
|
||||||
"mapserver/params"
|
"mapserver/params"
|
||||||
"mapserver/tilerendererjob"
|
"mapserver/tilerendererjob"
|
||||||
"mapserver/web"
|
"mapserver/web"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
|
||||||
|
|
||||||
//go:generate -command go run github.com/mjibson/esc -o vfs/static.go -prefix="static/" -pkg vfs static
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//Parse command line
|
//Parse command line
|
||||||
|
@ -11,15 +11,28 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="image-map"></div>
|
<div id="image-map"></div>
|
||||||
|
|
||||||
|
<!-- libs -->
|
||||||
<script src="js/lib/leaflet.js"></script>
|
<script src="js/lib/leaflet.js"></script>
|
||||||
<script src="js/lib/mithril.min.js"></script>
|
<script src="js/lib/mithril.min.js"></script>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<script src="js/util/debounce.js"></script>
|
||||||
|
|
||||||
|
<!-- api -->
|
||||||
<script src="js/api.js"></script>
|
<script src="js/api.js"></script>
|
||||||
|
|
||||||
|
<!-- components -->
|
||||||
<script src="js/LayerManager.js"></script>
|
<script src="js/LayerManager.js"></script>
|
||||||
<script src="js/SimpleCRS.js"></script>
|
<script src="js/SimpleCRS.js"></script>
|
||||||
<script src="js/WebSocketChannel.js"></script>
|
<script src="js/WebSocketChannel.js"></script>
|
||||||
<script src="js/RealtimeTileLayer.js"></script>
|
<script src="js/RealtimeTileLayer.js"></script>
|
||||||
<script src="js/CoordinatesDisplay.js"></script>
|
<script src="js/CoordinatesDisplay.js"></script>
|
||||||
|
|
||||||
|
<!-- overlays -->
|
||||||
<script src="js/overlays/TravelnetOverlay.js"></script>
|
<script src="js/overlays/TravelnetOverlay.js"></script>
|
||||||
|
<script src="js/overlays/PlayerOverlay.js"></script>
|
||||||
|
|
||||||
|
<!-- bootstrap -->
|
||||||
<script src="js/main.js"></script>
|
<script src="js/main.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -15,6 +15,17 @@ WebSocketChannel.prototype.addListener = function(type, listener){
|
|||||||
list.push(listener);
|
list.push(listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WebSocketChannel.prototype.removeListener = function(type, listener){
|
||||||
|
var list = this.listenerMap[type];
|
||||||
|
if (!list){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listenerMap[type] = list.filter(function(l){
|
||||||
|
return l != listener;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
WebSocketChannel.prototype.connect = function(){
|
WebSocketChannel.prototype.connect = function(){
|
||||||
var ws = new WebSocket(this.wsUrl);
|
var ws = new WebSocket(this.wsUrl);
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -25,7 +36,7 @@ WebSocketChannel.prototype.connect = function(){
|
|||||||
|
|
||||||
var listeners = self.listenerMap[event.type];
|
var listeners = self.listenerMap[event.type];
|
||||||
if (listeners){
|
if (listeners){
|
||||||
self.listeners.forEach(function(listener){
|
listeners.forEach(function(listener){
|
||||||
listener(event.data);
|
listener(event.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@ api.getConfig().then(function(cfg){
|
|||||||
var wsChannel = new WebSocketChannel();
|
var wsChannel = new WebSocketChannel();
|
||||||
wsChannel.connect();
|
wsChannel.connect();
|
||||||
|
|
||||||
|
wsChannel.addListener("minetest-info", function(e){
|
||||||
|
console.log(e); //XXX
|
||||||
|
});
|
||||||
|
|
||||||
var rtTiles = new RealtimeTileLayer(wsChannel);
|
var rtTiles = new RealtimeTileLayer(wsChannel);
|
||||||
|
|
||||||
var initialZoom = 11;
|
var initialZoom = 11;
|
||||||
@ -18,7 +22,7 @@ api.getConfig().then(function(cfg){
|
|||||||
crs: SimpleCRS
|
crs: SimpleCRS
|
||||||
});
|
});
|
||||||
|
|
||||||
map.attributionControl.addAttribution('<a href="https://github.com/thomasrudin-mt/mapserver">Mapserver</a>');
|
map.attributionControl.addAttribution('<a href="https://github.com/thomasrudin-mt/mapserver">Minetest Mapserver</a>');
|
||||||
|
|
||||||
var layers = {};
|
var layers = {};
|
||||||
var overlays = {}
|
var overlays = {}
|
||||||
@ -29,6 +33,7 @@ api.getConfig().then(function(cfg){
|
|||||||
tileLayer.addTo(map);
|
tileLayer.addTo(map);
|
||||||
|
|
||||||
layers["Base"] = tileLayer;
|
layers["Base"] = tileLayer;
|
||||||
|
overlays["Players"] = new PlayerOverlay(wsChannel, layerMgr);
|
||||||
overlays["Travelnet"] = new TravelnetOverlay(wsChannel, layerMgr);
|
overlays["Travelnet"] = new TravelnetOverlay(wsChannel, layerMgr);
|
||||||
|
|
||||||
L.control.layers(layers, overlays).addTo(map);
|
L.control.layers(layers, overlays).addTo(map);
|
||||||
|
53
server/static/js/overlays/PlayerOverlay.js
Normal file
53
server/static/js/overlays/PlayerOverlay.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var PlayerIcon = L.icon({
|
||||||
|
iconUrl: 'pics/sam.png',
|
||||||
|
|
||||||
|
iconSize: [16, 32],
|
||||||
|
iconAnchor: [8, 16],
|
||||||
|
popupAnchor: [0, -16]
|
||||||
|
});
|
||||||
|
|
||||||
|
var PlayerOverlay = L.LayerGroup.extend({
|
||||||
|
initialize: function(wsChannel, layerMgr) {
|
||||||
|
L.LayerGroup.prototype.initialize.call(this);
|
||||||
|
|
||||||
|
this.layerMgr = layerMgr;
|
||||||
|
this.wsChannel = wsChannel;
|
||||||
|
|
||||||
|
this.currentObjects = [];
|
||||||
|
|
||||||
|
this.onLayerChange = this.onLayerChange.bind(this);
|
||||||
|
this.reDraw = this.reDraw.bind(this);
|
||||||
|
this.onMapMove = debounce(this.onMapMove.bind(this), 50);
|
||||||
|
|
||||||
|
this.wsChannel.addListener("minetest-info", this.onMinetestUpdate.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
onLayerChange: function(layer){
|
||||||
|
this.reDraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
onMinetestUpdate: function(info){
|
||||||
|
//TODO
|
||||||
|
},
|
||||||
|
|
||||||
|
reDraw: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.clearLayers();
|
||||||
|
|
||||||
|
var mapLayer = this.layerMgr.getCurrentLayer()
|
||||||
|
//TODO
|
||||||
|
},
|
||||||
|
|
||||||
|
onAdd: function(map) {
|
||||||
|
this.layerMgr.addListener(this.reDraw);
|
||||||
|
this.reDraw(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemove: function(map) {
|
||||||
|
this.clearLayers();
|
||||||
|
this.layerMgr.removeListener(this.reDraw);
|
||||||
|
}
|
||||||
|
});
|
@ -10,11 +10,15 @@ var TravelnetIcon = L.icon({
|
|||||||
|
|
||||||
var TravelnetOverlay = L.LayerGroup.extend({
|
var TravelnetOverlay = L.LayerGroup.extend({
|
||||||
initialize: function(wsChannel, layerMgr) {
|
initialize: function(wsChannel, layerMgr) {
|
||||||
|
L.LayerGroup.prototype.initialize.call(this);
|
||||||
|
|
||||||
this.layerMgr = layerMgr;
|
this.layerMgr = layerMgr;
|
||||||
this.wsChannel = wsChannel;
|
this.wsChannel = wsChannel;
|
||||||
|
|
||||||
|
this.currentObjects = [];
|
||||||
|
|
||||||
this.onLayerChange = this.onLayerChange.bind(this);
|
this.onLayerChange = this.onLayerChange.bind(this);
|
||||||
this.onMapMove = this.onMapMove.bind(this);
|
this.onMapMove = debounce(this.onMapMove.bind(this), 50);
|
||||||
},
|
},
|
||||||
|
|
||||||
onLayerChange: function(layer){
|
onLayerChange: function(layer){
|
||||||
@ -28,29 +32,48 @@ var TravelnetOverlay = L.LayerGroup.extend({
|
|||||||
reDraw: function(full){
|
reDraw: function(full){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (full)
|
if (this._map.getZoom() < 10) {
|
||||||
this.clearLayers();
|
this.clearLayers();
|
||||||
|
this.currentObjects = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full){
|
||||||
|
this.clearLayers();
|
||||||
|
this.currentObjects = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapLayer = this.layerMgr.getCurrentLayer()
|
||||||
|
var min = this._map.getBounds().getSouthWest();
|
||||||
|
var max = this._map.getBounds().getNorthEast();
|
||||||
|
|
||||||
|
var y1 = parseInt(mapLayer.from/16);
|
||||||
|
var y2 = parseInt(mapLayer.to/16);
|
||||||
|
var x1 = parseInt(min.lng);
|
||||||
|
var x2 = parseInt(max.lng);
|
||||||
|
var z1 = parseInt(min.lat);
|
||||||
|
var z2 = parseInt(max.lat);
|
||||||
|
|
||||||
//TODO: get coords
|
//TODO: get coords
|
||||||
api.getMapObjects(-10,-10,-10,10,10,10,"travelnet")
|
api.getMapObjects(
|
||||||
|
x1, y1, y1,
|
||||||
|
x2, y2, z2,
|
||||||
|
"travelnet")
|
||||||
.then(function(travelnets){
|
.then(function(travelnets){
|
||||||
//TODO: remove non-existing markers, add new ones
|
//TODO: remove non-existing markers, add new ones
|
||||||
if (!full)
|
if (!full){
|
||||||
this.clearLayers();
|
self.clearLayers();
|
||||||
|
}
|
||||||
console.log(travelnets);
|
|
||||||
|
|
||||||
//TODO: attributes, coords
|
|
||||||
var marker = L.marker([travelnet.z, travelnet.x], {icon: TravelnetIcon});
|
|
||||||
|
|
||||||
travelnets.forEach(function(travelnet){
|
travelnets.forEach(function(travelnet){
|
||||||
var popup = "<h4>" + travelnet.name + "</h4><hr>" +
|
var popup = "<h4>" + travelnet.attributes.station_name + "</h4><hr>" +
|
||||||
"<b>X: </b> " + travelnet.x + "<br>" +
|
"<b>X: </b> " + travelnet.x + "<br>" +
|
||||||
"<b>Y: </b> " + travelnet.y + "<br>" +
|
"<b>Y: </b> " + travelnet.y + "<br>" +
|
||||||
"<b>Z: </b> " + travelnet.z + "<br>" +
|
"<b>Z: </b> " + travelnet.z + "<br>" +
|
||||||
"<b>Network: </b> " + travelnet.network + "<br>" +
|
"<b>Network: </b> " + travelnet.attributes.station_network + "<br>" +
|
||||||
"<b>Owner: </b> " + travelnet.owner + "<br>";
|
"<b>Owner: </b> " + travelnet.attributes.owner + "<br>";
|
||||||
|
|
||||||
|
var marker = L.marker([travelnet.z, travelnet.x], {icon: TravelnetIcon});
|
||||||
marker.bindPopup(popup).addTo(self);
|
marker.bindPopup(popup).addTo(self);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -58,12 +81,16 @@ var TravelnetOverlay = L.LayerGroup.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onAdd: function(map) {
|
onAdd: function(map) {
|
||||||
|
map.on("zoomend", this.onMapMove);
|
||||||
|
map.on("moveend", this.onMapMove);
|
||||||
this.layerMgr.addListener(this.onLayerChange);
|
this.layerMgr.addListener(this.onLayerChange);
|
||||||
console.log("TravelnetOverlay.onAdd", map);
|
this.reDraw(true)
|
||||||
},
|
},
|
||||||
|
|
||||||
onRemove: function(map) {
|
onRemove: function(map) {
|
||||||
|
this.clearLayers();
|
||||||
|
map.off("zoomend", this.onMapMove);
|
||||||
|
map.off("moveend", this.onMapMove);
|
||||||
this.layerMgr.removeListener(this.onLayerChange);
|
this.layerMgr.removeListener(this.onLayerChange);
|
||||||
console.log("TravelnetOverlay.onRemove");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
14
server/static/js/util/debounce.js
Normal file
14
server/static/js/util/debounce.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function debounce(func, wait, immediate) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
};
|
||||||
|
var callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
@ -6,12 +6,50 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PlayerPos struct {
|
||||||
|
X float64 `json:"x"`
|
||||||
|
Y float64 `json:"y"`
|
||||||
|
Z float64 `json:"z"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
Pos PlayerPos `json:"pos"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
HP int `json:"hp"`
|
||||||
|
Breath int `json:"breath"`
|
||||||
|
//TODO: stamina, skin, etc
|
||||||
|
}
|
||||||
|
|
||||||
|
type MinetestInfo struct {
|
||||||
|
MaxLag float64 `json:"max_lag"`
|
||||||
|
Players []Player `json:"players"`
|
||||||
|
Time float64 `json:"time"`
|
||||||
|
Uptime float64 `json:"uptime"`
|
||||||
|
}
|
||||||
|
|
||||||
type Minetest struct {
|
type Minetest struct {
|
||||||
ctx *app.App
|
ctx *app.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Minetest) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
|
func (this *Minetest) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
|
||||||
resp.Header().Add("content-type", "application/json")
|
if req.Header.Get("Authorization") != this.ctx.Config.WebApi.SecretKey {
|
||||||
json.NewEncoder(resp).Encode("stub")
|
resp.WriteHeader(403)
|
||||||
|
resp.Write([]byte("invalid key!"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Header().Add("content-type", "application/json")
|
||||||
|
data := &MinetestInfo{}
|
||||||
|
|
||||||
|
err := json.NewDecoder(req.Body).Decode(data)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
resp.WriteHeader(500)
|
||||||
|
resp.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ctx.WebEventbus.Emit("minetest-info", data)
|
||||||
|
|
||||||
|
json.NewEncoder(resp).Encode("stub")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user