diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index d20046895..bc204239a 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -119,7 +119,6 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { console.warn(`WorkerScript detected NaN for threadcount for ${workerScript.name} on ${workerScript.hostname}`); threads = 1; } - workerScript.dynamicRamUsage += ramCost; if (workerScript.dynamicRamUsage > 1.01 * workerScript.ramUsage) { throw makeRuntimeRejectMsg( @@ -521,8 +520,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { sprintf: sprintf, vsprintf: vsprintf, scan: function (_hostname: unknown = workerScript.hostname): string[] { - const hostname = helper.string("scan", "hostname", _hostname); updateDynamicRam("scan", getRamCost(Player, "scan")); + const hostname = helper.string("scan", "hostname", _hostname); const server = safeGetServer(hostname, "scan"); const out = []; for (let i = 0; i < server.serversOnNetwork.length; i++) { @@ -536,14 +535,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return out; }, hack: function (_hostname: unknown, { threads: requestedThreads, stock }: BasicHGWOptions = {}): Promise { - const hostname = helper.string("hack", "hostname", _hostname); updateDynamicRam("hack", getRamCost(Player, "hack")); + const hostname = helper.string("hack", "hostname", _hostname); return hack(hostname, false, { threads: requestedThreads, stock: stock }); }, hackAnalyzeThreads: function (_hostname: unknown, _hackAmount: unknown): number { + updateDynamicRam("hackAnalyzeThreads", getRamCost(Player, "hackAnalyzeThreads")); const hostname = helper.string("hackAnalyzeThreads", "hostname", _hostname); const hackAmount = helper.number("hackAnalyzeThreads", "hackAmount", _hackAmount); - updateDynamicRam("hackAnalyzeThreads", getRamCost(Player, "hackAnalyzeThreads")); // Check argument validity const server = safeGetServer(hostname, "hackAnalyzeThreads"); @@ -573,8 +572,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return hackAmount / Math.floor(server.moneyAvailable * percentHacked); }, hackAnalyze: function (_hostname: unknown): number { - const hostname = helper.string("hackAnalyze", "hostname", _hostname); updateDynamicRam("hackAnalyze", getRamCost(Player, "hackAnalyze")); + const hostname = helper.string("hackAnalyze", "hostname", _hostname); const server = safeGetServer(hostname, "hackAnalyze"); if (!(server instanceof Server)) { @@ -585,13 +584,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return calculatePercentMoneyHacked(server, Player); }, hackAnalyzeSecurity: function (_threads: unknown): number { - const threads = helper.number("hackAnalyzeSecurity", "threads", _threads); updateDynamicRam("hackAnalyzeSecurity", getRamCost(Player, "hackAnalyzeSecurity")); + const threads = helper.number("hackAnalyzeSecurity", "threads", _threads); return CONSTANTS.ServerFortifyAmount * threads; }, hackAnalyzeChance: function (_hostname: unknown): number { - const hostname = helper.string("hackAnalyzeChance", "hostname", _hostname); updateDynamicRam("hackAnalyzeChance", getRamCost(Player, "hackAnalyzeChance")); + const hostname = helper.string("hackAnalyzeChance", "hostname", _hostname); const server = safeGetServer(hostname, "hackAnalyzeChance"); if (!(server instanceof Server)) { @@ -602,8 +601,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return calculateHackingChance(server, Player); }, sleep: async function (_time: unknown = 0): Promise { - const time = helper.number("sleep", "time", _time); updateDynamicRam("sleep", getRamCost(Player, "sleep")); + const time = helper.number("sleep", "time", _time); if (time === undefined) { throw makeRuntimeErrorMsg("sleep", "Takes 1 argument."); } @@ -613,8 +612,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }); }, asleep: function (_time: unknown = 0): Promise { - const time = helper.number("asleep", "time", _time); updateDynamicRam("asleep", getRamCost(Player, "asleep")); + const time = helper.number("asleep", "time", _time); if (time === undefined) { throw makeRuntimeErrorMsg("asleep", "Takes 1 argument."); } @@ -625,8 +624,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { _hostname: unknown, { threads: requestedThreads, stock }: BasicHGWOptions = {}, ): Promise { - const hostname = helper.string("grow", "hostname", _hostname); updateDynamicRam("grow", getRamCost(Player, "grow")); + const hostname = helper.string("grow", "hostname", _hostname); const threads = resolveNetscriptRequestedThreads( workerScript, "grow", @@ -685,10 +684,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }); }, growthAnalyze: function (_hostname: unknown, _growth: unknown, _cores: unknown = 1): number { + updateDynamicRam("growthAnalyze", getRamCost(Player, "growthAnalyze")); const hostname = helper.string("growthAnalyze", "hostname", _hostname); const growth = helper.number("growthAnalyze", "growth", _growth); const cores = helper.number("growthAnalyze", "cores", _cores); - updateDynamicRam("growthAnalyze", getRamCost(Player, "growthAnalyze")); // Check argument validity const server = safeGetServer(hostname, "growthAnalyze"); @@ -703,13 +702,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return numCycleForGrowth(server, Number(growth), Player, cores); }, growthAnalyzeSecurity: function (_threads: unknown): number { - const threads = helper.number("growthAnalyzeSecurity", "threads", _threads); updateDynamicRam("growthAnalyzeSecurity", getRamCost(Player, "growthAnalyzeSecurity")); + const threads = helper.number("growthAnalyzeSecurity", "threads", _threads); return 2 * CONSTANTS.ServerFortifyAmount * threads; }, weaken: async function (_hostname: unknown, { threads: requestedThreads }: BasicHGWOptions = {}): Promise { - const hostname = helper.string("weaken", "hostname", _hostname); updateDynamicRam("weaken", getRamCost(Player, "weaken")); + const hostname = helper.string("weaken", "hostname", _hostname); const threads = resolveNetscriptRequestedThreads( workerScript, "weaken", @@ -762,9 +761,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }); }, weakenAnalyze: function (_threads: unknown, _cores: unknown = 1): number { + updateDynamicRam("weakenAnalyze", getRamCost(Player, "weakenAnalyze")); const threads = helper.number("weakenAnalyze", "threads", _threads); const cores = helper.number("weakenAnalyze", "cores", _cores); - updateDynamicRam("weakenAnalyze", getRamCost(Player, "weakenAnalyze")); const coreBonus = 1 + (cores - 1) / 16; return CONSTANTS.ServerWeakenAmount * threads * coreBonus * BitNodeMultipliers.ServerWeakenRate; }, @@ -789,8 +788,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { workerScript.print(argsToString(args)); }, printf: function (_format: unknown, ...args: any[]): void { - const format = helper.string("printf", "format", _format); updateDynamicRam("printf", getRamCost(Player, "printf")); + const format = helper.string("printf", "format", _format); if (typeof format !== "string") { throw makeRuntimeErrorMsg("printf", "First argument must be string for the format."); } @@ -821,8 +820,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { Terminal.print(`${workerScript.scriptRef.filename}: ${str}`); }, tprintf: function (_format: unknown, ...args: any[]): void { - const format = helper.string("printf", "format", _format); updateDynamicRam("tprintf", getRamCost(Player, "tprintf")); + const format = helper.string("printf", "format", _format); if (typeof format !== "string") { throw makeRuntimeErrorMsg("tprintf", "First argument must be string for the format."); } @@ -851,8 +850,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { workerScript.scriptRef.clearLog(); }, disableLog: function (_fn: unknown): void { - const fn = helper.string("disableLog", "fn", _fn); updateDynamicRam("disableLog", getRamCost(Player, "disableLog")); + const fn = helper.string("disableLog", "fn", _fn); if (fn === "ALL") { for (const fn of Object.keys(possibleLogs)) { workerScript.disableLogs[fn] = true; @@ -866,8 +865,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, enableLog: function (_fn: unknown): void { - const fn = helper.string("enableLog", "fn", _fn); updateDynamicRam("enableLog", getRamCost(Player, "enableLog")); + const fn = helper.string("enableLog", "fn", _fn); if (fn === "ALL") { for (const fn of Object.keys(possibleLogs)) { delete workerScript.disableLogs[fn]; @@ -880,8 +879,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { workerScript.log("enableLog", () => `Enabled logging for ${fn}`); }, isLogEnabled: function (_fn: unknown): boolean { - const fn = helper.string("isLogEnabled", "fn", _fn); updateDynamicRam("isLogEnabled", getRamCost(Player, "isLogEnabled")); + const fn = helper.string("isLogEnabled", "fn", _fn); if (possibleLogs[fn] === undefined) { throw makeRuntimeErrorMsg("isLogEnabled", `Invalid argument: ${fn}.`); } @@ -915,8 +914,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { LogBoxEvents.emit(runningScriptObj); }, nuke: function (_hostname: unknown): boolean { - const hostname = helper.string("tail", "hostname", _hostname); updateDynamicRam("nuke", getRamCost(Player, "nuke")); + const hostname = helper.string("tail", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("nuke", "Takes 1 argument."); } @@ -940,8 +939,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, brutessh: function (_hostname: unknown): boolean { - const hostname = helper.string("brutessh", "hostname", _hostname); updateDynamicRam("brutessh", getRamCost(Player, "brutessh")); + const hostname = helper.string("brutessh", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("brutessh", "Takes 1 argument."); } @@ -963,8 +962,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, ftpcrack: function (_hostname: unknown): boolean { - const hostname = helper.string("ftpcrack", "hostname", _hostname); updateDynamicRam("ftpcrack", getRamCost(Player, "ftpcrack")); + const hostname = helper.string("ftpcrack", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("ftpcrack", "Takes 1 argument."); } @@ -986,8 +985,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, relaysmtp: function (_hostname: unknown): boolean { - const hostname = helper.string("relaysmtp", "hostname", _hostname); updateDynamicRam("relaysmtp", getRamCost(Player, "relaysmtp")); + const hostname = helper.string("relaysmtp", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("relaysmtp", "Takes 1 argument."); } @@ -1009,8 +1008,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, httpworm: function (_hostname: unknown): boolean { - const hostname = helper.string("httpworm", "hostname", _hostname); updateDynamicRam("httpworm", getRamCost(Player, "httpworm")); + const hostname = helper.string("httpworm", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("httpworm", "Takes 1 argument"); } @@ -1032,8 +1031,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, sqlinject: function (_hostname: unknown): boolean { - const hostname = helper.string("sqlinject", "hostname", _hostname); updateDynamicRam("sqlinject", getRamCost(Player, "sqlinject")); + const hostname = helper.string("sqlinject", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("sqlinject", "Takes 1 argument."); } @@ -1055,9 +1054,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return true; }, run: function (_scriptname: unknown, _threads: unknown = 1, ...args: any[]): number { + updateDynamicRam("run", getRamCost(Player, "run")); const scriptname = helper.string("run", "scriptname", _scriptname); const threads = helper.number("run", "threads", _threads); - updateDynamicRam("run", getRamCost(Player, "run")); if (scriptname === undefined) { throw makeRuntimeErrorMsg("run", "Usage: run(scriptname, [numThreads], [arg1], [arg2]...)"); } @@ -1072,10 +1071,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return runScriptFromScript(Player, "run", scriptServer, scriptname, args, workerScript, threads); }, exec: function (_scriptname: unknown, _hostname: unknown, _threads: unknown = 1, ...args: any[]): number { + updateDynamicRam("exec", getRamCost(Player, "exec")); const scriptname = helper.string("exec", "scriptname", _scriptname); const hostname = helper.string("exec", "hostname", _hostname); const threads = helper.number("exec", "threads", _threads); - updateDynamicRam("exec", getRamCost(Player, "exec")); if (scriptname === undefined || hostname === undefined) { throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)"); } @@ -1086,9 +1085,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return runScriptFromScript(Player, "exec", server, scriptname, args, workerScript, threads); }, spawn: function (_scriptname: unknown, _threads: unknown = 1, ...args: any[]): void { + updateDynamicRam("spawn", getRamCost(Player, "spawn")); const scriptname = helper.string("spawn", "scriptname", _scriptname); const threads = helper.number("spawn", "threads", _threads); - updateDynamicRam("spawn", getRamCost(Player, "spawn")); if (!scriptname || !threads) { throw makeRuntimeErrorMsg("spawn", "Usage: spawn(scriptname, threads)"); } @@ -1160,8 +1159,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, killall: function (_hostname: unknown = workerScript.hostname): boolean { - const hostname = helper.string("killall", "hostname", _hostname); updateDynamicRam("killall", getRamCost(Player, "killall")); + const hostname = helper.string("killall", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("killall", "Takes 1 argument"); } @@ -1188,8 +1187,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, scp: async function (scriptname: any, _hostname1: unknown, hostname2?: any): Promise { - const hostname1 = helper.string("scp", "hostname1", _hostname1); updateDynamicRam("scp", getRamCost(Player, "scp")); + const hostname1 = helper.string("scp", "hostname1", _hostname1); if (arguments.length !== 2 && arguments.length !== 3) { throw makeRuntimeErrorMsg("scp", "Takes 2 or 3 arguments"); } @@ -1346,9 +1345,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }); }, ls: function (_hostname: unknown, _grep: unknown = ""): string[] { + updateDynamicRam("ls", getRamCost(Player, "ls")); const hostname = helper.string("ls", "hostname", _hostname); const grep = helper.string("ls", "grep", _grep); - updateDynamicRam("ls", getRamCost(Player, "ls")); if (hostname === undefined) { throw makeRuntimeErrorMsg("ls", "Usage: ls(hostname/ip, [grep filter])"); } @@ -1415,8 +1414,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return allFiles; }, ps: function (_hostname: unknown = workerScript.hostname): ProcessInfo[] { - const hostname = helper.string("ps", "hostname", _hostname); updateDynamicRam("ps", getRamCost(Player, "ps")); + const hostname = helper.string("ps", "hostname", _hostname); const server = safeGetServer(hostname, "ps"); const processes = []; for (const script of server.runningScripts) { @@ -1430,8 +1429,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return processes; }, hasRootAccess: function (_hostname: unknown): boolean { - const hostname = helper.string("hasRootAccess", "hostname", _hostname); updateDynamicRam("hasRootAccess", getRamCost(Player, "hasRootAccess")); + const hostname = helper.string("hasRootAccess", "hostname", _hostname); if (hostname === undefined) { throw makeRuntimeErrorMsg("hasRootAccess", "Takes 1 argument"); } @@ -1480,8 +1479,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return copy; }, getServer: function (_hostname: unknown = workerScript.hostname): IServerDef { - const hostname = helper.string("getServer", "hostname", _hostname); updateDynamicRam("getServer", getRamCost(Player, "getServer")); + const hostname = helper.string("getServer", "hostname", _hostname); const server = safeGetServer(hostname, "getServer"); const copy = Object.assign({}, server) as any; // These fields should be hidden. @@ -1504,8 +1503,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return copy; }, getServerMoneyAvailable: function (_hostname: unknown): number { - const hostname = helper.string("getServerMoneyAvailable", "hostname", _hostname); updateDynamicRam("getServerMoneyAvailable", getRamCost(Player, "getServerMoneyAvailable")); + const hostname = helper.string("getServerMoneyAvailable", "hostname", _hostname); const server = safeGetServer(hostname, "getServerMoneyAvailable"); if (!(server instanceof Server)) { workerScript.log("getServerMoneyAvailable", () => "Cannot be executed on this server."); @@ -1529,8 +1528,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.moneyAvailable; }, getServerSecurityLevel: function (_hostname: unknown): number { - const hostname = helper.string("getServerSecurityLevel", "hostname", _hostname); updateDynamicRam("getServerSecurityLevel", getRamCost(Player, "getServerSecurityLevel")); + const hostname = helper.string("getServerSecurityLevel", "hostname", _hostname); const server = safeGetServer(hostname, "getServerSecurityLevel"); if (!(server instanceof Server)) { workerScript.log("getServerSecurityLevel", () => "Cannot be executed on this server."); @@ -1546,8 +1545,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.hackDifficulty; }, getServerBaseSecurityLevel: function (_hostname: unknown): number { - const hostname = helper.string("getServerBaseSecurityLevel", "hostname", _hostname); updateDynamicRam("getServerBaseSecurityLevel", getRamCost(Player, "getServerBaseSecurityLevel")); + const hostname = helper.string("getServerBaseSecurityLevel", "hostname", _hostname); workerScript.log( "getServerBaseSecurityLevel", () => `getServerBaseSecurityLevel is deprecated because it's not useful.`, @@ -1567,8 +1566,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.baseDifficulty; }, getServerMinSecurityLevel: function (_hostname: unknown): number { - const hostname = helper.string("getServerMinSecurityLevel", "hostname", _hostname); updateDynamicRam("getServerMinSecurityLevel", getRamCost(Player, "getServerMinSecurityLevel")); + const hostname = helper.string("getServerMinSecurityLevel", "hostname", _hostname); const server = safeGetServer(hostname, "getServerMinSecurityLevel"); if (!(server instanceof Server)) { workerScript.log("getServerMinSecurityLevel", () => "Cannot be executed on this server."); @@ -1584,8 +1583,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.minDifficulty; }, getServerRequiredHackingLevel: function (_hostname: unknown): number { - const hostname = helper.string("getServerRequiredHackingLevel", "hostname", _hostname); updateDynamicRam("getServerRequiredHackingLevel", getRamCost(Player, "getServerRequiredHackingLevel")); + const hostname = helper.string("getServerRequiredHackingLevel", "hostname", _hostname); const server = safeGetServer(hostname, "getServerRequiredHackingLevel"); if (!(server instanceof Server)) { workerScript.log("getServerRequiredHackingLevel", () => "Cannot be executed on this server."); @@ -1601,8 +1600,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.requiredHackingSkill; }, getServerMaxMoney: function (_hostname: unknown): number { - const hostname = helper.string("getServerMaxMoney", "hostname", _hostname); updateDynamicRam("getServerMaxMoney", getRamCost(Player, "getServerMaxMoney")); + const hostname = helper.string("getServerMaxMoney", "hostname", _hostname); const server = safeGetServer(hostname, "getServerMaxMoney"); if (!(server instanceof Server)) { workerScript.log("getServerMaxMoney", () => "Cannot be executed on this server."); @@ -1618,8 +1617,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.moneyMax; }, getServerGrowth: function (_hostname: unknown): number { - const hostname = helper.string("getServerGrowth", "hostname", _hostname); updateDynamicRam("getServerGrowth", getRamCost(Player, "getServerGrowth")); + const hostname = helper.string("getServerGrowth", "hostname", _hostname); const server = safeGetServer(hostname, "getServerGrowth"); if (!(server instanceof Server)) { workerScript.log("getServerGrowth", () => "Cannot be executed on this server."); @@ -1632,8 +1631,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.serverGrowth; }, getServerNumPortsRequired: function (_hostname: unknown): number { - const hostname = helper.string("getServerNumPortsRequired", "hostname", _hostname); updateDynamicRam("getServerNumPortsRequired", getRamCost(Player, "getServerNumPortsRequired")); + const hostname = helper.string("getServerNumPortsRequired", "hostname", _hostname); const server = safeGetServer(hostname, "getServerNumPortsRequired"); if (!(server instanceof Server)) { workerScript.log("getServerNumPortsRequired", () => "Cannot be executed on this server."); @@ -1649,8 +1648,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return server.numOpenPortsRequired; }, getServerRam: function (_hostname: unknown): [number, number] { - const hostname = helper.string("getServerRam", "hostname", _hostname); updateDynamicRam("getServerRam", getRamCost(Player, "getServerRam")); + const hostname = helper.string("getServerRam", "hostname", _hostname); workerScript.log( "getServerRam", () => `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`, @@ -1663,28 +1662,28 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return [server.maxRam, server.ramUsed]; }, getServerMaxRam: function (_hostname: unknown): number { - const hostname = helper.string("getServerMaxRam", "hostname", _hostname); updateDynamicRam("getServerMaxRam", getRamCost(Player, "getServerMaxRam")); + const hostname = helper.string("getServerMaxRam", "hostname", _hostname); const server = safeGetServer(hostname, "getServerMaxRam"); workerScript.log("getServerMaxRam", () => `returned ${numeralWrapper.formatRAM(server.maxRam)}`); return server.maxRam; }, getServerUsedRam: function (_hostname: unknown): number { - const hostname = helper.string("getServerUsedRam", "hostname", _hostname); updateDynamicRam("getServerUsedRam", getRamCost(Player, "getServerUsedRam")); + const hostname = helper.string("getServerUsedRam", "hostname", _hostname); const server = safeGetServer(hostname, "getServerUsedRam"); workerScript.log("getServerUsedRam", () => `returned ${numeralWrapper.formatRAM(server.ramUsed)}`); return server.ramUsed; }, serverExists: function (_hostname: unknown): boolean { - const hostname = helper.string("serverExists", "hostname", _hostname); updateDynamicRam("serverExists", getRamCost(Player, "serverExists")); + const hostname = helper.string("serverExists", "hostname", _hostname); return GetServer(hostname) !== null; }, fileExists: function (_filename: unknown, _hostname: unknown = workerScript.hostname): boolean { + updateDynamicRam("fileExists", getRamCost(Player, "fileExists")); const filename = helper.string("fileExists", "filename", _filename); const hostname = helper.string("fileExists", "hostname", _hostname); - updateDynamicRam("fileExists", getRamCost(Player, "fileExists")); if (filename === undefined) { throw makeRuntimeErrorMsg("fileExists", "Usage: fileExists(scriptname, [server])"); } @@ -1729,8 +1728,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return getPurchaseServerMaxRam(); }, getPurchasedServerCost: function (_ram: unknown): number { - const ram = helper.number("getPurchasedServerCost", "ram", _ram); updateDynamicRam("getPurchasedServerCost", getRamCost(Player, "getPurchasedServerCost")); + const ram = helper.number("getPurchasedServerCost", "ram", _ram); const cost = getPurchaseServerCost(ram); if (cost === Infinity) { @@ -1741,10 +1740,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return cost; }, purchaseServer: function (_name: unknown, _ram: unknown): string { + updateDynamicRam("purchaseServer", getRamCost(Player, "purchaseServer")); const name = helper.string("purchaseServer", "name", _name); const ram = helper.number("purchaseServer", "ram", _ram); if (arguments.length !== 2) throw makeRuntimeErrorMsg("purchaseServer", "Takes 2 arguments"); - updateDynamicRam("purchaseServer", getRamCost(Player, "purchaseServer")); let hostnameStr = String(name); hostnameStr = hostnameStr.replace(/\s+/g, ""); if (hostnameStr == "") { @@ -1805,8 +1804,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return newServ.hostname; }, deleteServer: function (_name: unknown): boolean { - const name = helper.string("purchaseServer", "name", _name); updateDynamicRam("deleteServer", getRamCost(Player, "deleteServer")); + const name = helper.string("purchaseServer", "name", _name); let hostnameStr = String(name); hostnameStr = hostnameStr.replace(/\s\s+/g, ""); const server = GetServer(hostnameStr); @@ -1890,8 +1889,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return res; }, writePort: function (_port: unknown, data: any = ""): Promise { - const port = helper.number("writePort", "port", _port); updateDynamicRam("writePort", getRamCost(Player, "writePort")); + const port = helper.number("writePort", "port", _port); if (typeof data !== "string" && typeof data !== "number") { throw makeRuntimeErrorMsg( "writePort", @@ -1902,9 +1901,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return Promise.resolve(iport.write(data)); }, write: function (_port: unknown, data: any = "", _mode: unknown = "a"): Promise { + updateDynamicRam("write", getRamCost(Player, "write")); const port = helper.string("write", "port", _port); const mode = helper.string("write", "mode", _mode); - updateDynamicRam("write", getRamCost(Player, "write")); if (isString(port)) { // Write to script or text file let fn = port; @@ -1957,8 +1956,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, tryWritePort: function (_port: unknown, data: any = ""): Promise { - let port = helper.number("tryWritePort", "port", _port); updateDynamicRam("tryWritePort", getRamCost(Player, "tryWritePort")); + let port = helper.number("tryWritePort", "port", _port); if (typeof data !== "string" && typeof data !== "number") { throw makeRuntimeErrorMsg( "tryWritePort", @@ -1983,16 +1982,16 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, readPort: function (_port: unknown): any { - const port = helper.number("readPort", "port", _port); updateDynamicRam("readPort", getRamCost(Player, "readPort")); + const port = helper.number("readPort", "port", _port); // Read from port const iport = helper.getValidPort("readPort", port); const x = iport.read(); return x; }, read: function (_port: unknown): string { - const port = helper.string("read", "port", _port); updateDynamicRam("read", getRamCost(Player, "read")); + const port = helper.string("read", "port", _port); if (isString(port)) { // Read from script or text file const fn = port; @@ -2021,15 +2020,15 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, peek: function (_port: unknown): any { - const port = helper.number("peek", "port", _port); updateDynamicRam("peek", getRamCost(Player, "peek")); + const port = helper.number("peek", "port", _port); const iport = helper.getValidPort("peek", port); const x = iport.peek(); return x; }, clear: function (_file: unknown): void { - const file = helper.string("peek", "file", _file); updateDynamicRam("clear", getRamCost(Player, "clear")); + const file = helper.string("peek", "file", _file); if (isString(file)) { // Clear text file const fn = file; @@ -2046,21 +2045,21 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, clearPort: function (_port: unknown): void { - const port = helper.number("clearPort", "port", _port); updateDynamicRam("clearPort", getRamCost(Player, "clearPort")); + const port = helper.number("clearPort", "port", _port); // Clear port const iport = helper.getValidPort("clearPort", port); iport.clear(); }, getPortHandle: function (_port: unknown): IPort { - const port = helper.number("getPortHandle", "port", _port); updateDynamicRam("getPortHandle", getRamCost(Player, "getPortHandle")); + const port = helper.number("getPortHandle", "port", _port); const iport = helper.getValidPort("getPortHandle", port); return iport; }, rm: function (_fn: unknown, hostname: any): boolean { - const fn = helper.string("rm", "fn", _fn); updateDynamicRam("rm", getRamCost(Player, "rm")); + const fn = helper.string("rm", "fn", _fn); if (hostname == null || hostname === "") { hostname = workerScript.hostname; @@ -2075,9 +2074,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return status.res; }, scriptRunning: function (_scriptname: unknown, _hostname: unknown): boolean { + updateDynamicRam("scriptRunning", getRamCost(Player, "scriptRunning")); const scriptname = helper.string("scriptRunning", "scriptname", _scriptname); const hostname = helper.string("scriptRunning", "hostname", _hostname); - updateDynamicRam("scriptRunning", getRamCost(Player, "scriptRunning")); const server = safeGetServer(hostname, "scriptRunning"); for (let i = 0; i < server.runningScripts.length; ++i) { if (server.runningScripts[i].filename == scriptname) { @@ -2087,9 +2086,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return false; }, scriptKill: function (_scriptname: unknown, _hostname: unknown): boolean { + updateDynamicRam("scriptKill", getRamCost(Player, "scriptKill")); const scriptname = helper.string("scriptKill", "scriptname", _scriptname); const hostname = helper.string("scriptKill", "hostname", _hostname); - updateDynamicRam("scriptKill", getRamCost(Player, "scriptKill")); const server = safeGetServer(hostname, "scriptKill"); let suc = false; for (let i = 0; i < server.runningScripts.length; i++) { @@ -2106,9 +2105,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return workerScript.name; }, getScriptRam: function (_scriptname: unknown, _hostname: unknown = workerScript.hostname): number { + updateDynamicRam("getScriptRam", getRamCost(Player, "getScriptRam")); const scriptname = helper.string("getScriptRam", "scriptname", _scriptname); const hostname = helper.string("getScriptRam", "hostname", _hostname); - updateDynamicRam("getScriptRam", getRamCost(Player, "getScriptRam")); const server = safeGetServer(hostname, "getScriptRam"); for (let i = 0; i < server.scripts.length; ++i) { if (server.scripts[i].filename == scriptname) { @@ -2146,8 +2145,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }; }, getHackTime: function (_hostname: unknown = workerScript.hostname): number { - const hostname = helper.string("getHackTime", "hostname", _hostname); updateDynamicRam("getHackTime", getRamCost(Player, "getHackTime")); + const hostname = helper.string("getHackTime", "hostname", _hostname); const server = safeGetServer(hostname, "getHackTime"); if (!(server instanceof Server)) { workerScript.log("getHackTime", () => "invalid for this kind of server"); @@ -2160,8 +2159,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return calculateHackingTime(server, Player) * 1000; }, getGrowTime: function (_hostname: unknown = workerScript.hostname): number { - const hostname = helper.string("getGrowTime", "hostname", _hostname); updateDynamicRam("getGrowTime", getRamCost(Player, "getGrowTime")); + const hostname = helper.string("getGrowTime", "hostname", _hostname); const server = safeGetServer(hostname, "getGrowTime"); if (!(server instanceof Server)) { workerScript.log("getGrowTime", () => "invalid for this kind of server"); @@ -2174,8 +2173,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return calculateGrowTime(server, Player) * 1000; }, getWeakenTime: function (_hostname: unknown = workerScript.hostname): number { - const hostname = helper.string("getWeakenTime", "hostname", _hostname); updateDynamicRam("getWeakenTime", getRamCost(Player, "getWeakenTime")); + const hostname = helper.string("getWeakenTime", "hostname", _hostname); const server = safeGetServer(hostname, "getWeakenTime"); if (!(server instanceof Server)) { workerScript.log("getWeakenTime", () => "invalid for this kind of server"); @@ -2239,9 +2238,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { } }, nFormat: function (_n: unknown, _format: unknown): string { + updateDynamicRam("nFormat", getRamCost(Player, "nFormat")); const n = helper.number("nFormat", "n", _n); const format = helper.string("nFormat", "format", _format); - updateDynamicRam("nFormat", getRamCost(Player, "nFormat")); if (isNaN(n)) { return ""; } @@ -2249,9 +2248,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return numeralWrapper.format(n, format); }, tFormat: function (_milliseconds: unknown, _milliPrecision: unknown = false): string { + updateDynamicRam("tFormat", getRamCost(Player, "tFormat")); const milliseconds = helper.number("tFormat", "milliseconds", _milliseconds); const milliPrecision = helper.boolean(_milliPrecision); - updateDynamicRam("tFormat", getRamCost(Player, "tFormat")); return convertTimeMsToTimeElapsedString(milliseconds, milliPrecision); }, getTimeSinceLastAug: function (): number { @@ -2259,21 +2258,21 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { return Player.playtimeSinceLastAug; }, alert: function (_message: unknown): void { - const message = helper.string("alert", "message", _message); updateDynamicRam("alert", getRamCost(Player, "alert")); + const message = helper.string("alert", "message", _message); dialogBoxCreate(message); }, toast: function (_message: unknown, _variant: unknown = "success", duration: any = 2000): void { + updateDynamicRam("toast", getRamCost(Player, "toast")); const message = helper.string("toast", "message", _message); const variant = helper.string("toast", "variant", _variant); - updateDynamicRam("toast", getRamCost(Player, "toast")); if (!["success", "info", "warning", "error"].includes(variant)) throw new Error(`variant must be one of "success", "info", "warning", or "error"`); SnackbarEvents.emit(message, variant as any, duration); }, prompt: function (_txt: unknown, options?: { type?: string; options?: string[] }): Promise { - const txt = helper.string("toast", "txt", _txt); updateDynamicRam("prompt", getRamCost(Player, "prompt")); + const txt = helper.string("toast", "txt", _txt); return new Promise(function (resolve) { PromptEvent.emit({ @@ -2288,10 +2287,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { _target: unknown, _hostname: unknown = workerScript.hostname, ): Promise { + updateDynamicRam("wget", getRamCost(Player, "wget")); const url = helper.string("wget", "url", _url); const target = helper.string("wget", "target", _target); const hostname = helper.string("wget", "hostname", _hostname); - updateDynamicRam("wget", getRamCost(Player, "wget")); if (!isScriptFilename(target) && !target.endsWith(".txt")) { workerScript.log("wget", () => `Invalid target file: '${target}'. Must be a script or text file.`); return Promise.resolve(false); @@ -2450,10 +2449,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }; // Wrap the user function to prevent WorkerScript leaking as 'this' }, mv: function (_host: unknown, _source: unknown, _destination: unknown): void { + updateDynamicRam("mv", getRamCost(Player, "mv")); const host = helper.string("mv", "host", _host); const source = helper.string("mv", "source", _source); const destination = helper.string("mv", "destination", _destination); - updateDynamicRam("mv", getRamCost(Player, "mv")); if (!isValidFilePath(source)) throw makeRuntimeErrorMsg("mv", `Invalid filename: '${source}'`); if (!isValidFilePath(destination)) throw makeRuntimeErrorMsg("mv", `Invalid filename: '${destination}'`); diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts index e6da8bbed..a0ad14ae7 100644 --- a/src/NetscriptFunctions/Bladeburner.ts +++ b/src/NetscriptFunctions/Bladeburner.ts @@ -56,53 +56,56 @@ export function NetscriptBladeburner( return actionObj; }; + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "bladeburner", funcName)); + return { getContractNames: function (): string[] { - helper.updateDynamicRam("getContractNames", getRamCost(player, "bladeburner", "getContractNames")); + updateRam("getContractNames"); checkBladeburnerAccess("getContractNames"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getContractNamesNetscriptFn(); }, getOperationNames: function (): string[] { - helper.updateDynamicRam("getOperationNames", getRamCost(player, "bladeburner", "getOperationNames")); + updateRam("getOperationNames"); checkBladeburnerAccess("getOperationNames"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getOperationNamesNetscriptFn(); }, getBlackOpNames: function (): string[] { - helper.updateDynamicRam("getBlackOpNames", getRamCost(player, "bladeburner", "getBlackOpNames")); + updateRam("getBlackOpNames"); checkBladeburnerAccess("getBlackOpNames"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getBlackOpNamesNetscriptFn(); }, getBlackOpRank: function (_blackOpName: unknown): number { + updateRam("getBlackOpRank"); const blackOpName = helper.string("getBlackOpRank", "blackOpName", _blackOpName); - helper.updateDynamicRam("getBlackOpRank", getRamCost(player, "bladeburner", "getBlackOpRank")); checkBladeburnerAccess("getBlackOpRank"); const action: any = getBladeburnerActionObject("getBlackOpRank", "blackops", blackOpName); return action.reqdRank; }, getGeneralActionNames: function (): string[] { - helper.updateDynamicRam("getGeneralActionNames", getRamCost(player, "bladeburner", "getGeneralActionNames")); + updateRam("getGeneralActionNames"); checkBladeburnerAccess("getGeneralActionNames"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getGeneralActionNamesNetscriptFn(); }, getSkillNames: function (): string[] { - helper.updateDynamicRam("getSkillNames", getRamCost(player, "bladeburner", "getSkillNames")); + updateRam("getSkillNames"); checkBladeburnerAccess("getSkillNames"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getSkillNamesNetscriptFn(); }, startAction: function (_type: unknown, _name: unknown): boolean { + updateRam("startAction"); const type = helper.string("startAction", "type", _type); const name = helper.string("startAction", "name", _name); - helper.updateDynamicRam("startAction", getRamCost(player, "bladeburner", "startAction")); checkBladeburnerAccess("startAction"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -113,23 +116,23 @@ export function NetscriptBladeburner( } }, stopBladeburnerAction: function (): void { - helper.updateDynamicRam("stopBladeburnerAction", getRamCost(player, "bladeburner", "stopBladeburnerAction")); + updateRam("stopBladeburnerAction"); checkBladeburnerAccess("stopBladeburnerAction"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.resetAction(); }, getCurrentAction: function (): BladeburnerCurAction { - helper.updateDynamicRam("getCurrentAction", getRamCost(player, "bladeburner", "getCurrentAction")); + updateRam("getCurrentAction"); checkBladeburnerAccess("getCurrentAction"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.getTypeAndNameFromActionId(bladeburner.action); }, getActionTime: function (_type: unknown, _name: unknown): number { + updateRam("getActionTime"); const type = helper.string("getActionTime", "type", _type); const name = helper.string("getActionTime", "name", _name); - helper.updateDynamicRam("getActionTime", getRamCost(player, "bladeburner", "getActionTime")); checkBladeburnerAccess("getActionTime"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -140,12 +143,9 @@ export function NetscriptBladeburner( } }, getActionEstimatedSuccessChance: function (_type: unknown, _name: unknown): [number, number] { + updateRam("getActionEstimatedSuccessChance"); const type = helper.string("getActionEstimatedSuccessChance", "type", _type); const name = helper.string("getActionEstimatedSuccessChance", "name", _name); - helper.updateDynamicRam( - "getActionEstimatedSuccessChance", - getRamCost(player, "bladeburner", "getActionEstimatedSuccessChance"), - ); checkBladeburnerAccess("getActionEstimatedSuccessChance"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -156,10 +156,10 @@ export function NetscriptBladeburner( } }, getActionRepGain: function (_type: unknown, _name: unknown, _level: unknown): number { + updateRam("getActionRepGain"); const type = helper.string("getActionRepGain", "type", _type); const name = helper.string("getActionRepGain", "name", _name); const level = helper.number("getActionRepGain", "level", _level); - helper.updateDynamicRam("getActionRepGain", getRamCost(player, "bladeburner", "getActionRepGain")); checkBladeburnerAccess("getActionRepGain"); const action = getBladeburnerActionObject("getActionRepGain", type, name); let rewardMultiplier; @@ -172,9 +172,9 @@ export function NetscriptBladeburner( return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank; }, getActionCountRemaining: function (_type: unknown, _name: unknown): number { + updateRam("getActionCountRemaining"); const type = helper.string("getActionCountRemaining", "type", _type); const name = helper.string("getActionCountRemaining", "name", _name); - helper.updateDynamicRam("getActionCountRemaining", getRamCost(player, "bladeburner", "getActionCountRemaining")); checkBladeburnerAccess("getActionCountRemaining"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -185,43 +185,43 @@ export function NetscriptBladeburner( } }, getActionMaxLevel: function (_type: unknown, _name: unknown): number { + updateRam("getActionMaxLevel"); const type = helper.string("getActionMaxLevel", "type", _type); const name = helper.string("getActionMaxLevel", "name", _name); - helper.updateDynamicRam("getActionMaxLevel", getRamCost(player, "bladeburner", "getActionMaxLevel")); checkBladeburnerAccess("getActionMaxLevel"); const action = getBladeburnerActionObject("getActionMaxLevel", type, name); return action.maxLevel; }, getActionCurrentLevel: function (_type: unknown, _name: unknown): number { + updateRam("getActionCurrentLevel"); const type = helper.string("getActionCurrentLevel", "type", _type); const name = helper.string("getActionCurrentLevel", "name", _name); - helper.updateDynamicRam("getActionCurrentLevel", getRamCost(player, "bladeburner", "getActionCurrentLevel")); checkBladeburnerAccess("getActionCurrentLevel"); const action = getBladeburnerActionObject("getActionCurrentLevel", type, name); return action.level; }, getActionAutolevel: function (_type: unknown, _name: unknown): boolean { + updateRam("getActionAutolevel"); const type = helper.string("getActionAutolevel", "type", _type); const name = helper.string("getActionAutolevel", "name", _name); - helper.updateDynamicRam("getActionAutolevel", getRamCost(player, "bladeburner", "getActionAutolevel")); checkBladeburnerAccess("getActionAutolevel"); const action = getBladeburnerActionObject("getActionCurrentLevel", type, name); return action.autoLevel; }, setActionAutolevel: function (_type: unknown, _name: unknown, _autoLevel: unknown = true): void { + updateRam("setActionAutolevel"); const type = helper.string("setActionAutolevel", "type", _type); const name = helper.string("setActionAutolevel", "name", _name); const autoLevel = helper.boolean(_autoLevel); - helper.updateDynamicRam("setActionAutolevel", getRamCost(player, "bladeburner", "setActionAutolevel")); checkBladeburnerAccess("setActionAutolevel"); const action = getBladeburnerActionObject("setActionAutolevel", type, name); action.autoLevel = autoLevel; }, setActionLevel: function (_type: unknown, _name: unknown, _level: unknown = 1): void { + updateRam("setActionLevel"); const type = helper.string("setActionLevel", "type", _type); const name = helper.string("setActionLevel", "name", _name); const level = helper.number("setActionLevel", "level", _level); - helper.updateDynamicRam("setActionLevel", getRamCost(player, "bladeburner", "setActionLevel")); checkBladeburnerAccess("setActionLevel"); const action = getBladeburnerActionObject("setActionLevel", type, name); if (level < 1 || level > action.maxLevel) { @@ -233,22 +233,22 @@ export function NetscriptBladeburner( action.level = level; }, getRank: function (): number { - helper.updateDynamicRam("getRank", getRamCost(player, "bladeburner", "getRank")); + updateRam("getRank"); checkBladeburnerAccess("getRank"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.rank; }, getSkillPoints: function (): number { - helper.updateDynamicRam("getSkillPoints", getRamCost(player, "bladeburner", "getSkillPoints")); + updateRam("getSkillPoints"); checkBladeburnerAccess("getSkillPoints"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.skillPoints; }, getSkillLevel: function (_skillName: unknown): number { + updateRam("getSkillLevel"); const skillName = helper.string("getSkillLevel", "skillName", _skillName); - helper.updateDynamicRam("getSkillLevel", getRamCost(player, "bladeburner", "getSkillLevel")); checkBladeburnerAccess("getSkillLevel"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -259,8 +259,8 @@ export function NetscriptBladeburner( } }, getSkillUpgradeCost: function (_skillName: unknown): number { + updateRam("getSkillUpgradeCost"); const skillName = helper.string("getSkillUpgradeCost", "skillName", _skillName); - helper.updateDynamicRam("getSkillUpgradeCost", getRamCost(player, "bladeburner", "getSkillUpgradeCost")); checkBladeburnerAccess("getSkillUpgradeCost"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -271,8 +271,8 @@ export function NetscriptBladeburner( } }, upgradeSkill: function (_skillName: unknown): boolean { + updateRam("upgradeSkill"); const skillName = helper.string("upgradeSkill", "skillName", _skillName); - helper.updateDynamicRam("upgradeSkill", getRamCost(player, "bladeburner", "upgradeSkill")); checkBladeburnerAccess("upgradeSkill"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -283,9 +283,9 @@ export function NetscriptBladeburner( } }, getTeamSize: function (_type: unknown, _name: unknown): number { + updateRam("getTeamSize"); const type = helper.string("getTeamSize", "type", _type); const name = helper.string("getTeamSize", "name", _name); - helper.updateDynamicRam("getTeamSize", getRamCost(player, "bladeburner", "getTeamSize")); checkBladeburnerAccess("getTeamSize"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -296,10 +296,10 @@ export function NetscriptBladeburner( } }, setTeamSize: function (_type: unknown, _name: unknown, _size: unknown): number { + updateRam("setTeamSize"); const type = helper.string("setTeamSize", "type", _type); const name = helper.string("setTeamSize", "name", _name); const size = helper.number("setTeamSize", "size", _size); - helper.updateDynamicRam("setTeamSize", getRamCost(player, "bladeburner", "setTeamSize")); checkBladeburnerAccess("setTeamSize"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); @@ -310,11 +310,8 @@ export function NetscriptBladeburner( } }, getCityEstimatedPopulation: function (_cityName: unknown): number { + updateRam("getCityEstimatedPopulation"); const cityName = helper.string("getCityEstimatedPopulation", "cityName", _cityName); - helper.updateDynamicRam( - "getCityEstimatedPopulation", - getRamCost(player, "bladeburner", "getCityEstimatedPopulation"), - ); checkBladeburnerAccess("getCityEstimatedPopulation"); checkBladeburnerCity("getCityEstimatedPopulation", cityName); const bladeburner = player.bladeburner; @@ -322,8 +319,8 @@ export function NetscriptBladeburner( return bladeburner.cities[cityName].popEst; }, getCityCommunities: function (_cityName: unknown): number { + updateRam("getCityCommunities"); const cityName = helper.string("getCityCommunities", "cityName", _cityName); - helper.updateDynamicRam("getCityCommunities", getRamCost(player, "bladeburner", "getCityCommunities")); checkBladeburnerAccess("getCityCommunities"); checkBladeburnerCity("getCityCommunities", cityName); const bladeburner = player.bladeburner; @@ -331,8 +328,8 @@ export function NetscriptBladeburner( return bladeburner.cities[cityName].comms; }, getCityChaos: function (_cityName: unknown): number { + updateRam("getCityChaos"); const cityName = helper.string("getCityChaos", "cityName", _cityName); - helper.updateDynamicRam("getCityChaos", getRamCost(player, "bladeburner", "getCityChaos")); checkBladeburnerAccess("getCityChaos"); checkBladeburnerCity("getCityChaos", cityName); const bladeburner = player.bladeburner; @@ -340,15 +337,15 @@ export function NetscriptBladeburner( return bladeburner.cities[cityName].chaos; }, getCity: function (): string { - helper.updateDynamicRam("getCity", getRamCost(player, "bladeburner", "getCity")); + updateRam("getCity"); checkBladeburnerAccess("getCityChaos"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.city; }, switchCity: function (_cityName: unknown): boolean { + updateRam("switchCity"); const cityName = helper.string("switchCity", "cityName", _cityName); - helper.updateDynamicRam("switchCity", getRamCost(player, "bladeburner", "switchCity")); checkBladeburnerAccess("switchCity"); checkBladeburnerCity("switchCity", cityName); const bladeburner = player.bladeburner; @@ -357,21 +354,21 @@ export function NetscriptBladeburner( return true; }, getStamina: function (): [number, number] { - helper.updateDynamicRam("getStamina", getRamCost(player, "bladeburner", "getStamina")); + updateRam("getStamina"); checkBladeburnerAccess("getStamina"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return [bladeburner.stamina, bladeburner.maxStamina]; }, joinBladeburnerFaction: function (): boolean { - helper.updateDynamicRam("joinBladeburnerFaction", getRamCost(player, "bladeburner", "joinBladeburnerFaction")); + updateRam("joinBladeburnerFaction"); checkBladeburnerAccess("joinBladeburnerFaction", true); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); return bladeburner.joinBladeburnerFactionNetscriptFn(workerScript); }, joinBladeburnerDivision: function (): boolean { - helper.updateDynamicRam("joinBladeburnerDivision", getRamCost(player, "bladeburner", "joinBladeburnerDivision")); + updateRam("joinBladeburnerDivision"); if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) { if (player.bitNodeN === 8) { return false; @@ -399,7 +396,7 @@ export function NetscriptBladeburner( return false; }, getBonusTime: function (): number { - helper.updateDynamicRam("getBonusTime", getRamCost(player, "bladeburner", "getBonusTime")); + updateRam("getBonusTime"); checkBladeburnerAccess("getBonusTime"); const bladeburner = player.bladeburner; if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); diff --git a/src/NetscriptFunctions/CodingContract.ts b/src/NetscriptFunctions/CodingContract.ts index ef908e83a..52901eef4 100644 --- a/src/NetscriptFunctions/CodingContract.ts +++ b/src/NetscriptFunctions/CodingContract.ts @@ -24,6 +24,9 @@ export function NetscriptCodingContract( return contract; }; + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "codingcontract", funcName)); + return { attempt: function ( answer: any, @@ -31,9 +34,9 @@ export function NetscriptCodingContract( _hostname: unknown = workerScript.hostname, { returnReward }: CodingAttemptOptions = { returnReward: false }, ): boolean | string { + updateRam("attempt"); const filename = helper.string("attempt", "filename", _filename); const hostname = helper.string("attempt", "hostname", _hostname); - helper.updateDynamicRam("attempt", getRamCost(player, "codingcontract", "attempt")); const contract = getCodingContract("attempt", hostname, filename); // Convert answer to string. If the answer is a 2D array, then we have to @@ -83,16 +86,16 @@ export function NetscriptCodingContract( } }, getContractType: function (_filename: unknown, _hostname: unknown = workerScript.hostname): string { + updateRam("getContractType"); const filename = helper.string("getContractType", "filename", _filename); const hostname = helper.string("getContractType", "hostname", _hostname); - helper.updateDynamicRam("getContractType", getRamCost(player, "codingcontract", "getContractType")); const contract = getCodingContract("getContractType", hostname, filename); return contract.getType(); }, getData: function (_filename: unknown, _hostname: unknown = workerScript.hostname): any { + updateRam("getData"); const filename = helper.string("getContractType", "filename", _filename); const hostname = helper.string("getContractType", "hostname", _hostname); - helper.updateDynamicRam("getData", getRamCost(player, "codingcontract", "getData")); const contract = getCodingContract("getData", hostname, filename); const data = contract.getData(); if (data.constructor === Array) { @@ -112,16 +115,16 @@ export function NetscriptCodingContract( } }, getDescription: function (_filename: unknown, _hostname: unknown = workerScript.hostname): string { + updateRam("getDescription"); const filename = helper.string("getDescription", "filename", _filename); const hostname = helper.string("getDescription", "hostname", _hostname); - helper.updateDynamicRam("getDescription", getRamCost(player, "codingcontract", "getDescription")); const contract = getCodingContract("getDescription", hostname, filename); return contract.getDescription(); }, getNumTriesRemaining: function (_filename: unknown, _hostname: unknown = workerScript.hostname): number { + updateRam("getNumTriesRemaining"); const filename = helper.string("getNumTriesRemaining", "filename", _filename); const hostname = helper.string("getNumTriesRemaining", "hostname", _hostname); - helper.updateDynamicRam("getNumTriesRemaining", getRamCost(player, "codingcontract", "getNumTriesRemaining")); const contract = getCodingContract("getNumTriesRemaining", hostname, filename); return contract.getMaxNumTries() - contract.tries; }, diff --git a/src/NetscriptFunctions/Gang.ts b/src/NetscriptFunctions/Gang.ts index 9ed49b808..de4e7ab87 100644 --- a/src/NetscriptFunctions/Gang.ts +++ b/src/NetscriptFunctions/Gang.ts @@ -47,10 +47,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return task; }; + const updateRam = (funcName: string): void => helper.updateDynamicRam(funcName, getRamCost(player, "gang", funcName)); + return { createGang: function (_faction: unknown): boolean { + updateRam("createGang"); const faction = helper.string("createGang", "faction", _faction); - helper.updateDynamicRam("createGang", getRamCost(player, "gang", "createGang")); // this list is copied from Faction/ui/Root.tsx if (!player.canAccessGang() || !GangConstants.Names.includes(faction)) return false; @@ -62,18 +64,18 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return true; }, inGang: function (): boolean { - helper.updateDynamicRam("inGang", getRamCost(player, "gang", "inGang")); + updateRam("inGang"); return player.inGang(); }, getMemberNames: function (): string[] { - helper.updateDynamicRam("getMemberNames", getRamCost(player, "gang", "getMemberNames")); + updateRam("getMemberNames"); checkGangApiAccess("getMemberNames"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); return gang.members.map((member) => member.name); }, getGangInformation: function (): GangGenInfo { - helper.updateDynamicRam("getGangInformation", getRamCost(player, "gang", "getGangInformation")); + updateRam("getGangInformation"); checkGangApiAccess("getGangInformation"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -93,7 +95,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe }; }, getOtherGangInformation: function (): GangOtherInfo { - helper.updateDynamicRam("getOtherGangInformation", getRamCost(player, "gang", "getOtherGangInformation")); + updateRam("getOtherGangInformation"); checkGangApiAccess("getOtherGangInformation"); const cpy: any = {}; for (const gang of Object.keys(AllGangs)) { @@ -103,8 +105,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return cpy; }, getMemberInformation: function (_memberName: unknown): GangMemberInfo { + updateRam("getMemberInformation"); const memberName = helper.string("getMemberInformation", "memberName", _memberName); - helper.updateDynamicRam("getMemberInformation", getRamCost(player, "gang", "getMemberInformation")); checkGangApiAccess("getMemberInformation"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -157,15 +159,15 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe }; }, canRecruitMember: function (): boolean { - helper.updateDynamicRam("canRecruitMember", getRamCost(player, "gang", "canRecruitMember")); + updateRam("canRecruitMember"); checkGangApiAccess("canRecruitMember"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); return gang.canRecruitMember(); }, recruitMember: function (_memberName: unknown): boolean { + updateRam("recruitMember"); const memberName = helper.string("recruitMember", "memberName", _memberName); - helper.updateDynamicRam("recruitMember", getRamCost(player, "gang", "recruitMember")); checkGangApiAccess("recruitMember"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -179,7 +181,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return recruited; }, getTaskNames: function (): string[] { - helper.updateDynamicRam("getTaskNames", getRamCost(player, "gang", "getTaskNames")); + updateRam("getTaskNames"); checkGangApiAccess("getTaskNames"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -188,9 +190,9 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return tasks; }, setMemberTask: function (_memberName: unknown, _taskName: unknown): boolean { + updateRam("setMemberTask"); const memberName = helper.string("setMemberTask", "memberName", _memberName); const taskName = helper.string("setMemberTask", "taskName", _taskName); - helper.updateDynamicRam("setMemberTask", getRamCost(player, "gang", "setMemberTask")); checkGangApiAccess("setMemberTask"); const member = getGangMember("setMemberTask", memberName); const gang = player.gang; @@ -219,8 +221,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return success; }, getTaskStats: function (_taskName: unknown): GangTaskStats { + updateRam("getTaskStats"); const taskName = helper.string("getTaskStats", "taskName", _taskName); - helper.updateDynamicRam("getTaskStats", getRamCost(player, "gang", "getTaskStats")); checkGangApiAccess("getTaskStats"); const task = getGangTask("getTaskStats", taskName); const copy = Object.assign({}, task); @@ -228,13 +230,13 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return copy; }, getEquipmentNames: function (): string[] { - helper.updateDynamicRam("getEquipmentNames", getRamCost(player, "gang", "getEquipmentNames")); + updateRam("getEquipmentNames"); checkGangApiAccess("getEquipmentNames"); return Object.keys(GangMemberUpgrades); }, getEquipmentCost: function (_equipName: any): number { + updateRam("getEquipmentCost"); const equipName = helper.string("getEquipmentCost", "equipName", _equipName); - helper.updateDynamicRam("getEquipmentCost", getRamCost(player, "gang", "getEquipmentCost")); checkGangApiAccess("getEquipmentCost"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -243,16 +245,16 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return gang.getUpgradeCost(upg); }, getEquipmentType: function (_equipName: unknown): string { + updateRam("getEquipmentType"); const equipName = helper.string("getEquipmentType", "equipName", _equipName); - helper.updateDynamicRam("getEquipmentType", getRamCost(player, "gang", "getEquipmentType")); checkGangApiAccess("getEquipmentType"); const upg = GangMemberUpgrades[equipName]; if (upg == null) return ""; return upg.getType(); }, getEquipmentStats: function (_equipName: unknown): EquipmentStats { + updateRam("getEquipmentStats"); const equipName = helper.string("getEquipmentStats", "equipName", _equipName); - helper.updateDynamicRam("getEquipmentStats", getRamCost(player, "gang", "getEquipmentStats")); checkGangApiAccess("getEquipmentStats"); const equipment = GangMemberUpgrades[equipName]; if (!equipment) { @@ -262,9 +264,9 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return Object.assign({}, typecheck) as any; }, purchaseEquipment: function (_memberName: unknown, _equipName: unknown): boolean { + updateRam("purchaseEquipment"); const memberName = helper.string("purchaseEquipment", "memberName", _memberName); const equipName = helper.string("purchaseEquipment", "equipName", _equipName); - helper.updateDynamicRam("purchaseEquipment", getRamCost(player, "gang", "purchaseEquipment")); checkGangApiAccess("purchaseEquipment"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -284,8 +286,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return res; }, ascendMember: function (_memberName: unknown): GangMemberAscension | undefined { + updateRam("ascendMember"); const memberName = helper.string("ascendMember", "memberName", _memberName); - helper.updateDynamicRam("ascendMember", getRamCost(player, "gang", "ascendMember")); checkGangApiAccess("ascendMember"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -294,8 +296,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return gang.ascendMember(member, workerScript); }, getAscensionResult: function (_memberName: unknown): GangMemberAscension | undefined { + updateRam("getAscensionResult"); const memberName = helper.string("getAscensionResult", "memberName", _memberName); - helper.updateDynamicRam("getAscensionResult", getRamCost(player, "gang", "getAscensionResult")); checkGangApiAccess("getAscensionResult"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -307,8 +309,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe }; }, setTerritoryWarfare: function (_engage: unknown): void { + updateRam("setTerritoryWarfare"); const engage = helper.boolean(_engage); - helper.updateDynamicRam("setTerritoryWarfare", getRamCost(player, "gang", "setTerritoryWarfare")); checkGangApiAccess("setTerritoryWarfare"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -321,8 +323,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe } }, getChanceToWinClash: function (_otherGang: unknown): number { + updateRam("getChanceToWinClash"); const otherGang = helper.string("getChanceToWinClash", "otherGang", _otherGang); - helper.updateDynamicRam("getChanceToWinClash", getRamCost(player, "gang", "getChanceToWinClash")); checkGangApiAccess("getChanceToWinClash"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); @@ -336,7 +338,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe return playerPower / (otherPower + playerPower); }, getBonusTime: function (): number { - helper.updateDynamicRam("getBonusTime", getRamCost(player, "gang", "getBonusTime")); + updateRam("getBonusTime"); checkGangApiAccess("getBonusTime"); const gang = player.gang; if (gang === null) throw new Error("Should not be called without Gang"); diff --git a/src/NetscriptFunctions/Grafting.ts b/src/NetscriptFunctions/Grafting.ts index 8057a207e..63c5cbd7b 100644 --- a/src/NetscriptFunctions/Grafting.ts +++ b/src/NetscriptFunctions/Grafting.ts @@ -20,10 +20,13 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h } }; + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "grafting", funcName)); + return { getAugmentationGraftPrice: (_augName: unknown): number => { + updateRam("getAugmentationGraftPrice"); const augName = helper.string("getAugmentationGraftPrice", "augName", _augName); - helper.updateDynamicRam("getAugmentationGraftPrice", getRamCost(player, "grafting", "getAugmentationGraftPrice")); checkGraftingAPIAccess("getAugmentationGraftPrice"); if (!Augmentations.hasOwnProperty(augName)) { throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftPrice", `Invalid aug: ${augName}`); @@ -33,8 +36,8 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h }, getAugmentationGraftTime: (_augName: string): number => { + updateRam("getAugmentationGraftTime"); const augName = helper.string("getAugmentationGraftTime", "augName", _augName); - helper.updateDynamicRam("getAugmentationGraftTime", getRamCost(player, "grafting", "getAugmentationGraftTime")); checkGraftingAPIAccess("getAugmentationGraftTime"); if (!Augmentations.hasOwnProperty(augName)) { throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftTime", `Invalid aug: ${augName}`); @@ -44,9 +47,9 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h }, graftAugmentation: (_augName: string, _focus: unknown = true): boolean => { + updateRam("graftAugmentation"); const augName = helper.string("graftAugmentation", "augName", _augName); const focus = helper.boolean(_focus); - helper.updateDynamicRam("graftAugmentation", getRamCost(player, "grafting", "graftAugmentation")); checkGraftingAPIAccess("graftAugmentation"); if (player.city !== CityName.NewTokyo) { throw helper.makeRuntimeErrorMsg( diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 976a150ff..79393a61a 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -96,10 +96,12 @@ export function NetscriptSingularity( } } }; + + const updateRam = (funcName: string): void => helper.updateDynamicRam(funcName, getRamCost(player, funcName)); return { getOwnedAugmentations: function (_purchased: unknown = false): string[] { + updateRam("getOwnedAugmentations"); const purchased = helper.boolean(_purchased); - helper.updateDynamicRam("getOwnedAugmentations", getRamCost(player, "getOwnedAugmentations")); helper.checkSingularityAccess("getOwnedAugmentations"); const res = []; for (let i = 0; i < player.augmentations.length; ++i) { @@ -113,52 +115,52 @@ export function NetscriptSingularity( return res; }, getAugmentationsFromFaction: function (_facName: unknown): string[] { + updateRam("getAugmentationsFromFaction"); const facName = helper.string("getAugmentationsFromFaction", "facName", _facName); - helper.updateDynamicRam("getAugmentationsFromFaction", getRamCost(player, "getAugmentationsFromFaction")); helper.checkSingularityAccess("getAugmentationsFromFaction"); const faction = getFaction("getAugmentationsFromFaction", facName); return getFactionAugmentationsFiltered(player, faction); }, getAugmentationCost: function (_augName: unknown): [number, number] { + updateRam("getAugmentationCost"); const augName = helper.string("getAugmentationCost", "augName", _augName); - helper.updateDynamicRam("getAugmentationCost", getRamCost(player, "getAugmentationCost")); helper.checkSingularityAccess("getAugmentationCost"); const aug = getAugmentation("getAugmentationCost", augName); return [aug.baseRepRequirement, aug.baseCost]; }, getAugmentationPrereq: function (_augName: unknown): string[] { + updateRam("getAugmentationPrereq"); const augName = helper.string("getAugmentationPrereq", "augName", _augName); - helper.updateDynamicRam("getAugmentationPrereq", getRamCost(player, "getAugmentationPrereq")); helper.checkSingularityAccess("getAugmentationPrereq"); const aug = getAugmentation("getAugmentationPrereq", augName); return aug.prereqs.slice(); }, getAugmentationPrice: function (_augName: unknown): number { + updateRam("getAugmentationPrice"); const augName = helper.string("getAugmentationPrice", "augName", _augName); - helper.updateDynamicRam("getAugmentationPrice", getRamCost(player, "getAugmentationPrice")); helper.checkSingularityAccess("getAugmentationPrice"); const aug = getAugmentation("getAugmentationPrice", augName); return aug.baseCost; }, getAugmentationRepReq: function (_augName: unknown): number { + updateRam("getAugmentationRepReq"); const augName = helper.string("getAugmentationRepReq", "augName", _augName); - helper.updateDynamicRam("getAugmentationRepReq", getRamCost(player, "getAugmentationRepReq")); helper.checkSingularityAccess("getAugmentationRepReq"); const aug = getAugmentation("getAugmentationRepReq", augName); return aug.baseRepRequirement; }, getAugmentationStats: function (_augName: unknown): AugmentationStats { + updateRam("getAugmentationStats"); const augName = helper.string("getAugmentationStats", "augName", _augName); - helper.updateDynamicRam("getAugmentationStats", getRamCost(player, "getAugmentationStats")); helper.checkSingularityAccess("getAugmentationStats"); const aug = getAugmentation("getAugmentationStats", augName); return Object.assign({}, aug.mults); }, purchaseAugmentation: function (_facName: unknown, _augName: unknown): boolean { + updateRam("purchaseAugmentation"); const facName = helper.string("purchaseAugmentation", "facName", _facName); const augName = helper.string("purchaseAugmentation", "augName", _augName); - helper.updateDynamicRam("purchaseAugmentation", getRamCost(player, "purchaseAugmentation")); helper.checkSingularityAccess("purchaseAugmentation"); const fac = getFaction("purchaseAugmentation", facName); const aug = getAugmentation("purchaseAugmentation", augName); @@ -204,8 +206,8 @@ export function NetscriptSingularity( } }, softReset: function (_cbScript: unknown): void { + updateRam("softReset"); const cbScript = helper.string("softReset", "cbScript", _cbScript); - helper.updateDynamicRam("softReset", getRamCost(player, "softReset")); helper.checkSingularityAccess("softReset"); workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed"); @@ -219,8 +221,8 @@ export function NetscriptSingularity( killWorkerScript(workerScript); }, installAugmentations: function (_cbScript: unknown): boolean { + updateRam("installAugmentations"); const cbScript = helper.string("installAugmentations", "cbScript", _cbScript); - helper.updateDynamicRam("installAugmentations", getRamCost(player, "installAugmentations")); helper.checkSingularityAccess("installAugmentations"); if (player.queuedAugmentations.length === 0) { @@ -243,8 +245,8 @@ export function NetscriptSingularity( }, goToLocation: function (_locationName: unknown): boolean { + updateRam("goToLocation"); const locationName = helper.string("goToLocation", "locationName", _locationName); - helper.updateDynamicRam("goToLocation", getRamCost(player, "goToLocation")); helper.checkSingularityAccess("goToLocation"); const location = Object.values(Locations).find((l) => l.name === locationName); if (!location) { @@ -260,10 +262,10 @@ export function NetscriptSingularity( return true; }, universityCourse: function (_universityName: unknown, _className: unknown, _focus: unknown = true): boolean { + updateRam("universityCourse"); const universityName = helper.string("universityCourse", "universityName", _universityName); const className = helper.string("universityCourse", "className", _className); const focus = helper.boolean(_focus); - helper.updateDynamicRam("universityCourse", getRamCost(player, "universityCourse")); helper.checkSingularityAccess("universityCourse"); const wasFocusing = player.focus; if (player.isWorking) { @@ -351,10 +353,10 @@ export function NetscriptSingularity( }, gymWorkout: function (_gymName: unknown, _stat: unknown, _focus: unknown = true): boolean { + updateRam("gymWorkout"); const gymName = helper.string("gymWorkout", "gymName", _gymName); const stat = helper.string("gymWorkout", "stat", _stat); const focus = helper.boolean(_focus); - helper.updateDynamicRam("gymWorkout", getRamCost(player, "gymWorkout")); helper.checkSingularityAccess("gymWorkout"); const wasFocusing = player.focus; if (player.isWorking) { @@ -466,8 +468,8 @@ export function NetscriptSingularity( }, travelToCity: function (_cityName: unknown): boolean { + updateRam("travelToCity"); const cityName = helper.city("travelToCity", "cityName", _cityName); - helper.updateDynamicRam("travelToCity", getRamCost(player, "travelToCity")); helper.checkSingularityAccess("travelToCity"); switch (cityName) { @@ -492,7 +494,7 @@ export function NetscriptSingularity( }, purchaseTor: function (): boolean { - helper.updateDynamicRam("purchaseTor", getRamCost(player, "purchaseTor")); + updateRam("purchaseTor"); helper.checkSingularityAccess("purchaseTor"); if (player.hasTorRouter()) { @@ -524,8 +526,8 @@ export function NetscriptSingularity( return true; }, purchaseProgram: function (_programName: unknown): boolean { + updateRam("purchaseProgram"); const programName = helper.string("purchaseProgram", "programName", _programName).toLowerCase(); - helper.updateDynamicRam("purchaseProgram", getRamCost(player, "purchaseProgram")); helper.checkSingularityAccess("purchaseProgram"); if (!player.hasTorRouter()) { @@ -562,13 +564,13 @@ export function NetscriptSingularity( return true; }, getCurrentServer: function (): string { - helper.updateDynamicRam("getCurrentServer", getRamCost(player, "getCurrentServer")); + updateRam("getCurrentServer"); helper.checkSingularityAccess("getCurrentServer"); return player.getCurrentServer().hostname; }, connect: function (_hostname: unknown): boolean { + updateRam("connect"); const hostname = helper.string("purchaseProgram", "hostname", _hostname); - helper.updateDynamicRam("connect", getRamCost(player, "connect")); helper.checkSingularityAccess("connect"); if (!hostname) { throw helper.makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`); @@ -603,13 +605,13 @@ export function NetscriptSingularity( return false; }, manualHack: function (): Promise { - helper.updateDynamicRam("manualHack", getRamCost(player, "manualHack")); + updateRam("manualHack"); helper.checkSingularityAccess("manualHack"); const server = player.getCurrentServer(); return helper.hack(server.hostname, true); }, installBackdoor: function (): Promise { - helper.updateDynamicRam("installBackdoor", getRamCost(player, "installBackdoor")); + updateRam("installBackdoor"); helper.checkSingularityAccess("installBackdoor"); const baseserver = player.getCurrentServer(); if (!(baseserver instanceof Server)) { @@ -642,13 +644,13 @@ export function NetscriptSingularity( }); }, isFocused: function (): boolean { - helper.updateDynamicRam("isFocused", getRamCost(player, "isFocused")); + updateRam("isFocused"); helper.checkSingularityAccess("isFocused"); return player.focus; }, setFocus: function (_focus: unknown): boolean { + updateRam("setFocus"); const focus = helper.boolean(_focus); - helper.updateDynamicRam("setFocus", getRamCost(player, "setFocus")); helper.checkSingularityAccess("setFocus"); if (!player.isWorking) { throw helper.makeRuntimeErrorMsg("setFocus", "Not currently working"); @@ -676,7 +678,7 @@ export function NetscriptSingularity( return false; }, getStats: function (): PlayerSkills { - helper.updateDynamicRam("getStats", getRamCost(player, "getStats")); + updateRam("getStats"); helper.checkSingularityAccess("getStats"); workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`); @@ -691,7 +693,7 @@ export function NetscriptSingularity( }; }, getCharacterInformation: function (): CharacterInfo { - helper.updateDynamicRam("getCharacterInformation", getRamCost(player, "getCharacterInformation")); + updateRam("getCharacterInformation"); helper.checkSingularityAccess("getCharacterInformation"); workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`); @@ -741,7 +743,7 @@ export function NetscriptSingularity( }; }, hospitalize: function (): void { - helper.updateDynamicRam("hospitalize", getRamCost(player, "hospitalize")); + updateRam("hospitalize"); helper.checkSingularityAccess("hospitalize"); if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) { workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy."); @@ -750,12 +752,12 @@ export function NetscriptSingularity( player.hospitalize(); }, isBusy: function (): boolean { - helper.updateDynamicRam("isBusy", getRamCost(player, "isBusy")); + updateRam("isBusy"); helper.checkSingularityAccess("isBusy"); return player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse; }, stopAction: function (): boolean { - helper.updateDynamicRam("stopAction", getRamCost(player, "stopAction")); + updateRam("stopAction"); helper.checkSingularityAccess("stopAction"); if (player.isWorking) { if (player.focus) { @@ -769,7 +771,7 @@ export function NetscriptSingularity( return false; }, upgradeHomeCores: function (): boolean { - helper.updateDynamicRam("upgradeHomeCores", getRamCost(player, "upgradeHomeCores")); + updateRam("upgradeHomeCores"); helper.checkSingularityAccess("upgradeHomeCores"); // Check if we're at max cores @@ -799,13 +801,13 @@ export function NetscriptSingularity( return true; }, getUpgradeHomeCoresCost: function (): number { - helper.updateDynamicRam("getUpgradeHomeCoresCost", getRamCost(player, "getUpgradeHomeCoresCost")); + updateRam("getUpgradeHomeCoresCost"); helper.checkSingularityAccess("getUpgradeHomeCoresCost"); return player.getUpgradeHomeCoresCost(); }, upgradeHomeRam: function (): boolean { - helper.updateDynamicRam("upgradeHomeRam", getRamCost(player, "upgradeHomeRam")); + updateRam("upgradeHomeRam"); helper.checkSingularityAccess("upgradeHomeRam"); // Check if we're at max RAM @@ -838,15 +840,15 @@ export function NetscriptSingularity( return true; }, getUpgradeHomeRamCost: function (): number { - helper.updateDynamicRam("getUpgradeHomeRamCost", getRamCost(player, "getUpgradeHomeRamCost")); + updateRam("getUpgradeHomeRamCost"); helper.checkSingularityAccess("getUpgradeHomeRamCost"); return player.getUpgradeHomeRamCost(); }, workForCompany: function (_companyName: unknown, _focus: unknown = true): boolean { + updateRam("workForCompany"); let companyName = helper.string("workForCompany", "companyName", _companyName); const focus = helper.boolean(_focus); - helper.updateDynamicRam("workForCompany", getRamCost(player, "workForCompany")); helper.checkSingularityAccess("workForCompany"); // Sanitize input @@ -900,9 +902,9 @@ export function NetscriptSingularity( return true; }, applyToCompany: function (_companyName: unknown, _field: unknown): boolean { + updateRam("applyToCompany"); const companyName = helper.string("applyToCompany", "companyName", _companyName); const field = helper.string("applyToCompany", "field", _field); - helper.updateDynamicRam("applyToCompany", getRamCost(player, "applyToCompany")); helper.checkSingularityAccess("applyToCompany"); getCompany("applyToCompany", companyName); @@ -972,22 +974,22 @@ export function NetscriptSingularity( return res; }, getCompanyRep: function (_companyName: unknown): number { + updateRam("getCompanyRep"); const companyName = helper.string("getCompanyRep", "companyName", _companyName); - helper.updateDynamicRam("getCompanyRep", getRamCost(player, "getCompanyRep")); helper.checkSingularityAccess("getCompanyRep"); const company = getCompany("getCompanyRep", companyName); return company.playerReputation; }, getCompanyFavor: function (_companyName: unknown): number { + updateRam("getCompanyFavor"); const companyName = helper.string("getCompanyFavor", "companyName", _companyName); - helper.updateDynamicRam("getCompanyFavor", getRamCost(player, "getCompanyFavor")); helper.checkSingularityAccess("getCompanyFavor"); const company = getCompany("getCompanyFavor", companyName); return company.favor; }, getCompanyFavorGain: function (_companyName: unknown): number { + updateRam("getCompanyFavorGain"); const companyName = helper.string("getCompanyFavorGain", "companyName", _companyName); - helper.updateDynamicRam("getCompanyFavorGain", getRamCost(player, "getCompanyFavorGain")); helper.checkSingularityAccess("getCompanyFavorGain"); const company = getCompany("getCompanyFavorGain", companyName); return company.getFavorGain(); @@ -999,8 +1001,8 @@ export function NetscriptSingularity( return player.factionInvitations.slice(); }, joinFaction: function (_facName: unknown): boolean { + updateRam("joinFaction"); const facName = helper.string("joinFaction", "facName", _facName); - helper.updateDynamicRam("joinFaction", getRamCost(player, "joinFaction")); helper.checkSingularityAccess("joinFaction"); getFaction("joinFaction", facName); @@ -1023,10 +1025,10 @@ export function NetscriptSingularity( return true; }, workForFaction: function (_facName: unknown, _type: unknown, _focus: unknown = true): boolean { + updateRam("workForFaction"); const facName = helper.string("workForFaction", "facName", _facName); const type = helper.string("workForFaction", "type", _type); const focus = helper.boolean(_focus); - helper.updateDynamicRam("workForFaction", getRamCost(player, "workForFaction")); helper.checkSingularityAccess("workForFaction"); getFaction("workForFaction", facName); @@ -1109,30 +1111,30 @@ export function NetscriptSingularity( return true; }, getFactionRep: function (_facName: unknown): number { + updateRam("getFactionRep"); const facName = helper.string("getFactionRep", "facName", _facName); - helper.updateDynamicRam("getFactionRep", getRamCost(player, "getFactionRep")); helper.checkSingularityAccess("getFactionRep"); const faction = getFaction("getFactionRep", facName); return faction.playerReputation; }, getFactionFavor: function (_facName: unknown): number { + updateRam("getFactionFavor"); const facName = helper.string("getFactionRep", "facName", _facName); - helper.updateDynamicRam("getFactionFavor", getRamCost(player, "getFactionFavor")); helper.checkSingularityAccess("getFactionFavor"); const faction = getFaction("getFactionFavor", facName); return faction.favor; }, getFactionFavorGain: function (_facName: unknown): number { + updateRam("getFactionFavorGain"); const facName = helper.string("getFactionFavorGain", "facName", _facName); - helper.updateDynamicRam("getFactionFavorGain", getRamCost(player, "getFactionFavorGain")); helper.checkSingularityAccess("getFactionFavorGain"); const faction = getFaction("getFactionFavorGain", facName); return faction.getFavorGain(); }, donateToFaction: function (_facName: unknown, _amt: unknown): boolean { + updateRam("donateToFaction"); const facName = helper.string("donateToFaction", "facName", _facName); const amt = helper.number("donateToFaction", "amt", _amt); - helper.updateDynamicRam("donateToFaction", getRamCost(player, "donateToFaction")); helper.checkSingularityAccess("donateToFaction"); const faction = getFaction("donateToFaction", facName); if (!player.factions.includes(faction.name)) { @@ -1179,9 +1181,9 @@ export function NetscriptSingularity( return true; }, createProgram: function (_programName: unknown, _focus: unknown = true): boolean { + updateRam("createProgram"); const programName = helper.string("createProgram", "programName", _programName).toLowerCase(); const focus = helper.boolean(_focus); - helper.updateDynamicRam("createProgram", getRamCost(player, "createProgram")); helper.checkSingularityAccess("createProgram"); const wasFocusing = player.focus; @@ -1228,8 +1230,8 @@ export function NetscriptSingularity( return true; }, commitCrime: function (_crimeRoughName: unknown): number { + updateRam("commitCrime"); const crimeRoughName = helper.string("commitCrime", "crimeRoughName", _crimeRoughName); - helper.updateDynamicRam("commitCrime", getRamCost(player, "commitCrime")); helper.checkSingularityAccess("commitCrime"); if (player.isWorking) { @@ -1249,8 +1251,8 @@ export function NetscriptSingularity( return crime.commit(Router, player, 1, workerScript); }, getCrimeChance: function (_crimeRoughName: unknown): number { + updateRam("getCrimeChance"); const crimeRoughName = helper.string("getCrimeChance", "crimeRoughName", _crimeRoughName); - helper.updateDynamicRam("getCrimeChance", getRamCost(player, "getCrimeChance")); helper.checkSingularityAccess("getCrimeChance"); const crime = findCrime(crimeRoughName.toLowerCase()); @@ -1261,8 +1263,8 @@ export function NetscriptSingularity( return crime.successRate(player); }, getCrimeStats: function (_crimeRoughName: unknown): CrimeStats { + updateRam("getCrimeStats"); const crimeRoughName = helper.string("getCrimeStats", "crimeRoughName", _crimeRoughName); - helper.updateDynamicRam("getCrimeStats", getRamCost(player, "getCrimeStats")); helper.checkSingularityAccess("getCrimeStats"); const crime = findCrime(crimeRoughName.toLowerCase()); @@ -1273,7 +1275,7 @@ export function NetscriptSingularity( return Object.assign({}, crime); }, getDarkwebPrograms: function (): string[] { - helper.updateDynamicRam("getDarkwebPrograms", getRamCost(player, "getDarkwebPrograms")); + updateRam("getDarkwebPrograms"); helper.checkSingularityAccess("getDarkwebPrograms"); // If we don't have Tor, log it and return [] (empty list) @@ -1284,8 +1286,8 @@ export function NetscriptSingularity( return Object.values(DarkWebItems).map((p) => p.program); }, getDarkwebProgramCost: function (_programName: unknown): number { + updateRam("getDarkwebProgramCost"); const programName = helper.string("getDarkwebProgramCost", "programName", _programName).toLowerCase(); - helper.updateDynamicRam("getDarkwebProgramCost", getRamCost(player, "getDarkwebProgramCost")); helper.checkSingularityAccess("getDarkwebProgramCost"); // If we don't have Tor, log it and return -1 diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index 40ac1faad..2f2b4302a 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -50,30 +50,33 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel }; }; + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "sleeve", funcName)); + return { getNumSleeves: function (): number { - helper.updateDynamicRam("getNumSleeves", getRamCost(player, "sleeve", "getNumSleeves")); + updateRam("getNumSleeves"); checkSleeveAPIAccess("getNumSleeves"); return player.sleeves.length; }, setToShockRecovery: function (_sleeveNumber: unknown): boolean { + updateRam("setToShockRecovery"); const sleeveNumber = helper.number("setToShockRecovery", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("setToShockRecovery", getRamCost(player, "sleeve", "setToShockRecovery")); checkSleeveAPIAccess("setToShockRecovery"); checkSleeveNumber("setToShockRecovery", sleeveNumber); return player.sleeves[sleeveNumber].shockRecovery(player); }, setToSynchronize: function (_sleeveNumber: unknown): boolean { + updateRam("setToSynchronize"); const sleeveNumber = helper.number("setToSynchronize", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("setToSynchronize", getRamCost(player, "sleeve", "setToSynchronize")); checkSleeveAPIAccess("setToSynchronize"); checkSleeveNumber("setToSynchronize", sleeveNumber); return player.sleeves[sleeveNumber].synchronize(player); }, setToCommitCrime: function (_sleeveNumber: unknown, _crimeRoughName: unknown): boolean { + updateRam("setToCommitCrime"); const sleeveNumber = helper.number("setToCommitCrime", "sleeveNumber", _sleeveNumber); const crimeRoughName = helper.string("setToCommitCrime", "crimeName", _crimeRoughName); - helper.updateDynamicRam("setToCommitCrime", getRamCost(player, "sleeve", "setToCommitCrime")); checkSleeveAPIAccess("setToCommitCrime"); checkSleeveNumber("setToCommitCrime", sleeveNumber); const crime = findCrime(crimeRoughName); @@ -83,26 +86,26 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel return player.sleeves[sleeveNumber].commitCrime(player, crime.name); }, setToUniversityCourse: function (_sleeveNumber: unknown, _universityName: unknown, _className: unknown): boolean { + updateRam("setToUniversityCourse"); const sleeveNumber = helper.number("setToUniversityCourse", "sleeveNumber", _sleeveNumber); const universityName = helper.string("setToUniversityCourse", "universityName", _universityName); const className = helper.string("setToUniversityCourse", "className", _className); - helper.updateDynamicRam("setToUniversityCourse", getRamCost(player, "sleeve", "setToUniversityCourse")); checkSleeveAPIAccess("setToUniversityCourse"); checkSleeveNumber("setToUniversityCourse", sleeveNumber); return player.sleeves[sleeveNumber].takeUniversityCourse(player, universityName, className); }, travel: function (_sleeveNumber: unknown, _cityName: unknown): boolean { + updateRam("travel"); const sleeveNumber = helper.number("travel", "sleeveNumber", _sleeveNumber); const cityName = helper.string("setToUniversityCourse", "cityName", _cityName); - helper.updateDynamicRam("travel", getRamCost(player, "sleeve", "travel")); checkSleeveAPIAccess("travel"); checkSleeveNumber("travel", sleeveNumber); return player.sleeves[sleeveNumber].travel(player, cityName as CityName); }, setToCompanyWork: function (_sleeveNumber: unknown, acompanyName: unknown): boolean { + updateRam("setToCompanyWork"); const sleeveNumber = helper.number("setToCompanyWork", "sleeveNumber", _sleeveNumber); const companyName = helper.string("setToUniversityCourse", "companyName", acompanyName); - helper.updateDynamicRam("setToCompanyWork", getRamCost(player, "sleeve", "setToCompanyWork")); checkSleeveAPIAccess("setToCompanyWork"); checkSleeveNumber("setToCompanyWork", sleeveNumber); @@ -127,10 +130,10 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel _factionName: unknown, _workType: unknown, ): boolean | undefined { + updateRam("setToFactionWork"); const sleeveNumber = helper.number("setToFactionWork", "sleeveNumber", _sleeveNumber); const factionName = helper.string("setToUniversityCourse", "factionName", _factionName); const workType = helper.string("setToUniversityCourse", "workType", _workType); - helper.updateDynamicRam("setToFactionWork", getRamCost(player, "sleeve", "setToFactionWork")); checkSleeveAPIAccess("setToFactionWork"); checkSleeveNumber("setToFactionWork", sleeveNumber); @@ -158,25 +161,25 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel return player.sleeves[sleeveNumber].workForFaction(player, factionName, workType); }, setToGymWorkout: function (_sleeveNumber: unknown, _gymName: unknown, _stat: unknown): boolean { + updateRam("setToGymWorkout"); const sleeveNumber = helper.number("setToGymWorkout", "sleeveNumber", _sleeveNumber); const gymName = helper.string("setToUniversityCourse", "gymName", _gymName); const stat = helper.string("setToUniversityCourse", "stat", _stat); - helper.updateDynamicRam("setToGymWorkout", getRamCost(player, "sleeve", "setToGymWorkout")); checkSleeveAPIAccess("setToGymWorkout"); checkSleeveNumber("setToGymWorkout", sleeveNumber); return player.sleeves[sleeveNumber].workoutAtGym(player, gymName, stat); }, getSleeveStats: function (_sleeveNumber: unknown): SleeveSkills { + updateRam("getSleeveStats"); const sleeveNumber = helper.number("getSleeveStats", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("getSleeveStats", getRamCost(player, "sleeve", "getSleeveStats")); checkSleeveAPIAccess("getSleeveStats"); checkSleeveNumber("getSleeveStats", sleeveNumber); return getSleeveStats(sleeveNumber); }, getTask: function (_sleeveNumber: unknown): SleeveTask { + updateRam("getTask"); const sleeveNumber = helper.number("getTask", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("getTask", getRamCost(player, "sleeve", "getTask")); checkSleeveAPIAccess("getTask"); checkSleeveNumber("getTask", sleeveNumber); @@ -190,8 +193,8 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel }; }, getInformation: function (_sleeveNumber: unknown): SleeveInformation { + updateRam("getInformation"); const sleeveNumber = helper.number("getInformation", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("getInformation", getRamCost(player, "sleeve", "getInformation")); checkSleeveAPIAccess("getInformation"); checkSleeveNumber("getInformation", sleeveNumber); @@ -256,8 +259,8 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel }; }, getSleeveAugmentations: function (_sleeveNumber: unknown): string[] { + updateRam("getSleeveAugmentations"); const sleeveNumber = helper.number("getSleeveAugmentations", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("getSleeveAugmentations", getRamCost(player, "sleeve", "getSleeveAugmentations")); checkSleeveAPIAccess("getSleeveAugmentations"); checkSleeveNumber("getSleeveAugmentations", sleeveNumber); @@ -268,8 +271,8 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel return augs; }, getSleevePurchasableAugs: function (_sleeveNumber: unknown): AugmentPair[] { + updateRam("getSleevePurchasableAugs"); const sleeveNumber = helper.number("getSleevePurchasableAugs", "sleeveNumber", _sleeveNumber); - helper.updateDynamicRam("getSleevePurchasableAugs", getRamCost(player, "sleeve", "getSleevePurchasableAugs")); checkSleeveAPIAccess("getSleevePurchasableAugs"); checkSleeveNumber("getSleevePurchasableAugs", sleeveNumber); @@ -286,9 +289,9 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel return augs; }, purchaseSleeveAug: function (_sleeveNumber: unknown, _augName: unknown): boolean { + updateRam("purchaseSleeveAug"); const sleeveNumber = helper.number("purchaseSleeveAug", "sleeveNumber", _sleeveNumber); const augName = helper.string("purchaseSleeveAug", "augName", _augName); - helper.updateDynamicRam("purchaseSleeveAug", getRamCost(player, "sleeve", "purchaseSleeveAug")); checkSleeveAPIAccess("purchaseSleeveAug"); checkSleeveNumber("purchaseSleeveAug", sleeveNumber); diff --git a/src/NetscriptFunctions/Stanek.ts b/src/NetscriptFunctions/Stanek.ts index eefaff190..6c55e21bd 100644 --- a/src/NetscriptFunctions/Stanek.ts +++ b/src/NetscriptFunctions/Stanek.ts @@ -21,22 +21,24 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel } } + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "stanek", funcName)); + return { giftWidth: function (): number { - helper.updateDynamicRam("giftWidth", getRamCost(player, "stanek", "giftWidth")); + updateRam("giftWidth"); checkStanekAPIAccess("giftWidth"); return staneksGift.width(); }, giftHeight: function (): number { - helper.updateDynamicRam("giftHeight", getRamCost(player, "stanek", "giftHeight")); + updateRam("giftHeight"); checkStanekAPIAccess("giftHeight"); return staneksGift.height(); }, chargeFragment: function (_rootX: unknown, _rootY: unknown): Promise { + updateRam("chargeFragment"); const rootX = helper.number("stanek.chargeFragment", "rootX", _rootX); const rootY = helper.number("stanek.chargeFragment", "rootY", _rootY); - - helper.updateDynamicRam("chargeFragment", getRamCost(player, "stanek", "chargeFragment")); checkStanekAPIAccess("chargeFragment"); const fragment = staneksGift.findFragment(rootX, rootY); if (!fragment) @@ -49,13 +51,13 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel }); }, fragmentDefinitions: function (): IFragment[] { - helper.updateDynamicRam("fragmentDefinitions", getRamCost(player, "stanek", "fragmentDefinitions")); + updateRam("fragmentDefinitions"); checkStanekAPIAccess("fragmentDefinitions"); workerScript.log("stanek.fragmentDefinitions", () => `Returned ${Fragments.length} fragments`); return Fragments.map((f) => f.copy()); }, activeFragments: function (): IActiveFragment[] { - helper.updateDynamicRam("activeFragments", getRamCost(player, "stanek", "activeFragments")); + updateRam("activeFragments"); checkStanekAPIAccess("activeFragments"); workerScript.log("stanek.activeFragments", () => `Returned ${staneksGift.fragments.length} fragments`); return staneksGift.fragments.map((af) => { @@ -63,17 +65,17 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel }); }, clearGift: function (): void { - helper.updateDynamicRam("clearGift", getRamCost(player, "stanek", "clearGift")); + updateRam("clearGift"); checkStanekAPIAccess("clearGift"); workerScript.log("stanek.clearGift", () => `Cleared Stanek's Gift.`); staneksGift.clear(); }, canPlaceFragment: function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean { + updateRam("canPlaceFragment"); const rootX = helper.number("stanek.canPlaceFragment", "rootX", _rootX); const rootY = helper.number("stanek.canPlaceFragment", "rootY", _rootY); const rotation = helper.number("stanek.canPlaceFragment", "rotation", _rotation); const fragmentId = helper.number("stanek.canPlaceFragment", "fragmentId", _fragmentId); - helper.updateDynamicRam("canPlaceFragment", getRamCost(player, "stanek", "canPlaceFragment")); checkStanekAPIAccess("canPlaceFragment"); const fragment = FragmentById(fragmentId); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.canPlaceFragment", `Invalid fragment id: ${fragmentId}`); @@ -81,29 +83,29 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel return can; }, placeFragment: function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean { + updateRam("placeFragment"); const rootX = helper.number("stanek.placeFragment", "rootX", _rootX); const rootY = helper.number("stanek.placeFragment", "rootY", _rootY); const rotation = helper.number("stanek.placeFragment", "rotation", _rotation); const fragmentId = helper.number("stanek.placeFragment", "fragmentId", _fragmentId); - helper.updateDynamicRam("placeFragment", getRamCost(player, "stanek", "placeFragment")); checkStanekAPIAccess("placeFragment"); const fragment = FragmentById(fragmentId); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.placeFragment", `Invalid fragment id: ${fragmentId}`); return staneksGift.place(rootX, rootY, rotation, fragment); }, getFragment: function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined { + updateRam("getFragment"); const rootX = helper.number("stanek.getFragment", "rootX", _rootX); const rootY = helper.number("stanek.getFragment", "rootY", _rootY); - helper.updateDynamicRam("getFragment", getRamCost(player, "stanek", "getFragment")); checkStanekAPIAccess("getFragment"); const fragment = staneksGift.findFragment(rootX, rootY); if (fragment !== undefined) return fragment.copy(); return undefined; }, removeFragment: function (_rootX: unknown, _rootY: unknown): boolean { + updateRam("removeFragment"); const rootX = helper.number("stanek.removeFragment", "rootX", _rootX); const rootY = helper.number("stanek.removeFragment", "rootY", _rootY); - helper.updateDynamicRam("removeFragment", getRamCost(player, "stanek", "removeFragment")); checkStanekAPIAccess("removeFragment"); return staneksGift.delete(rootX, rootY); }, diff --git a/src/NetscriptFunctions/StockMarket.ts b/src/NetscriptFunctions/StockMarket.ts index 52fac413c..d2c535b09 100644 --- a/src/NetscriptFunctions/StockMarket.ts +++ b/src/NetscriptFunctions/StockMarket.ts @@ -38,14 +38,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock; }; + + const updateRam = (funcName: string): void => + helper.updateDynamicRam(funcName, getRamCost(player, "stock", funcName)); + return { getSymbols: function (): string[] { - helper.updateDynamicRam("getSymbols", getRamCost(player, "stock", "getSymbols")); + updateRam("getSymbols"); checkTixApiAccess("getSymbols"); return Object.values(StockSymbols); }, getPrice: function (_symbol: unknown): number { - helper.updateDynamicRam("getPrice", getRamCost(player, "stock", "getPrice")); + updateRam("getPrice"); const symbol = helper.string("getPrice", "symbol", _symbol); checkTixApiAccess("getPrice"); const stock = getStockFromSymbol(symbol, "getPrice"); @@ -53,7 +57,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock.price; }, getAskPrice: function (_symbol: unknown): number { - helper.updateDynamicRam("getAskPrice", getRamCost(player, "stock", "getAskPrice")); + updateRam("getAskPrice"); const symbol = helper.string("getAskPrice", "symbol", _symbol); checkTixApiAccess("getAskPrice"); const stock = getStockFromSymbol(symbol, "getAskPrice"); @@ -61,7 +65,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock.getAskPrice(); }, getBidPrice: function (_symbol: unknown): number { - helper.updateDynamicRam("getBidPrice", getRamCost(player, "stock", "getBidPrice")); + updateRam("getBidPrice"); const symbol = helper.string("getBidPrice", "symbol", _symbol); checkTixApiAccess("getBidPrice"); const stock = getStockFromSymbol(symbol, "getBidPrice"); @@ -69,7 +73,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock.getBidPrice(); }, getPosition: function (_symbol: unknown): [number, number, number, number] { - helper.updateDynamicRam("getPosition", getRamCost(player, "stock", "getPosition")); + updateRam("getPosition"); const symbol = helper.string("getPosition", "symbol", _symbol); checkTixApiAccess("getPosition"); const stock = SymbolToStockMap[symbol]; @@ -79,7 +83,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx]; }, getMaxShares: function (_symbol: unknown): number { - helper.updateDynamicRam("getMaxShares", getRamCost(player, "stock", "getMaxShares")); + updateRam("getMaxShares"); const symbol = helper.string("getMaxShares", "symbol", _symbol); checkTixApiAccess("getMaxShares"); const stock = getStockFromSymbol(symbol, "getMaxShares"); @@ -87,7 +91,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock.maxShares; }, getPurchaseCost: function (_symbol: unknown, _shares: unknown, _posType: unknown): number { - helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost")); + updateRam("getPurchaseCost"); const symbol = helper.string("getPurchaseCost", "symbol", _symbol); let shares = helper.number("getPurchaseCost", "shares", _shares); const posType = helper.string("getPurchaseCost", "posType", _posType); @@ -113,7 +117,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res; }, getSaleGain: function (_symbol: unknown, _shares: unknown, _posType: unknown): number { - helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain")); + updateRam("getSaleGain"); const symbol = helper.string("getSaleGain", "symbol", _symbol); let shares = helper.number("getSaleGain", "shares", _shares); const posType = helper.string("getSaleGain", "posType", _posType); @@ -139,7 +143,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res; }, buy: function (_symbol: unknown, _shares: unknown): number { - helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy")); + updateRam("buy"); const symbol = helper.string("buy", "symbol", _symbol); const shares = helper.number("buy", "shares", _shares); checkTixApiAccess("buy"); @@ -148,7 +152,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res ? stock.getAskPrice() : 0; }, sell: function (_symbol: unknown, _shares: unknown): number { - helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell")); + updateRam("sell"); const symbol = helper.string("sell", "symbol", _symbol); const shares = helper.number("sell", "shares", _shares); checkTixApiAccess("sell"); @@ -158,7 +162,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res ? stock.getBidPrice() : 0; }, short: function (_symbol: unknown, _shares: unknown): number { - helper.updateDynamicRam("short", getRamCost(player, "stock", "short")); + updateRam("short"); const symbol = helper.string("short", "symbol", _symbol); const shares = helper.number("short", "shares", _shares); checkTixApiAccess("short"); @@ -176,7 +180,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res ? stock.getBidPrice() : 0; }, sellShort: function (_symbol: unknown, _shares: unknown): number { - helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort")); + updateRam("sellShort"); const symbol = helper.string("sellShort", "symbol", _symbol); const shares = helper.number("sellShort", "shares", _shares); checkTixApiAccess("sellShort"); @@ -194,7 +198,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return res ? stock.getAskPrice() : 0; }, placeOrder: function (_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean { - helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder")); + updateRam("placeOrder"); const symbol = helper.string("placeOrder", "symbol", _symbol); const shares = helper.number("placeOrder", "shares", _shares); const price = helper.number("placeOrder", "price", _price); @@ -244,7 +248,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript _type: unknown, _pos: unknown, ): boolean { - helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder")); + updateRam("cancelOrder"); const symbol = helper.string("cancelOrder", "symbol", _symbol); const shares = helper.number("cancelOrder", "shares", _shares); const price = helper.number("cancelOrder", "price", _price); @@ -299,7 +303,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return cancelOrder(params, workerScript); }, getOrders: function (): any { - helper.updateDynamicRam("getOrders", getRamCost(player, "stock", "getOrders")); + updateRam("getOrders"); checkTixApiAccess("getOrders"); if (player.bitNodeN !== 8) { if (player.sourceFileLvl(8) <= 2) { @@ -331,7 +335,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return orders; }, getVolatility: function (_symbol: unknown): number { - helper.updateDynamicRam("getVolatility", getRamCost(player, "stock", "getVolatility")); + updateRam("getVolatility"); const symbol = helper.string("getVolatility", "symbol", _symbol); if (!player.has4SDataTixApi) { throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!"); @@ -341,7 +345,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return stock.mv / 100; // Convert from percentage to decimal }, getForecast: function (_symbol: unknown): number { - helper.updateDynamicRam("getForecast", getRamCost(player, "stock", "getForecast")); + updateRam("getForecast"); const symbol = helper.string("getForecast", "symbol", _symbol); if (!player.has4SDataTixApi) { throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!"); @@ -353,7 +357,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return forecast / 100; // Convert from percentage to decimal }, purchase4SMarketData: function (): boolean { - helper.updateDynamicRam("purchase4SMarketData", getRamCost(player, "stock", "purchase4SMarketData")); + updateRam("purchase4SMarketData"); checkTixApiAccess("purchase4SMarketData"); if (player.has4SData) { @@ -372,7 +376,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return true; }, purchase4SMarketDataTixApi: function (): boolean { - helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost(player, "stock", "purchase4SMarketDataTixApi")); + updateRam("purchase4SMarketDataTixApi"); checkTixApiAccess("purchase4SMarketDataTixApi"); if (player.has4SDataTixApi) { @@ -394,7 +398,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return true; }, purchaseWseAccount: function (): boolean { - helper.updateDynamicRam("PurchaseWseAccount", getRamCost(player, "stock", "purchaseWseAccount")); + updateRam("PurchaseWseAccount"); if (player.hasWseAccount) { workerScript.log("stock.purchaseWseAccount", () => "Already purchased WSE Account"); @@ -412,7 +416,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript return true; }, purchaseTixApi: function (): boolean { - helper.updateDynamicRam("purchaseTixApi", getRamCost(player, "stock", "purchaseTixApi")); + updateRam("purchaseTixApi"); if (player.hasTixApiAccess) { workerScript.log("stock.purchaseTixApi", () => "Already purchased TIX API"); diff --git a/src/NetscriptFunctions/UserInterface.ts b/src/NetscriptFunctions/UserInterface.ts index ca6d3be61..b639f718a 100644 --- a/src/NetscriptFunctions/UserInterface.ts +++ b/src/NetscriptFunctions/UserInterface.ts @@ -20,19 +20,20 @@ export function NetscriptUserInterface( workerScript: WorkerScript, helper: INetscriptHelper, ): IUserInterface { + const updateRam = (funcName: string): void => helper.updateDynamicRam(funcName, getRamCost(player, "ui", funcName)); return { getTheme: function (): UserInterfaceTheme { - helper.updateDynamicRam("getTheme", getRamCost(player, "ui", "getTheme")); + updateRam("getTheme"); return { ...Settings.theme }; }, getStyles: function (): IStyleSettings { - helper.updateDynamicRam("getStyles", getRamCost(player, "ui", "getStyles")); + updateRam("getStyles"); return { ...Settings.styles }; }, setTheme: function (newTheme: UserInterfaceTheme): void { - helper.updateDynamicRam("setTheme", getRamCost(player, "ui", "setTheme")); + updateRam("setTheme"); const hex = /^(#)((?:[A-Fa-f0-9]{2}){3,4}|(?:[A-Fa-f0-9]{3}))$/; const currentTheme = { ...Settings.theme }; const errors: string[] = []; @@ -57,7 +58,7 @@ export function NetscriptUserInterface( }, setStyles: function (newStyles: IStyleSettings): void { - helper.updateDynamicRam("setStyles", getRamCost(player, "ui", "setStyles")); + updateRam("setStyles"); const currentStyles = { ...Settings.styles }; const errors: string[] = []; @@ -80,21 +81,21 @@ export function NetscriptUserInterface( }, resetTheme: function (): void { - helper.updateDynamicRam("resetTheme", getRamCost(player, "ui", "resetTheme")); + updateRam("resetTheme"); Settings.theme = { ...defaultTheme }; ThemeEvents.emit(); workerScript.log("ui.resetTheme", () => `Reinitialized theme to default`); }, resetStyles: function (): void { - helper.updateDynamicRam("resetStyles", getRamCost(player, "ui", "resetStyles")); + updateRam("resetStyles"); Settings.styles = { ...defaultStyles }; ThemeEvents.emit(); workerScript.log("ui.resetStyles", () => `Reinitialized styles to default`); }, getGameInfo: function (): GameInfo { - helper.updateDynamicRam("getGameInfo", getRamCost(player, "ui", "getGameInfo")); + updateRam("getGameInfo"); const version = CONSTANTS.VersionString; const commit = hash(); const platform = navigator.userAgent.toLowerCase().indexOf(" electron/") > -1 ? "Steam" : "Browser"; diff --git a/test/jest/Netscript/StaticRamParsingCalculation.test.js b/test/jest/Netscript/StaticRamParsingCalculation.test.js new file mode 100644 index 000000000..eba80b16c --- /dev/null +++ b/test/jest/Netscript/StaticRamParsingCalculation.test.js @@ -0,0 +1,330 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { describe, expect, jest } from "@jest/globals"; + +// Player is needed for calculating costs like Singularity functions, that depend on acquired source files +import { Player } from "../../../src/Player"; + +import { RamCostConstants } from "../../../src/Netscript/RamCostGenerator"; +import { calculateRamUsage } from "../../../src/Script/RamCalculations"; +import { Script } from "../../../src/Script/Script"; + +jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", { + virtual: true, +}); + +const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost; +const HackCost = 0.1; +const GrowCost = 0.15; +const SleeveGetTaskCost = 4; +const HacknetCost = 4; +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 + function expectCost(val, expected) { + const expectedWithBase = expected + ScriptBaseCost; + expect(val).toBeGreaterThanOrEqual(expectedWithBase - 100 * Number.EPSILON); + expect(val).toBeLessThanOrEqual(expectedWithBase + 100 * Number.EPSILON); + } + + describe("Single files with basic NS functions", function () { + it("Empty main function", async function () { + const code = ` + export async function main(ns) { } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, 0); + }); + + it("Free NS function directly in main", async function () { + const code = ` + export async function main(ns) { + ns.print("Slum snakes r00l!"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, 0); + }); + + it("Single simple base NS function directly in main", async function () { + const code = ` + export async function main(ns) { + await ns.hack("joesguns"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + + it("Single simple base NS function directly in main with differing arg name", async function () { + const code = ` + export async function main(X) { + await X.hack("joesguns"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + + it("Repeated simple base NS function directly in main", async function () { + const code = ` + export async function main(ns) { + await ns.hack("joesguns"); + await ns.hack("joesguns"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + + it("Multiple simple base NS functions directly in main", async function () { + const code = ` + export async function main(ns) { + await ns.hack("joesguns"); + await ns.grow("joesguns"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost + GrowCost); + }); + + it("Simple base NS functions in a referenced function", async function () { + const code = ` + export async function main(ns) { + doHacking(ns); + } + async function doHacking(ns) { + await ns.hack("joesguns"); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + + it("Simple base NS functions in a referenced class", async function () { + const code = ` + export async function main(ns) { + await new Hacker(ns).doHacking(); + } + class Hacker { + ns; + constructor(ns) { this.ns = ns; } + async doHacking() { await this.ns.hack("joesguns"); } + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + + it("Simple base NS functions in a referenced class", async function () { + const code = ` + export async function main(ns) { + await new Hacker(ns).doHacking(); + } + class Hacker { + #ns; + constructor(ns) { this.#ns = ns; } + async doHacking() { await this.#ns.hack("joesguns"); } + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HackCost); + }); + }); + + describe("Functions that can be confused with NS functions", function () { + it("Function 'get' that can be confused with Stanek.get", async function () { + const code = ` + export async function main(ns) { + get(); + } + function get() { return 0; } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, 0); + }); + + it("Function 'purchaseNode' that can be confused with Hacknet.purchaseNode", async function () { + const code = ` + export async function main(ns) { + purchaseNode(); + } + function purchaseNode() { return 0; } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + // Works at present, because the parser checks the namespace only, not the function name + expectCost(calculated, 0); + }); + + // TODO: once we fix static parsing this should pass + it.skip("Function 'getTask' that can be confused with Sleeve.getTask", async function () { + const code = ` + export async function main(ns) { + getTask(); + } + function getTask() { return 0; } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, 0); + }); + }); + + describe("Single files with non-core NS functions", function () { + it("Hacknet NS function with a cost from namespace", async function () { + const code = ` + export async function main(ns) { + ns.hacknet.purchaseNode(0); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, HacknetCost); + }); + + it("Corporation NS function with a cost from namespace", async function () { + const code = ` + export async function main(ns) { + ns.corporation.getCorporation(); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, CorpCost); + }); + + it("Both Corporation and Hacknet functions", async function () { + const code = ` + export async function main(ns) { + ns.corporation.getCorporation(); + ns.hacknet.purchaseNode(0); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, CorpCost + HacknetCost); + }); + + it("Sleeve functions with an individual cost", async function () { + const code = ` + export async function main(ns) { + ns.sleeve.getTask(3); + } + `; + const calculated = (await calculateRamUsage(Player, code, [])).cost; + expectCost(calculated, SleeveGetTaskCost); + }); + }); + + describe("Imported files", function () { + it("Simple imported function with no cost", async function () { + const libCode = ` + export function dummy() { return 0; } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import { dummy } from "libTest"; + export async function main(ns) { + dummy(); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, 0); + }); + + it("Imported ns function", async function () { + const libCode = ` + export async function doHack(ns) { return await ns.hack("joesguns"); } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import { doHack } from "libTest"; + export async function main(ns) { + await doHack(ns); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, HackCost); + }); + + it("Importing a single function from a library that exports multiple", async function () { + const libCode = ` + export async function doHack(ns) { return await ns.hack("joesguns"); } + export async function doGrow(ns) { return await ns.grow("joesguns"); } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import { doHack } from "libTest"; + export async function main(ns) { + await doHack(ns); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, HackCost); + }); + + it("Importing all functions from a library that exports multiple", async function () { + const libCode = ` + export async function doHack(ns) { return await ns.hack("joesguns"); } + export async function doGrow(ns) { return await ns.grow("joesguns"); } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import * as test from "libTest"; + export async function main(ns) { + await test.doHack(ns); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, HackCost + GrowCost); + }); + + // TODO: once we fix static parsing this should pass + it.skip("Importing a function from a library that contains a class", async function () { + const libCode = ` + export async function doHack(ns) { return await ns.hack("joesguns"); } + class Grower { + ns; + constructor(ns) { this.ns = ns; } + async doGrow() { return await this.ns.grow("joesguns"); } + } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import * as test from "libTest"; + export async function main(ns) { + await test.doHack(ns); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, HackCost); + }); + + it("Importing a function from a library that creates a class in a function", async function () { + const libCode = ` + export function createClass() { + class Grower { + ns; + constructor(ns) { this.ns = ns; } + async doGrow() { return await this.ns.grow("joesguns"); } + } + return Grower; + } + `; + const lib = new Script(Player, "libTest.js", libCode, []); + + const code = ` + import { createClass } from "libTest"; + + export async function main(ns) { + const grower = createClass(); + const growerInstance = new grower(ns); + await growerInstance.doGrow(); + } + `; + const calculated = (await calculateRamUsage(Player, code, [lib])).cost; + expectCost(calculated, GrowCost); + }); + }); +}); diff --git a/test/jest/ui/nFormat.test.js b/test/jest/ui/nFormat.test.js index 9c75588a6..7ddc427aa 100644 --- a/test/jest/ui/nFormat.test.js +++ b/test/jest/ui/nFormat.test.js @@ -18,14 +18,14 @@ describe("Numeral formatting for positive numbers", () => { expect(numeralWrapper.format(1, decimalFormat)).toEqual("1"); }); test("should format big numbers in short format", () => { - expect(numeralWrapper.formatBigNumber(987654000000000000)).toEqual("987654t"); - expect(numeralWrapper.formatBigNumber(987654300000000000)).toEqual("987654.3t"); - expect(numeralWrapper.formatBigNumber(987654320000000000)).toEqual("987654.32t"); + expect(numeralWrapper.formatBigNumber(987654000000000000)).toEqual("987654.000t"); + expect(numeralWrapper.formatBigNumber(987654300000000000)).toEqual("987654.300t"); + expect(numeralWrapper.formatBigNumber(987654320000000000)).toEqual("987654.320t"); expect(numeralWrapper.formatBigNumber(987654321000000000)).toEqual("987654.321t"); expect(numeralWrapper.formatBigNumber(987654321900000000)).toEqual("987654.322t"); }); test("should format really big numbers in readable format", () => { - expect(numeralWrapper.formatReallyBigNumber(987)).toEqual("987"); + expect(numeralWrapper.formatReallyBigNumber(987)).toEqual("987.000"); expect(numeralWrapper.formatReallyBigNumber(987654)).toEqual("987.654k"); expect(numeralWrapper.formatReallyBigNumber(987654321)).toEqual("987.654m"); expect(numeralWrapper.formatReallyBigNumber(987654321987)).toEqual("987.654b"); @@ -62,14 +62,14 @@ describe("Numeral formatting for negative numbers", () => { expect(numeralWrapper.format(-1, decimalFormat)).toEqual("-1"); }); test("should format big numbers in short format", () => { - expect(numeralWrapper.formatBigNumber(-987654000000000000)).toEqual("-987654t"); - expect(numeralWrapper.formatBigNumber(-987654300000000000)).toEqual("-987654.3t"); - expect(numeralWrapper.formatBigNumber(-987654320000000000)).toEqual("-987654.32t"); + expect(numeralWrapper.formatBigNumber(-987654000000000000)).toEqual("-987654.000t"); + expect(numeralWrapper.formatBigNumber(-987654300000000000)).toEqual("-987654.300t"); + expect(numeralWrapper.formatBigNumber(-987654320000000000)).toEqual("-987654.320t"); expect(numeralWrapper.formatBigNumber(-987654321000000000)).toEqual("-987654.321t"); expect(numeralWrapper.formatBigNumber(-987654321900000000)).toEqual("-987654.322t"); }); test("should format really big numbers in readable format", () => { - expect(numeralWrapper.formatReallyBigNumber(-987)).toEqual("-987"); + expect(numeralWrapper.formatReallyBigNumber(-987)).toEqual("-987.000"); expect(numeralWrapper.formatReallyBigNumber(-987654)).toEqual("-987.654k"); expect(numeralWrapper.formatReallyBigNumber(-987654321)).toEqual("-987.654m"); expect(numeralWrapper.formatReallyBigNumber(-987654321987)).toEqual("-987.654b"); @@ -112,19 +112,19 @@ describe("Numeral formatting of text", () => { expect(numeralWrapper.format("-1", decimalFormat)).toEqual("-1"); }); test("should format big numbers in short format", () => { - expect(numeralWrapper.formatBigNumber("987654000000000000")).toEqual("987654t"); - expect(numeralWrapper.formatBigNumber("987654300000000000")).toEqual("987654.3t"); - expect(numeralWrapper.formatBigNumber("987654320000000000")).toEqual("987654.32t"); + expect(numeralWrapper.formatBigNumber("987654000000000000")).toEqual("987654.000t"); + expect(numeralWrapper.formatBigNumber("987654300000000000")).toEqual("987654.300t"); + expect(numeralWrapper.formatBigNumber("987654320000000000")).toEqual("987654.320t"); expect(numeralWrapper.formatBigNumber("987654321000000000")).toEqual("987654.321t"); expect(numeralWrapper.formatBigNumber("987654321900000000")).toEqual("987654.322t"); - expect(numeralWrapper.formatBigNumber("-987654000000000000")).toEqual("-987654t"); - expect(numeralWrapper.formatBigNumber("-987654300000000000")).toEqual("-987654.3t"); - expect(numeralWrapper.formatBigNumber("-987654320000000000")).toEqual("-987654.32t"); + expect(numeralWrapper.formatBigNumber("-987654000000000000")).toEqual("-987654.000t"); + expect(numeralWrapper.formatBigNumber("-987654300000000000")).toEqual("-987654.300t"); + expect(numeralWrapper.formatBigNumber("-987654320000000000")).toEqual("-987654.320t"); expect(numeralWrapper.formatBigNumber("-987654321000000000")).toEqual("-987654.321t"); expect(numeralWrapper.formatBigNumber("-987654321900000000")).toEqual("-987654.322t"); }); test("should format really big numbers in readable format", () => { - expect(numeralWrapper.formatReallyBigNumber("987")).toEqual("987"); + expect(numeralWrapper.formatReallyBigNumber("987")).toEqual("987.000"); expect(numeralWrapper.formatReallyBigNumber("987654")).toEqual("987.654k"); expect(numeralWrapper.formatReallyBigNumber("987654321")).toEqual("987.654m"); expect(numeralWrapper.formatReallyBigNumber("987654321987")).toEqual("987.654b"); @@ -135,7 +135,7 @@ describe("Numeral formatting of text", () => { expect(numeralWrapper.formatReallyBigNumber("987654321987654321987654321")).toEqual("987.654S"); expect(numeralWrapper.formatReallyBigNumber("987654321987654321987654321987")).toEqual("987.654o"); expect(numeralWrapper.formatReallyBigNumber("987654321987654321987654321987654")).toEqual("987.654n"); - expect(numeralWrapper.formatReallyBigNumber("-987")).toEqual("-987"); + expect(numeralWrapper.formatReallyBigNumber("-987")).toEqual("-987.000"); expect(numeralWrapper.formatReallyBigNumber("-987654")).toEqual("-987.654k"); expect(numeralWrapper.formatReallyBigNumber("-987654321")).toEqual("-987.654m"); expect(numeralWrapper.formatReallyBigNumber("-987654321987")).toEqual("-987.654b");