Skip to content

Commit

Permalink
refac the "speedrun" mode
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Istador committed Apr 27, 2024
1 parent 61e6fcf commit f4eaf38
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
37 changes: 21 additions & 16 deletions Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ async Task LoadShines()
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<int> clientBag = (ConcurrentBag<int>) (client.Metadata["shineSync"] ??= new ConcurrentBag<int>());
foreach (int shine in shineBag.Except(clientBag).Except(Settings.Instance.Shines.Excluded).ToArray()) {
if (!client.Connected) return;
Expand Down Expand Up @@ -139,21 +139,28 @@ void logError(Task x) {
c.Metadata["lastGamePacket"] = gamePacket;

switch (gamePacket.Stage) {
case "CapWorldHomeStage" when gamePacket.ScenarioNum == 0:
c.Metadata["speedrun"] = true;
((ConcurrentBag<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).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<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).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;
}

Expand Down Expand Up @@ -574,9 +581,7 @@ await server.Broadcast(new TagPacket {
);
case "clear" when args.Length == 1:
shineBag.Clear();
Task.Run(async () => {
await PersistShines();
});
Task.Run(PersistShines);

foreach (ConcurrentBag<int> playerBag in server.Clients.Select(serverClient =>
(ConcurrentBag<int>)serverClient.Metadata["shineSync"]!)) playerBag?.Clear();
Expand Down
1 change: 1 addition & 0 deletions Server/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class DiscordTable {
public class ShineTable {
public bool Enabled { get; set; } = true;
public ISet<int> Excluded { get; set; } = new SortedSet<int> { 496 };
public bool ClearOnNewSaves { get; set; } = false;
}

public class PersistShinesTable
Expand Down

0 comments on commit f4eaf38

Please sign in to comment.