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 unit id', { itemStocks: { 'ghost-unit': { bean: 1 } } }],
|
||||||
['unknown item stock item id', { itemStocks: { 'liu-bei': { phantomItem: 1 } } }],
|
['unknown item stock item id', { itemStocks: { 'liu-bei': { phantomItem: 1 } } }],
|
||||||
['invalid buff turns', { battleBuffs: [{ ...validState.battleBuffs[0], turns: 0 }] }],
|
['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' }] }],
|
['unknown buff unit id', { battleBuffs: [{ ...validState.battleBuffs[0], unitId: 'ghost-unit' }] }],
|
||||||
['duplicate buff unit id', { battleBuffs: [validState.battleBuffs[0], { ...validState.battleBuffs[0] }] }],
|
['duplicate buff unit id', { battleBuffs: [validState.battleBuffs[0], { ...validState.battleBuffs[0] }] }],
|
||||||
['invalid status kind', { battleStatuses: [{ ...validState.battleStatuses[0], kind: 'poison' }] }],
|
['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' }] }],
|
['unknown status unit id', { battleStatuses: [{ ...validState.battleStatuses[0], unitId: 'ghost-unit' }] }],
|
||||||
['duplicate status unit kind', { battleStatuses: [validState.battleStatuses[0], { ...validState.battleStatuses[0] }] }],
|
['duplicate status unit kind', { battleStatuses: [validState.battleStatuses[0], { ...validState.battleStatuses[0] }] }],
|
||||||
['invalid stats shape', { battleStats: { 'liu-bei': { damageDealt: 10 } } }],
|
['invalid stats shape', { battleStats: { 'liu-bei': { damageDealt: 10 } } }],
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ const maxBattleBondEntries = 128;
|
|||||||
const maxTriggeredBattleEventLength = 96;
|
const maxTriggeredBattleEventLength = 96;
|
||||||
const defaultBattleSaveArrayLimit = 128;
|
const defaultBattleSaveArrayLimit = 128;
|
||||||
const defaultBattleItemStockLimit = 9;
|
const defaultBattleItemStockLimit = 9;
|
||||||
|
const maxBattleEffectLabelLength = 32;
|
||||||
|
const maxBattleEffectTurns = 9;
|
||||||
|
const maxBattleBuffBonus = 99;
|
||||||
|
const maxBattleStatusPower = 99;
|
||||||
const maxStatusKindsPerUnit = 2;
|
const maxStatusKindsPerUnit = 2;
|
||||||
const maxBattleItemStockById: Record<string, number> = {
|
const maxBattleItemStockById: Record<string, number> = {
|
||||||
bean: 3,
|
bean: 3,
|
||||||
@@ -165,6 +169,10 @@ function isPositiveInteger(value: unknown) {
|
|||||||
return Number.isInteger(value) && Number(value) >= 1;
|
return Number.isInteger(value) && Number(value) >= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPositiveIntegerAtMost(value: unknown, max: number) {
|
||||||
|
return isPositiveInteger(value) && Number(value) <= max;
|
||||||
|
}
|
||||||
|
|
||||||
function isNonNegativeFiniteNumber(value: unknown) {
|
function isNonNegativeFiniteNumber(value: unknown) {
|
||||||
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
||||||
}
|
}
|
||||||
@@ -177,6 +185,10 @@ function isFiniteNumber(value: unknown) {
|
|||||||
return typeof value === 'number' && Number.isFinite(value);
|
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) {
|
function isValidIsoLikeDate(value: unknown) {
|
||||||
return typeof value === 'string' && value.length > 0 && !Number.isNaN(Date.parse(value));
|
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);
|
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) {
|
function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOptions) {
|
||||||
return (
|
return (
|
||||||
value === undefined ||
|
value === undefined ||
|
||||||
@@ -393,11 +409,11 @@ function isOptionalBuffArray(value: unknown, options: BattleSaveValidationOption
|
|||||||
isRecord(buff) &&
|
isRecord(buff) &&
|
||||||
typeof buff.unitId === 'string' &&
|
typeof buff.unitId === 'string' &&
|
||||||
isKnownUnitId(buff.unitId, options) &&
|
isKnownUnitId(buff.unitId, options) &&
|
||||||
typeof buff.label === 'string' &&
|
isValidEffectLabel(buff.label) &&
|
||||||
isPositiveInteger(buff.turns) &&
|
isPositiveIntegerAtMost(buff.turns, maxBattleEffectTurns) &&
|
||||||
isFiniteNumber(buff.attackBonus) &&
|
isIntegerInRange(buff.attackBonus, 0, maxBattleBuffBonus) &&
|
||||||
isFiniteNumber(buff.hitBonus) &&
|
isIntegerInRange(buff.hitBonus, 0, maxBattleBuffBonus) &&
|
||||||
isFiniteNumber(buff.criticalBonus)
|
isIntegerInRange(buff.criticalBonus, 0, maxBattleBuffBonus)
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -414,9 +430,9 @@ function isOptionalStatusArray(value: unknown, options: BattleSaveValidationOpti
|
|||||||
typeof status.unitId === 'string' &&
|
typeof status.unitId === 'string' &&
|
||||||
isKnownUnitId(status.unitId, options) &&
|
isKnownUnitId(status.unitId, options) &&
|
||||||
isBattleStatusKind(status.kind) &&
|
isBattleStatusKind(status.kind) &&
|
||||||
typeof status.label === 'string' &&
|
isValidEffectLabel(status.label) &&
|
||||||
isPositiveInteger(status.turns) &&
|
isPositiveIntegerAtMost(status.turns, maxBattleEffectTurns) &&
|
||||||
isFiniteNumber(status.power)
|
isPositiveIntegerAtMost(status.power, maxBattleStatusPower)
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user