Clamp campaign save numeric fields

This commit is contained in:
2026-07-05 13:52:42 +09:00
parent fe5a3edfd2
commit 1145ef14aa
2 changed files with 10 additions and 8 deletions

View File

@@ -282,7 +282,7 @@ try {
updatedAt: '',
step: 'third-camp',
activeSaveSlot: '2',
gold: '410',
gold: '1000000',
roster: { corrupted: true },
bonds: [
{ id: 'broken-bond', title: 'Broken Bond', unitIds: { corrupted: true }, level: 3, exp: 12, battleExp: 2 },
@@ -315,7 +315,7 @@ try {
);
const malformed = loadCampaignState();
assert(malformed.step === 'third-camp', `Expected malformed save progress to survive: ${JSON.stringify(malformed)}`);
assert(malformed.activeSaveSlot === 2 && malformed.gold === 410, `Expected malformed numeric fields to normalize: ${JSON.stringify(malformed)}`);
assert(malformed.activeSaveSlot === 2 && malformed.gold === 999999, `Expected malformed numeric fields to normalize and clamp: ${JSON.stringify(malformed)}`);
assert(Array.isArray(malformed.roster) && malformed.roster.length === 0, `Expected malformed roster to reset to an array: ${JSON.stringify(malformed)}`);
assert(
Array.isArray(malformed.bonds) &&
@@ -577,11 +577,11 @@ try {
battleTitle: ' ',
outcome: 'victory',
turnNumber: '4',
rewardGold: '120',
rewardGold: '1000000',
defeatedEnemies: '3',
totalEnemies: '5',
objectives: [
{ id: 'village', label: 'Village', achieved: true, detail: 12, summary: 'x'.repeat(220), rewardGold: '80' },
{ id: 'village', label: 'Village', achieved: true, detail: 12, summary: 'x'.repeat(220), rewardGold: '1000000' },
{ id: '', label: 'Broken', achieved: true },
...Array.from({ length: 30 }, (_, index) => ({
id: `bonus-${index}`,
@@ -640,7 +640,7 @@ try {
battleExp: 1
}))
],
mvp: { unitId: 'liu-bei', name: 'Liu Bei', damageDealt: '88', defeats: '2' },
mvp: { unitId: 'liu-bei', name: 'Liu Bei', damageDealt: '1000000', defeats: '2' },
itemRewards: ['Bean', 'Bean', 10, 'x'.repeat(97)],
campaignRewards: {
supplies: [' Bean ', 'Bean', 20, 'x'.repeat(97)],
@@ -673,14 +673,15 @@ try {
malformedReport.firstBattleReport?.battleId === 'first-battle-zhuo-commandery' &&
malformedReport.firstBattleReport.battleTitle === firstScenario.title &&
malformedReport.firstBattleReport.turnNumber === 4 &&
malformedReport.firstBattleReport.rewardGold === 999999 &&
malformedReport.firstBattleReport.objectives.length === 24 &&
malformedReport.firstBattleReport.objectives[0].rewardGold === 80 &&
malformedReport.firstBattleReport.objectives[0].rewardGold === 999999 &&
malformedReport.firstBattleReport.objectives[0].summary.length === 180 &&
malformedReport.firstBattleReport.units.length === 96 &&
malformedReport.firstBattleReport.units[0].level === 5 &&
malformedReport.firstBattleReport.bonds.length === 96 &&
malformedReport.firstBattleReport.bonds[0].battleExp === 4 &&
malformedReport.firstBattleReport.mvp?.damageDealt === 88 &&
malformedReport.firstBattleReport.mvp?.damageDealt === 999999 &&
malformedReport.firstBattleReport.itemRewards.length === 1 &&
malformedReport.firstBattleReport.campaignRewards?.supplies.length === 1 &&
malformedReport.firstBattleReport.campaignRewards?.supplies[0] === 'Bean' &&

View File

@@ -276,6 +276,7 @@ const maxCampaignBattleBondEntries = 96;
const maxCampaignReserveTrainingEntries = 96;
const maxCampaignSortieAssignmentUnits = 96;
const maxCampaignDisplayTextLength = 180;
const maxCampaignNumericValue = 999999;
export const campaignReserveTrainingFocusDefinitions: CampaignReserveTrainingFocusDefinition[] = [
{
@@ -945,7 +946,7 @@ function normalizedRosterUnitIds(roster: UnitData[]) {
function normalizeNonNegativeInteger(value: unknown) {
const numeric = Math.floor(Number(value));
return Number.isFinite(numeric) && numeric > 0 ? numeric : 0;
return Number.isFinite(numeric) && numeric > 0 ? Math.min(numeric, maxCampaignNumericValue) : 0;
}
function normalizeCharacterLevel(value: unknown) {