Clamp battle save effect state
This commit is contained in:
@@ -89,9 +89,17 @@ try {
|
||||
['unknown item stock unit id', { itemStocks: { 'ghost-unit': { bean: 1 } } }],
|
||||
['unknown item stock item id', { itemStocks: { 'liu-bei': { phantomItem: 1 } } }],
|
||||
['invalid buff turns', { battleBuffs: [{ ...validState.battleBuffs[0], turns: 0 }] }],
|
||||
['too many buff turns', { battleBuffs: [{ ...validState.battleBuffs[0], turns: 10 }] }],
|
||||
['too long buff label', { battleBuffs: [{ ...validState.battleBuffs[0], label: 'x'.repeat(33) }] }],
|
||||
['invalid buff bonus', { battleBuffs: [{ ...validState.battleBuffs[0], hitBonus: 1.5 }] }],
|
||||
['too high buff bonus', { battleBuffs: [{ ...validState.battleBuffs[0], criticalBonus: 100 }] }],
|
||||
['unknown buff unit id', { battleBuffs: [{ ...validState.battleBuffs[0], unitId: 'ghost-unit' }] }],
|
||||
['duplicate buff unit id', { battleBuffs: [validState.battleBuffs[0], { ...validState.battleBuffs[0] }] }],
|
||||
['invalid status kind', { battleStatuses: [{ ...validState.battleStatuses[0], kind: 'poison' }] }],
|
||||
['too many status turns', { battleStatuses: [{ ...validState.battleStatuses[0], turns: 10 }] }],
|
||||
['too long status label', { battleStatuses: [{ ...validState.battleStatuses[0], label: 'x'.repeat(33) }] }],
|
||||
['invalid status power', { battleStatuses: [{ ...validState.battleStatuses[0], power: 0 }] }],
|
||||
['too high status power', { battleStatuses: [{ ...validState.battleStatuses[0], power: 100 }] }],
|
||||
['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 } } }],
|
||||
|
||||
@@ -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)
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user