From d9a50ba0640eb8960153018c567a88c2f512662f Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sun, 5 Jul 2026 13:37:00 +0900 Subject: [PATCH] Limit battle save item stocks --- scripts/verify-battle-save-normalization.mjs | 1 + src/game/state/battleSaveState.ts | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/verify-battle-save-normalization.mjs b/scripts/verify-battle-save-normalization.mjs index 9d19705..d9470c8 100644 --- a/scripts/verify-battle-save-normalization.mjs +++ b/scripts/verify-battle-save-normalization.mjs @@ -85,6 +85,7 @@ try { ['invalid max-level bond exp threshold', { bonds: [{ ...validState.bonds[0], level: 100, exp: 101 }] }], ['invalid bond battle exp', { bonds: [{ ...validState.bonds[0], battleExp: 1.5 }] }], ['invalid item stock count', { itemStocks: { 'liu-bei': { bean: -1 } } }], + ['too many item stock count', { itemStocks: { 'liu-bei': { bean: 4, wine: 2 } } }], ['unknown item stock unit id', { itemStocks: { 'ghost-unit': { bean: 1 } } }], ['unknown item stock item id', { itemStocks: { 'liu-bei': { phantomItem: 1 } } }], ['invalid buff turns', { battleBuffs: [{ ...validState.battleBuffs[0], turns: 0 }] }], diff --git a/src/game/state/battleSaveState.ts b/src/game/state/battleSaveState.ts index a5ab8ee..96c8bcc 100644 --- a/src/game/state/battleSaveState.ts +++ b/src/game/state/battleSaveState.ts @@ -86,7 +86,13 @@ const maxBattleLogEntryLength = 96; const maxBattleBondEntries = 128; const maxTriggeredBattleEventLength = 96; const defaultBattleSaveArrayLimit = 128; +const defaultBattleItemStockLimit = 9; const maxStatusKindsPerUnit = 2; +const maxBattleItemStockById: Record = { + bean: 3, + salve: 2, + wine: 1 +}; export function normalizeBattleSaveSlot(slot: number, slotCount: number) { const safeSlot = Number.isFinite(slot) ? Math.floor(slot) : 1; @@ -367,11 +373,15 @@ function isOptionalItemStockRecord(value: unknown, options: BattleSaveValidation Object.keys(stocks).length <= itemReferenceLimit(options) && Object.entries(stocks).every( ([itemId, count]) => - (!options.validItemIds || options.validItemIds.has(itemId)) && Number.isInteger(count) && Number(count) >= 0 + (!options.validItemIds || options.validItemIds.has(itemId)) && isValidItemStockCount(itemId, count) ) ); } +function isValidItemStockCount(itemId: string, count: unknown) { + return Number.isInteger(count) && Number(count) >= 0 && Number(count) <= (maxBattleItemStockById[itemId] ?? defaultBattleItemStockLimit); +} + function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOptions) { return ( value === undefined ||