Clamp battle save unit stats

This commit is contained in:
2026-07-05 13:44:35 +09:00
parent 3a5ee11a6d
commit deaec059ee
2 changed files with 12 additions and 5 deletions

View File

@@ -103,6 +103,8 @@ try {
['unknown status unit id', { battleStatuses: [{ ...validState.battleStatuses[0], unitId: 'ghost-unit' }] }],
['duplicate status unit kind', { battleStatuses: [validState.battleStatuses[0], { ...validState.battleStatuses[0] }] }],
['invalid stats shape', { battleStats: { 'liu-bei': { damageDealt: 10 } } }],
['invalid stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], actions: 1.5 } } }],
['too high stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], damageDealt: 1000000 } } }],
['unknown stats unit id', { battleStats: { 'ghost-unit': validState.battleStats['liu-bei'] } }],
['invalid enemy usable keys', { enemyUsableUseKeys: [1] }],
['malformed enemy usable key', { enemyUsableUseKeys: ['rebel-1:shout'] }],

View File

@@ -91,6 +91,7 @@ const maxBattleEffectLabelLength = 32;
const maxBattleEffectTurns = 9;
const maxBattleBuffBonus = 99;
const maxBattleStatusPower = 99;
const maxBattleUnitStatValue = 999999;
const maxStatusKindsPerUnit = 2;
const maxBattleItemStockById: Record<string, number> = {
bean: 3,
@@ -398,6 +399,10 @@ function isValidEffectLabel(value: unknown) {
return typeof value === 'string' && value.length > 0 && value.length <= maxBattleEffectLabelLength;
}
function isBattleUnitStatValue(value: unknown) {
return isIntegerInRange(value, 0, maxBattleUnitStatValue);
}
function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOptions) {
return (
value === undefined ||
@@ -454,11 +459,11 @@ function isOptionalStatsRecord(value: unknown, options: BattleSaveValidationOpti
([unitId, stats]) =>
isKnownUnitId(unitId, options) &&
isRecord(stats) &&
isNonNegativeFiniteNumber(stats.damageDealt) &&
isNonNegativeFiniteNumber(stats.damageTaken) &&
isNonNegativeFiniteNumber(stats.defeats) &&
isNonNegativeFiniteNumber(stats.actions) &&
isNonNegativeFiniteNumber(stats.support)
isBattleUnitStatValue(stats.damageDealt) &&
isBattleUnitStatValue(stats.damageTaken) &&
isBattleUnitStatValue(stats.defeats) &&
isBattleUnitStatValue(stats.actions) &&
isBattleUnitStatValue(stats.support)
);
}