Clamp battle save effect state

This commit is contained in:
2026-07-05 13:40:20 +09:00
parent d9a50ba064
commit 3a5ee11a6d
2 changed files with 32 additions and 8 deletions

View File

@@ -87,6 +87,10 @@ const maxBattleBondEntries = 128;
const maxTriggeredBattleEventLength = 96;
const defaultBattleSaveArrayLimit = 128;
const defaultBattleItemStockLimit = 9;
const maxBattleEffectLabelLength = 32;
const maxBattleEffectTurns = 9;
const maxBattleBuffBonus = 99;
const maxBattleStatusPower = 99;
const maxStatusKindsPerUnit = 2;
const maxBattleItemStockById: Record<string, number> = {
bean: 3,
@@ -165,6 +169,10 @@ function isPositiveInteger(value: unknown) {
return Number.isInteger(value) && Number(value) >= 1;
}
function isPositiveIntegerAtMost(value: unknown, max: number) {
return isPositiveInteger(value) && Number(value) <= max;
}
function isNonNegativeFiniteNumber(value: unknown) {
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
}
@@ -177,6 +185,10 @@ function isFiniteNumber(value: unknown) {
return typeof value === 'number' && Number.isFinite(value);
}
function isIntegerInRange(value: unknown, min: number, max: number) {
return Number.isInteger(value) && Number(value) >= min && Number(value) <= max;
}
function isValidIsoLikeDate(value: unknown) {
return typeof value === 'string' && value.length > 0 && !Number.isNaN(Date.parse(value));
}
@@ -382,6 +394,10 @@ function isValidItemStockCount(itemId: string, count: unknown) {
return Number.isInteger(count) && Number(count) >= 0 && Number(count) <= (maxBattleItemStockById[itemId] ?? defaultBattleItemStockLimit);
}
function isValidEffectLabel(value: unknown) {
return typeof value === 'string' && value.length > 0 && value.length <= maxBattleEffectLabelLength;
}
function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOptions) {
return (
value === undefined ||
@@ -393,11 +409,11 @@ function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOption
isRecord(buff) &&
typeof buff.unitId === 'string' &&
isKnownUnitId(buff.unitId, options) &&
typeof buff.label === 'string' &&
isPositiveInteger(buff.turns) &&
isFiniteNumber(buff.attackBonus) &&
isFiniteNumber(buff.hitBonus) &&
isFiniteNumber(buff.criticalBonus)
isValidEffectLabel(buff.label) &&
isPositiveIntegerAtMost(buff.turns, maxBattleEffectTurns) &&
isIntegerInRange(buff.attackBonus, 0, maxBattleBuffBonus) &&
isIntegerInRange(buff.hitBonus, 0, maxBattleBuffBonus) &&
isIntegerInRange(buff.criticalBonus, 0, maxBattleBuffBonus)
))
);
}
@@ -414,9 +430,9 @@ function isOptionalStatusArray(value: unknown, options: BattleSaveValidationOpti
typeof status.unitId === 'string' &&
isKnownUnitId(status.unitId, options) &&
isBattleStatusKind(status.kind) &&
typeof status.label === 'string' &&
isPositiveInteger(status.turns) &&
isFiniteNumber(status.power)
isValidEffectLabel(status.label) &&
isPositiveIntegerAtMost(status.turns, maxBattleEffectTurns) &&
isPositiveIntegerAtMost(status.power, maxBattleStatusPower)
))
);
}