From 234760b193287a50910550a9b714b6010feff4e5 Mon Sep 17 00:00:00 2001 From: Hector Gimenez Date: Wed, 27 Mar 2024 22:28:56 +0900 Subject: [PATCH] make stats handler event based for the pause and ensure the game memory is restored when closing koolo window, properly stopping the bot --- README.md | 6 ++++-- cmd/koolo/main.go | 8 ++++---- internal/bot.go | 16 ++++++++++------ internal/event/event.go | 12 ++++++++++++ internal/manager.go | 6 ++++++ internal/stats.go | 10 ++++++---- internal/supervisor.go | 7 ------- 7 files changed, 42 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 7ee3a353..720c1bd8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -![Koolo](images/you_died.png) -

Koolo

+

+ Koolo +

+

Koolo

--- diff --git a/cmd/koolo/main.go b/cmd/koolo/main.go index 2e757feb..976ae2fe 100644 --- a/cmd/koolo/main.go +++ b/cmd/koolo/main.go @@ -34,6 +34,9 @@ func main() { winproc.SetProcessDpiAware.Call() // Set DPI awareness to be able to read the correct scale and show the window correctly + eventListener := event.NewListener(logger) + manager := koolo.NewSupervisorManager(logger, eventListener) + g.Go(func() error { displayScale := config.GetCurrentDisplayScale() w, err := gowebview.New(&gowebview.Config{URL: "http://localhost:8087", WindowConfig: &gowebview.WindowConfig{ @@ -56,12 +59,11 @@ func main() { w.Run() cancel() + manager.StopAll() os.Exit(0) return nil }) - eventListener := event.NewListener(logger) - // Discord Bot initialization if config.Koolo.Discord.Enabled { discordBot, err := discord.NewBot(config.Koolo.Discord.Token, config.Koolo.Discord.ChannelID) @@ -90,8 +92,6 @@ func main() { }) } - manager := koolo.NewSupervisorManager(logger, eventListener) - g.Go(func() error { srv := server.New(logger, manager) return srv.Listen(8087) diff --git a/internal/bot.go b/internal/bot.go index 06d9b1c6..7954d3e8 100644 --- a/internal/bot.go +++ b/internal/bot.go @@ -21,7 +21,7 @@ type Bot struct { logger *slog.Logger hm health.Manager ab *action.Builder - container container.Container + c container.Container paused bool supervisorName string } @@ -37,7 +37,7 @@ func NewBot( logger: logger, hm: hm, ab: ab, - container: container, + c: container, supervisorName: supervisorName, } } @@ -80,7 +80,7 @@ func (b *Bot) Run(ctx context.Context, firstRun bool, runs []run.Run) (err error time.Sleep(time.Millisecond*10 - time.Since(loopTime)) } - d := b.container.Reader.GetData(false) + d := b.c.Reader.GetData(false) // Skip running stuff if loading screen is present if d.OpenMenus.LoadingScreen { @@ -108,13 +108,13 @@ func (b *Bot) Run(ctx context.Context, firstRun bool, runs []run.Run) (err error } // TODO: Maybe add some kind of "on every iteration action", something that can be executed/skipped on every iteration - if b.ab.IsRebuffRequired(d) && (buffAct == nil || buffAct.Steps == nil || buffAct.Steps[len(buffAct.Steps)-1].Status(d, b.container) == step.StatusCompleted) { + if b.ab.IsRebuffRequired(d) && (buffAct == nil || buffAct.Steps == nil || buffAct.Steps[len(buffAct.Steps)-1].Status(d, b.c) == step.StatusCompleted) { buffAct = b.ab.BuffIfRequired(d) actions = append([]action.Action{buffAct}, actions...) } for k, act := range actions { - err := act.NextStep(d, b.container) + err := act.NextStep(d, b.c) loopTime = time.Now() if errors.Is(err, action.ErrNoMoreSteps) { if len(actions)-1 == k { @@ -129,7 +129,7 @@ func (b *Bot) Run(ctx context.Context, firstRun bool, runs []run.Run) (err error break } if errors.Is(err, action.ErrCanBeSkipped) { - event.Send(event.RunFinished(event.WithScreenshot(b.supervisorName, err.Error(), b.container.Reader.Screenshot()), r.Name(), event.FinishedError)) + event.Send(event.RunFinished(event.WithScreenshot(b.supervisorName, err.Error(), b.c.Reader.Screenshot()), r.Name(), event.FinishedError)) b.logger.Warn("error occurred on action that can be skipped, game will continue", slog.Any("error", err)) act.Skip() break @@ -186,9 +186,13 @@ func (b *Bot) postRunActions(currentRun int, runs []run.Run) []action.Action { func (b *Bot) TogglePause() { if b.paused { b.logger.Info("Resuming...") + b.c.Injector.Load() + event.Send(event.GamePaused(event.Text(b.supervisorName, "Game resumed"), false)) b.paused = false } else { b.logger.Info("Pausing...") + b.c.Injector.RestoreMemory() + event.Send(event.GamePaused(event.Text(b.supervisorName, "Game paused"), true)) b.paused = true } } diff --git a/internal/event/event.go b/internal/event/event.go index 3a1521fb..f5bf57fd 100644 --- a/internal/event/event.go +++ b/internal/event/event.go @@ -152,3 +152,15 @@ func CompanionLeaderAttack(be BaseEvent, targetUnitID data.UnitID) CompanionLead TargetUnitID: targetUnitID, } } + +type GamePausedEvent struct { + BaseEvent + Paused bool +} + +func GamePaused(be BaseEvent, paused bool) GamePausedEvent { + return GamePausedEvent{ + BaseEvent: be, + Paused: paused, + } +} diff --git a/internal/manager.go b/internal/manager.go index f62e6073..b149b863 100644 --- a/internal/manager.go +++ b/internal/manager.go @@ -56,6 +56,12 @@ func (mng *SupervisorManager) Start(supervisorName string) error { return supervisor.Start() } +func (mng *SupervisorManager) StopAll() { + for _, s := range mng.supervisors { + s.Stop() + } +} + func (mng *SupervisorManager) Stop(supervisor string) { s, found := mng.supervisors[supervisor] if found { diff --git a/internal/stats.go b/internal/stats.go index 82107a6c..dc420172 100644 --- a/internal/stats.go +++ b/internal/stats.go @@ -67,6 +67,12 @@ func (h *StatsHandler) Handle(_ context.Context, e event.Event) error { Name: evt.RunName, StartedAt: evt.OccurredAt(), }) + case event.GamePausedEvent: + if evt.Paused { + h.stats.SupervisorStatus = Paused + } else { + h.stats.SupervisorStatus = InGame + } case event.RunFinishedEvent: h.stats.Games[len(h.stats.Games)-1].Runs[len(h.stats.Games[len(h.stats.Games)-1].Runs)-1].FinishedAt = evt.OccurredAt() h.stats.Games[len(h.stats.Games)-1].Runs[len(h.stats.Games[len(h.stats.Games)-1].Runs)-1].Reason = evt.Reason @@ -79,10 +85,6 @@ func (h *StatsHandler) Handle(_ context.Context, e event.Event) error { return nil } -func (h *StatsHandler) SetStatus(status SupervisorStatus) { - h.stats.SupervisorStatus = status -} - func (h *StatsHandler) updateGameStatsFile() { if _, err := os.Stat("stats"); os.IsNotExist(err) { err = os.MkdirAll("stats", os.ModePerm) diff --git a/internal/supervisor.go b/internal/supervisor.go index ef0360b6..23940c1e 100644 --- a/internal/supervisor.go +++ b/internal/supervisor.go @@ -54,13 +54,6 @@ func (s *baseSupervisor) Stats() Stats { func (s *baseSupervisor) TogglePause() { s.bot.TogglePause() - if s.bot.paused { - s.statsHandler.SetStatus(Paused) - s.c.Injector.RestoreMemory() - } else { - s.statsHandler.SetStatus(InGame) - s.c.Injector.Load() - } } func (s *baseSupervisor) Stop() {