1
0
forked from MTSR/mapserver

Merge branch 'master' into HEAD

This commit is contained in:
NatureFreshMilk 2020-02-14 07:55:28 +01:00
commit 0f2a509f72
74 changed files with 30317 additions and 8860 deletions

View File

@ -1,6 +1,6 @@
name: go-test
on: [push]
on: [push, pull_request]
jobs:
build:

View File

@ -1,6 +1,6 @@
name: jshint
on: [push]
on: [push, pull_request]
jobs:
build:

View File

@ -89,6 +89,8 @@ func Setup(p params.ParamsType, cfg *Config) *App {
"/colors/vanessa.txt",
"/colors/advtrains.txt",
"/colors/scifi_nodes.txt",
"/colors/mcl2_colors.txt",
"/colors/miles.txt",
"/colors/custom.txt",
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 13 KiB

61
doc/api.md Normal file
View File

@ -0,0 +1,61 @@
# Api documentation
REST Api documentation
## Mapobjects
Query for `bones` / `poi`/ `shop` / etc
* **Path:** `api/mapobjects`
* **Method:** `POST`
* **Consumes:** `application/json`
* **Produces:** `application/json`
POST-Payload:
```json
{
"pos1": {
"x":-2048,
"y":-2048,
"z":-2048
},
"pos2": {
"x":2048,
"y":2048,
"z":2048
},
"type":"bones"
}
```
**Note**: `pos1` and `pos2` are in mapblocks
Example query:
```bash
curl 'http://127.0.0.1:8080/api/mapobjects/' \
-H 'Content-Type: application/json; charset=utf-8' \
--data '{"pos1":{"x":-2048,"y":-2048,"z":-2048},"pos2":{"x":2048,"y":2048,"z":2048},"type":"bones"}' \
| jq
```
Result:
```json
[{
"mapblock": {
"x": -1671,
"y": 0,
"z": -82
},
"x": -26729,
"y": 1,
"z": -1306,
"type": "bones",
"mtime": 1554099532,
"attributes": {
"owner": "Brzezowski58",
"time": "0"
}
}]
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 KiB

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 KiB

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@ -10,3 +10,20 @@ Searchable objects:
Example:
<img src="../pics/search.png">
# Ingame search
The ingame-search is enabled if the mapserver active mode is configured.
Commands:
```
/search bones SomeDude
/search bones *
/search shop papyrus
/search shop *
```
Result (Exmple):
<img src="../pics/ingame-search.png">

11
doc/stats_webfragment.md Normal file
View File

@ -0,0 +1,11 @@
# Stats webfragment
<img src="./pics/stats_webfragment.png"></img>
The "world stats" info from the bottom right corner of the mapserver
can be embedded as an iframe into any existing web-page:
```html
<iframe src="http://127.0.0.1:8080/stats.html"></iframe>
```

2
go.mod
View File

@ -3,7 +3,7 @@ module mapserver
require (
github.com/disintegration/imaging v1.6.2
github.com/gorilla/websocket v1.4.1
github.com/lib/pq v1.2.0
github.com/lib/pq v1.3.0
github.com/mattn/go-sqlite3 v1.13.0
github.com/mjibson/esc v0.1.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible

2
go.sum
View File

@ -37,6 +37,8 @@ github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=

View File

@ -69,10 +69,6 @@ func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
return cr.Count, nil
}
if version != 2 {
return 0, errors.New("Wrong metadata version: " + strconv.Itoa(int(version)))
}
offset++
count := readU16(metadata, offset)
@ -106,7 +102,15 @@ func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
pairsMap[key] = value
offset++
priv := 0
if version >= 2 { /* private tag doesn't exist in version=1 */
priv = readU8(metadata, offset)
offset++
}
if priv != 0 {
// do something usefull
logrus.Info("Private items in Inventory")
}
}
var currentInventoryName *string

View File

@ -68,6 +68,7 @@ type SearchQuery struct {
Pos2 *coords.MapBlockCoords `json:"pos2"`
Type string `json:"type"`
AttributeLike *SearchAttributeLike `json:"attributelike"`
Limit *int `json:"limit"`
}
type DBAccessor interface {

View File

@ -10,6 +10,11 @@ func (db *PostgresAccessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobject
var rows *sql.Rows
var err error
var limit = 1000
if q.Limit != nil {
limit = *q.Limit
}
if q.AttributeLike == nil {
//plain pos search
@ -17,6 +22,7 @@ func (db *PostgresAccessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobject
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
limit,
)
} else {
@ -26,6 +32,7 @@ func (db *PostgresAccessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobject
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
q.AttributeLike.Key, q.AttributeLike.Value,
limit,
)
}

View File

@ -11,6 +11,7 @@ where o.type = $1
and o.posx >= $2 and o.posy >= $3 and o.posz >= $4
and o.posx <= $5 and o.posy <= $6 and o.posz <= $7
order by o.id
limit $8
`
const getMapDataWithAttributeLikePosQuery = `
select o.id, o.type, o.mtime,
@ -26,6 +27,7 @@ and o.type = $1
and o.posx >= $2 and o.posy >= $3 and o.posz >= $4
and o.posx <= $5 and o.posy <= $6 and o.posz <= $7
order by o.id
limit $10
`
const removeMapDataQuery = `

View File

@ -11,12 +11,18 @@ func (db *Sqlite3Accessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobjectd
var rows *sql.Rows
var err error
var limit = 1000
if q.Limit != nil {
limit = *q.Limit
}
if q.AttributeLike == nil {
//plain pos search
rows, err = db.db.Query(getMapDataPosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
limit,
)
} else {
@ -26,6 +32,7 @@ func (db *Sqlite3Accessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobjectd
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
limit,
)
}

View File

@ -11,6 +11,7 @@ where o.type = ?
and o.posx >= ? and o.posy >= ? and o.posz >= ?
and o.posx <= ? and o.posy <= ? and o.posz <= ?
order by o.id
limit ?
`
const getMapDataWithAttributeLikePosQuery = `
@ -27,6 +28,7 @@ and o.type = ?
and o.posx >= ? and o.posy >= ? and o.posz >= ?
and o.posx <= ? and o.posy <= ? and o.posz <= ?
order by o.id
limit ?
`
const removeMapDataQuery = `

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
pics/ingame-search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 KiB

After

Width:  |  Height:  |  Size: 449 KiB

View File

@ -5,8 +5,17 @@ Minetest mapserver
![](https://github.com/minetest-mapserver/mapserver/workflows/jshint/badge.svg)
![](https://github.com/minetest-mapserver/mapserver/workflows/go-test/badge.svg)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/minetest-mapserver/mapserver)
![GitHub repo size](https://img.shields.io/github/repo-size/minetest-tools/mapserver.svg)
![GitHub closed issues](https://img.shields.io/github/issues-closed/minetest-tools/mapserver.svg)
![GitHub issues](https://img.shields.io/github/issues/minetest-mapserver/mapserver)
![GitHub All Releases](https://img.shields.io/github/downloads/minetest-mapserver/mapserver/total)
![Docker Pulls](https://img.shields.io/docker/pulls/minetestmapserver/mapserver)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/minetest-mapserver/mapserver)
[![Go Report Card](https://goreportcard.com/badge/github.com/minetest-mapserver/mapserver)](https://goreportcard.com/report/github.com/minetest-mapserver/mapserver)
<img src="./doc/pics/General_map_preview.png">
@ -23,6 +32,8 @@ Demo: [Pandorabox Server map](https://pandorabox.io/map/#-1782.25/493.5/10)
* [Search](doc/search.md)
* [Configuration](doc/config.md)
* [Recommended specs](doc/recommended_specs.md)
* [Stats webfragment](doc/stats_webfragment.md)
* [Web API](doc/api.md)
* [Contribution](doc/contrib.md)
* [Development](doc/dev.md)
* [License](doc/license.md)

File diff suppressed because it is too large Load Diff

28562
static/colors/miles.txt Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -1,2 +1,3 @@
bundle.js
bundle-stats.js
lib/*

104
static/js/bundle-stats.js Normal file
View File

@ -0,0 +1,104 @@
(function(f){typeof define==='function'&&define.amd?define(f):f();}((function(){'use strict';function WorldStats(info){
var timeIcon = m("span", { class: "fa fa-sun", style: "color: orange;" });
if (info.time < 5500 || info.time > 19000) //0 - 24'000
timeIcon = m("span", { class: "fa fa-moon", style: "color: blue;" });
function getHour(){
return Math.floor(info.time/1000);
}
function getMinute(){
var min = Math.floor((info.time % 1000) / 1000 * 60);
return min > 10 ? min : "0" + min;
}
function getLag(){
var color = "green";
if (info.max_lag > 0.8)
color = "orange";
else if (info.max_lag > 1.2)
color = "red";
return [
m("span", { class: "fa fa-wifi", style: "color: " + color }),
parseInt(info.max_lag*1000),
" ms"
];
}
function getPlayers(){
return [
m("span", { class: "fa fa-users" }),
info.players ? info.players.length : "0"
];
}
return m("div", [
getPlayers(),
" ",
getLag(),
" ",
m("span", { class: "fa fa-clock" }),
timeIcon,
getHour(), ":", getMinute()
]);
}class WebSocketChannel {
constructor(){
this.wsUrl = window.location.protocol.replace("http", "ws") +
"//" + window.location.host +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")) +
"/api/ws";
this.listenerMap = {/* type -> [listeners] */};
}
addListener(type, listener){
var list = this.listenerMap[type];
if (!list){
list = [];
this.listenerMap[type] = list;
}
list.push(listener);
}
removeListener(type, listener){
var list = this.listenerMap[type];
if (!list){
return;
}
this.listenerMap[type] = list.filter(l => l != listener);
}
connect(){
var ws = new WebSocket(this.wsUrl);
var self = this;
ws.onmessage = function(e){
var event = JSON.parse(e.data);
//rendered-tile, mapobject-created, mapobjects-cleared
var listeners = self.listenerMap[event.type];
if (listeners){
listeners.forEach(function(listener){
listener(event.data);
});
}
};
ws.onerror = function(){
//reconnect after some time
setTimeout(self.connect.bind(self), 1000);
};
}
}
var wsChannel = new WebSocketChannel();wsChannel.connect();
wsChannel.addListener("minetest-info", function(info){
m.render(document.getElementById("app"), WorldStats(info));
});})));//# sourceMappingURL=bundle-stats.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,49 @@
export default function(info){
var timeIcon = m("span", { class: "fa fa-sun", style: "color: orange;" });
if (info.time < 5500 || info.time > 19000) //0 - 24'000
timeIcon = m("span", { class: "fa fa-moon", style: "color: blue;" });
function getHour(){
return Math.floor(info.time/1000);
}
function getMinute(){
var min = Math.floor((info.time % 1000) / 1000 * 60);
return min >= 10 ? min : "0" + min;
}
function getLag(){
var color = "green";
if (info.max_lag > 0.8)
color = "orange";
else if (info.max_lag > 1.2)
color = "red";
return [
m("span", { class: "fa fa-wifi", style: "color: " + color }),
parseInt(info.max_lag*1000),
" ms"
];
}
function getPlayers(){
return [
m("span", { class: "fa fa-users" }),
info.players ? info.players.length : "0"
];
}
return m("div", [
getPlayers(),
" ",
getLag(),
" ",
m("span", { class: "fa fa-clock" }),
timeIcon,
getHour(), ":", getMinute()
]);
}

View File

@ -1,53 +1,5 @@
/* exported WorldInfoDisplay */
var worldInfoRender = function(info){
var timeIcon = m("span", { class: "fa fa-sun", style: "color: orange;" });
if (info.time < 5500 || info.time > 19000) //0 - 24'000
timeIcon = m("span", { class: "fa fa-moon", style: "color: blue;" });
function getHour(){
return Math.floor(info.time/1000);
}
function getMinute(){
var min = Math.floor((info.time % 1000) / 1000 * 60);
return min > 10 ? min : "0" + min;
}
function getLag(){
var color = "green";
if (info.max_lag > 0.8)
color = "orange";
else if (info.max_lag > 1.2)
color = "red";
return [
m("span", { class: "fa fa-wifi", style: "color: " + color }),
parseInt(info.max_lag*1000),
" ms"
];
}
function getPlayers(){
return [
m("span", { class: "fa fa-users" }),
info.players ? info.players.length : "0"
];
}
return m("div", [
getPlayers(),
" ",
getLag(),
" ",
m("span", { class: "fa fa-clock" }),
timeIcon,
getHour(), ":", getMinute()
]);
};
import WorldStats from '../components/WorldStats.js';
// coord display
export default L.Control.extend({
@ -60,7 +12,7 @@ export default L.Control.extend({
var div = L.DomUtil.create('div', 'leaflet-bar leaflet-custom-display');
this.wsChannel.addListener("minetest-info", function(info){
m.render(div, worldInfoRender(info));
m.render(div, WorldStats(info));
});
return div;

View File

@ -1,5 +1,5 @@
export default {
export default [{
input: 'main.js',
output: {
file :'bundle.js',
@ -7,4 +7,12 @@ export default {
sourcemap: true,
compact: true
}
};
},{
input: 'stats.js',
output: {
file :'bundle-stats.js',
format: 'umd',
sourcemap: true,
compact: true
}
}];

9
static/js/stats.js Normal file
View File

@ -0,0 +1,9 @@
import WorldStats from './components/WorldStats.js';
import wsChannel from './WebSocketChannel.js';
wsChannel.connect();
wsChannel.addListener("minetest-info", function(info){
m.render(document.getElementById("app"), WorldStats(info));
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 662 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

22
static/stats.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- styles -->
<link rel="stylesheet" href="css/fontawesome.min.css"/>
<title>Minetest Mapserver stats</title>
</head>
<body>
<div id="app"></div>
<!-- libraries -->
<script src="js/lib/mithril.min.js"></script>
<!-- main module -->
<script src="js/stats.js" type="module"></script>
<!-- no modules -->
<script src="js/bundle-stats.js" nomodule></script>
</body>
</html>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 678 KiB

After

Width:  |  Height:  |  Size: 673 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 139 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 798 KiB

After

Width:  |  Height:  |  Size: 786 KiB

View File

@ -1,16 +1,14 @@
package tiledb
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"io/ioutil"
"mapserver/coords"
"os"
"strconv"
"sync"
)
var mutex = &sync.RWMutex{}
"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
)
func New(path string) (*TileDB, error) {
return &TileDB{
@ -40,9 +38,6 @@ func (this *TileDB) GetTile(pos *coords.TileCoords) ([]byte, error) {
timer := prometheus.NewTimer(tiledbLoadDuration)
defer timer.ObserveDuration()
mutex.RLock()
defer mutex.RUnlock()
fields := logrus.Fields{
"pos": pos,
}
@ -66,9 +61,6 @@ func (this *TileDB) SetTile(pos *coords.TileCoords, tile []byte) error {
timer := prometheus.NewTimer(tiledbSaveDuration)
defer timer.ObserveDuration()
mutex.Lock()
defer mutex.Unlock()
fields := logrus.Fields{
"pos": pos,
"size": len(tile),