Support for configuration file in webmapper

This commit is contained in:
Sascha L. Teichmann 2022-03-01 23:30:31 +01:00
parent 25e62b3a8b
commit e6ea8fe3d1
4 changed files with 115 additions and 75 deletions

81
cmd/mtwebmapper/config.go Normal file
View File

@ -0,0 +1,81 @@
// Copyright 2014, 2015, 2022 by Sascha L. Teichmann
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package main
import (
"flag"
"time"
"github.com/BurntSushi/toml"
"bitbucket.org/s_l_teichmann/mtsatellite/common"
)
type config struct {
WebPort int `toml:"web_port"`
WebHost string `toml:"web_host"`
WebDir string `toml:"web"`
MapDir string `toml:"map"`
RedisPort int `toml:"redis_port"`
RedisHost string `toml:"redis_host"`
ColorsFile string `toml:"update_hosts"`
BGColor string `toml:"background"`
Workers int `toml:"workers"`
Transparent bool `toml:"transparent"`
TransparentDim float64 `toml:"transparent_dim"`
UpdateHosts string `toml:"update_hosts"`
Websockets bool `toml:"websockets"`
PlayersFIFO string `toml:"players"`
YMin int `toml:"ymin"`
YMax int `toml:"ymax"`
ChangeDuration time.Duration `toml:"change_duration"`
}
func (cfg *config) bindFlags() {
defaultBgColor := common.ColorToHex(common.BackgroundColor)
flag.IntVar(&cfg.WebPort, "web-port", 8808, "port of the web server")
flag.IntVar(&cfg.WebPort, "p", 8808, "port of the web server (shorthand)")
flag.StringVar(&cfg.WebHost, "web-host", "localhost", "address to bind web server")
flag.StringVar(&cfg.WebHost, "h", "localhost", "address to bind web server(shorthand)")
flag.StringVar(&cfg.WebDir, "web", "web", "static served web files.")
flag.StringVar(&cfg.WebDir, "w", "web", "static served web files (shorthand)")
flag.StringVar(&cfg.MapDir, "map", "map", "directory of prerendered tiles")
flag.StringVar(&cfg.MapDir, "m", "map", "directory of prerendered tiles (shorthand)")
flag.StringVar(&cfg.UpdateHosts, "update-hosts", "localhost",
"';' separated list of hosts which are allowed to send map update requests")
flag.StringVar(&cfg.UpdateHosts, "u", "localhost",
"';' separated list of hosts which are allowed to send map update requests (shorthand)")
flag.StringVar(&cfg.RedisHost, "redis-host", "", "address of the backend Redis server")
flag.StringVar(&cfg.RedisHost, "rh", "", "address of the backend Redis server (shorthand)")
flag.IntVar(&cfg.RedisPort, "redis-port", 6379, "port of the backend Redis server")
flag.IntVar(&cfg.RedisPort, "rp", 6379, "port of the backend Redis server (shorthand)")
flag.IntVar(&cfg.Workers, "workers", 1, "number of workers to render tiles")
flag.StringVar(&cfg.ColorsFile, "colors", "colors.txt", "colors used to render map tiles.")
flag.StringVar(&cfg.ColorsFile, "c", "colors.txt", "colors used to render map tiles (shorthand).")
flag.StringVar(&cfg.BGColor, "background", defaultBgColor, "background color")
flag.StringVar(&cfg.BGColor, "bg", defaultBgColor, "background color (shorthand)")
flag.BoolVar(&cfg.Transparent, "transparent", false, "Render transparent blocks.")
flag.BoolVar(&cfg.Transparent, "t", false, "Render transparent blocks (shorthand).")
flag.Float64Var(&cfg.TransparentDim,
"transparent-dim", common.DefaultTransparentDim*100.0,
"Extra dimming of transparent nodes each depth meter in percent.")
flag.Float64Var(&cfg.TransparentDim,
"td", common.DefaultTransparentDim*100.0,
"Extra dimming of transparent nodes each depth meter in percent. (shorthand)")
flag.BoolVar(&cfg.Websockets, "websockets", false, "Forward tile changes to clients via websockets.")
flag.BoolVar(&cfg.Websockets, "ws", false, "Forward tile changes to clients via websockets (shorthand).")
flag.StringVar(&cfg.PlayersFIFO, "players", "", "Path to FIFO file to read active players from.")
flag.StringVar(&cfg.PlayersFIFO, "ps", "", "Path to FIFO file to read active players from (shorthand).")
flag.IntVar(&cfg.YMin, "ymin", common.MinHeight, "Minimum y in blocks.")
flag.IntVar(&cfg.YMax, "ymax", common.MaxHeight, "Maximum y in blocks.")
flag.DurationVar(&cfg.ChangeDuration,
"change-duration", time.Second, "Duration to aggregate changes. (PG only)")
}
func (cfg *config) load(fname string) error {
_, err := toml.DecodeFile(fname, &cfg)
return err
}

