diff --git a/bot.go b/bot.go index 06c021e..9aa996d 100644 --- a/bot.go +++ b/bot.go @@ -110,6 +110,10 @@ func (b *Bot) BotHandlers() { b.bot.Handle("/value", botGraphValue) b.bot.Handle("/value_delta", botGraphValueDelta) + b.bot.Handle("/money", botGraphMoney) + b.bot.Handle("/income", botGraphIncome) + b.bot.Handle("/loan", botGraphLoan) + b.bot.Handle("/perf", botGraphPerf) b.bot.Handle("/planes", botGraphPlanes) b.bot.Handle("/busses", botGraphBusses) b.bot.Handle("/trains", botGraphTrains) @@ -151,9 +155,15 @@ func botHelp(m *tb.Message) { msg = fmt.Sprintf("%s/offline - set player offline\r\n", msg) msg = fmt.Sprintf("%s/value - value graph\r\n", msg) msg = fmt.Sprintf("%s/value_delta - delta value graph\r\n", msg) + msg = fmt.Sprintf("%s/money - money graph\r\n", msg) + msg = fmt.Sprintf("%s/income - income graph\r\n", msg) + msg = fmt.Sprintf("%s/loan - loan graph\r\n", msg) + msg = fmt.Sprintf("%s/perf - perf graph\r\n", msg) msg = fmt.Sprintf("%s/busses - busses graph\r\n", msg) msg = fmt.Sprintf("%s/trains - trains graph\r\n", msg) msg = fmt.Sprintf("%s/planes - planes graph\r\n", msg) + msg = fmt.Sprintf("%s/lorries - lorries graph\r\n", msg) + msg = fmt.Sprintf("%s/ships - ships graph\r\n", msg) msg = fmt.Sprintf("%s/version - version\r\n", msg) msg = fmt.Sprintf("%s/help - this\r\n", msg) @@ -379,7 +389,7 @@ func botActuallyReset(m *tb.Message) { } else { cfg.Save("backup." + *configFlag) cfg.Game.Started = false - cfg.Stats = make(map[uint8]map[string]*Stat) + cfg.Stats = make(map[int]map[string]*Stat) for _, cc := range cfg.Clients { cc.Ready = false cc.CompanyID = 255 @@ -933,13 +943,11 @@ func botGraphValue(m *tb.Message) { unitFactor float64 unitName string ) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - for _, stat := range dStats { - valueFloat := float64(stat.CompanyValueLastQuarter) - if math.Abs(valueFloat) > maxVal { - maxVal = math.Abs(valueFloat) - } + for _, dStats := range cfg.Stats { + for _, stat := range dStats { + valueFloat := float64(stat.CompanyValueLastQuarter) + if math.Abs(valueFloat) > maxVal { + maxVal = math.Abs(valueFloat) } } } @@ -954,28 +962,26 @@ func botGraphValue(m *tb.Message) { unitName = "" } - var vals map[uint8]plotter.XYs - vals = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - vals[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphValue : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - valueFloat := float64(stat.CompanyValueLastQuarter) - pt := plotter.XY{ - X: dateFloat, - Y: valueFloat / unitFactor, - } - vals[coID] = append(vals[coID], pt) + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphValue : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(vals[coID], func(i, j int) bool { return vals[coID][i].X < vals[coID][j].X }) + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[ccID] = append(vals[ccID], pt) } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) } p := plot.New() @@ -988,8 +994,8 @@ func botGraphValue(m *tb.Message) { } i := 0 - for coID, xys := range vals { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range vals { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphValue : plotter.NewLinePoints") @@ -1029,37 +1035,35 @@ func botGraphValueDelta(m *tb.Message) { unitName string ) - var vals map[uint8]plotter.XYs - vals = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - vals[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphValueDelta : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - pt := plotter.XY{ - X: float64(d.Year()) + float64(d.Month()-1)/12, - Y: float64(stat.CompanyValuePreviousQuarter), - } - vals[coID] = append(vals[coID], pt) + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphValueDelta : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(vals[coID], func(i, j int) bool { return vals[coID][i].X < vals[coID][j].X }) + pt := plotter.XY{ + X: float64(d.Year()) + float64(d.Month()-1)/12, + Y: float64(stat.CompanyValuePreviousQuarter), + } + vals[ccID] = append(vals[ccID], pt) } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) } - for coID, v := range vals { + for ccID, v := range vals { v2 := make(plotter.XYs, 0) for i := 0; i < len(v); i = i + 3 { v2 = append(v2, v[i]) } - vals[coID] = v2 + vals[ccID] = v2 } - for coID, v := range vals { + for ccID, v := range vals { v0 := v[0].Y for i := 1; i < len(v); i++ { v[i].Y, v0 = v[i].Y-v0, v[i].Y @@ -1067,7 +1071,7 @@ func botGraphValueDelta(m *tb.Message) { maxVal = math.Abs(v[i].Y) } } - vals[coID] = v[1:] + vals[ccID] = v[1:] } if maxVal > 1000000000 { @@ -1081,14 +1085,14 @@ func botGraphValueDelta(m *tb.Message) { unitName = "" } - for coID, v := range vals { + for ccID, v := range vals { for i := 0; i < len(v); i++ { v[i].Y = v[i].Y / unitFactor if math.IsNaN(v[i].Y) { - logInfoDebug("botGraphValueDelta : NaN : %d / %f", coID, v[i].X) + logInfoDebug("botGraphValueDelta : NaN : %d / %f", ccID, v[i].X) } } - vals[coID] = v + vals[ccID] = v } p := plot.New() @@ -1101,8 +1105,8 @@ func botGraphValueDelta(m *tb.Message) { } i := 0 - for coID, xys := range vals { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range vals { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphValueDelta : plotter.NewLinePoints") @@ -1135,37 +1139,398 @@ func botGraphValueDelta(m *tb.Message) { return } -func botGraphPlanes(m *tb.Message) { - var planes, airports map[uint8]plotter.XYs - planes = make(map[uint8]plotter.XYs) - airports = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - planes[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphPlanes : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - pt := plotter.XY{ - X: dateFloat, - Y: float64(stat.Planes), - } - planes[coID] = append(planes[coID], pt) - pt = plotter.XY{ - X: dateFloat, - Y: float64(stat.Airports), - } - airports[coID] = append(airports[coID], pt) +func botGraphMoney(m *tb.Message) { + var ( + maxVal float64 + unitFactor float64 + unitName string + ) + for _, dStats := range cfg.Stats { + for _, stat := range dStats { + valueFloat := float64(stat.Money) + if math.Abs(valueFloat) > maxVal { + maxVal = math.Abs(valueFloat) } - sort.Slice(planes[coID], func(i, j int) bool { return planes[coID][i].X < planes[coID][j].X }) - sort.Slice(airports[coID], func(i, j int) bool { return airports[coID][i].X < airports[coID][j].X }) - } } + if maxVal > 1000000000 { + unitFactor = 1000000000 + unitName = "billion" + } else if maxVal > 1000000 { + unitFactor = 1000000 + unitName = "million" + } else { + unitFactor = 1 + unitName = "" + } + + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphMoney : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[ccID] = append(vals[ccID], pt) + } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) + } + + p := plot.New() + p.Title.Text = "Company Money" + p.X.Label.Text = "Year" + if unitName != "" { + p.Y.Label.Text = fmt.Sprintf("Value (%s)", unitName) + } else { + p.Y.Label.Text = "Value" + } + + i := 0 + for ccID, xys := range vals { + cc := cfg.Clients[ccID] + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphMoney : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphMoney : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphIncome(m *tb.Message) { + var ( + maxVal float64 + unitFactor float64 + unitName string + ) + for _, dStats := range cfg.Stats { + for _, stat := range dStats { + valueFloat := float64(stat.Income) + if math.Abs(valueFloat) > maxVal { + maxVal = math.Abs(valueFloat) + } + } + } + if maxVal > 1000000000 { + unitFactor = 1000000000 + unitName = "billion" + } else if maxVal > 1000000 { + unitFactor = 1000000 + unitName = "million" + } else { + unitFactor = 1 + unitName = "" + } + + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphIncome : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[ccID] = append(vals[ccID], pt) + } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) + } + + p := plot.New() + p.Title.Text = "Company Income" + p.X.Label.Text = "Year" + if unitName != "" { + p.Y.Label.Text = fmt.Sprintf("Value (%s)", unitName) + } else { + p.Y.Label.Text = "Value" + } + + i := 0 + for ccID, xys := range vals { + cc := cfg.Clients[ccID] + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphIncome : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphIncome : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphLoan(m *tb.Message) { + var ( + maxVal float64 + unitFactor float64 + unitName string + ) + for _, dStats := range cfg.Stats { + for _, stat := range dStats { + valueFloat := float64(stat.Loan) + if math.Abs(valueFloat) > maxVal { + maxVal = math.Abs(valueFloat) + } + } + } + if maxVal > 1000000000 { + unitFactor = 1000000000 + unitName = "billion" + } else if maxVal > 1000000 { + unitFactor = 1000000 + unitName = "million" + } else { + unitFactor = 1 + unitName = "" + } + + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphLoan : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[ccID] = append(vals[ccID], pt) + } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) + } + + p := plot.New() + p.Title.Text = "Company Loan" + p.X.Label.Text = "Year" + if unitName != "" { + p.Y.Label.Text = fmt.Sprintf("Value (%s)", unitName) + } else { + p.Y.Label.Text = "Value" + } + + i := 0 + for ccID, xys := range vals { + cc := cfg.Clients[ccID] + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphLoan : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphLoan : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphPerf(m *tb.Message) { + var ( + maxVal float64 + unitFactor float64 + unitName string + ) + for _, dStats := range cfg.Stats { + for _, stat := range dStats { + valueFloat := float64(stat.PerformancePreviousQuarter) + if math.Abs(valueFloat) > maxVal { + maxVal = math.Abs(valueFloat) + } + } + } + if maxVal > 1000000000 { + unitFactor = 1000000000 + unitName = "billion" + } else if maxVal > 1000000 { + unitFactor = 1000000 + unitName = "million" + } else { + unitFactor = 1 + unitName = "" + } + + var vals map[int]plotter.XYs + vals = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + vals[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphPerf : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[ccID] = append(vals[ccID], pt) + } + sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X }) + } + + p := plot.New() + p.Title.Text = "Company Loan" + p.X.Label.Text = "Year" + if unitName != "" { + p.Y.Label.Text = fmt.Sprintf("Value (%s)", unitName) + } else { + p.Y.Label.Text = "Value" + } + + i := 0 + for ccID, xys := range vals { + cc := cfg.Clients[ccID] + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphPerf : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphPerf : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphPlanes(m *tb.Message) { + var planes, airports map[int]plotter.XYs + planes = make(map[int]plotter.XYs) + airports = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + planes[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphPlanes : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Planes), + } + planes[ccID] = append(planes[ccID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.Airports), + } + airports[ccID] = append(airports[ccID], pt) + } + sort.Slice(planes[ccID], func(i, j int) bool { return planes[ccID][i].X < planes[ccID][j].X }) + sort.Slice(airports[ccID], func(i, j int) bool { return airports[ccID][i].X < airports[ccID][j].X }) + } p := plot.New() p.Title.Text = "Planes summary" @@ -1174,8 +1539,8 @@ func botGraphPlanes(m *tb.Message) { p.Y.Min = 0 i := 0 - for coID, xys := range planes { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range planes { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphPlanes : plotter.NewLinePoints") @@ -1209,35 +1574,32 @@ func botGraphPlanes(m *tb.Message) { } func botGraphBusses(m *tb.Message) { - var busses, busStops map[uint8]plotter.XYs - busses = make(map[uint8]plotter.XYs) - busStops = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - busses[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphBusses : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - pt := plotter.XY{ - X: dateFloat, - Y: float64(stat.Busses), - } - busses[coID] = append(busses[coID], pt) - pt = plotter.XY{ - X: dateFloat, - Y: float64(stat.BusStops), - } - busStops[coID] = append(busStops[coID], pt) + var busses, busStops map[int]plotter.XYs + busses = make(map[int]plotter.XYs) + busStops = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + busses[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphBusses : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(busses[coID], func(i, j int) bool { return busses[coID][i].X < busses[coID][j].X }) - sort.Slice(busStops[coID], func(i, j int) bool { return busStops[coID][i].X < busStops[coID][j].X }) - + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Busses), + } + busses[ccID] = append(busses[ccID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.BusStops), + } + busStops[ccID] = append(busStops[ccID], pt) } + sort.Slice(busses[ccID], func(i, j int) bool { return busses[ccID][i].X < busses[ccID][j].X }) + sort.Slice(busStops[ccID], func(i, j int) bool { return busStops[ccID][i].X < busStops[ccID][j].X }) } p := plot.New() @@ -1247,8 +1609,8 @@ func botGraphBusses(m *tb.Message) { p.Y.Min = 0 i := 0 - for coID, xys := range busses { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range busses { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphBusses : plotter.NewLinePoints") @@ -1282,35 +1644,32 @@ func botGraphBusses(m *tb.Message) { } func botGraphTrains(m *tb.Message) { - var trains, trainStations map[uint8]plotter.XYs - trains = make(map[uint8]plotter.XYs) - trainStations = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - trains[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphTrains : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - pt := plotter.XY{ - X: dateFloat, - Y: float64(stat.Trains), - } - trains[coID] = append(trains[coID], pt) - pt = plotter.XY{ - X: dateFloat, - Y: float64(stat.TrainStations), - } - trainStations[coID] = append(trainStations[coID], pt) + var trains, trainStations map[int]plotter.XYs + trains = make(map[int]plotter.XYs) + trainStations = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + trains[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphTrains : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(trains[coID], func(i, j int) bool { return trains[coID][i].X < trains[coID][j].X }) - sort.Slice(trainStations[coID], func(i, j int) bool { return trainStations[coID][i].X < trainStations[coID][j].X }) - + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Trains), + } + trains[ccID] = append(trains[ccID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.TrainStations), + } + trainStations[ccID] = append(trainStations[ccID], pt) } + sort.Slice(trains[ccID], func(i, j int) bool { return trains[ccID][i].X < trains[ccID][j].X }) + sort.Slice(trainStations[ccID], func(i, j int) bool { return trainStations[ccID][i].X < trainStations[ccID][j].X }) } p := plot.New() @@ -1320,8 +1679,8 @@ func botGraphTrains(m *tb.Message) { p.Y.Min = 0 i := 0 - for coID, xys := range trains { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range trains { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphTrains : plotter.NewLinePoints") @@ -1355,35 +1714,32 @@ func botGraphTrains(m *tb.Message) { } func botGraphLorries(m *tb.Message) { - var lorries, lorriesStations map[uint8]plotter.XYs - lorries = make(map[uint8]plotter.XYs) - lorriesStations = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - lorries[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphLorries : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - pt := plotter.XY{ - X: dateFloat, - Y: float64(stat.Lorries), - } - lorries[coID] = append(lorries[coID], pt) - pt = plotter.XY{ - X: dateFloat, - Y: float64(stat.LorryStations), - } - lorriesStations[coID] = append(lorriesStations[coID], pt) + var lorries, lorriesStations map[int]plotter.XYs + lorries = make(map[int]plotter.XYs) + lorriesStations = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + lorries[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphLorries : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(lorries[coID], func(i, j int) bool { return lorries[coID][i].X < lorries[coID][j].X }) - sort.Slice(lorriesStations[coID], func(i, j int) bool { return lorriesStations[coID][i].X < lorriesStations[coID][j].X }) - + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Lorries), + } + lorries[ccID] = append(lorries[ccID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.LorryStations), + } + lorriesStations[ccID] = append(lorriesStations[ccID], pt) } + sort.Slice(lorries[ccID], func(i, j int) bool { return lorries[ccID][i].X < lorries[ccID][j].X }) + sort.Slice(lorriesStations[ccID], func(i, j int) bool { return lorriesStations[ccID][i].X < lorriesStations[ccID][j].X }) } p := plot.New() @@ -1393,8 +1749,8 @@ func botGraphLorries(m *tb.Message) { p.Y.Min = 0 i := 0 - for coID, xys := range lorries { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range lorries { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphLorries : plotter.NewLinePoints") @@ -1428,35 +1784,32 @@ func botGraphLorries(m *tb.Message) { } func botGraphShips(m *tb.Message) { - var ships, harbours map[uint8]plotter.XYs - ships = make(map[uint8]plotter.XYs) - harbours = make(map[uint8]plotter.XYs) - for coID, dStats := range cfg.Stats { - if cfg.CompanyIsRegistered(coID) { - ships[coID] = make(plotter.XYs, 0) - for dStr, stat := range dStats { - d, err := time.Parse("20060102", dStr) - logErrorDebug(err, "botGraphShips : time.Parse") - if err != nil { - bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) - return - } - dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 - pt := plotter.XY{ - X: dateFloat, - Y: float64(stat.Ships), - } - ships[coID] = append(ships[coID], pt) - pt = plotter.XY{ - X: dateFloat, - Y: float64(stat.Harbours), - } - harbours[coID] = append(harbours[coID], pt) + var ships, harbours map[int]plotter.XYs + ships = make(map[int]plotter.XYs) + harbours = make(map[int]plotter.XYs) + for ccID, dStats := range cfg.Stats { + ships[ccID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphShips : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return } - sort.Slice(ships[coID], func(i, j int) bool { return ships[coID][i].X < ships[coID][j].X }) - sort.Slice(harbours[coID], func(i, j int) bool { return harbours[coID][i].X < harbours[coID][j].X }) - + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Ships), + } + ships[ccID] = append(ships[ccID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.Harbours), + } + harbours[ccID] = append(harbours[ccID], pt) } + sort.Slice(ships[ccID], func(i, j int) bool { return ships[ccID][i].X < ships[ccID][j].X }) + sort.Slice(harbours[ccID], func(i, j int) bool { return harbours[ccID][i].X < harbours[ccID][j].X }) } p := plot.New() @@ -1466,8 +1819,8 @@ func botGraphShips(m *tb.Message) { p.Y.Min = 0 i := 0 - for coID, xys := range ships { - cc := cfg.GetCompanyClient(coID) + for ccID, xys := range ships { + cc := cfg.Clients[ccID] l, s, err := plotter.NewLinePoints(xys) logErrorDebug(err, "botGraphShips : plotter.NewLinePoints") diff --git a/config.go b/config.go index 97ce2bb..4043d4b 100644 --- a/config.go +++ b/config.go @@ -44,18 +44,18 @@ type ClientConfig struct { } type Config struct { - Server *ServerConfig `json:"server"` - Telegram *TelegramConfig `json:"telegram"` - Game *GameConfig `json:"game"` - Clients map[int]*ClientConfig `json:"clients"` - Stats map[uint8]map[string]*Stat `json:"stats"` + Server *ServerConfig `json:"server"` + Telegram *TelegramConfig `json:"telegram"` + Game *GameConfig `json:"game"` + Clients map[int]*ClientConfig `json:"clients"` + Stats map[int]map[string]*Stat `json:"stats"` } // Init values for a config based on package defaults func (c *Config) Init() error { err := json.Unmarshal(cfgSample, &c) c.Clients = make(map[int]*ClientConfig) - c.Stats = make(map[uint8]map[string]*Stat) + c.Stats = make(map[int]map[string]*Stat) if err != nil { return err diff --git a/ttd.go b/ttd.go index 4ed7dc2..eb8732c 100644 --- a/ttd.go +++ b/ttd.go @@ -385,32 +385,35 @@ func (s *ServerTTD) Poll(stop chan struct{}) { logInfoDebug("Server.Poll() : PacketServerCompanyEconomy :\n- CompanyID: %d\n- M: %d\tL: %d\tI: %d\n- Delivered now: %d\tLast: %d\tPrevious: %d\n- Performance last: %d\t Previous: %d\n- Value last: %d\t Previous: %d", sp.CompanyID, sp.Money, sp.Loan, sp.Income, sp.DeliveredCargoThisQuarter, sp.DeliveredCargoLastQuarter, sp.DeliveredCargoPreviousQuarter, sp.PerformanceLastQuarter, sp.PerformancePreviousQuarter, sp.CompanyValueLastQuarter, sp.CompanyValuePreviousQuarter) if cfg.Stats == nil { - cfg.Stats = make(map[uint8]map[string]*Stat) + cfg.Stats = make(map[int]map[string]*Stat) } - _, ok := cfg.Stats[sp.CompanyID] - if !ok { - cfg.Stats[sp.CompanyID] = make(map[string]*Stat) - } - stats, ok := cfg.Stats[sp.CompanyID][s.Status.GameDate.Format("20060102")] - if !ok { - stats = &Stat{ - CompanyID: sp.CompanyID, - Date: s.Status.GameDate, + if cfg.CompanyIsRegistered(sp.CompanyID) { + cc := cfg.GetCompanyClient(sp.CompanyID) + _, ok := cfg.Stats[cc.UserID] + if !ok { + cfg.Stats[cc.UserID] = make(map[string]*Stat) + } + stats, ok := cfg.Stats[cc.UserID][s.Status.GameDate.Format("20060102")] + if !ok { + stats = &Stat{ + CompanyID: sp.CompanyID, + Date: s.Status.GameDate, + } + cfg.Stats[cc.UserID][s.Status.GameDate.Format("20060102")] = stats } - cfg.Stats[sp.CompanyID][s.Status.GameDate.Format("20060102")] = stats - } - stats.Money = int64(sp.Money) - stats.Loan = int64(sp.Loan) - stats.Income = sp.Income - stats.DeliveredCargoThisQuarter = int(sp.DeliveredCargoThisQuarter) - stats.DeliveredCargoLastQuarter = int(sp.DeliveredCargoLastQuarter) - stats.DeliveredCargoPreviousQuarter = int(sp.DeliveredCargoPreviousQuarter) - stats.PerformanceLastQuarter = int(sp.PerformanceLastQuarter) - stats.PerformancePreviousQuarter = int(sp.PerformancePreviousQuarter) - stats.CompanyValueLastQuarter = int64(sp.CompanyValueLastQuarter) - stats.CompanyValuePreviousQuarter = int64(sp.CompanyValuePreviousQuarter) + stats.Money = int64(sp.Money) + stats.Loan = int64(sp.Loan) + stats.Income = sp.Income + stats.DeliveredCargoThisQuarter = int(sp.DeliveredCargoThisQuarter) + stats.DeliveredCargoLastQuarter = int(sp.DeliveredCargoLastQuarter) + stats.DeliveredCargoPreviousQuarter = int(sp.DeliveredCargoPreviousQuarter) + stats.PerformanceLastQuarter = int(sp.PerformanceLastQuarter) + stats.PerformancePreviousQuarter = int(sp.PerformancePreviousQuarter) + stats.CompanyValueLastQuarter = int64(sp.CompanyValueLastQuarter) + stats.CompanyValuePreviousQuarter = int64(sp.CompanyValuePreviousQuarter) + } case AdminPacketServerCompanyStats: sp := PacketServerCompanyStats{ Packet: p, @@ -419,33 +422,35 @@ func (s *ServerTTD) Poll(stop chan struct{}) { logInfoDebug("Server.Poll() : PacketServerCompanyStats :\n- CompanyID: %d\n- Vehicles T: %d\tL: %d\tB: %d\tP: %d\tS: %d\n- Stations T: %d\tL: %d\tB: %d\tP: %d\tS: %d", sp.CompanyID, sp.Trains, sp.Lorries, sp.Busses, sp.Planes, sp.Ships, sp.TrainStations, sp.LorryStations, sp.BusStops, sp.Airports, sp.Harbours) if cfg.Stats == nil { - cfg.Stats = make(map[uint8]map[string]*Stat) + cfg.Stats = make(map[int]map[string]*Stat) } - _, ok := cfg.Stats[sp.CompanyID] - if !ok { - cfg.Stats[sp.CompanyID] = make(map[string]*Stat) - } - stats, ok := cfg.Stats[sp.CompanyID][s.Status.GameDate.Format("20060102")] - if !ok { - stats = &Stat{ - CompanyID: sp.CompanyID, - Date: s.Status.GameDate, + if cfg.CompanyIsRegistered(sp.CompanyID) { + cc := cfg.GetCompanyClient(sp.CompanyID) + _, ok := cfg.Stats[cc.UserID] + if !ok { + cfg.Stats[cc.UserID] = make(map[string]*Stat) } - cfg.Stats[sp.CompanyID][s.Status.GameDate.Format("20060102")] = stats + stats, ok := cfg.Stats[cc.UserID][s.Status.GameDate.Format("20060102")] + if !ok { + stats = &Stat{ + CompanyID: sp.CompanyID, + Date: s.Status.GameDate, + } + cfg.Stats[cc.UserID][s.Status.GameDate.Format("20060102")] = stats + } + + stats.Trains = int(sp.Trains) + stats.TrainStations = int(sp.TrainStations) + stats.Busses = int(sp.Busses) + stats.BusStops = int(sp.BusStops) + stats.Lorries = int(sp.Lorries) + stats.LorryStations = int(sp.LorryStations) + stats.Planes = int(sp.Planes) + stats.Airports = int(sp.Airports) + stats.Ships = int(sp.Ships) + stats.Harbours = int(sp.Harbours) } - - stats.Trains = int(sp.Trains) - stats.TrainStations = int(sp.TrainStations) - stats.Busses = int(sp.Busses) - stats.BusStops = int(sp.BusStops) - stats.Lorries = int(sp.Lorries) - stats.LorryStations = int(sp.LorryStations) - stats.Planes = int(sp.Planes) - stats.Airports = int(sp.Airports) - stats.Ships = int(sp.Ships) - stats.Harbours = int(sp.Harbours) - case AdminPacketServerChat: sp := PacketServerChat{ Packet: p, diff --git a/version.go b/version.go index a2b6f65..b6bd079 100644 --- a/version.go +++ b/version.go @@ -1,6 +1,6 @@ // Code generated by version.sh (@generated) DO NOT EDIT. package main -var githash = "e7f47ca" -var buildstamp = "2021-12-08_14:23:02" -var commits = "246" -var version = "e7f47ca-b246 - 2021-12-08_14:23:02" +var githash = "be1712b" +var buildstamp = "2021-12-09_13:41:53" +var commits = "247" +var version = "be1712b-b247 - 2021-12-09_13:41:53"