From 15df3532fbc7f0ca356b1672af2ed5bba7b2ca5c Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sun, 5 Jul 2026 14:05:03 +0900 Subject: [PATCH] Validate battle save campaign step --- scripts/verify-battle-save-normalization.mjs | 1 + src/game/state/battleSaveState.ts | 6 +++++- src/game/state/campaignState.ts | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/verify-battle-save-normalization.mjs b/scripts/verify-battle-save-normalization.mjs index 656fc19..12b4535 100644 --- a/scripts/verify-battle-save-normalization.mjs +++ b/scripts/verify-battle-save-normalization.mjs @@ -44,6 +44,7 @@ try { ['invalid turnNumber', { turnNumber: 0 }], ['invalid activeFaction', { activeFaction: 'neutral' }], ['invalid rosterTab', { rosterTab: 'neutral' }], + ['invalid campaign step', { campaignStep: 'lost-progress' }], ['invalid actedUnitIds', { actedUnitIds: 'liu-bei' }], ['unknown acted unit id', { actedUnitIds: ['ghost-unit'] }], ['duplicate acted unit id', { actedUnitIds: ['liu-bei', 'liu-bei'] }], diff --git a/src/game/state/battleSaveState.ts b/src/game/state/battleSaveState.ts index 492d825..a8063c3 100644 --- a/src/game/state/battleSaveState.ts +++ b/src/game/state/battleSaveState.ts @@ -1,5 +1,5 @@ import type { BattleBond, UnitData } from '../data/scenario'; -import type { CampaignStep } from './campaignState'; +import { isCampaignStep, type CampaignStep } from './campaignState'; import type { UnitDirection } from '../data/unitAssets'; import { equipmentExpToNext, equipmentSlots, type EquipmentSlot } from '../data/battleItems'; @@ -142,6 +142,10 @@ export function isValidBattleSaveState(state: unknown, options: BattleSaveValida return false; } + if (state.campaignStep !== undefined && !isCampaignStep(state.campaignStep)) { + return false; + } + const attackIntents = state.attackIntents; const units = state.units; diff --git a/src/game/state/campaignState.ts b/src/game/state/campaignState.ts index d7e3dca..2a6b99f 100644 --- a/src/game/state/campaignState.ts +++ b/src/game/state/campaignState.ts @@ -1237,8 +1237,12 @@ function normalizeReserveTrainingFocusId(focusId?: string): CampaignReserveTrain : defaultCampaignReserveTrainingFocusId; } +export function isCampaignStep(value: unknown): value is CampaignStep { + return typeof value === 'string' && campaignStepIds.has(value as CampaignStep); +} + function normalizeCampaignStep(step: unknown): CampaignStep { - return typeof step === 'string' && campaignStepIds.has(step as CampaignStep) ? step as CampaignStep : 'new'; + return isCampaignStep(step) ? step : 'new'; } function normalizeFirstBattleReport(report: unknown): FirstBattleReport | undefined {