From 816c53870552887031b28cd8a8cafefa33450ab1 Mon Sep 17 00:00:00 2001 From: MrMaho Date: Thu, 1 Oct 2026 20:36:07 +0200 Subject: [PATCH] Fewer hitches: regular save-game pull only when something changed since the last save (saving freezes the game briefly), default interval 10 min Co-Authored-By: Claude Opus 5.5 --- GameServer.cs | 3 ++- ServerConfig.cs | 2 +- WorldState.cs | 13 +++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/GameServer.cs b/GameServer.cs index 3b6a9ba..0257d9e 100644 --- a/GameServer.cs +++ b/GameServer.cs @@ -268,7 +268,8 @@ public sealed class GameServer if (config.SaveSyncMinutes > 0 && now >= nextSaveSync) { nextSaveSync = now + config.SaveSyncMinutes * 60.0; - RequestSave("regular save"); + // Nur wenn sich seit dem letzten Spielstand etwas geändert hat - Speichern lässt das Spiel kurz hängen + if (world.ChangesSinceSave > 0) RequestSave("regular save"); } // Hochladen dauert zu lange (Spieler weg, alte Mod ...): Wartende bekommen den bisherigen Spielstand if (saveUpload != null && DateTime.UtcNow > saveUpload.Deadline) diff --git a/ServerConfig.cs b/ServerConfig.cs index 41a112e..e6e9e66 100644 --- a/ServerConfig.cs +++ b/ServerConfig.cs @@ -25,7 +25,7 @@ public sealed class ServerConfig /// So oft (Minuten) lässt sich der Server von einem Spieler im Spiel den aktuellen Spielstand hochladen /// (Schrauben, Teile, alles wie im Spiel gespeichert). Zusätzlich immer, wenn jemand beitritt. 0 = nur beim Beitreten. /// - public int SaveSyncMinutes { get; set; } = 5; + public int SaveSyncMinutes { get; set; } = 10; /// Optional: Steam Web API Key, um Steam-Tickets der Spieler bei Steam zu prüfen. public string SteamWebApiKey { get; set; } = ""; /// Gesperrte SteamID64s. diff --git a/WorldState.cs b/WorldState.cs index caa22a2..058ba9e 100644 --- a/WorldState.cs +++ b/WorldState.cs @@ -40,6 +40,12 @@ public sealed class WorldState public const int MaxDestroyed = 5000; public bool Dirty { get; private set; } + /// + /// Änderungen, die im Spielstand landen (Aktionen, Fahrzeugwerte, Geld, Türen, Käufe ...) seit dem letzten hochgeladenen + /// Spielstand. 0 = der regelmäßige Spielstand-Abruf kann ausfallen (Speichern lässt das Spiel kurz hängen). + /// + [System.Text.Json.Serialization.JsonIgnore] + public int ChangesSinceSave { get; set; } = 1; static readonly JsonSerializerOptions Options = new() { WriteIndented = false }; @@ -64,6 +70,7 @@ public sealed class WorldState /// public void ResetForNewSave() { + ChangesSinceSave = 0; Objects.Clear(); Events.Clear(); MoneyDelta = 0f; @@ -141,6 +148,7 @@ public sealed class WorldState public void ApplyMoney(byte[] payload) { + ChangesSinceSave++; if (payload.Length < 4) return; MoneyDelta += BitConverter.ToSingle(payload, 0); Dirty = true; @@ -148,6 +156,7 @@ public sealed class WorldState public void ApplyDoor(byte[] payload) { + ChangesSinceSave++; using var r = new BinaryReader(new MemoryStream(payload)); string key = r.ReadString(); Doors[key] = r.ReadString(); @@ -156,6 +165,7 @@ public sealed class WorldState public void ApplyVars(byte[] payload) { + ChangesSinceSave++; using var r = new BinaryReader(new MemoryStream(payload)); int count = r.ReadInt32(); if (count < 0 || count > 10000) return; @@ -187,6 +197,7 @@ public sealed class WorldState public void AddAppeared(byte[] payload) { + ChangesSinceSave++; if (Appeared.Count >= MaxAppeared) return; Appeared.Add(Convert.ToBase64String(payload)); Dirty = true; @@ -194,6 +205,7 @@ public sealed class WorldState public void AddDestroyed(int id) { + ChangesSinceSave++; if (Destroyed.Count >= MaxDestroyed || Destroyed.Contains(id)) return; Destroyed.Add(id); Objects.Remove(id); @@ -203,6 +215,7 @@ public sealed class WorldState public void AddFsmEvent(byte[] payload) { if (Events.Count >= MaxEvents) return; + ChangesSinceSave++; Events.Add(Convert.ToBase64String(payload)); Dirty = true; }