View File

@ -10,7 +10,6 @@ import (
"log" "log"
"net" "net"
"net/http" "net/http"
"time"
"bitbucket.org/s_l_teichmann/mtsatellite/common" "bitbucket.org/s_l_teichmann/mtsatellite/common"
@ -18,66 +17,17 @@ import (
) )
func main() { func main() {
var ( var (
webPort int cfg config
webHost string cfgFile string
webDir string
mapDir string
redisPort int
redisHost string
colorsFile string
bgColor string
workers int
transparent bool
transparentDim float64
updateHosts string
websockets bool
playersFIFO string
version bool version bool
yMin int
yMax int
changeDuration time.Duration
) )
defaultBgColor := common.ColorToHex(common.BackgroundColor) flag.StringVar(&cfgFile, "config", "", "configuration file")
flag.StringVar(&cfgFile, "c", "", "configuration file (shorthand)")
flag.IntVar(&webPort, "web-port", 8808, "port of the web server")
flag.IntVar(&webPort, "p", 8808, "port of the web server (shorthand)")
flag.StringVar(&webHost, "web-host", "localhost", "address to bind web server")
flag.StringVar(&webHost, "h", "localhost", "address to bind web server(shorthand)")
flag.StringVar(&webDir, "web", "web", "static served web files.")
flag.StringVar(&webDir, "w", "web", "static served web files (shorthand)")
flag.StringVar(&mapDir, "map", "map", "directory of prerendered tiles")
flag.StringVar(&mapDir, "m", "map", "directory of prerendered tiles (shorthand)")
flag.StringVar(&updateHosts, "update-hosts", "localhost",
"';' separated list of hosts which are allowed to send map update requests")
flag.StringVar(&updateHosts, "u", "localhost",
"';' separated list of hosts which are allowed to send map update requests (shorthand)")
flag.StringVar(&redisHost, "redis-host", "", "address of the backend Redis server")
flag.StringVar(&redisHost, "rh", "", "address of the backend Redis server (shorthand)")
flag.IntVar(&redisPort, "redis-port", 6379, "port of the backend Redis server")
flag.IntVar(&redisPort, "rp", 6379, "port of the backend Redis server (shorthand)")
flag.IntVar(&workers, "workers", 1, "number of workers to render tiles")
flag.StringVar(&colorsFile, "colors", "colors.txt", "colors used to render map tiles.")
flag.StringVar(&colorsFile, "c", "colors.txt", "colors used to render map tiles (shorthand).")
flag.StringVar(&bgColor, "background", defaultBgColor, "background color")
flag.StringVar(&bgColor, "bg", defaultBgColor, "background color (shorthand)")
flag.BoolVar(&transparent, "transparent", false, "Render transparent blocks.")
flag.BoolVar(&transparent, "t", false, "Render transparent blocks (shorthand).")
flag.Float64Var(&transparentDim,
"transparent-dim", common.DefaultTransparentDim*100.0,
"Extra dimming of transparent nodes each depth meter in percent.")
flag.Float64Var(&transparentDim,
"td", common.DefaultTransparentDim*100.0,
"Extra fimming of transparent nodes each depth meter in percent. (shorthand)")
flag.BoolVar(&websockets, "websockets", false, "Forward tile changes to clients via websockets.")
flag.BoolVar(&websockets, "ws", false, "Forward tile changes to clients via websockets (shorthand).")
flag.StringVar(&playersFIFO, "players", "", "Path to FIFO file to read active players from.")
flag.StringVar(&playersFIFO, "ps", "", "Path to FIFO file to read active players from (shorthand).")
flag.IntVar(&yMin, "ymin", common.MinHeight, "Minimum y in blocks.")
flag.IntVar(&yMax, "ymax", common.MaxHeight, "Maximum y in blocks.")
flag.DurationVar(&changeDuration, "change-duration", time.Second, "Duration to aggregate changes. (PG only)")
flag.BoolVar(&version, "version", false, "Print version and exit.") flag.BoolVar(&version, "version", false, "Print version and exit.")
cfg.bindFlags()
flag.Parse() flag.Parse()
@ -85,72 +35,78 @@ func main() {
common.PrintVersionAndExit() common.PrintVersionAndExit()
} }
bg := common.ParseColorDefault(bgColor, common.BackgroundColor) if cfgFile != "" {
if err := cfg.load(cfgFile); err != nil {
log.Fatalf("error: %v\n", err)
}
}
bg := common.ParseColorDefault(cfg.BGColor, common.BackgroundColor)
router := mux.NewRouter() router := mux.NewRouter()
subBaseLine := newSubBaseLine(mapDir, bg) subBaseLine := newSubBaseLine(cfg.MapDir, bg)
router.Path("/map/{z:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.png").Handler(subBaseLine) router.Path("/map/{z:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.png").Handler(subBaseLine)
var btu baseTilesUpdates var btu baseTilesUpdates
var wsf *websocketForwarder var wsf *websocketForwarder
if websockets { if cfg.Websockets {
wsf = newWebsocketForwarder() wsf = newWebsocketForwarder()
go wsf.run() go wsf.run()
router.Path("/ws").Methods("GET").Handler(wsf) router.Path("/ws").Methods("GET").Handler(wsf)
btu = wsf btu = wsf
} }
if playersFIFO != "" { if cfg.PlayersFIFO != "" {
plys := newPlayers(playersFIFO, wsf) plys := newPlayers(cfg.PlayersFIFO, wsf)
go plys.run() go plys.run()
router.Path("/players").Methods("GET").Handler(plys) router.Path("/players").Methods("GET").Handler(plys)
} }
if redisHost != "" { if cfg.RedisHost != "" {
var colors *common.Colors var colors *common.Colors
var err error var err error
if colors, err = common.ParseColors(colorsFile); err != nil { if colors, err = common.ParseColors(cfg.ColorsFile); err != nil {
log.Fatalf("ERROR: problem loading colors: %s", err) log.Fatalf("ERROR: problem loading colors: %s", err)
} }
colors.TransparentDim = common.Clamp32f( colors.TransparentDim = common.Clamp32f(
float32(transparentDim/100.0), 0.0, 100.0) float32(cfg.TransparentDim/100.0), 0.0, 100.0)
dbcf, err := common.CreateDBClientFactory(redisHost, redisPort) dbcf, err := common.CreateDBClientFactory(cfg.RedisHost, cfg.RedisPort)
if err != nil { if err != nil {
log.Fatalf("error: %v\n", err) log.Fatalf("error: %v\n", err)
} }
defer dbcf.Close() defer dbcf.Close()
var allowedUpdateIps []net.IP var allowedUpdateIps []net.IP
if allowedUpdateIps, err = ipsFromHosts(updateHosts); err != nil { if allowedUpdateIps, err = ipsFromHosts(cfg.UpdateHosts); err != nil {
log.Fatalf("ERROR: name resolving problem: %s", err) log.Fatalf("ERROR: name resolving problem: %s", err)
} }
tu := newTileUpdater( tu := newTileUpdater(
mapDir, cfg.MapDir,
dbcf, dbcf,
allowedUpdateIps, allowedUpdateIps,
colors, bg, colors, bg,
yMin, yMax, cfg.YMin, cfg.YMax,
transparent, cfg.Transparent,
workers, cfg.Workers,
btu) btu)
go tu.doUpdates() go tu.doUpdates()
if pgHost, ok := common.IsPostgreSQL(redisHost); btu != nil && ok { if pgHost, ok := common.IsPostgreSQL(cfg.RedisHost); btu != nil && ok {
go tu.listen(pgHost, changeDuration) go tu.listen(pgHost, cfg.ChangeDuration)
} else { } else {
router.Path("/update").Methods("POST").Handler(tu) router.Path("/update").Methods("POST").Handler(tu)
} }
} }
router.PathPrefix("/").Handler(http.FileServer(http.Dir(webDir))) router.PathPrefix("/").Handler(http.FileServer(http.Dir(cfg.WebDir)))
http.Handle("/", router) http.Handle("/", router)
addr := fmt.Sprintf("%s:%d", webHost, webPort) addr := fmt.Sprintf("%s:%d", cfg.WebHost, cfg.WebPort)
if err := http.ListenAndServe(addr, nil); err != nil { if err := http.ListenAndServe(addr, nil); err != nil {
log.Fatalf("Starting server failed: %s\n", err) log.Fatalf("Starting server failed: %s\n", err)
} }

1
go.mod
View File

@ -3,6 +3,7 @@ module bitbucket.org/s_l_teichmann/mtsatellite
go 1.13 go 1.13
require ( require (
github.com/BurntSushi/toml v1.0.0 // indirect
github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0

2
go.sum
View File

@ -1,4 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b h1:5Ci5wpOL75rYF6RQGRoqhEAU6xLJ6n/D4SckXX1yB74= github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b h1:5Ci5wpOL75rYF6RQGRoqhEAU6xLJ6n/D4SckXX1yB74=