diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 74ce942c0..191a3104d 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -70,17 +70,17 @@ export class Bladeburner implements IBladeburner { type: ActionTypes["Idle"], }); - cities: any = {}; + cities: Record = {}; city: string = BladeburnerConstants.CityNames[2]; - skills: any = {}; - skillMultipliers: any = {}; + skills: Record = {}; + skillMultipliers: Record = {}; staminaBonus = 0; maxStamina = 0; stamina = 0; - contracts: any = {}; - operations: any = {}; - blackops: any = {}; - logging: any = { + contracts: Record = {}; + operations: Record = {}; + blackops: Record = {}; + logging = { general: true, contracts: true, ops: true, @@ -477,54 +477,54 @@ export class Bladeburner implements IBladeburner { this.postToConsole("Effects: "); const multKeys = Object.keys(this.skillMultipliers); for (let i = 0; i < multKeys.length; ++i) { - let mult = this.skillMultipliers[multKeys[i]]; + const mult = this.skillMultipliers[multKeys[i]]; if (mult && mult !== 1) { - mult = formatNumber(mult, 3); + const mults = formatNumber(mult, 3); switch (multKeys[i]) { case "successChanceAll": - this.postToConsole("Total Success Chance: x" + mult); + this.postToConsole("Total Success Chance: x" + mults); break; case "successChanceStealth": - this.postToConsole("Stealth Success Chance: x" + mult); + this.postToConsole("Stealth Success Chance: x" + mults); break; case "successChanceKill": - this.postToConsole("Retirement Success Chance: x" + mult); + this.postToConsole("Retirement Success Chance: x" + mults); break; case "successChanceContract": - this.postToConsole("Contract Success Chance: x" + mult); + this.postToConsole("Contract Success Chance: x" + mults); break; case "successChanceOperation": - this.postToConsole("Operation Success Chance: x" + mult); + this.postToConsole("Operation Success Chance: x" + mults); break; case "successChanceEstimate": - this.postToConsole("Synthoid Data Estimate: x" + mult); + this.postToConsole("Synthoid Data Estimate: x" + mults); break; case "actionTime": - this.postToConsole("Action Time: x" + mult); + this.postToConsole("Action Time: x" + mults); break; case "effHack": - this.postToConsole("Hacking Skill: x" + mult); + this.postToConsole("Hacking Skill: x" + mults); break; case "effStr": - this.postToConsole("Strength: x" + mult); + this.postToConsole("Strength: x" + mults); break; case "effDef": - this.postToConsole("Defense: x" + mult); + this.postToConsole("Defense: x" + mults); break; case "effDex": - this.postToConsole("Dexterity: x" + mult); + this.postToConsole("Dexterity: x" + mults); break; case "effAgi": - this.postToConsole("Agility: x" + mult); + this.postToConsole("Agility: x" + mults); break; case "effCha": - this.postToConsole("Charisma: x" + mult); + this.postToConsole("Charisma: x" + mults); break; case "effInt": - this.postToConsole("Intelligence: x" + mult); + this.postToConsole("Intelligence: x" + mults); break; case "stamina": - this.postToConsole("Stamina: x" + mult); + this.postToConsole("Stamina: x" + mults); break; default: console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`); @@ -2029,12 +2029,12 @@ export class Bladeburner implements IBladeburner { this.stamina = Math.min(this.maxStamina, this.stamina); // Count increase for contracts/operations - for (const contract of Object.values(this.contracts) ) { + for (const contract of Object.values(this.contracts)) { const growthF = Growths[contract.name]; if (growthF === undefined) throw new Error(`growth formula for action '${contract.name}' is undefined`); contract.count += (seconds * growthF()) / BladeburnerConstants.ActionCountGrowthPeriod; } - for (const op of Object.values(this.operations) ) { + for (const op of Object.values(this.operations)) { const growthF = Growths[op.name]; if (growthF === undefined) throw new Error(`growth formula for action '${op.name}' is undefined`); if (growthF !== undefined) { diff --git a/src/DevMenu.tsx b/src/DevMenu.tsx index 91321e3a3..6bcb2eab3 100644 --- a/src/DevMenu.tsx +++ b/src/DevMenu.tsx @@ -66,7 +66,7 @@ export function DevMenuRoot(props: IProps): React.ReactElement { - + ); } diff --git a/src/Netscript/Environment.ts b/src/Netscript/Environment.ts index 3c4da20ed..ca98b5af6 100644 --- a/src/Netscript/Environment.ts +++ b/src/Netscript/Environment.ts @@ -2,6 +2,7 @@ * The environment in which a script runs. The environment holds * Netscript functions and arguments for that script. */ +import { NS } from "src/ScriptEditor/NetscriptDefinitions"; import { IMap } from "../types"; export class Environment { @@ -18,7 +19,7 @@ export class Environment { /** * Environment variables (currently only Netscript functions) */ - vars: IMap = {}; + vars: any = {}; constructor(parent: Environment | null) { if (parent instanceof Environment) { diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts index 5979142d2..e07a92ea0 100644 --- a/src/Netscript/WorkerScript.ts +++ b/src/Netscript/WorkerScript.ts @@ -14,6 +14,7 @@ import { Script } from "../Script/Script"; import { GetServer } from "../Server/AllServers"; import { BaseServer } from "../Server/BaseServer"; import { IMap } from "../types"; +import { NS } from "../ScriptEditor/NetscriptDefinitions"; export class WorkerScript { /** @@ -116,7 +117,7 @@ export class WorkerScript { */ infiniteLoopSafety = performance.now(); - constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => any) { + constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => NS) { this.name = runningScriptObj.filename; this.hostname = runningScriptObj.server; diff --git a/src/utils/helpers/clearObject.ts b/src/utils/helpers/clearObject.ts index e3184d901..2fa973e13 100644 --- a/src/utils/helpers/clearObject.ts +++ b/src/utils/helpers/clearObject.ts @@ -5,11 +5,12 @@ * @param obj the object to clear all properties */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function clearObject(obj: any): void { - for (const key in obj) { +export function clearObject(obj: unknown): void { + if (typeof obj !== "object" || obj === null || obj === undefined) return; + for (const key of Object.getOwnPropertyNames(obj)) { if (obj.hasOwnProperty(key)) { // tslint:disable-next-line:no-dynamic-delete - delete obj[key]; + delete (obj as any)[key]; } } } diff --git a/src/utils/helpers/compareArrays.ts b/src/utils/helpers/compareArrays.ts index c729add7b..fc3d0009c 100644 --- a/src/utils/helpers/compareArrays.ts +++ b/src/utils/helpers/compareArrays.ts @@ -9,18 +9,18 @@ export function compareArrays(a1: T[], a2: T[]): boolean { } for (let i = 0; i < a1.length; ++i) { - if (Array.isArray(a1[i])) { + const v1 = a1[i]; + const v2 = a2[i]; + if (Array.isArray(v1)) { // If the other element is not an array, then these cannot be equal - if (!Array.isArray(a2[i])) { + if (!Array.isArray(v2)) { return false; } - const elem1 = a1[i] as any; - const elem2 = a2[i] as any; - if (!compareArrays(elem1, elem2)) { + if (!compareArrays(v1, v2)) { return false; } - } else if (a1[i] !== a2[i] && !(Number.isNaN(a1[i]) && Number.isNaN(a2[i]))) { + } else if (v1 !== v2 && !(Number.isNaN(v1) && Number.isNaN(v2))) { // strict (in)equality considers NaN not equal to itself return false; } diff --git a/src/utils/helpers/exceptionAlert.ts b/src/utils/helpers/exceptionAlert.ts index 45b0991ec..c466cfd6f 100644 --- a/src/utils/helpers/exceptionAlert.ts +++ b/src/utils/helpers/exceptionAlert.ts @@ -7,15 +7,25 @@ interface IError { export function exceptionAlert(e: IError | string): void { console.error(e); + let msg = ""; + let file = "UNKNOWN FILE NAME"; + let line = "UNKNOWN LINE NUMBER"; + const isError = (e: IError | string): e is IError => e.hasOwnProperty("fileName"); + if (isError(e)) { + file = e.fileName ?? file; + line = e.lineNumber?.toString() ?? line; + } else { + msg = e; + } dialogBoxCreate( "Caught an exception: " + - e + + msg + "

" + "Filename: " + - ((e as any).fileName || "UNKNOWN FILE NAME") + + file + "

" + "Line Number: " + - ((e as any).lineNumber || "UNKNOWN LINE NUMBER") + + line + "

" + "This is a bug, please report to game developer with this " + "message as well as details about how to reproduce the bug.

" + diff --git a/src/utils/helpers/is2DArray.ts b/src/utils/helpers/is2DArray.ts index 7475dac83..868785d04 100644 --- a/src/utils/helpers/is2DArray.ts +++ b/src/utils/helpers/is2DArray.ts @@ -1,12 +1,10 @@ +export function isArray(arr: unknown): arr is unknown[] { + return Array.isArray(arr); +} + // Checks whether an array is a 2D array. // For this, a 2D array is an array which contains only other arrays. // If one element in the array is a number or string, it is NOT a 2D array -export function is2DArray(arr: any[]): boolean { - if (arr.constructor !== Array) { - return false; - } - - return arr.every((e) => { - return e.constructor === Array; - }); +export function is2DArray(arr: unknown): arr is unknown[][] { + return isArray(arr) && arr.every((u) => isArray(u)); } diff --git a/test/jest/Netscript/DynamicRamCalculation.test.js b/test/jest/Netscript/DynamicRamCalculation.test.js index be823ed70..319a7ef2b 100644 --- a/test/jest/Netscript/DynamicRamCalculation.test.js +++ b/test/jest/Netscript/DynamicRamCalculation.test.js @@ -13,6 +13,11 @@ const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost; describe("Netscript Dynamic RAM Calculation/Generation Tests", function () { // Creates a mock RunningScript object + /** + * + * @param {string} code + * @returns + */ async function createRunningScript(code) { const script = new Script(); script.code = code; @@ -24,12 +29,23 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () { } // Tests numeric equality, allowing for floating point imprecision + /** + * + * @param {number} val + * @param {number} expected + */ function testEquality(val, expected) { expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON); expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON); } // Runs a Netscript function and properly catches it if it returns promise + + /** + * + * @param {(...args: unknown[]) => unknown} fn + * @param {unknown[]} args + */ function runPotentiallyAsyncFunction(fn, ...args) { const res = fn(...args); if (res instanceof Promise) { @@ -93,7 +109,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () { runPotentiallyAsyncFunction(curr, ...args); } catch (e) {} } else { - throw new Error(`Invalid function specified: [${fnDesc}]`); + throw new Error(`Invalid function specified: [${fnDesc.toString()}]`); } const fnName = fnDesc[fnDesc.length - 1]; diff --git a/test/jest/Netscript/StaticRamCalculation.test.js b/test/jest/Netscript/StaticRamCalculation.test.js index 9d5a11b10..d248047a8 100644 --- a/test/jest/Netscript/StaticRamCalculation.test.js +++ b/test/jest/Netscript/StaticRamCalculation.test.js @@ -11,6 +11,11 @@ const HacknetNamespaceCost = RamCostConstants.ScriptHacknetNodesRamCost; describe("Netscript Static RAM Calculation/Generation Tests", function () { // Tests numeric equality, allowing for floating point imprecision + /** + * + * @param {number} val + * @param {number} expected + */ function testEquality(val, expected) { expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON); expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON); @@ -25,9 +30,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () { * including the namespace(s). e.g. ["gang", "getMemberNames"] */ async function expectNonZeroRamCost(fnDesc) { - if (!Array.isArray(fnDesc)) { - expect.fail("Non-array passed to expectNonZeroRamCost()"); - } const expected = getRamCost(Player, ...fnDesc); expect(expected).toBeGreaterThan(0); @@ -50,9 +52,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () { * including the namespace(s). e.g. ["gang", "getMemberNames"] */ async function expectZeroRamCost(fnDesc) { - if (!Array.isArray(fnDesc)) { - expect.fail("Non-array passed to expectZeroRamCost()"); - } const expected = getRamCost(Player, ...fnDesc); expect(expected).toEqual(0); @@ -64,7 +63,12 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () { expect(multipleCallsCalculated).toEqual(ScriptBaseCost); } - // simplyfied version from RamCostGenerator.ts + /** + * + * @param {Player} player + * @param {number} cost + * @returns + */ function SF4Cost(player, cost) { if (player.bitNodeN === 4) return cost; const sf4 = player.sourceFileLvl(4); @@ -83,9 +87,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () { * @param {number} cost - expected cost */ async function expectSpecificRamCost(fnDesc, cost) { - if (!Array.isArray(fnDesc)) { - expect.fail("Non-array passed to expectZeroRamCost()"); - } const expected = getRamCost(Player, ...fnDesc); expect(expected).toEqual(SF4Cost(Player, cost)); diff --git a/test/jest/Netscript/StaticRamParsingCalculation.test.js b/test/jest/Netscript/StaticRamParsingCalculation.test.js index 86a2fa14a..01a927313 100644 --- a/test/jest/Netscript/StaticRamParsingCalculation.test.js +++ b/test/jest/Netscript/StaticRamParsingCalculation.test.js @@ -18,6 +18,11 @@ const CorpCost = 1024 - ScriptBaseCost; describe("Parsing NetScript code to work out static RAM costs", function () { // Tests numeric equality, allowing for floating point imprecision - and includes script base cost + /** + * + * @param {number} val + * @param {number} expected + */ function expectCost(val, expected) { const expectedWithBase = expected + ScriptBaseCost; expect(val).toBeGreaterThanOrEqual(expectedWithBase - 100 * Number.EPSILON); diff --git a/test/jest/StockMarket.test.ts b/test/jest/StockMarket.test.ts index f531d714f..6cab27121 100644 --- a/test/jest/StockMarket.test.ts +++ b/test/jest/StockMarket.test.ts @@ -457,17 +457,13 @@ describe("Stock Market Tests", function () { it("should trigger a price update when it has enough cycles", function () { // Get the initial prices - const initialValues: IMap = {}; + const initialValues: IMap = {}; for (const stockName in StockMarket) { const stock = StockMarket[stockName]; if (!(stock instanceof Stock)) { continue; } - initialValues[stock.symbol] = { - b: stock.b, - otlkMag: stock.otlkMag, - price: stock.price, - }; + initialValues[stock.symbol] = stock; } // Don't know or care how many exact cycles are required