From 30d0297d54810b934ee211979fb6e49e37f10f4d Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sun, 6 Sep 2026 18:25:44 +0200 Subject: [PATCH] Flush progression only while server is idle --- gamemode/sv_progression.lua | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/gamemode/sv_progression.lua b/gamemode/sv_progression.lua index 110f851..08cf7bd 100644 --- a/gamemode/sv_progression.lua +++ b/gamemode/sv_progression.lua @@ -2,6 +2,7 @@ if not SERVER then return end local Progression = CustomCoopProgression local playerStates = setmetatable({}, { __mode = "k" }) +local disconnectedStates = {} local requestCooldowns = setmetatable({}, { __mode = "k" }) local shopPrices = {} local dirtyShopPrices = {} @@ -190,6 +191,17 @@ local function LoadPlayer(ply) local steamID64 = ply:SteamID64() if not steamID64 or steamID64 == "" then return end + -- A reconnect can happen before an idle write. Reuse the newer in-memory + -- state instead of replacing it with the older database snapshot. + local disconnectedState = disconnectedStates[steamID64] + if disconnectedState then + disconnectedStates[steamID64] = nil + disconnectedState.playerName = ply:Nick() + playerStates[ply] = disconnectedState + SyncPlayer(ply, disconnectedState) + return disconnectedState + end + local row = Query( "SELECT lifetime_score, credits, equipped_model, equipped_weapon " .. "FROM custom_coop_players WHERE steamid64 = " .. SQLString(steamID64) .. " LIMIT 1", @@ -352,15 +364,26 @@ local function FlushDirtyProgression() SavePlayerState(ply, state) end + for steamID64, state in pairs(disconnectedStates) do + if SavePlayerState(nil, state) then + disconnectedStates[steamID64] = nil + end + end + SaveDirtyShopPrices() end +local function FlushProgressionWhenServerIsEmpty() + if #player.GetHumans() > 0 then return end + FlushDirtyProgression() +end + local function StartProgressionSaveTimer() timer.Create( "CustomCoopProgressionSaveTotals", math.max(totalsSaveInterval:GetFloat(), 10), 0, - FlushDirtyProgression + FlushProgressionWhenServerIsEmpty ) end @@ -659,9 +682,15 @@ hook.Add("PlayerInitialSpawn", "CustomCoopProgressionLoad", function(ply) end) hook.Add("PlayerDisconnected", "CustomCoopProgressionForget", function(ply) - SavePlayerState(ply, playerStates[ply]) + local state = playerStates[ply] + if state and (state.profileDirty or next(state.pendingOwnedItems) ~= nil) then + disconnectedStates[state.steamID64] = state + end + playerStates[ply] = nil requestCooldowns[ply] = nil + + timer.Simple(0, FlushProgressionWhenServerIsEmpty) end) hook.Add("ShutDown", "CustomCoopProgressionSaveOnShutdown", function()