From 66f348e84544d3423e5cc2b3e51cd99b7dc406a9 Mon Sep 17 00:00:00 2001 From: Brian Buller Date: Tue, 4 Sep 2018 09:00:47 -0500 Subject: [PATCH] Real Initial Commit --- helpers.go | 18 +++++++ main.go | 95 +++++++++++++++++++++++++++++++++++ structs.go | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 helpers.go create mode 100644 main.go create mode 100644 structs.go diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..9e1f793 --- /dev/null +++ b/helpers.go @@ -0,0 +1,18 @@ +package main + +func LeftPad(val string, vallen int) string { + for len(val) < vallen { + val = " " + val + } + return val +} + +func Center(val string, vallen int) string { + for len(val) < vallen { + val = " " + val + if len(val) < vallen { + val = val + " " + } + } + return val +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..abaeb1b --- /dev/null +++ b/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/jroimartin/gocui" +) + +var dcfg *DynmapConfig +var serverName, baseURL string +var close bool + +const VIEW_KEY = "MAIN_VIEW_KEY" + +func main() { + serverName = "minecraft.br0xen.com" + fmt.Println(serverName) + baseURL = "http://minecraft.br0xen.com:8123/up/" + dcfg = NewDynmapConfig(serverName, baseURL) + dcfg.Update() + + g, err := gocui.NewGui(gocui.OutputNormal) + if err != nil { + log.Panicln(err) + } + defer g.Close() + list := NewListWidget(VIEW_KEY, 1, 1, LeftPad(" ", 35)+"\n\n\n\n\n\n\n\n") + g.SetManager(list) + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + log.Panicln(err) + } + go func() { + for !close { + dcfg.Update() + g.Update(func(g *gocui.Gui) error { + lst, _ := g.View(VIEW_KEY) + lst.Clear() + fmt.Fprintln(lst, Center(dcfg.Name, 35)) + fmt.Fprintln(lst, Center(fmt.Sprintf("~ %s ~", dcfg.GetServerTime()), 35)) + num := fmt.Sprintf("[ %d ]", dcfg.GetOnlinePlayerCount()) + for _, v := range dcfg.GetPlayerList() { + fmt.Fprintln(lst, "* %s", v) + } + for i := dcfg.GetOnlinePlayerCount(); i < 6; i++ { + fmt.Fprintln(lst, " ") + } + fmt.Fprintln(lst, LeftPad(num, 35)) + return nil + }) + time.Sleep(time.Second * 5) + } + }() + if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { + log.Panicln(err) + } + close = true +} + +func quit(g *gocui.Gui, v *gocui.View) error { + return gocui.ErrQuit +} + +type ListWidget struct { + name string + x, y int + w, h int + body string +} + +func NewListWidget(name string, x, y int, body string) *ListWidget { + lines := strings.Split(body, "\n") + w := 0 + for _, l := range lines { + if len(l) > w { + w = len(l) + } + } + h := len(lines) + 1 + w = w + 1 + return &ListWidget{name: name, x: x, y: y, w: w, h: h, body: body} +} + +func (w *ListWidget) Layout(g *gocui.Gui) error { + v, err := g.SetView(w.name, w.x, w.y, w.x+w.w, w.y+w.h) + if err != nil { + if err != gocui.ErrUnknownView { + return err + } + fmt.Fprint(v, w.body) + } + return nil +} diff --git a/structs.go b/structs.go new file mode 100644 index 0000000..e5cd2c0 --- /dev/null +++ b/structs.go @@ -0,0 +1,143 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "net/http/cookiejar" + "time" + + "golang.org/x/net/publicsuffix" +) + +type DynmapConfig struct { + URL string + Name string + Config *Config + cookiejar *cookiejar.Jar + client *http.Client +} + +func NewDynmapConfig(name, url string) *DynmapConfig { + d := new(DynmapConfig) + d.Name = name + d.URL = url + var err error + d.cookiejar, err = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) + if err != nil { + log.Fatal(err) + } + return d +} + +func (d *DynmapConfig) Update() error { + if err := d.FetchConfig(); err != nil { + return err + } + + if err := d.FetchAllWorlds(); err != nil { + return err + } + return nil +} + +func (d *DynmapConfig) GetWorlds() []World { + return d.Config.Worlds +} + +func (d *DynmapConfig) FetchConfig() error { + body := d.fetchURL(d.URL + "configuration") + return json.Unmarshal(body, &d.Config) +} + +func (d *DynmapConfig) FetchAllWorlds() error { + var err error + for i, v := range d.Config.Worlds { + d.Config.Worlds[i].Status = new(WorldStatus) + url := fmt.Sprintf("%sworld/%s/%d", d.URL, v.Name, time.Now().Unix()) + body := d.fetchURL(url) + if jsonErr := json.Unmarshal(body, d.Config.Worlds[i].Status); jsonErr != nil { + err = jsonErr + } + } + return err +} + +func (d *DynmapConfig) GetTheStatusString() string { + ret := "~ " + d.Config.Worlds[0].Status.ParsedTime() + " ~\n" + longest := 0 + for _, v := range d.Config.Worlds { + if len(v.Title) > longest { + longest = len(v.Title) + } + } + for _, v := range d.Config.Worlds { + title := v.Title + for i := 0; len(title) < longest; i++ { + title = title + " " + } + ret = fmt.Sprintf("%s[%s]\t\t\t\t%d (%d)\n", ret, title, v.Status.CurrentCount, len(v.Status.Players)) + } + return ret +} + +func (d *DynmapConfig) GetServerTime() string { + return d.Config.Worlds[0].Status.ParsedTime() +} + +func (d *DynmapConfig) GetOnlinePlayerCount() int { + return d.Config.Worlds[0].Status.CurrentCount +} + +func (d *DynmapConfig) GetPlayerList() []string { + return d.Config.Worlds[0].Status.Players +} + +func (d *DynmapConfig) fetchURL(url string) []byte { + client := &http.Client{Jar: d.cookiejar} + resp, err := client.Get(url) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return []byte{} + } + return body +} + +type Config struct { + Worlds []World +} + +type World struct { + Sealevel int + Protected bool + Center *Coord + Name string + Title string + WorldHeight int + Status *WorldStatus +} + +type WorldStatus struct { + CurrentCount int + Players []string + + HasStorm bool + IsThundering bool + ConfigHash int + ServerTime int +} + +func (w *WorldStatus) ParsedTime() string { + hrs := ((w.ServerTime / 1000) + 6) % 24 + mins := (w.ServerTime / 1000) + return fmt.Sprintf("%d:%02d", hrs, mins) +} + +type Coord struct { + X float64 + Y float64 + Z float64 +}