New game from the panel instead of an uploaded save (2.9.3)

World & Backups -> Start new game (console: new-game, also when stopped):
the save is backed up and replaced by a new-game marker (also as reset
point). Joining players are told to start a new game; the server pulls the
first player's save and from then on runs normally. Reset world returns to
a new game when the reset point is one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 17:36:33 +02:00
co-authored by Claude Opus 5.5
parent 06a58e08d5
commit e94123fa40
9 changed files with 174 additions and 11 deletions
+17 -1
View File
@@ -554,6 +554,20 @@ async Task PanelTests()
}
Check(code == 200 && host.Panel.SharesGamePort, "Panel is back on the game port");
// Neues Spiel statt hochgeladenem Spielstand
var ng = await Call(owner, "POST", "api/world/newgame");
Check(ng.status == 200 && File.Exists(Path.Combine(dir, "save", SaveStore.NewGameMarker)) && !SaveStore.HasSave(dir),
"New game: the save is backed up and replaced by a new-game marker: " + ng.json);
await WaitForState(HostState.Running);
for (int i = 0; i < 40 && (Srv() == null || !Srv().NewGame); i++) await Task.Delay(100);
Check(Srv() != null && Srv().NewGame && SaveStore.ResetPointIsNewGame(dir), "The server runs a new game (also as reset point)");
var fresh = await TestClient.Join("Fresh", 0, null);
var start = fresh.StartGamePayload;
bool startsNew = false;
if (start != null && start.Length >= 2) { var sr = new BinaryReader(new MemoryStream(start)); sr.ReadBoolean(); startsNew = sr.ReadBoolean(); }
Check(startsNew, "Joining players are told to start a new game");
fresh.Close();
await Call(owner, "POST", "api/logout");
Check((await Call(owner, "GET", "api/status")).status == 401, "Logout ends the session");
}
@@ -647,6 +661,7 @@ sealed class TestClient
public bool? AdminStatus;
public int SaveFiles;
public bool GotStartGame;
public byte[] StartGamePayload;
public string RejectReason;
public Dictionary<string, byte[]> Files = new();
@@ -683,7 +698,8 @@ sealed class TestClient
string fname = fr.ReadString();
c.Files[fname] = fr.ReadBytes(fr.ReadInt32());
}
c.GotStartGame = await c.WaitFor(MsgType.StartGame, 1500) != null || c.SaveFiles > 0;
c.StartGamePayload = await c.WaitFor(MsgType.StartGame, 1500);
c.GotStartGame = c.StartGamePayload != null || c.SaveFiles > 0;
return c;
}