Merge branch 'master' into threejs-wip

This commit is contained in:
NatureFreshMilk 2019-08-05 15:52:29 +02:00
commit 0f88d05ca3
365 changed files with 32719 additions and 17345 deletions

11
.gitignore vendored
View File

@ -1,2 +1,11 @@
output
.releasetoken .releasetoken
mapserver
world.mt
output
test-output
map.sqlite
mapserver.tiles
mapserver.sqlite
mapserver.sqlite-journal
mapserver.json
debug.txt

View File

@ -1,11 +1,14 @@
sudo: required language: go
sudo: false
services: go:
- docker - 1.11.x
install: os:
- docker build -t thomasrudin-mt/mapserver ./server - linux
deploy: script:
provider: script - go get github.com/mjibson/esc
script: echo - go generate
- go build
- go test

View File

@ -1,25 +1,78 @@
STATIC_VFS=vfs/static.go
OUT_DIR=output OUT_DIR=output
ENV=GO111MODULE=on
VERSION=git-$(shell git rev-parse HEAD) VERSION=git-$(shell git rev-parse HEAD)
all: builder_image $(OUT_DIR) $(MOD_ZIP)
# -ldflags="-X mapserver/app.Version=1.0"
GO_LDFLAGS=-ldflags "-linkmode external -extldflags -static -X mapserver/app.Version=$(VERSION)"
GO_LDFLAGS_WIN=-ldflags "-X mapserver/app.Version=$(VERSION)"
GO_BUILD=CGO_ENABLED=1 go build
BINARIES = $(OUT_DIR)/mapserver-linux-x86_64
BINARIES += $(OUT_DIR)/mapserver-linux-x86
BINARIES += $(OUT_DIR)/mapserver-windows-x86.exe
BINARIES += $(OUT_DIR)/mapserver-windows-x86-64.exe
BINARIES += $(OUT_DIR)/mapserver-linux-arm
all: $(STATIC_VFS)
go build
$(OUT_DIR):
mkdir $@
fmt:
go fmt ./...
test: $(OUT_DIR)
go generate
go build
go vet ./...
$(ENV) go test ./...
clean:
rm -rf $(STATIC_VFS) test-output
rm -rf $(OUT_DIR)
jshint:
jshint static/js/*.js static/js/util static/js/overlays static/js/search
$(STATIC_VFS):
go generate
$(OUT_DIR)/mapserver-linux-x86_64: $(OUT_DIR)
# native (linux x86_64)
GOOS=linux GOARCH=amd64 CC=x86_64-linux-gnu-gcc $(GO_BUILD) $(GO_LDFLAGS) -o $@
$(OUT_DIR)/mapserver-linux-x86: $(OUT_DIR)
# apt install gcc-8-i686-linux-gnu
GOOS=linux GOARCH=386 CC=i686-linux-gnu-gcc-7 $(GO_BUILD) $(GO_LDFLAGS) -o $@
$(OUT_DIR)/mapserver-windows-x86.exe: $(OUT_DIR)
# apt install gcc-mingw-w64
GOARCH=386 GOOS=windows CC=i686-w64-mingw32-gcc $(GO_BUILD) $(GO_LDFLAGS_WIN) -o $@
$(OUT_DIR)/mapserver-windows-x86-64.exe: $(OUT_DIR)
GOARCH=amd64 GOOS=windows CC=x86_64-w64-mingw32-gcc $(GO_BUILD) $(GO_LDFLAGS_WIN) -o $@
$(OUT_DIR)/mapserver-linux-arm: $(OUT_DIR)
# apt install gcc-5-arm-linux-gnueabihf
GOARCH=arm GOARM=7 CC=arm-linux-gnueabihf-gcc-5 $(GO_BUILD) $(GO_LDFLAGS) -o $@
release: builder_image $(OUT_DIR) $(MOD_ZIP)
# build all with the docker image # build all with the docker image
sudo docker run --rm -it\ sudo docker run --rm -it\
-v $(shell pwd)/server/:/app\ -v $(shell pwd):/app\
-v mapserver-volume:/root/go\ -v mapserver-volume:/root/go\
-w /app\ -w /app\
mapserver-builder\ mapserver-builder\
make test jshint all VERSION=$(VERSION) make test jshint release-all VERSION=$(VERSION)
# copy generated files to output dir # copy generated files to output dir
cp server/output/* $(OUT_DIR)/
builder_image: builder_image:
# build the docker image with all dependencies # build the docker image with all dependencies
$(MAKE) -C docker_builder build $(MAKE) -C docker_builder build
$(OUT_DIR): release-all: $(STATIC_VFS) $(BINARIES)
mkdir $@
clean:
rm -rf $(OUT_DIR)
$(MAKE) -C server clean

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"mapserver/blockaccessor"
"mapserver/colormapping" "mapserver/colormapping"
"mapserver/db" "mapserver/db"
"mapserver/eventbus" "mapserver/eventbus"
@ -23,10 +24,13 @@ type App struct {
TileDB *tiledb.TileDB TileDB *tiledb.TileDB
Settings settings.Settings Settings settings.Settings
BlockAccessor *mapblockaccessor.MapBlockAccessor MapBlockAccessor *mapblockaccessor.MapBlockAccessor
BlockAccessor *blockaccessor.BlockAccessor
Colormapping *colormapping.ColorMapping Colormapping *colormapping.ColorMapping
Mapblockrenderer *mapblockrenderer.MapBlockRenderer Mapblockrenderer *mapblockrenderer.MapBlockRenderer
Tilerenderer *tilerenderer.TileRenderer Tilerenderer *tilerenderer.TileRenderer
MediaRepo map[string][]byte
WebEventbus *eventbus.Eventbus WebEventbus *eventbus.Eventbus
} }

View File

@ -17,6 +17,7 @@ type Config struct {
EnableSearch bool `json:"enablesearch"` EnableSearch bool `json:"enablesearch"`
EnableInitialRendering bool `json:"enableinitialrendering"` EnableInitialRendering bool `json:"enableinitialrendering"`
EnableTransparency bool `json:"enabletransparency"` EnableTransparency bool `json:"enabletransparency"`
EnableMediaRepository bool `json:"enablemediarepository"`
Webdev bool `json:"webdev"` Webdev bool `json:"webdev"`
WebApi *WebApiConfig `json:"webapi"` WebApi *WebApiConfig `json:"webapi"`
Layers []*layer.Layer `json:"layers"` Layers []*layer.Layer `json:"layers"`
@ -60,7 +61,9 @@ type MapObjectConfig struct {
Fancyvend bool `json:"fancyvend"` Fancyvend bool `json:"fancyvend"`
ATM bool `json:"atm"` ATM bool `json:"atm"`
Train bool `json:"train"` Train bool `json:"train"`
TrainSignal bool `json:"trainsignal"`
Minecart bool `json:"minecart"` Minecart bool `json:"minecart"`
Locator bool `json:"locator"`
} }
type WebApiConfig struct { type WebApiConfig struct {
@ -137,9 +140,9 @@ func ParseConfig(filename string) (*Config, error) {
Travelnet: true, Travelnet: true,
MapserverPlayer: true, MapserverPlayer: true,
MapserverPOI: true, MapserverPOI: true,
MapserverLabel: false, MapserverLabel: true,
MapserverTrainline: true, MapserverTrainline: true,
MapserverBorder: false, MapserverBorder: true,
TileServerLegacy: true, TileServerLegacy: true,
Mission: true, Mission: true,
Jumpdrive: true, Jumpdrive: true,
@ -147,13 +150,15 @@ func ParseConfig(filename string) (*Config, error) {
Fancyvend: true, Fancyvend: true,
ATM: true, ATM: true,
Train: true, Train: true,
TrainSignal: true,
Minecart: false, Minecart: false,
Locator: false,
} }
mapblockaccessor := MapBlockAccessorConfig{ mapblockaccessor := MapBlockAccessorConfig{
Expiretime: "15s", Expiretime: "15s",
Purgetime: "30s", Purgetime: "30s",
MaxItems: 5000, MaxItems: 500,
} }
defaultoverlays := []string{ defaultoverlays := []string{
@ -170,6 +175,7 @@ func ParseConfig(filename string) (*Config, error) {
EnableSearch: true, EnableSearch: true,
EnableInitialRendering: true, EnableInitialRendering: true,
EnableTransparency: false, EnableTransparency: false,
EnableMediaRepository: false,
Webdev: false, Webdev: false,
WebApi: &webapi, WebApi: &webapi,
Layers: layers, Layers: layers,

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"mapserver/blockaccessor"
"mapserver/colormapping" "mapserver/colormapping"
"mapserver/db/postgres" "mapserver/db/postgres"
"mapserver/db/sqlite" "mapserver/db/sqlite"
@ -9,6 +10,7 @@ import (
"mapserver/mapblockrenderer" "mapserver/mapblockrenderer"
postgresobjdb "mapserver/mapobjectdb/postgres" postgresobjdb "mapserver/mapobjectdb/postgres"
sqliteobjdb "mapserver/mapobjectdb/sqlite" sqliteobjdb "mapserver/mapobjectdb/sqlite"
"mapserver/media"
"mapserver/params" "mapserver/params"
"mapserver/settings" "mapserver/settings"
"mapserver/tiledb" "mapserver/tiledb"
@ -70,20 +72,32 @@ func Setup(p params.ParamsType, cfg *Config) *App {
panic(err) panic(err)
} }
a.BlockAccessor = mapblockaccessor.NewMapBlockAccessor( // mapblock accessor
a.MapBlockAccessor = mapblockaccessor.NewMapBlockAccessor(
a.Blockdb, a.Blockdb,
expireDuration, purgeDuration, expireDuration, purgeDuration,
cfg.MapBlockAccessorCfg.MaxItems) cfg.MapBlockAccessorCfg.MaxItems)
// block accessor
a.BlockAccessor = blockaccessor.New(a.MapBlockAccessor)
//color mapping //color mapping
a.Colormapping = colormapping.NewColorMapping() a.Colormapping = colormapping.NewColorMapping()
//load default colors colorfiles := []string{
count, err := a.Colormapping.LoadVFSColors(false, "/colors.txt") //https://daconcepts.com/vanessa/hobbies/minetest/colors.txt
if err != nil { "/colors/custom.txt",
panic(err) "/colors/vanessa.txt",
"/colors/advtrains.txt",
"/colors/scifi_nodes.txt",
}
for _, colorfile := range colorfiles {
_, err := a.Colormapping.LoadVFSColors(false, colorfile)
if err != nil {
panic(err.Error() + " file:" + colorfile)
}
} }
logrus.WithFields(logrus.Fields{"count": count}).Info("Loaded default colors")
//load provided colors, if available //load provided colors, if available
info, err := os.Stat("colors.txt") info, err := os.Stat("colors.txt")
@ -95,7 +109,7 @@ func Setup(p params.ParamsType, cfg *Config) *App {
panic(err) panic(err)
} }
count, err = a.Colormapping.LoadBytes(data) count, err := a.Colormapping.LoadBytes(data)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -105,7 +119,7 @@ func Setup(p params.ParamsType, cfg *Config) *App {
} }
//mapblock renderer //mapblock renderer
a.Mapblockrenderer = mapblockrenderer.NewMapBlockRenderer(a.BlockAccessor, a.Colormapping) a.Mapblockrenderer = mapblockrenderer.NewMapBlockRenderer(a.MapBlockAccessor, a.Colormapping)
//mapserver database //mapserver database
if a.Worldconfig[worldconfig.CONFIG_PSQL_MAPSERVER] != "" { if a.Worldconfig[worldconfig.CONFIG_PSQL_MAPSERVER] != "" {
@ -143,5 +157,19 @@ func Setup(p params.ParamsType, cfg *Config) *App {
a.Config.Layers, a.Config.Layers,
) )
//create media repo
repo := make(map[string][]byte)
if a.Config.EnableMediaRepository {
mediasize, _ := media.ScanDir(repo, ".", []string{"mapserver.tiles", ".git"})
fields := logrus.Fields{
"count": len(repo),
"bytes": mediasize,
}
logrus.WithFields(fields).Info("Created media repository")
}
a.MediaRepo = repo
return &a return &a
} }

View File

@ -0,0 +1,43 @@
package blockaccessor
import (
"mapserver/coords"
"mapserver/mapblockaccessor"
)
func New(mba *mapblockaccessor.MapBlockAccessor) *BlockAccessor {
return &BlockAccessor{mba: mba}
}
type BlockAccessor struct {
mba *mapblockaccessor.MapBlockAccessor
}
type Block struct {
Name string
//TODO: param1, param2
}
func (this *BlockAccessor) GetBlock(x, y, z int) (*Block, error) {
mbc := coords.NewMapBlockCoordsFromBlock(x, y, z)
mapblock, err := this.mba.GetMapBlock(mbc)
if err != nil {
return nil, err
}
if mapblock == nil {
return nil, nil
}
relx := x % 16
rely := y % 16
relz := z % 16
block := Block{
Name: mapblock.GetNodeName(relx, rely, relz),
}
return &block, nil
}

View File

@ -0,0 +1,59 @@
package blockaccessor
import (
"fmt"
"io/ioutil"
"mapserver/db/sqlite"
"mapserver/mapblockaccessor"
"mapserver/testutils"
"os"
"testing"
"time"
"github.com/sirupsen/logrus"
)
func TestSimpleAccess(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
tmpfile, err := ioutil.TempFile("", "TestMigrate.*.sqlite")
if err != nil {
panic(err)
}
defer os.Remove(tmpfile.Name())
testutils.CreateTestDatabase(tmpfile.Name())
a, err := sqlite.New(tmpfile.Name())
if err != nil {
panic(err)
}
err = a.Migrate()
if err != nil {
panic(err)
}
mba := mapblockaccessor.NewMapBlockAccessor(a, 500*time.Millisecond, 1000*time.Millisecond, 1000)
if mba == nil {
t.Fatal("Mapblockaccessor is nil")
}
ba := New(mba)
if ba == nil {
t.Fatal("blockaccessor is nil")
}
block, err := ba.GetBlock(0, 2, 0)
if err != nil {
panic(err)
}
if block == nil {
t.Fatal("block is nil")
}
fmt.Println(block.Name)
}

View File

@ -14,9 +14,17 @@ import (
type ColorMapping struct { type ColorMapping struct {
colors map[string]*color.RGBA colors map[string]*color.RGBA
extendedpaletteblock map[string]bool
extendedpalette *Palette
}
func (m *ColorMapping) GetColor(name string, param2 int) *color.RGBA {
//TODO: list of node->palette
if m.extendedpaletteblock[name] {
// param2 coloring
return m.extendedpalette.GetColor(param2)
} }
func (m *ColorMapping) GetColor(name string) *color.RGBA {
return m.colors[name] return m.colors[name]
} }
@ -86,18 +94,46 @@ func (m *ColorMapping) LoadBytes(buffer []byte) (int, error) {
} }
func (m *ColorMapping) LoadVFSColors(useLocal bool, filename string) (int, error) { func (m *ColorMapping) LoadVFSColors(useLocal bool, filename string) (int, error) {
buffer, err := vfs.FSByte(useLocal, "/colors.txt") buffer, err := vfs.FSByte(useLocal, filename)
if err != nil { if err != nil {
return 0, err return 0, err
} }
log.WithFields(logrus.Fields{"size": len(buffer), log.WithFields(logrus.Fields{"size": len(buffer),
"filename": filename, "filename": filename,
"useLocal": useLocal}).Info("Loading default colors") "useLocal": useLocal}).Info("Loading colors")
return m.LoadBytes(buffer) return m.LoadBytes(buffer)
} }
func NewColorMapping() *ColorMapping { func NewColorMapping() *ColorMapping {
return &ColorMapping{colors: make(map[string]*color.RGBA)} extendedpalette, err := NewPalette(vfs.FSMustByte(false, "/pics/unifieddyes_palette_extended.png"))
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(bytes.NewReader(vfs.FSMustByte(false, "/extended_palette.txt")))
extendedpaletteblock := make(map[string]bool)
if err != nil {
panic(err)
}
for scanner.Scan() {
txt := strings.Trim(scanner.Text(), " ")
if len(txt) == 0 {
//empty
continue
}
extendedpaletteblock[txt] = true
}
return &ColorMapping{
colors: make(map[string]*color.RGBA),
extendedpaletteblock: extendedpaletteblock,
extendedpalette: extendedpalette,
}
} }

View File

@ -0,0 +1,38 @@
package colormapping
import (
"testing"
)
func TestNewMapping(t *testing.T) {
m := NewColorMapping()
_, err := m.LoadVFSColors(false, "/colors/vanessa.txt")
if err != nil {
t.Fatal(err)
}
_, err = m.LoadVFSColors(false, "/colors/scifi_nodes.txt")
if err != nil {
t.Fatal(err)
}
c := m.GetColor("scifi_nodes:blacktile2", 0)
if c == nil {
panic("no color")
}
c = m.GetColor("default:river_water_flowing", 0)
if c == nil {
panic("no color")
}
c = m.GetColor("unifiedbricks:brickblock_multicolor_dark", 100)
if c == nil {
panic("no color")
}
//if c.A != 128 {
// panic("wrong alpha")
//}
}

45
colormapping/palette.go Normal file
View File

@ -0,0 +1,45 @@
package colormapping
import (
"bytes"
"image/color"
"image/png"
)
type Palette struct {
colors map[int]*color.RGBA
}
func NewPalette(imagefile []byte) (*Palette, error) {
palette := &Palette{
colors: make(map[int]*color.RGBA),
}
reader := bytes.NewReader(imagefile)
img, err := png.Decode(reader)
if err != nil {
return nil, err
}
bounds := img.Bounds()
index := 0
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
c := img.At(x, y)
r, g, b, a := c.RGBA()
//fmt.Println("x ", x, " y ", y, " Index: ", index, " Color ", c)
palette.colors[index] = &color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
index++
}
}
return palette, nil
}
func (m *Palette) GetColor(param2 int) *color.RGBA {
return m.colors[param2]
}

View File

@ -0,0 +1,30 @@
package colormapping
import (
"fmt"
"io/ioutil"
"testing"
)
func TestNewPalette(t *testing.T) {
data, err := ioutil.ReadFile("./testdata/unifieddyes_palette_extended.png")
if err != nil {
t.Fatal(err)
}
palette, err := NewPalette(data)
if err != nil {
t.Fatal(err)
}
color := palette.GetColor(0)
if color == nil {
t.Fatal("color not found!")
}
fmt.Println(color)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

View File

@ -1,5 +1,9 @@
package coords package coords
import (
"math"
)
type MapBlockCoords struct { type MapBlockCoords struct {
X int `json:"x"` X int `json:"x"`
Y int `json:"y"` Y int `json:"y"`
@ -10,6 +14,14 @@ func NewMapBlockCoords(x, y, z int) *MapBlockCoords {
return &MapBlockCoords{X: x, Y: y, Z: z} return &MapBlockCoords{X: x, Y: y, Z: z}
} }
func NewMapBlockCoordsFromBlock(x, y, z int) *MapBlockCoords {
return &MapBlockCoords{
X: int(math.Floor(float64(x) / 16)),
Y: int(math.Floor(float64(y) / 16)),
Z: int(math.Floor(float64(z) / 16)),
}
}
type MapBlockRange struct { type MapBlockRange struct {
Pos1, Pos2 *MapBlockCoords Pos1, Pos2 *MapBlockCoords
} }

View File

@ -0,0 +1,26 @@
package coords
import (
"testing"
)
func TestNewMapBlockCoordsFromBlock(t *testing.T) {
c := NewMapBlockCoordsFromBlock(1, 1, 1)
if c.X != 0 || c.Y != 0 || c.Z != 0 {
t.Fatal("mismatch", c)
}
c = NewMapBlockCoordsFromBlock(16, 1, 1)
if c.X != 1 || c.Y != 0 || c.Z != 0 {
t.Fatal("mismatch", c)
}
c = NewMapBlockCoordsFromBlock(16, 1, -1)
if c.X != 1 || c.Y != 0 || c.Z != -1 {
t.Fatal("mismatch", c)
}
}

24
doc/building.md Normal file
View File

@ -0,0 +1,24 @@
# Building the mapserver
Instructions to build the mapserver from source
## Build dependencies
* go >= 1.11
Ubuntu install: https://github.com/golang/go/wiki/Ubuntu
## Compile
```bash
# generate the static web files
go generate
# build the binary for the current playtform
go build
# (optionally) run the unit-tests
go test ./...
```

View File

@ -1,6 +1,31 @@
# Changelog # Changelog
## Next
* Train overlay decluttering
## 3.0.0
* Javascript ES6 frontend
* Param2 coloring
* More player infos (RTT)
* Search ability for LCD displays
* City border support
* Label support (street, city names, regions)
* Various bugfixes
## 2.2.0
* Added ATM overlay
* Added locator overlay
* Add ability for bone-owner search
* Separate mapserver_mod into own repository
## 2.1.1
* force tcp v4 for listener
## 2.1.0 ## 2.1.0
* Added search bar * Added search bar

View File

@ -3,7 +3,7 @@
**Please make a backup of your world in case something goes wrong** **Please make a backup of your world in case something goes wrong**
* Download the binary from the [releases](https://github.com/thomasrudin-mt/mapserver/releases) for your architecture and platform * Download the binary from the [releases](https://github.com/minetest-tools/mapserver/releases) for your architecture and platform
* Drop the binary into your world folder (the one with the `world.mt` and `map.sqlite` files) * Drop the binary into your world folder (the one with the `world.mt` and `map.sqlite` files)
* Start the mapserver via command-line: `./mapserver` or `./mapserver.exe` * Start the mapserver via command-line: `./mapserver` or `./mapserver.exe`
* Point your browser to `http://127.0.0.1:8080` * Point your browser to `http://127.0.0.1:8080`

View File

@ -11,31 +11,31 @@
* sam.png * sam.png
* heart.png * heart.png
* default_tool_mesepick.png * default_tool_mesepick.png
** License: CC BY-SA 3.0 * License: CC BY-SA 3.0
** Source: [minetest_game](https://github.com/minetest/minetest_game) * Source: [minetest_game](https://github.com/minetest/minetest_game)
* travelnet_inv.png * travelnet_inv.png
** License: CC BY-SA 3.0 * License: CC BY-SA 3.0
** Source: [travelnet](https://github.com/Sokomine/travelnet) * Source: [travelnet](https://github.com/Sokomine/travelnet)
* technic_admin_anchor.png * technic_admin_anchor.png
* technic_hv_nuclear_reactor_core.png * technic_hv_nuclear_reactor_core.png
* technic_water_mill_top_active.png * technic_water_mill_top_active.png
** LGPL, V2 * LGPL, V2
** Source: [technic](https://github.com/minetest-mods/technic) * Source: [technic](https://github.com/minetest-mods/technic)
* lcd_lcd.png * lcd_lcd.png
** WTFPL * WTFPL
** Source: [digilines](https://github.com/minetest-mods/digilines) * Source: [digilines](https://github.com/minetest-mods/digilines)
* jeija_luacontroller_top.png * jeija_luacontroller_top.png
* jeija_luacontroller_burnt_top.png * jeija_luacontroller_burnt_top.png
** CC-BY-SA-3.0 * CC-BY-SA-3.0
** Source [mesecons](https://github.com/minetest-mods/mesecons) * Source [mesecons](https://github.com/minetest-mods/mesecons)
* digiterms_beige_front.png * digiterms_beige_front.png
** License: CC BY-SA 3.0 * License: CC BY-SA 3.0
** Source [digiterms](https://github.com/Pyrollo/digiterms) * Source [digiterms](https://github.com/Pyrollo/digiterms)
* advtrains_detailed_engine_steam_inv.png * advtrains_detailed_engine_steam_inv.png
@ -48,13 +48,27 @@
* advtrains_wagon_japan_inv.png * advtrains_wagon_japan_inv.png
* advtrains_wagon_tank_inv.png * advtrains_wagon_tank_inv.png
* advtrains_wagon_wood_inv.png * advtrains_wagon_wood_inv.png
** License: CC BY-SA 3.0 * advtrains_signal_on.png
** Source [advtrains](http://advtrains.bleipb.de/) * advtrains_signal_off.png
* License: CC BY-SA 3.0
* Source [advtrains](http://advtrains.bleipb.de/)
* minecart_logo.png * minecart_logo.png
** License: CC0 * License: CC0
** Source [minecart](https://github.com/joe7575/minecart) * Source [minecart](https://github.com/joe7575/minecart)
* mapserver_gold_block.png * mapserver_gold_block.png
** License: CC BY-SA 3.0 * License: CC BY-SA 3.0
** Source [minetest_game](https://github.com/minetest/minetest_game) * Source [minetest_game](https://github.com/minetest/minetest_game)
* atm_front_wt.png
* atm_front.png
* atm2_front.png
* atm3_front.png
* WTFPL
* Source: http://git.gpcf.eu/?p=atm.git;a=summary
* unifieddyes_palette_extended.png
* GPL 2.0
* Source: https://gitlab.com/VanessaE/unifieddyes

View File

@ -1,7 +1,7 @@
# Mapserver mod # Mapserver mod
* Repository: https://github.com/thomasrudin/mapserver_mod * Repository: https://github.com/minetest-tools/mapserver_mod
If the `mapserver-mod` is installed and configured If the `mapserver-mod` is installed and configured
you get more realtime-data from within your minetest-world: you get more realtime-data from within your minetest-world:
@ -15,8 +15,7 @@ You can use the `mapserver-mod` either passive or active:
## Installing and configuring the bridge-mod ## Installing and configuring the bridge-mod
The mod itself is available in the git [repo](../mapserver_mod) Download or clone from https://github.com/minetest-tools/mapserver_mod
or as a zip package in the [releases](../../../releases)
If you want to enable craftable mapobjects (poi, labels, trainblocks, etc) you If you want to enable craftable mapobjects (poi, labels, trainblocks, etc) you
can enable the setting in your `minetest.conf` (defaults to false) can enable the setting in your `minetest.conf` (defaults to false)
@ -25,6 +24,13 @@ can enable the setting in your `minetest.conf` (defaults to false)
mapserver.enable_crafting = true mapserver.enable_crafting = true
``` ```
The update interval of the players on the map can be changed with:
```
mapserver.send_interval = 1
```
Default is `2`, means that the player, time and lag info get sent every 2 seconds.
## Passive mode ## Passive mode
You don't have to set up anything, passive mode is the default. You don't have to set up anything, passive mode is the default.

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
doc/pics/border.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
doc/pics/labels.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
doc/pics/labels2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
doc/pics/labels3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

BIN
doc/pics/layers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
doc/pics/lcd_display.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
doc/pics/markers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
doc/pics/protector.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

BIN
doc/pics/shops.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
doc/pics/shopsearch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
doc/pics/trainlines.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
doc/pics/travelnet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

820
doc/wip/advtrains.json Normal file
View File

@ -0,0 +1,820 @@
{
"147592" : {
"name" : "Section 147592",
"route" : {
"entry" : {
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -902
},
"s" : 2
},
"first" : true,
"origin" : {
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -902
},
"s" : 2
},
"rsn" : "Route 'x4' from signal 'Signal at (-1346,6501,-902)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1431,
"y" : 6501,
"z" : -902
},
"s" : 1
},
{
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -902
},
"s" : 2
}
],
"trains" : null
},
"202775" : {
"name" : "Section 202775",
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -905
},
"s" : 2
},
{
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -902
},
"s" : 1
}
],
"trains" : [ "347062" ]
},
"245036" : {
"name" : "Section 245036",
"route" : {
"entry" : {
"p" : {
"x" : -907,
"y" : 2,
"z" : 310
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -907,
"y" : 2,
"z" : 310
},
"s" : 1
},
"rsn" : "Route 'x' from signal 'Signal at (-907,2,310)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -907,
"y" : 2,
"z" : 320
},
"s" : 2
},
{
"p" : {
"x" : -907,
"y" : 2,
"z" : 310
},
"s" : 1
}
]
},
"287775" : {
"name" : "Section 287775",
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1877,
"y" : 42,
"z" : 395
},
"s" : 1
},
{
"p" : {
"x" : -1066,
"y" : 42,
"z" : 395
},
"s" : 2
}
],
"trains" : [ "506728" ]
},
"308300" : {
"name" : "Section 308300",
"route" : {
"entry" : {
"p" : {
"x" : -2124,
"y" : 28,
"z" : 562
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -2124,
"y" : 28,
"z" : 562
},
"s" : 1
},
"rsn" : "Route 'x' from signal 'Signal at (-2124,28,562)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -2124,
"y" : 28,
"z" : 593
},
"s" : 2
},
{
"p" : {
"x" : -2124,
"y" : 28,
"z" : 562
},
"s" : 1
}
],
"trains" : null
},
"332248" : {
"name" : "Section 332248",
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -911,
"y" : 2,
"z" : 321
},
"s" : 2
},
{
"p" : {
"x" : -911,
"y" : 2,
"z" : 312
},
"s" : 2
}
],
"trains" : [ "525416" ]
},
"380370" : {
"name" : "Section 380370",
"tc_breaks" : [
{
"p" : {
"x" : -1879,
"y" : 42,
"z" : 392
},
"s" : 1
},
{
"p" : {
"x" : -1080,
"y" : 42,
"z" : 392
},
"s" : 2
}
],
"trains" : null
},
"396699" : {
"name" : "Section 396699",
"tc_breaks" : [
{
"p" : {
"x" : -2127,
"y" : 28,
"z" : 595
},
"s" : 2
},
{
"p" : {
"x" : -2127,
"y" : 28,
"z" : 562
},
"s" : 1
}
],
"trains" : null
},
"424731" : {
"name" : "Section 424731",
"route" : {
"entry" : {
"p" : {
"x" : -2088,
"y" : 21,
"z" : 774
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -2088,
"y" : 21,
"z" : 774
},
"s" : 1
},
"rsn" : "Route 'TR-JOIN' from signal 'Signal at (-2088,21,774)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -2103,
"y" : 21,
"z" : 772
},
"s" : 2
},
{
"p" : {
"x" : -2088,
"y" : 21,
"z" : 774
},
"s" : 1
}
],
"trains" : null
},
"448317" : {
"name" : "Section 448317",
"tc_breaks" : [
{
"p" : {
"x" : -907,
"y" : 2,
"z" : 320
},
"s" : 1
},
{
"p" : {
"x" : -925,
"y" : 2,
"z" : 339
},
"s" : 2
},
{
"p" : {
"x" : -927,
"y" : 2,
"z" : 335
},
"s" : 2
},
{
"p" : {
"x" : -911,
"y" : 2,
"z" : 321
},
"s" : 1
}
],
"trains" : [ "525416" ]
},
"495941" : {
"name" : "Section 495941",
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1927,
"y" : 42,
"z" : 392
},
"s" : 1
},
{
"p" : {
"x" : -1877,
"y" : 42,
"z" : 395
},
"s" : 2
}
],
"trains" : [ "238799" ]
},
"509928" : {
"name" : "Section 509928",
"route" : {
"entry" : {
"p" : {
"x" : -1045,
"y" : 42,
"z" : 392
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -1045,
"y" : 42,
"z" : 392
},
"s" : 1
},
"rsn" : "Route 'x' from signal 'Signal at (-1045,42,392)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1066,
"y" : 42,
"z" : 395
},
"s" : 1
},
{
"p" : {
"x" : -1021,
"y" : 42,
"z" : 395
},
"s" : 1
},
{
"p" : {
"x" : -1045,
"y" : 42,
"z" : 392
},
"s" : 1
}
],
"trains" : null
},
"594356" : {
"name" : "Section 594356",
"tc_breaks" : [
{
"p" : {
"x" : -2124,
"y" : 28,
"z" : 593
},
"s" : 1
},
{
"p" : {
"x" : -2127,
"y" : 28,
"z" : 595
},
"s" : 1
}
],
"trains" : [ "830099" ]
},
"614720" : {
"name" : "Section 614720",
"route" : {
"entry" : {
"p" : {
"x" : -1927,
"y" : 42,
"z" : 392
},
"s" : 2
},
"first" : true,
"origin" : {
"p" : {
"x" : -1927,
"y" : 42,
"z" : 392
},
"s" : 2
},
"rsn" : "Route 'x' from signal 'Signal at (-1927,42,392)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -2124,
"y" : 28,
"z" : 562
},
"s" : 2
},
{
"p" : {
"x" : -1927,
"y" : 42,
"z" : 392
},
"s" : 2
}
],
"trains" : null
},
"623523" : {
"name" : "Section 623523",
"tc_breaks" : [
{
"p" : {
"x" : -2127,
"y" : 28,
"z" : 562
},
"s" : 2
},
{
"p" : {
"x" : -1924,
"y" : 42,
"z" : 390
},
"s" : 2
}
],
"trains" : null
},
"651629" : {
"name" : "Section 651629",
"tc_breaks" : [
{
"p" : {
"x" : -1924,
"y" : 42,
"z" : 390
},
"s" : 1
},
{
"p" : {
"x" : -1879,
"y" : 42,
"z" : 392
},
"s" : 2
}
],
"trains" : null
},
"676937" : {
"name" : "Section 676937",
"tc_breaks" : [
{
"p" : {
"x" : -2088,
"y" : 21,
"z" : 774
},
"s" : 2
},
{
"p" : {
"x" : -2101,
"y" : 22,
"z" : 787
},
"s" : 2
}
],
"trains" : [ "747089", "358528" ]
},
"778640" : {
"name" : "Section 778640",
"route" : {
"entry" : {
"p" : {
"x" : -1432,
"y" : 6501,
"z" : -905
},
"s" : 2
},
"first" : true,
"origin" : {
"p" : {
"x" : -1432,
"y" : 6501,
"z" : -905
},
"s" : 2
},
"rsn" : "Route 'x5' from signal 'Signal at (-1432,6501,-905)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1432,
"y" : 6501,
"z" : -905
},
"s" : 2
},
{
"p" : {
"x" : -1346,
"y" : 6501,
"z" : -905
},
"s" : 1
}
],
"trains" : null
},
"819070" : {
"name" : "Section 819070",
"route" : {
"entry" : {
"p" : {
"x" : -1080,
"y" : 42,
"z" : 392
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -1080,
"y" : 42,
"z" : 392
},
"s" : 1
},
"rsn" : "Route 'x' from signal 'Signal at (-1080,42,392)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1045,
"y" : 42,
"z" : 392
},
"s" : 2
},
{
"p" : {
"x" : -1080,
"y" : 42,
"z" : 392
},
"s" : 1
}
],
"trains" : null
},
"819379" : {
"name" : "Section 819379",
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1431,
"y" : 6501,
"z" : -902
},
"s" : 2
},
{
"p" : {
"x" : -1432,
"y" : 6501,
"z" : -905
},
"s" : 1
}
],
"trains" : [ "279633" ]
},
"853427" : {
"name" : "Section 853427",
"route" : {
"entry" : {
"p" : {
"x" : -2109,
"y" : 22,
"z" : 787
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -2109,
"y" : 22,
"z" : 787
},
"s" : 1
},
"rsn" : "Route 'TR01' from signal 'Signal at (-2109,22,787)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -2109,
"y" : 22,
"z" : 787
},
"s" : 1
},
{
"p" : {
"x" : -2101,
"y" : 22,
"z" : 787
},
"s" : 1
}
],
"trains" : null
},
"908240" : {
"name" : "Section 908240",
"route" : {
"entry" : {
"p" : {
"x" : -1027,
"y" : 2,
"z" : 335
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -1027,
"y" : 2,
"z" : 335
},
"s" : 1
},
"rsn" : "Route 'x' from signal 'Signal at (-1027,2,335)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1027,
"y" : 2,
"z" : 335
},
"s" : 1
},
{
"p" : {
"x" : -927,
"y" : 2,
"z" : 335
},
"s" : 1
}
]
},
"937130" : {
"name" : "Section 937130",
"tc_breaks" : [
{
"p" : {
"x" : -2063,
"y" : 19,
"z" : 806
},
"s" : 2
},
{
"p" : {
"x" : -2085,
"y" : 22,
"z" : 798
},
"s" : 1
}
],
"trains" : null
},
"963095" : {
"name" : "Section 963095",
"route" : {
"entry" : {
"p" : {
"x" : -925,
"y" : 2,
"z" : 339
},
"s" : 1
},
"first" : true,
"origin" : {
"p" : {
"x" : -925,
"y" : 2,
"z" : 339
},
"s" : 1
},
"rsn" : "Route 'y' from signal 'Signal at (-925,2,339)', segment #1"
},
"route_post" : {
"locks" : null
},
"tc_breaks" : [
{
"p" : {
"x" : -1026,
"y" : 2,
"z" : 339
},
"s" : 1
},
{
"p" : {
"x" : -925,
"y" : 2,
"z" : 339
},
"s" : 1
}
],
"trains" : null
}
}

View File

@ -0,0 +1,10 @@
minetest.after(2, function()
local world_path = minetest.get_worldpath()
local file, err = io.open(world_path .. "advtrains.json", "w")
local data = advtrains.interlocking.db.save()
local json = minetest.write_json(data.ts, true)
file:write(json)
file:close()
end)

View File

@ -0,0 +1,28 @@
minetest.after(2, function()
local world_path = minetest.get_worldpath()
local file, err = io.open(world_path .. "advtrains_tcbs.json", "w")
local data = advtrains.interlocking.db.save()
local tmp = {}
for _, entry in pairs(data.tcbs) do
local tcb = entry[1]
-- print(dump(tcb))
if tcb.signal then
table.insert(tmp, {
signal = tcb.signal,
aspect = tcb.aspect,
signal_name = tcb.signal_name
})
end
end
local json, err = minetest.write_json(tmp, true)
if err then
error(err)
end
file:write(json)
file:close()
end)

222
doc/wip/advtrains_tcbs.json Normal file
View File

@ -0,0 +1,222 @@
[
{
"signal" : {
"x" : -2103,
"y" : 22,
"z" : 790
},
"signal_name" : "Signal at (-2109,22,787)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : -2125,
"y" : 28,
"z" : 562
},
"signal_name" : "Signal at (-2124,28,562)"
},
{
"signal" : {
"x" : 10003,
"y" : 9699,
"z" : 15558
},
"signal_name" : "Signal at (10003,9696,15559)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : 10000,
"y" : 9699,
"z" : 15391
},
"signal_name" : "Signal at (10000,9696,15391)"
},
{
"signal" : {
"x" : -2087,
"y" : 21,
"z" : 775
},
"signal_name" : "Signal at (-2088,21,774)"
},
{
"signal" : {
"x" : -1323,
"y" : 42,
"z" : 393
},
"signal_name" : "Signal at (-1323,42,392)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : 10003,
"y" : 9699,
"z" : 15027
},
"signal_name" : "Signal at (10003,9696,15027)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : -1044,
"y" : 42,
"z" : 393
},
"signal_name" : "Signal at (-1045,42,392)"
},
{
"signal" : {
"x" : -1019,
"y" : 42,
"z" : 396
},
"signal_name" : "Signal at (-1021,42,395)"
},
{
"signal" : {
"x" : -2428,
"y" : 18,
"z" : 3954
},
"signal_name" : "Signal at (-2426,18,3953)"
},
{
"signal" : {
"x" : -1875,
"y" : 42,
"z" : 393
},
"signal_name" : "Signal at (-1875,42,392)"
},
{
"signal" : {
"x" : -1925,
"y" : 42,
"z" : 388
},
"signal_name" : "Signal at (-1924,42,390)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : -1079,
"y" : 42,
"z" : 393
},
"signal_name" : "Signal at (-1080,42,392)"
},
{
"signal" : {
"x" : 10003,
"y" : 9699,
"z" : 15160
},
"signal_name" : "Signal at (10003,9696,15160)"
},
{
"signal" : {
"x" : -1292,
"y" : 42,
"z" : 393
},
"signal_name" : "Signal at (-1292,42,392)"
},
{
"aspect" : {
"dst" : {
"free" : true,
"speed" : -1
},
"info" : null,
"main" : {
"free" : true,
"speed" : -1
},
"shunt" : {
"free" : false
}
},
"signal" : {
"x" : -2125,
"y" : 28,
"z" : 595
},
"signal_name" : "Signal at (-2124,28,593)"
},
{
"signal" : {
"x" : 10003,
"y" : 9699,
"z" : 15249
},
"signal_name" : "Signal at (10003,9696,15249)"
}
]

View File

@ -84,6 +84,11 @@ func (mb *MapBlock) GetNodeId(x, y, z int) int {
return mb.Mapdata.ContentId[pos] return mb.Mapdata.ContentId[pos]
} }
func (mb *MapBlock) GetParam2(x, y, z int) int {
pos := getNodePos(x, y, z)
return mb.Mapdata.Param2[pos]
}
func (mb *MapBlock) GetNodeName(x, y, z int) string { func (mb *MapBlock) GetNodeName(x, y, z int) string {
id := mb.GetNodeId(x, y, z) id := mb.GetNodeId(x, y, z)
return mb.BlockMapping[id] return mb.BlockMapping[id]

View File

@ -39,8 +39,8 @@ func parseMapdata(mapblock *MapBlock, data []byte) (int, error) {
for i := 0; i < 4096; i++ { for i := 0; i < 4096; i++ {
mapd.ContentId[i] = readU16(rawdata, i*2) mapd.ContentId[i] = readU16(rawdata, i*2)
mapd.Param1[i] = readU8(rawdata, (i*2)+2) mapd.Param1[i] = readU8(rawdata, (4096*2)+i)
mapd.Param2[i] = readU8(rawdata, (i*2)+3) //TODO: last item has wrong value mapd.Param2[i] = readU8(rawdata, (4096*3)+i)
} }
return cr.Count, nil return cr.Count, nil

Some files were not shown because too many files have changed in this diff Show More