Tighten battle bond save validation

This commit is contained in:
2026-07-05 13:21:47 +09:00
parent 70cd7305a8
commit 9985998a5b
2 changed files with 22 additions and 3 deletions

View File

@@ -72,6 +72,12 @@ try {
['duplicate unit id', { units: [validState.units[0], { ...validState.units[0], x: 2 }, validState.units[2]] }],
['invalid bonds', { bonds: [{ ...validState.bonds[0], unitIds: ['liu-bei'] }] }],
['unknown bond unit id', { bonds: [{ ...validState.bonds[0], unitIds: ['liu-bei', 'ghost-unit'] }] }],
['invalid bond level', { bonds: [{ ...validState.bonds[0], level: 0 }] }],
['too high bond level', { bonds: [{ ...validState.bonds[0], level: 101 }] }],
['invalid bond exp', { bonds: [{ ...validState.bonds[0], exp: -1 }] }],
['invalid bond exp threshold', { bonds: [{ ...validState.bonds[0], level: 1, exp: 100 }] }],
['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 } } }],
['unknown item stock unit id', { itemStocks: { 'ghost-unit': { bean: 1 } } }],
['unknown item stock item id', { itemStocks: { 'liu-bei': { phantomItem: 1 } } }],

View File

@@ -162,6 +162,10 @@ function isNonNegativeFiniteNumber(value: unknown) {
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
}
function isNonNegativeInteger(value: unknown) {
return Number.isInteger(value) && Number(value) >= 0;
}
function isFiniteNumber(value: unknown) {
return typeof value === 'number' && Number.isFinite(value);
}
@@ -313,13 +317,22 @@ function isBondArray(value: unknown, options: BattleSaveValidationOptions) {
Array.isArray(bond.unitIds) &&
bond.unitIds.length === 2 &&
bond.unitIds.every((unitId) => typeof unitId === 'string' && isKnownUnitId(unitId, options)) &&
isPositiveInteger(bond.level) &&
isNonNegativeFiniteNumber(bond.exp) &&
isNonNegativeFiniteNumber(bond.battleExp)
isValidBondProgress(bond.level, bond.exp) &&
isNonNegativeInteger(bond.battleExp)
)
);
}
function isValidBondProgress(level: unknown, exp: unknown) {
return (
isPositiveInteger(level) &&
Number(level) <= 100 &&
Number.isInteger(exp) &&
Number(exp) >= 0 &&
(Number(level) >= 100 ? Number(exp) <= 100 : Number(exp) < 100)
);
}
function isOptionalItemStockRecord(value: unknown, options: BattleSaveValidationOptions) {
if (value === undefined) {
return true;