diff --git a/src/Hacknet/HacknetNode.ts b/src/Hacknet/HacknetNode.ts index 9d79f334d..5cb950232 100644 --- a/src/Hacknet/HacknetNode.ts +++ b/src/Hacknet/HacknetNode.ts @@ -18,34 +18,16 @@ import { HacknetNodeConstants } from "./data/Constants"; import { dialogBoxCreate } from "../ui/React/DialogBox"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver"; -import { ObjectValidator } from "src/utils/Validator"; +import { ObjectValidator, minMax } from "../utils/Validator"; export class HacknetNode implements IHacknetNode { static validationData: ObjectValidator = { - cores: { - default: 1, - min: 1, - max: HacknetNodeConstants.MaxCores - }, - level: { - default: 1, - min: 1, - max: HacknetNodeConstants.MaxLevel - }, - ram: { - default: 1, - min: 1, - max: HacknetNodeConstants.MaxRam - }, - onlineTimeSeconds: { - default: 0, - min: 0 - }, - totalMoneyGenerated: { - default: 0, - min: 0 - } + cores: minMax(1, 1, HacknetNodeConstants.MaxCores), + level: minMax(1, 1, HacknetNodeConstants.MaxLevel), + ram: minMax(1, 1, HacknetNodeConstants.MaxRam), + onlineTimeSeconds: minMax(0, 0, Infinity), + totalMoneyGenerated: minMax(0, 0, Infinity) } // Node's number of cores diff --git a/src/utils/Validator.ts b/src/utils/Validator.ts index a97b5b039..21daba59e 100644 --- a/src/utils/Validator.ts +++ b/src/utils/Validator.ts @@ -2,30 +2,77 @@ export type ObjectValidator = { [key in keyof T]?: ParameterValidator; } -interface ParameterValidator { +interface ParameterValidatorObject { default?: any; min?: number; max?: number; - func?: (obj: T, validator: ObjectValidator, key: U) => void; + func?: (obj: Type, validator: ObjectValidator, key: Key) => void; } +type ParameterValidatorFunction = (obj: Type, key: Key) => void; +type ParameterValidator = ParameterValidatorObject | ParameterValidatorFunction -export function validateObject, U extends keyof T>(obj: T, validator: ObjectValidator): void { - for (const key of Object.keys(validator) as U[]) { +export function validateObject, Key extends keyof Type>(obj: Type, validator: ObjectValidator): void { + for (const key of Object.keys(validator) as Key[]) { const paramValidator = validator[key]; if (paramValidator !== undefined) { - if (paramValidator.func !== undefined) { - paramValidator.func(obj, validator, key); + if (typeof paramValidator === 'function') { + paramValidator(obj, key); } else { - if ((typeof obj[key]) !== (typeof paramValidator.default)) { - obj[key] = paramValidator.default - } - if (typeof obj[key] === 'number' && paramValidator.min !== undefined) { - if (obj[key] < paramValidator.min) obj[key] = paramValidator.min as T[U]; - } - if (typeof obj[key] === 'number' && paramValidator.max !== undefined) { - if (obj[key] > paramValidator.max) obj[key] = paramValidator.max as T[U]; + if (paramValidator.func !== undefined) { + paramValidator.func(obj, validator, key); + } else { + if ((typeof obj[key]) !== (typeof paramValidator.default)) { + obj[key] = paramValidator.default + } + if (typeof obj[key] === 'number' && paramValidator.min !== undefined) { + if (obj[key] < paramValidator.min) obj[key] = paramValidator.min as Type[Key]; + } + if (typeof obj[key] === 'number' && paramValidator.max !== undefined) { + if (obj[key] > paramValidator.max) obj[key] = paramValidator.max as Type[Key]; + } } } } } +} + +export function minMax(def: number, min: number, max: number): (obj: Type, key: Key & keyof Type) => void { + return (obj, key) => { + if (typeof obj[key] !== 'number') { + obj[key] = def as unknown as Type[Key]; + return; + } + if ((obj[key] as unknown as number) < min) { + obj[key] = min as unknown as Type[Key]; + } + if ((obj[key] as unknown as number) > max) { + obj[key] = max as unknown as Type[Key]; + } + }; +} + +export function oneOf(def: Value, options: Value[]): (obj: Type, key: Key & keyof Type) => void { + return (obj, key) => { + if (typeof obj[key] !== typeof def) { + obj[key] = def as unknown as Type[Key]; + return; + } + if (!options.includes(obj[key] as unknown as Value)) { + obj[key] = def as unknown as Type[Key]; + } + }; +} + +export function subsetOf(options: Value[]): (obj: Type, key: Key & keyof Type) => void { + return (obj, key) => { + if (typeof obj[key] !== 'object' || !Array.isArray(obj[key])) { + obj[key] = [] as unknown as Type[Key]; + return; + } + const validValues: Value[] = []; + for (const value of obj[key] as unknown as Value[]) { + if (options.includes(value)) validValues.push(value); + } + obj[key] = validValues as unknown as Type[Key]; + }; } \ No newline at end of file