Admin world actions (reset, backup, restore) over AdminAction; backup list in admin list; 'backup' command; safer restore via staging; tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 16:43:48 +02:00
co-authored by Claude Opus 5.5
parent 9444ffa109
commit 0f62c17c90
4 changed files with 94 additions and 26 deletions
+19
View File
@@ -232,6 +232,25 @@ try
Check(fresh2.Ok && fresh2.Info.Contains("0 events"), "Replayed actions are cleared - they are in the save now (" + fresh2.Info + ")");
Check(Directory.Exists(Path.Combine(dir, "save_backups")) && Directory.GetDirectories(Path.Combine(dir, "save_backups")).Length > 0,
"The previous save game is kept as a backup");
Console.WriteLine("== World admin: reset / backup / restore");
newcomer.Send(MsgType.AdminAction, Wire.Build(w => { w.Write((byte)5); w.Write(-1); w.Write(""); }));
var resetTry = await newcomer.WaitFor(MsgType.AdminResult);
Check(resetTry != null && ReadString(resetTry).Contains("not an admin") && !newcomer.IsClosedByServer(), "Non-admin cannot reset the world");
newcomer.Send(MsgType.AdminAction, Wire.Build(w => { w.Write((byte)7); w.Write(-1); w.Write("1"); }));
var restoreTry = await newcomer.WaitFor(MsgType.AdminResult);
Check(restoreTry != null && ReadString(restoreTry).Contains("not an admin"), "Non-admin cannot restore a backup");
string backupsDir = Path.Combine(dir, "save_backups");
int before = Directory.GetDirectories(backupsDir).Length;
await Task.Delay(1100); // Backups heißen nach der Sekunde
server.EnqueueCommand("backup");
await Task.Delay(500);
Check(Directory.GetDirectories(backupsDir).Length == Math.Min(before + 1, 5), "'backup' creates a new backup of the current save");
// Aktuellen Spielstand verändern, dann das neueste Backup (= CURRENT-SAVE) zurückholen
File.WriteAllText(Path.Combine(dir, "save", "defaultES2File.txt"), "BROKEN");
server.EnqueueCommand("restore-save 1");
var restoreMsg = await newcomer.WaitFor(MsgType.Reconnect);
Check(restoreMsg != null, "Restoring a backup makes everyone reconnect");
Check(File.ReadAllText(Path.Combine(dir, "save", "defaultES2File.txt")).EndsWith("CURRENT-SAVE"), "The backup's files are back in the active save");
inGame.Close();
newcomer.Close();
}