From f4eaf381e3647df86175d1beeeaad32d8df23a47 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 23 Sep 2023 00:12:16 +0200 Subject: [PATCH] refac the "speedrun" mode By not detecting new saves correctly before, players were sent all moons while still being in cap kingdom. Having those moons made the game crash if the cutscenes from cap to cascade were skipped. Changes: - Rename: `speedrun => `disableShineSync`. - Correctly detect new saves by scenario 1 instead of 0. - Let all stages that are not cap in scenario 1 enable shine sync again (e.g. for switching back to an older save). - Only disable shine sync once and not on every stage change (e.g. when entering cap overworld again and again). - Disable shine bag clearing by default, option to enable it again via `Shines/ClearOnNewSaves` (for speedruns). - Persist shines after clearing (otherwise a server crash/restart might load old moons from a previous run and sync them). - Clear only once per player till reaching cascade (otherwise collected moons might be cleared mid-run). - Reduce delay from 15s to 2s (even w/o a delay I couldn't reproduce a crash, but keeping it feels safer). - Only enable shine sync again after the delay, the delay was circumvented before by other tasks triggering shine sync earlier. --- Server/Program.cs | 37 +++++++++++++++++++++---------------- Server/Settings.cs | 1 + 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Server/Program.cs b/Server/Program.cs index 7b98085..d27582d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -66,13 +66,13 @@ server.ClientJoined += (c, _) => { c.Metadata["loadedSave"] = false; c.Metadata["scenario"] = (byte?) 0; c.Metadata["2d"] = false; - c.Metadata["speedrun"] = false; + c.Metadata["disableShineSync"] = false; }; async Task ClientSyncShineBag(Client client) { if (!Settings.Instance.Shines.Enabled) return; try { - if ((bool?) client.Metadata["speedrun"] ?? false) return; + if ((bool?) client.Metadata["disableShineSync"] ?? false) return; ConcurrentBag clientBag = (ConcurrentBag) (client.Metadata["shineSync"] ??= new ConcurrentBag()); foreach (int shine in shineBag.Except(clientBag).Except(Settings.Instance.Shines.Excluded).ToArray()) { if (!client.Connected) return; @@ -139,21 +139,28 @@ server.PacketHandler = (c, p) => { c.Metadata["lastGamePacket"] = gamePacket; switch (gamePacket.Stage) { - case "CapWorldHomeStage" when gamePacket.ScenarioNum == 0: - c.Metadata["speedrun"] = true; - ((ConcurrentBag) (c.Metadata["shineSync"] ??= new ConcurrentBag())).Clear(); - shineBag.Clear(); - c.Logger.Info("Entered Cap on new save, preventing moon sync until Cascade"); + case "CapWorldHomeStage" when gamePacket.ScenarioNum == 1: + case "CapWorldTowerStage" when gamePacket.ScenarioNum == 1: + if (!((bool?) c.Metadata["disableShineSync"] ?? false)) { + c.Metadata["disableShineSync"] = true; + ((ConcurrentBag) (c.Metadata["shineSync"] ??= new ConcurrentBag())).Clear(); + c.Logger.Info("Entered Cap on new save, preventing moon sync until Cascade"); + if (Settings.Instance.Shines.ClearOnNewSaves) { + shineBag.Clear(); + c.Logger.Info("Cleared shine bags"); + Task.Run(PersistShines); + } + } break; - case "WaterfallWorldHomeStage": - bool wasSpeedrun = (bool) c.Metadata["speedrun"]!; - c.Metadata["speedrun"] = false; - if (wasSpeedrun) + default: + if ((bool?) c.Metadata["disableShineSync"] ?? false) { Task.Run(async () => { - c.Logger.Info("Entered Cascade with moon sync disabled, enabling moon sync"); - await Task.Delay(15000); + c.Logger.Info("Entered Cascade or later with moon sync disabled, enabling moon sync again"); + await Task.Delay(2000); + c.Metadata["disableShineSync"] = false; await ClientSyncShineBag(c); }); + } break; } @@ -574,9 +581,7 @@ CommandHandler.RegisterCommand("shine", args => { ); case "clear" when args.Length == 1: shineBag.Clear(); - Task.Run(async () => { - await PersistShines(); - }); + Task.Run(PersistShines); foreach (ConcurrentBag playerBag in server.Clients.Select(serverClient => (ConcurrentBag)serverClient.Metadata["shineSync"]!)) playerBag?.Clear(); diff --git a/Server/Settings.cs b/Server/Settings.cs index f696a7d..46b0633 100644 --- a/Server/Settings.cs +++ b/Server/Settings.cs @@ -81,6 +81,7 @@ public class Settings { public class ShineTable { public bool Enabled { get; set; } = true; public ISet Excluded { get; set; } = new SortedSet { 496 }; + public bool ClearOnNewSaves { get; set; } = false; } public class PersistShinesTable