diff --git a/package-lock.json b/package-lock.json index 4f90b38cf..095e70e82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,8 +18,9 @@ "@mui/material": "^5.0.3", "@mui/styles": "^5.0.1", "@mui/system": "^5.0.3", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", + "@types/estree": "^1.0.0", + "acorn": "^8.7.1", + "acorn-walk": "^8.2.0", "arg": "^5.0.0", "bcryptjs": "^2.4.3", "better-react-mathjax": "^1.0.3", @@ -4000,10 +4001,9 @@ "dev": true }, "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "node_modules/@types/file-saver": { "version": "2.0.3", @@ -25221,10 +25221,9 @@ "dev": true }, "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "@types/file-saver": { "version": "2.0.3", diff --git a/package.json b/package.json index 39e41fb4c..eb408b2a8 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,9 @@ "@mui/material": "^5.0.3", "@mui/styles": "^5.0.1", "@mui/system": "^5.0.3", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", + "@types/estree": "^1.0.0", + "acorn": "^8.7.1", + "acorn-walk": "^8.2.0", "arg": "^5.0.0", "bcryptjs": "^2.4.3", "better-react-mathjax": "^1.0.3", diff --git a/src/Arcade/ui/BBCabinet.tsx b/src/Arcade/ui/BBCabinet.tsx index 137b579d9..b0627b2f0 100644 --- a/src/Arcade/ui/BBCabinet.tsx +++ b/src/Arcade/ui/BBCabinet.tsx @@ -9,7 +9,7 @@ const style = { width: "1060px", height: "800px", border: "0px", -} as any; +}; export function BBCabinetRoot(): React.ReactElement { const player = use.Player(); diff --git a/src/Milestones/Milestones.ts b/src/Milestones/Milestones.ts index a420c90ce..24df22411 100644 --- a/src/Milestones/Milestones.ts +++ b/src/Milestones/Milestones.ts @@ -4,6 +4,7 @@ import { Factions } from "../Faction/Factions"; import { Faction } from "../Faction/Faction"; import { GetServer } from "../Server/AllServers"; import { FactionNames } from "../Faction/data/FactionNames"; +import { Server } from "../Server/Server"; function allFactionAugs(p: IPlayer, f: Faction): boolean { const factionAugs = f.augmentations.slice().filter((aug) => aug !== "NeuroFlux Governor"); @@ -24,7 +25,7 @@ export const Milestones: Milestone[] = [ fulfilled: (): boolean => { const server = GetServer("CSEC"); if (!server || !server.hasOwnProperty("hasAdminRights")) return false; - return (server as any).hasAdminRights; + return server instanceof Server && server.hasAdminRights; }, }, { @@ -32,7 +33,7 @@ export const Milestones: Milestone[] = [ fulfilled: (): boolean => { const server = GetServer("CSEC"); if (!server || !server.hasOwnProperty("backdoorInstalled")) return false; - return (server as any).backdoorInstalled; + return server instanceof Server && server.backdoorInstalled; }, }, { diff --git a/src/NetscriptJSEvaluator.ts b/src/NetscriptJSEvaluator.ts index c90aa55a6..191bad566 100644 --- a/src/NetscriptJSEvaluator.ts +++ b/src/NetscriptJSEvaluator.ts @@ -12,6 +12,9 @@ import { Script } from "./Script/Script"; import { areImportsEquals } from "./Terminal/DirectoryHelpers"; import { IPlayer } from "./PersonObjects/IPlayer"; +// Acorn type def is straight up incomplete so we have to fill with our own. +export type Node = any; + // Makes a blob that contains the code of a given script. function makeScriptBlob(code: string): Blob { return new Blob([code], { type: "text/javascript" }); @@ -144,36 +147,39 @@ function _getScriptUrls(script: Script, scripts: Script[], seen: Script[]): Scri // Where the blob URL contains the script content. // Parse the code into an ast tree - const ast: any = parse(script.code, { sourceType: "module", ecmaVersion: "latest", ranges: true }); - - const importNodes: Array = []; + const ast = parse(script.code, { sourceType: "module", ecmaVersion: "latest", ranges: true }); + interface importNode { + filename: string; + start: number; + end: number; + } + const importNodes: importNode[] = []; // Walk the nodes of this tree and find any import declaration statements. walk.simple(ast, { - ImportDeclaration(node: any) { + ImportDeclaration(node: Node) { // Push this import onto the stack to replace + if (!node.source) return; importNodes.push({ filename: node.source.value, start: node.source.range[0] + 1, end: node.source.range[1] - 1, }); }, - ExportNamedDeclaration(node: any) { - if (node.source) { - importNodes.push({ - filename: node.source.value, - start: node.source.range[0] + 1, - end: node.source.range[1] - 1, - }); - } + ExportNamedDeclaration(node: Node) { + if (!node.source) return; + importNodes.push({ + filename: node.source.value, + start: node.source.range[0] + 1, + end: node.source.range[1] - 1, + }); }, - ExportAllDeclaration(node: any) { - if (node.source) { - importNodes.push({ - filename: node.source.value, - start: node.source.range[0] + 1, - end: node.source.range[1] - 1, - }); - } + ExportAllDeclaration(node: Node) { + if (!node.source) return; + importNodes.push({ + filename: node.source.value, + start: node.source.range[0] + 1, + end: node.source.range[1] - 1, + }); }, }); // Sort the nodes from last start index to first. This replaces the last import with a blob first, diff --git a/src/NetscriptWorker.ts b/src/NetscriptWorker.ts index c0a779a8a..298f9438e 100644 --- a/src/NetscriptWorker.ts +++ b/src/NetscriptWorker.ts @@ -485,9 +485,6 @@ function processNetscript1Imports(code: string, workerScript: WorkerScript): any * Used to start a RunningScript (by creating and starting its * corresponding WorkerScript), and add the RunningScript to the server on which * it is active - * @param {RunningScript} runningScriptObj - Script that's being run - * @param {Server} server - Server on which the script is to be run - * @returns {number} pid of started script */ export function startWorkerScript( player: IPlayer, diff --git a/src/Player.ts b/src/Player.ts index b936aa382..dce46eb01 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -7,6 +7,6 @@ export let Player = new PlayerObject(); export function loadPlayer(saveString: string): void { Player = JSON.parse(saveString, Reviver); - Player.money = parseFloat(Player.money as any); + Player.money = parseFloat(Player.money + ""); Player.exploits = sanitizeExploits(Player.exploits); } diff --git a/src/Script/RamCalculations.ts b/src/Script/RamCalculations.ts index 97f630b65..b7216e816 100644 --- a/src/Script/RamCalculations.ts +++ b/src/Script/RamCalculations.ts @@ -15,6 +15,7 @@ import { Script } from "./Script"; import { WorkerScript } from "../Netscript/WorkerScript"; import { areImportsEquals } from "../Terminal/DirectoryHelpers"; import { IPlayer } from "../PersonObjects/IPlayer"; +import { Node } from "../NetscriptJSEvaluator"; export interface RamUsageEntry { type: "ns" | "dom" | "fn" | "misc"; @@ -282,11 +283,11 @@ export function checkInfiniteLoop(code: string): number { ast, {}, { - WhileStatement: (node: acorn.Node, st: unknown, walkDeeper: walk.WalkerCallback) => { - if (nodeHasTrueTest((node as any).test) && !hasAwait(node)) { + WhileStatement: (node: Node, st: unknown, walkDeeper: walk.WalkerCallback) => { + if (nodeHasTrueTest(node.test) && !hasAwait(node)) { missingAwaitLine = (code.slice(0, node.start).match(/\n/g) || []).length + 1; } else { - (node as any).body && walkDeeper((node as any).body, st); + node.body && walkDeeper(node.body, st); } }, }, @@ -295,13 +296,20 @@ export function checkInfiniteLoop(code: string): number { return missingAwaitLine; } +interface ParseDepsResult { + dependencyMap: { + [key: string]: Set | undefined; + }; + additionalModules: string[]; +} + /** * Helper function that parses a single script. It returns a map of all dependencies, * which are items in the code's AST that potentially need to be evaluated * for RAM usage calculations. It also returns an array of additional modules * that need to be parsed (i.e. are 'import'ed scripts). */ -function parseOnlyCalculateDeps(code: string, currentModule: string): any { +function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsResult { const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" }); // Everything from the global scope goes in ".". Everything else goes in ".function", where only // the outermost layer of functions counts. @@ -330,52 +338,56 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): any { //A list of identifiers that resolve to "native Javascript code" const objectPrototypeProperties = Object.getOwnPropertyNames(Object.prototype); + interface State { + key: string; + } + // If we discover a dependency identifier, state.key is the dependent identifier. // walkDeeper is for doing recursive walks of expressions in composites that we handle. - function commonVisitors(): any { + function commonVisitors(): walk.RecursiveVisitors { return { - Identifier: (node: any, st: any) => { + Identifier: (node: Node, st: State) => { if (objectPrototypeProperties.includes(node.name)) { return; } addRef(st.key, node.name); }, - WhileStatement: (node: any, st: any, walkDeeper: any) => { + WhileStatement: (node: Node, st: State, walkDeeper: walk.WalkerCallback) => { addRef(st.key, specialReferenceWHILE); node.test && walkDeeper(node.test, st); node.body && walkDeeper(node.body, st); }, - DoWhileStatement: (node: any, st: any, walkDeeper: any) => { + DoWhileStatement: (node: Node, st: State, walkDeeper: walk.WalkerCallback) => { addRef(st.key, specialReferenceWHILE); node.test && walkDeeper(node.test, st); node.body && walkDeeper(node.body, st); }, - ForStatement: (node: any, st: any, walkDeeper: any) => { + ForStatement: (node: Node, st: State, walkDeeper: walk.WalkerCallback) => { addRef(st.key, specialReferenceFOR); node.init && walkDeeper(node.init, st); node.test && walkDeeper(node.test, st); node.update && walkDeeper(node.update, st); node.body && walkDeeper(node.body, st); }, - IfStatement: (node: any, st: any, walkDeeper: any) => { + IfStatement: (node: Node, st: State, walkDeeper: walk.WalkerCallback) => { addRef(st.key, specialReferenceIF); node.test && walkDeeper(node.test, st); node.consequent && walkDeeper(node.consequent, st); node.alternate && walkDeeper(node.alternate, st); }, - MemberExpression: (node: any, st: any, walkDeeper: any) => { + MemberExpression: (node: Node, st: State, walkDeeper: walk.WalkerCallback) => { node.object && walkDeeper(node.object, st); node.property && walkDeeper(node.property, st); }, }; } - walk.recursive( + walk.recursive( ast, { key: globalKey }, Object.assign( { - ImportDeclaration: (node: any, st: any) => { + ImportDeclaration: (node: Node, st: State) => { const importModuleName = node.source.value; additionalModules.push(importModuleName); @@ -398,7 +410,7 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): any { } } }, - FunctionDeclaration: (node: any) => { + FunctionDeclaration: (node: Node) => { // node.id will be null when using 'export default'. Add a module name indicating the default export. const key = currentModule + "." + (node.id === null ? "__SPECIAL_DEFAULT_EXPORT__" : node.id.name); walk.recursive(node, { key: key }, commonVisitors()); diff --git a/src/Sidebar/ui/SidebarRoot.tsx b/src/Sidebar/ui/SidebarRoot.tsx index 3161715f4..09531197d 100644 --- a/src/Sidebar/ui/SidebarRoot.tsx +++ b/src/Sidebar/ui/SidebarRoot.tsx @@ -157,11 +157,11 @@ export function SidebarRoot(props: IProps): React.ReactElement { const canOpenSleeves = props.player.sleeves.length > 0; - const canCorporation = !!(props.player.corporation as any); - const canGang = !!(props.player.gang as any); + const canCorporation = !!props.player.corporation; + const canGang = !!props.player.gang; const canJob = props.player.companyName !== ""; const canStockMarket = props.player.hasWseAccount; - const canBladeburner = !!(props.player.bladeburner as any); + const canBladeburner = !!props.player.bladeburner; const canStaneksGift = props.player.augmentations.some((aug) => aug.name === AugmentationNames.StaneksGift1); function clickTerminal(): void { diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index c19ce6742..cd2fb2d3f 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -518,7 +518,7 @@ export class Terminal implements ITerminal { const d = depthQueue.pop(); if (d === undefined) continue; const isHacknet = s instanceof HacknetServer; - if (!all && (s as any).purchasedByPlayer && s.hostname != "home") { + if (!all && s.purchasedByPlayer && s.hostname != "home") { continue; // Purchased server } else if (visited[s.hostname] || d > depth) { continue; // Already visited or out-of-depth @@ -548,12 +548,14 @@ export class Terminal implements ITerminal { if (s.hasAdminRights) { c = "YES"; } - this.print( - `${dashes}Root Access: ${c}${!isHacknet ? ", Required hacking skill: " + (s as any).requiredHackingSkill : ""}`, - ); + if (s instanceof Server) { + this.print( + `${dashes}Root Access: ${c}${!isHacknet ? ", Required hacking skill: " + s.requiredHackingSkill : ""}`, + ); - if (s.hasOwnProperty("numOpenPortsRequired")) { - this.print(dashes + "Number of open ports required to NUKE: " + (s as any).numOpenPortsRequired); + if (s.hasOwnProperty("numOpenPortsRequired")) { + this.print(dashes + "Number of open ports required to NUKE: " + s.numOpenPortsRequired); + } } this.print(dashes + "RAM: " + numeralWrapper.formatRAM(s.maxRam)); this.print(" ");