From a232bd616a8ff2432cebabee012595eb333e7d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Snorre=20L=C3=B8v=C3=A5s?= Date: Wed, 15 Jul 2026 19:50:53 +0200 Subject: [PATCH] fix: use default capacity if savegame value is invalid A savegame capacity that that is invalid/overflow Int32 was set to 0. Use default capacity instead to avoid losing all fill --- scripts/RmAdjustStorageCapacity.lua | 7 ++++ .../placeables/RmPlaceableStorageCapacity.lua | 36 +++++++++++++------ scripts/vehicles/RmVehicleStorageCapacity.lua | 12 ++++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/scripts/RmAdjustStorageCapacity.lua b/scripts/RmAdjustStorageCapacity.lua index 7d3505a..c2350a8 100644 --- a/scripts/RmAdjustStorageCapacity.lua +++ b/scripts/RmAdjustStorageCapacity.lua @@ -78,6 +78,13 @@ function RmAdjustStorageCapacity.clampToMax(value) return value, false end +--- Check if value is valid. +---@param value any Value parsed from the savegame (XMLValueType.INT -> number/nil/other) +---@return boolean valid True when value is a number in [0, MAX_CAPACITY] +function RmAdjustStorageCapacity.isStoredCapacityValid(value) + return type(value) == "number" and value >= 0 and value <= RmAdjustStorageCapacity.MAX_CAPACITY +end + -- ============================================================================ -- Storage Enumeration and Type Detection -- ============================================================================ diff --git a/scripts/placeables/RmPlaceableStorageCapacity.lua b/scripts/placeables/RmPlaceableStorageCapacity.lua index 980609b..97432c0 100644 --- a/scripts/placeables/RmPlaceableStorageCapacity.lua +++ b/scripts/placeables/RmPlaceableStorageCapacity.lua @@ -137,14 +137,18 @@ function RmPlaceableStorageCapacity:onLoad(savegame) local name = xmlFile:getValue(ftKey .. "#name") local capacity = xmlFile:getValue(ftKey .. "#capacity") if name and capacity then - -- Defensive [0, MAX] clamp: heal a pre-fix / hand-edited save (over-max or wrapped-negative). - capacity = math.max(0, (RmAdjustStorageCapacity.clampToMax(capacity))) - local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(name) - if fillTypeIndex then - entry.fillTypes[fillTypeIndex] = capacity - Log:debug("LOAD_SAVEGAME: Read fillType %s = %d", name, capacity) + -- Check if the parsed capacity is valid. If not, keep the engine default + if not RmAdjustStorageCapacity.isStoredCapacityValid(capacity) then + Log:warning("LOAD_SAVEGAME: %s dropped corrupt fillType '%s' capacity (parsed %s) - keeping engine default", + placeableName, name, tostring(capacity)) else - Log:warning("LOAD_SAVEGAME: Unknown fill type '%s' in savegame", name) + local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(name) + if fillTypeIndex then + entry.fillTypes[fillTypeIndex] = capacity + Log:debug("LOAD_SAVEGAME: Read fillType %s = %d", name, capacity) + else + Log:warning("LOAD_SAVEGAME: Unknown fill type '%s' in savegame", name) + end end end end) @@ -152,15 +156,25 @@ function RmPlaceableStorageCapacity:onLoad(savegame) -- Read husbandry food capacity entry.husbandryFood = xmlFile:getValue(modKey .. ".husbandryFood#capacity") if entry.husbandryFood then - entry.husbandryFood = math.max(0, (RmAdjustStorageCapacity.clampToMax(entry.husbandryFood))) - Log:debug("LOAD_SAVEGAME: Read husbandryFood = %d", entry.husbandryFood) + if not RmAdjustStorageCapacity.isStoredCapacityValid(entry.husbandryFood) then + Log:warning("LOAD_SAVEGAME: %s dropped corrupt husbandryFood capacity (parsed %s) - keeping engine default", + placeableName, tostring(entry.husbandryFood)) + entry.husbandryFood = nil + else + Log:debug("LOAD_SAVEGAME: Read husbandryFood = %d", entry.husbandryFood) + end end -- Read shared capacity entry.sharedCapacity = xmlFile:getValue(modKey .. ".sharedCapacity#value") if entry.sharedCapacity then - entry.sharedCapacity = math.max(0, (RmAdjustStorageCapacity.clampToMax(entry.sharedCapacity))) - Log:debug("LOAD_SAVEGAME: Read sharedCapacity = %d", entry.sharedCapacity) + if not RmAdjustStorageCapacity.isStoredCapacityValid(entry.sharedCapacity) then + Log:warning("LOAD_SAVEGAME: %s dropped corrupt sharedCapacity (parsed %s) - keeping engine default", + placeableName, tostring(entry.sharedCapacity)) + entry.sharedCapacity = nil + else + Log:debug("LOAD_SAVEGAME: Read sharedCapacity = %d", entry.sharedCapacity) + end end -- Apply if we have data diff --git a/scripts/vehicles/RmVehicleStorageCapacity.lua b/scripts/vehicles/RmVehicleStorageCapacity.lua index b9b51b1..95bc5c4 100644 --- a/scripts/vehicles/RmVehicleStorageCapacity.lua +++ b/scripts/vehicles/RmVehicleStorageCapacity.lua @@ -393,10 +393,14 @@ function RmVehicleStorageCapacity:onLoad(savegame) local index = xmlFile:getValue(fuKey .. "#index") local capacity = xmlFile:getValue(fuKey .. "#capacity") if index and capacity then - -- Defensive [0, MAX] clamp: heal a pre-fix / hand-edited save (over-max or wrapped-negative). - capacity = math.max(0, (RmAdjustStorageCapacity.clampToMax(capacity))) - entry[index] = capacity - Log:debug("LOAD_SAVEGAME: Read fillUnit %d = %d", index, capacity) + -- Check if the parsed capacity is valid. If not, keep the engine default. + if not RmAdjustStorageCapacity.isStoredCapacityValid(capacity) then + Log:warning("LOAD_SAVEGAME: %s dropped corrupt fillUnit[%s] capacity (parsed %s) - keeping engine default", + vehicleName, tostring(index), tostring(capacity)) + else + entry[index] = capacity + Log:debug("LOAD_SAVEGAME: Read fillUnit %d = %d", index, capacity) + end end end)