Some cleanup

This commit is contained in:
Snarling 2022-08-09 18:08:04 -04:00
parent 931ea730a5
commit 648b7e84bf
7 changed files with 162 additions and 234 deletions

@ -1,6 +1,6 @@
import { NetscriptContext } from "./APIWrapper"; import { NetscriptContext } from "./APIWrapper";
import { WorkerScript } from "./WorkerScript"; import { WorkerScript } from "./WorkerScript";
import { GetServer } from "../Server/AllServers"; import { GetAllServers, GetServer } from "../Server/AllServers";
import { Player } from "../Player"; import { Player } from "../Player";
import { ScriptDeath } from "./ScriptDeath"; import { ScriptDeath } from "./ScriptDeath";
import { isString } from "../utils/helpers/isString"; import { isString } from "../utils/helpers/isString";
@ -28,24 +28,24 @@ import { GangMember } from "../Gang/GangMember";
import { GangMemberTask } from "../Gang/GangMemberTask"; import { GangMemberTask } from "../Gang/GangMemberTask";
import { RunningScript } from "../Script/RunningScript"; import { RunningScript } from "../Script/RunningScript";
import { toNative } from "../NetscriptFunctions/toNative"; import { toNative } from "../NetscriptFunctions/toNative";
import { ScriptIdentifier } from "./ScriptIdentifier";
//Helpers that are not specific to use in WorkerScripts/NetscriptContexts should be in src/utils/helpers instead import { findRunningScript, findRunningScriptByPid } from "../Script/ScriptHelpers";
import { RunningScript as IRunningScript } from "../ScriptEditor/NetscriptDefinitions";
import { arrayToString } from "../utils/helpers/arrayToString";
import { HacknetServer } from "../Hacknet/HacknetServer";
import { BaseServer } from "../Server/BaseServer";
export const helpers = { export const helpers = {
//Type checking, conversion, validation
string, string,
number, number,
scriptArgs, scriptArgs,
argsToString, argsToString,
isScriptErrorMessage, isScriptErrorMessage,
//Error checking and generation
makeRuntimeRejectMsg, makeRuntimeRejectMsg,
makeRuntimeErrorMsg, makeRuntimeErrorMsg,
resolveNetscriptRequestedThreads, resolveNetscriptRequestedThreads,
//Checking for API access or flags that would prevent a function from running
checkEnvFlags, checkEnvFlags,
checkSingularityAccess, checkSingularityAccess,
//Functionality
netscriptDelay, netscriptDelay,
updateDynamicRam, updateDynamicRam,
city, city,
@ -59,25 +59,22 @@ export const helpers = {
gangMember, gangMember,
gangTask, gangTask,
log, log,
getFunctionNames,
getRunningScript,
getRunningScriptByArgs, getRunningScriptByArgs,
getCannotFindRunningScriptErrorMessage,
createPublicRunningScript,
failOnHacknetServer,
}; };
export type ScriptIdentifier = //This was previously in INetscriptHelper.ts, may move to its own file or a generic types file. /** Convert a provided value v for argument argName to string. If it wasn't originally a string or number, throw. */
| number
| {
scriptname: string;
hostname: string;
args: ScriptArg[];
};
/** If v is a number or string, returns the string representation. Error for other non-strings. */
function string(ctx: NetscriptContext, argName: string, v: unknown): string { function string(ctx: NetscriptContext, argName: string, v: unknown): string {
if (typeof v === "string") return v; if (typeof v === "string") return v;
if (typeof v === "number") return v + ""; // cast to string; if (typeof v === "number") return v + ""; // cast to string;
throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a string.`); throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a string.`);
} }
/** Validates v as non-NaN number, or as a string representation of a number, and returns that number. Error on NaN or non-number. */ /** Convert provided value v for argument argName to number. Throw if could not convert to a non-NaN number. */
function number(ctx: NetscriptContext, argName: string, v: unknown): number { function number(ctx: NetscriptContext, argName: string, v: unknown): number {
if (typeof v === "string") { if (typeof v === "string") {
const x = parseFloat(v); const x = parseFloat(v);
@ -89,7 +86,7 @@ function number(ctx: NetscriptContext, argName: string, v: unknown): number {
throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a number.`); throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a number.`);
} }
/** Validates args as a ScriptArg[]. Throws an error if it is not. */ /** Returns args back if it is a ScriptArg[]. Throws an error if it is not. */
function scriptArgs(ctx: NetscriptContext, args: unknown) { function scriptArgs(ctx: NetscriptContext, args: unknown) {
if (!isScriptArgs(args)) throw makeRuntimeErrorMsg(ctx, "'args' is not an array of script args"); if (!isScriptArgs(args)) throw makeRuntimeErrorMsg(ctx, "'args' is not an array of script args");
return args; return args;
@ -104,7 +101,7 @@ function isScriptErrorMessage(msg: string): boolean {
return splitMsg.length == 4; return splitMsg.length == 4;
} }
/** Used to convert multiple arguments for tprint or print into a single string. */ /** Convert multiple arguments for tprint or print into a single string. */
function argsToString(args: unknown[]): string { function argsToString(args: unknown[]): string {
let out = ""; let out = "";
for (let arg of args) { for (let arg of args) {
@ -253,6 +250,7 @@ function checkEnvFlags(ctx: NetscriptContext): void {
} }
} }
/** Set a timeout for performing a task, mark the script as busy in the meantime. */
function netscriptDelay(ctx: NetscriptContext, time: number): Promise<void> { function netscriptDelay(ctx: NetscriptContext, time: number): Promise<void> {
const ws = ctx.workerScript; const ws = ctx.workerScript;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -268,6 +266,7 @@ function netscriptDelay(ctx: NetscriptContext, time: number): Promise<void> {
}); });
} }
/** Adds to dynamic ram cost when calling new ns functions from a script */
function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void { function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
const ws = ctx.workerScript; const ws = ctx.workerScript;
const fnName = ctx.function; const fnName = ctx.function;
@ -302,6 +301,7 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
} }
} }
/** Validates the input v as being a CityName. Throws an error if it is not. */
function city(ctx: NetscriptContext, argName: string, v: unknown): CityName { function city(ctx: NetscriptContext, argName: string, v: unknown): CityName {
if (typeof v !== "string") throw makeRuntimeErrorMsg(ctx, `${argName} should be a city name.`); if (typeof v !== "string") throw makeRuntimeErrorMsg(ctx, `${argName} should be a city name.`);
const s = v as CityName; const s = v as CityName;
@ -574,3 +574,92 @@ function getRunningScriptByArgs(
// If no arguments are specified, return the current RunningScript // If no arguments are specified, return the current RunningScript
return ctx.workerScript.scriptRef; return ctx.workerScript.scriptRef;
} }
/** Provides an array of all function names on a nested object */
function getFunctionNames(obj: object, prefix: string): string[] {
const functionNames: string[] = [];
for (const [key, value] of Object.entries(obj)) {
if (key === "args") {
continue;
} else if (typeof value == "function") {
functionNames.push(prefix + key);
} else if (typeof value == "object") {
functionNames.push(...getFunctionNames(value, key + "."));
}
}
return functionNames;
}
function getRunningScriptByPid(pid: number): RunningScript | null {
for (const server of GetAllServers()) {
const runningScript = findRunningScriptByPid(pid, server);
if (runningScript) return runningScript;
}
return null;
}
function getRunningScript(ctx: NetscriptContext, ident: ScriptIdentifier): RunningScript | null {
if (typeof ident === "number") {
return getRunningScriptByPid(ident);
} else {
return getRunningScriptByArgs(ctx, ident.scriptname, ident.hostname, ident.args);
}
}
/**
* Helper function for getting the error log message when the user specifies
* a nonexistent running script
* @param {string} fn - Filename of script
* @param {string} hostname - Hostname/ip of the server on which the script resides
* @param {any[]} scriptArgs - Running script's arguments
* @returns {string} Error message to print to logs
*/
function getCannotFindRunningScriptErrorMessage(ident: ScriptIdentifier): string {
if (typeof ident === "number") return `Cannot find running script with pid: ${ident}`;
return `Cannot find running script ${ident.scriptname} on server ${ident.hostname} with args: ${arrayToString(
ident.args,
)}`;
}
/**
* Sanitizes a `RunningScript` to remove sensitive information, making it suitable for
* return through an NS function.
* @see NS.getRecentScripts
* @see NS.getRunningScript
* @param runningScript Existing, internal RunningScript
* @returns A sanitized, NS-facing copy of the RunningScript
*/
function createPublicRunningScript(runningScript: RunningScript): IRunningScript {
return {
args: runningScript.args.slice(),
filename: runningScript.filename,
logs: runningScript.logs.slice(),
offlineExpGained: runningScript.offlineExpGained,
offlineMoneyMade: runningScript.offlineMoneyMade,
offlineRunningTime: runningScript.offlineRunningTime,
onlineExpGained: runningScript.onlineExpGained,
onlineMoneyMade: runningScript.onlineMoneyMade,
onlineRunningTime: runningScript.onlineRunningTime,
pid: runningScript.pid,
ramUsage: runningScript.ramUsage,
server: runningScript.server,
threads: runningScript.threads,
};
}
/**
* Used to fail a function if the function's target is a Hacknet Server.
* This is used for functions that should run on normal Servers, but not Hacknet Servers
* @param {Server} server - Target server
* @param {string} callingFn - Name of calling function. For logging purposes
* @returns {boolean} True if the server is a Hacknet Server, false otherwise
*/
function failOnHacknetServer(ctx: NetscriptContext, server: BaseServer, callingFn = ""): boolean {
if (server instanceof HacknetServer) {
ctx.workerScript.log(callingFn, () => `Does not work on Hacknet Servers`);
return true;
} else {
return false;
}
}

@ -0,0 +1,9 @@
import { ScriptArg } from "./ScriptArg";
export type ScriptIdentifier = //This was previously in INetscriptHelper.ts, may move to its own file or a generic types file.
| number
| {
scriptname: string;
hostname: string;
args: ScriptArg[];
};

@ -1,12 +1,8 @@
import $ from "jquery"; import $ from "jquery";
import { vsprintf, sprintf } from "sprintf-js"; import { vsprintf, sprintf } from "sprintf-js";
import { WorkerScriptStartStopEventEmitter } from "./Netscript/WorkerScriptStartStopEventEmitter"; import { WorkerScriptStartStopEventEmitter } from "./Netscript/WorkerScriptStartStopEventEmitter";
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
import { CONSTANTS } from "./Constants"; import { CONSTANTS } from "./Constants";
import { import {
calculateHackingChance, calculateHackingChance,
calculateHackingExpGain, calculateHackingExpGain,
@ -15,22 +11,14 @@ import {
calculateGrowTime, calculateGrowTime,
calculateWeakenTime, calculateWeakenTime,
} from "./Hacking"; } from "./Hacking";
import { netscriptCanGrow, netscriptCanWeaken } from "./Hacking/netscriptCanHack"; import { netscriptCanGrow, netscriptCanWeaken } from "./Hacking/netscriptCanHack";
import { HacknetServer } from "./Hacknet/HacknetServer";
import { Terminal } from "./Terminal"; import { Terminal } from "./Terminal";
import { Player } from "./Player"; import { Player } from "./Player";
import { Programs } from "./Programs/Programs"; import { Programs } from "./Programs/Programs";
import { Script } from "./Script/Script"; import { Script } from "./Script/Script";
import { findRunningScript, findRunningScriptByPid } from "./Script/ScriptHelpers";
import { isScriptFilename } from "./Script/isScriptFilename"; import { isScriptFilename } from "./Script/isScriptFilename";
import { PromptEvent } from "./ui/React/PromptManager"; import { PromptEvent } from "./ui/React/PromptManager";
import { GetServer, DeleteServer, AddToAllServers, createUniqueRandomIp } from "./Server/AllServers";
import { GetServer, GetAllServers, DeleteServer, AddToAllServers, createUniqueRandomIp } from "./Server/AllServers";
import { RunningScript } from "./Script/RunningScript";
import { import {
getServerOnNetwork, getServerOnNetwork,
numCycleForGrowth, numCycleForGrowth,
@ -41,24 +29,18 @@ import {
import { getPurchaseServerCost, getPurchaseServerLimit, getPurchaseServerMaxRam } from "./Server/ServerPurchases"; import { getPurchaseServerCost, getPurchaseServerLimit, getPurchaseServerMaxRam } from "./Server/ServerPurchases";
import { Server } from "./Server/Server"; import { Server } from "./Server/Server";
import { influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing"; import { influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing";
import { isValidFilePath, removeLeadingSlash } from "./Terminal/DirectoryHelpers"; import { isValidFilePath, removeLeadingSlash } from "./Terminal/DirectoryHelpers";
import { TextFile, getTextFile, createTextFile } from "./TextFile"; import { TextFile, getTextFile, createTextFile } from "./TextFile";
import { NetscriptPorts, runScriptFromScript } from "./NetscriptWorker"; import { NetscriptPorts, runScriptFromScript } from "./NetscriptWorker";
import { killWorkerScript } from "./Netscript/killWorkerScript"; import { killWorkerScript } from "./Netscript/killWorkerScript";
import { workerScripts } from "./Netscript/WorkerScripts"; import { workerScripts } from "./Netscript/WorkerScripts";
import { WorkerScript } from "./Netscript/WorkerScript"; import { WorkerScript } from "./Netscript/WorkerScript";
import { helpers, ScriptIdentifier } from "./Netscript/NetscriptHelpers"; import { helpers } from "./Netscript/NetscriptHelpers";
import { numeralWrapper } from "./ui/numeralFormat"; import { numeralWrapper } from "./ui/numeralFormat";
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions"; import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
import { LogBoxEvents, LogBoxCloserEvents } from "./ui/React/LogBoxManager"; import { LogBoxEvents, LogBoxCloserEvents } from "./ui/React/LogBoxManager";
import { arrayToString } from "./utils/helpers/arrayToString"; import { arrayToString } from "./utils/helpers/arrayToString";
import { isString } from "./utils/helpers/isString"; import { isString } from "./utils/helpers/isString";
import { BaseServer } from "./Server/BaseServer";
import { NetscriptGang } from "./NetscriptFunctions/Gang"; import { NetscriptGang } from "./NetscriptFunctions/Gang";
import { NetscriptSleeve } from "./NetscriptFunctions/Sleeve"; import { NetscriptSleeve } from "./NetscriptFunctions/Sleeve";
import { NetscriptExtra } from "./NetscriptFunctions/Extra"; import { NetscriptExtra } from "./NetscriptFunctions/Extra";
@ -73,15 +55,9 @@ import { NetscriptFormulas } from "./NetscriptFunctions/Formulas";
import { NetscriptStockMarket } from "./NetscriptFunctions/StockMarket"; import { NetscriptStockMarket } from "./NetscriptFunctions/StockMarket";
import { NetscriptGrafting } from "./NetscriptFunctions/Grafting"; import { NetscriptGrafting } from "./NetscriptFunctions/Grafting";
import { IPort } from "./NetscriptPort"; import { IPort } from "./NetscriptPort";
import { import {
NS as INS, NS,
Player as INetscriptPlayer, Player as INetscriptPlayer,
Gang as IGang,
Bladeburner as IBladeburner,
Stanek as IStanek,
Infiltration as IInfiltration,
RunningScript as IRunningScript,
RecentScript as IRecentScript, RecentScript as IRecentScript,
BasicHGWOptions, BasicHGWOptions,
ProcessInfo, ProcessInfo,
@ -90,12 +66,9 @@ import {
BitNodeMultipliers as IBNMults, BitNodeMultipliers as IBNMults,
Server as IServerDef, Server as IServerDef,
RunningScript as IRunningScriptDef, RunningScript as IRunningScriptDef,
// ToastVariant,
} from "./ScriptEditor/NetscriptDefinitions"; } from "./ScriptEditor/NetscriptDefinitions";
import { NetscriptSingularity } from "./NetscriptFunctions/Singularity"; import { NetscriptSingularity } from "./NetscriptFunctions/Singularity";
import { toNative } from "./NetscriptFunctions/toNative";
import { dialogBoxCreate } from "./ui/React/DialogBox"; import { dialogBoxCreate } from "./ui/React/DialogBox";
import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar"; import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar";
import { checkEnum } from "./utils/helpers/checkEnum"; import { checkEnum } from "./utils/helpers/checkEnum";
@ -107,163 +80,13 @@ import { recentScripts } from "./Netscript/RecentScripts";
import { InternalAPI, NetscriptContext, wrapAPI } from "./Netscript/APIWrapper"; import { InternalAPI, NetscriptContext, wrapAPI } from "./Netscript/APIWrapper";
import { ScriptArg } from "./Netscript/ScriptArg"; import { ScriptArg } from "./Netscript/ScriptArg";
interface NS extends INS {
[key: string]: any;
gang: IGang;
bladeburner: IBladeburner;
stanek: IStanek;
infiltration: IInfiltration;
}
const argsToString = function (args: unknown[]): string {
let out = "";
for (let arg of args) {
if (arg === null) {
out += "null";
continue;
}
if (arg === undefined) {
out += "undefined";
continue;
}
arg = toNative(arg);
out += typeof arg === "object" ? JSON.stringify(arg) : `${arg}`;
}
return out;
};
function getFunctionNames(obj: object, prefix: string): string[] {
const functionNames: string[] = [];
for (const [key, value] of Object.entries(obj)) {
if (key === "args") {
continue;
} else if (typeof value == "function") {
functionNames.push(prefix + key);
} else if (typeof value == "object") {
functionNames.push(...getFunctionNames(value, key + "."));
}
}
return functionNames;
}
const getRunningScriptByPid = function (pid: number): RunningScript | null {
for (const server of GetAllServers()) {
const runningScript = findRunningScriptByPid(pid, server);
if (runningScript) return runningScript;
}
return null;
};
const getRunningScript = (ctx: NetscriptContext, ident: ScriptIdentifier): RunningScript | null => {
if (typeof ident === "number") {
return getRunningScriptByPid(ident);
} else {
return getRunningScriptByArgs(ctx, ident.scriptname, ident.hostname, ident.args);
}
};
/**
* Searches for and returns the RunningScript object for the specified script.
* If the 'fn' argument is not specified, this returns the current RunningScript.
* @param {string} fn - Filename of script
* @param {string} hostname - Hostname/ip of the server on which the script resides
* @param {any[]} scriptArgs - Running script's arguments
* @returns {RunningScript}
* Running script identified by the parameters, or null if no such script
* exists, or the current running script if the first argument 'fn'
* is not specified.
*/
const getRunningScriptByArgs = function (
ctx: NetscriptContext,
fn: string,
hostname: string,
scriptArgs: ScriptArg[],
): RunningScript | null {
if (!Array.isArray(scriptArgs)) {
throw helpers.makeRuntimeRejectMsg(
ctx.workerScript,
`Invalid scriptArgs argument passed into getRunningScript() from ${ctx.function}(). ` +
`This is probably a bug. Please report to game developer`,
);
}
if (fn != null && typeof fn === "string") {
// Get Logs of another script
if (hostname == null) {
hostname = ctx.workerScript.hostname;
}
const server = helpers.getServer(ctx, hostname);
return findRunningScript(fn, scriptArgs, server);
}
// If no arguments are specified, return the current RunningScript
return ctx.workerScript.scriptRef;
};
/**
* Helper function for getting the error log message when the user specifies
* a nonexistent running script
* @param {string} fn - Filename of script
* @param {string} hostname - Hostname/ip of the server on which the script resides
* @param {any[]} scriptArgs - Running script's arguments
* @returns {string} Error message to print to logs
*/
const getCannotFindRunningScriptErrorMessage = function (ident: ScriptIdentifier): string {
if (typeof ident === "number") return `Cannot find running script with pid: ${ident}`;
return `Cannot find running script ${ident.scriptname} on server ${ident.hostname} with args: ${arrayToString(
ident.args,
)}`;
};
/**
* Sanitizes a `RunningScript` to remove sensitive information, making it suitable for
* return through an NS function.
* @see NS.getRecentScripts
* @see NS.getRunningScript
* @param runningScript Existing, internal RunningScript
* @returns A sanitized, NS-facing copy of the RunningScript
*/
const createPublicRunningScript = function (runningScript: RunningScript): IRunningScript {
return {
args: runningScript.args.slice(),
filename: runningScript.filename,
logs: runningScript.logs.slice(),
offlineExpGained: runningScript.offlineExpGained,
offlineMoneyMade: runningScript.offlineMoneyMade,
offlineRunningTime: runningScript.offlineRunningTime,
onlineExpGained: runningScript.onlineExpGained,
onlineMoneyMade: runningScript.onlineMoneyMade,
onlineRunningTime: runningScript.onlineRunningTime,
pid: runningScript.pid,
ramUsage: runningScript.ramUsage,
server: runningScript.server,
threads: runningScript.threads,
};
};
/**
* Used to fail a function if the function's target is a Hacknet Server.
* This is used for functions that should run on normal Servers, but not Hacknet Servers
* @param {Server} server - Target server
* @param {string} callingFn - Name of calling function. For logging purposes
* @returns {boolean} True if the server is a Hacknet Server, false otherwise
*/
const failOnHacknetServer = function (ctx:NetscriptContext, server: BaseServer, callingFn = ""): boolean {
if (server instanceof HacknetServer) {
ctx.workerScript.log(callingFn, () => `Does not work on Hacknet Servers`);
return true;
} else {
return false;
}
};
export function NetscriptFunctions(workerScript: WorkerScript): NS { export function NetscriptFunctions(workerScript: WorkerScript): NS {
const wrappedNS = wrapAPI({}, workerScript, ns) as unknown as NS;
const wrappedNS = wrapAPI({}, workerScript, ns) as unknown as INS;
(wrappedNS.args as ScriptArg[]) = workerScript.args; (wrappedNS.args as ScriptArg[]) = workerScript.args;
return wrappedNS; return wrappedNS;
} }
const base: InternalAPI<INS> = { const base: InternalAPI<NS> = {
args: [], args: [],
enums: { enums: {
toast: ToastVariant, toast: ToastVariant,
@ -586,7 +409,7 @@ const base: InternalAPI<INS> = {
if (args.length === 0) { if (args.length === 0) {
throw helpers.makeRuntimeErrorMsg(ctx, "Takes at least 1 argument."); throw helpers.makeRuntimeErrorMsg(ctx, "Takes at least 1 argument.");
} }
ctx.workerScript.print(argsToString(args)); ctx.workerScript.print(helpers.argsToString(args));
}, },
printf: printf:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -603,7 +426,7 @@ const base: InternalAPI<INS> = {
if (args.length === 0) { if (args.length === 0) {
throw helpers.makeRuntimeErrorMsg(ctx, "Takes at least 1 argument."); throw helpers.makeRuntimeErrorMsg(ctx, "Takes at least 1 argument.");
} }
const str = argsToString(args); const str = helpers.argsToString(args);
if (str.startsWith("ERROR") || str.startsWith("FAIL")) { if (str.startsWith("ERROR") || str.startsWith("FAIL")) {
Terminal.error(`${ctx.workerScript.scriptRef.filename}: ${str}`); Terminal.error(`${ctx.workerScript.scriptRef.filename}: ${str}`);
return; return;
@ -693,9 +516,9 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(scriptID: unknown, hostname: unknown, ...scriptArgs: unknown[]): string[] => { (scriptID: unknown, hostname: unknown, ...scriptArgs: unknown[]): string[] => {
const ident = helpers.scriptIdentifier(ctx, scriptID, hostname, scriptArgs); const ident = helpers.scriptIdentifier(ctx, scriptID, hostname, scriptArgs);
const runningScriptObj = getRunningScript(ctx, ident); const runningScriptObj = helpers.getRunningScript(ctx, ident);
if (runningScriptObj == null) { if (runningScriptObj == null) {
helpers.log(ctx, () => getCannotFindRunningScriptErrorMessage(ident)); helpers.log(ctx, () => helpers.getCannotFindRunningScriptErrorMessage(ident));
return []; return [];
} }
@ -705,9 +528,9 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(scriptID: unknown, hostname: unknown, ...scriptArgs: unknown[]): void => { (scriptID: unknown, hostname: unknown, ...scriptArgs: unknown[]): void => {
const ident = helpers.scriptIdentifier(ctx, scriptID, hostname, scriptArgs); const ident = helpers.scriptIdentifier(ctx, scriptID, hostname, scriptArgs);
const runningScriptObj = getRunningScript(ctx, ident); const runningScriptObj = helpers.getRunningScript(ctx, ident);
if (runningScriptObj == null) { if (runningScriptObj == null) {
helpers.log(ctx, () => getCannotFindRunningScriptErrorMessage(ident)); helpers.log(ctx, () => helpers.getCannotFindRunningScriptErrorMessage(ident));
return; return;
} }
@ -943,9 +766,9 @@ const base: InternalAPI<INS> = {
} }
const server = helpers.getServer(ctx, ident.hostname); const server = helpers.getServer(ctx, ident.hostname);
const runningScriptObj = getRunningScriptByArgs(ctx, ident.scriptname, ident.hostname, ident.args); const runningScriptObj = helpers.getRunningScriptByArgs(ctx, ident.scriptname, ident.hostname, ident.args);
if (runningScriptObj == null) { if (runningScriptObj == null) {
helpers.log(ctx, () => getCannotFindRunningScriptErrorMessage(ident)); helpers.log(ctx, () => helpers.getCannotFindRunningScriptErrorMessage(ident));
return false; return false;
} }
@ -1214,7 +1037,7 @@ const base: InternalAPI<INS> = {
getRecentScripts: () => (): IRecentScript[] => { getRecentScripts: () => (): IRecentScript[] => {
return recentScripts.map((rs) => ({ return recentScripts.map((rs) => ({
timeOfDeath: rs.timeOfDeath, timeOfDeath: rs.timeOfDeath,
...createPublicRunningScript(rs.runningScript), ...helpers.createPublicRunningScript(rs.runningScript),
})); }));
}, },
ps: ps:
@ -1311,7 +1134,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 0; return 0;
} }
if (failOnHacknetServer(ctx, server, "getServerMoneyAvailable")) { if (helpers.failOnHacknetServer(ctx, server, "getServerMoneyAvailable")) {
return 0; return 0;
} }
if (server.hostname == "home") { if (server.hostname == "home") {
@ -1331,7 +1154,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(ctx, server, "getServerSecurityLevel")) { if (helpers.failOnHacknetServer(ctx, server, "getServerSecurityLevel")) {
return 1; return 1;
} }
helpers.log( helpers.log(
@ -1350,7 +1173,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(ctx, server, "getServerBaseSecurityLevel")) { if (helpers.failOnHacknetServer(ctx, server, "getServerBaseSecurityLevel")) {
return 1; return 1;
} }
helpers.log( helpers.log(
@ -1368,7 +1191,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(ctx, server, "getServerMinSecurityLevel")) { if (helpers.failOnHacknetServer(ctx, server, "getServerMinSecurityLevel")) {
return 1; return 1;
} }
helpers.log( helpers.log(
@ -1386,7 +1209,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(ctx, server, "getServerRequiredHackingLevel")) { if (helpers.failOnHacknetServer(ctx, server, "getServerRequiredHackingLevel")) {
return 1; return 1;
} }
helpers.log( helpers.log(
@ -1404,7 +1227,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 0; return 0;
} }
if (failOnHacknetServer(ctx, server, "getServerMaxMoney")) { if (helpers.failOnHacknetServer(ctx, server, "getServerMaxMoney")) {
return 0; return 0;
} }
helpers.log(ctx, () => `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`); helpers.log(ctx, () => `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`);
@ -1419,7 +1242,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(ctx, server, "getServerGrowth")) { if (helpers.failOnHacknetServer(ctx, server, "getServerGrowth")) {
return 1; return 1;
} }
helpers.log(ctx, () => `returned ${server.serverGrowth} for '${server.hostname}'`); helpers.log(ctx, () => `returned ${server.serverGrowth} for '${server.hostname}'`);
@ -1434,7 +1257,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "Cannot be executed on this server."); helpers.log(ctx, () => "Cannot be executed on this server.");
return 5; return 5;
} }
if (failOnHacknetServer(ctx, server, "getServerNumPortsRequired")) { if (helpers.failOnHacknetServer(ctx, server, "getServerNumPortsRequired")) {
return 5; return 5;
} }
helpers.log(ctx, () => `returned ${server.numOpenPortsRequired} for '${server.hostname}'`); helpers.log(ctx, () => `returned ${server.numOpenPortsRequired} for '${server.hostname}'`);
@ -1505,7 +1328,7 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(fn: unknown, hostname: unknown, ...scriptArgs: unknown[]): boolean => { (fn: unknown, hostname: unknown, ...scriptArgs: unknown[]): boolean => {
const ident = helpers.scriptIdentifier(ctx, fn, hostname, scriptArgs); const ident = helpers.scriptIdentifier(ctx, fn, hostname, scriptArgs);
return getRunningScript(ctx, ident) !== null; return helpers.getRunningScript(ctx, ident) !== null;
}, },
getPurchasedServerLimit: () => (): number => { getPurchasedServerLimit: () => (): number => {
return getPurchaseServerLimit(); return getPurchaseServerLimit();
@ -1907,9 +1730,9 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(fn: unknown, hostname: unknown, ...args: unknown[]): IRunningScriptDef | null => { (fn: unknown, hostname: unknown, ...args: unknown[]): IRunningScriptDef | null => {
const ident = helpers.scriptIdentifier(ctx, fn, hostname, args); const ident = helpers.scriptIdentifier(ctx, fn, hostname, args);
const runningScript = getRunningScript(ctx, ident); const runningScript = helpers.getRunningScript(ctx, ident);
if (runningScript === null) return null; if (runningScript === null) return null;
return createPublicRunningScript(runningScript); return helpers.createPublicRunningScript(runningScript);
}, },
getHackTime: getHackTime:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -1920,7 +1743,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "invalid for this kind of server"); helpers.log(ctx, () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(ctx, server, "getHackTime")) { if (helpers.failOnHacknetServer(ctx, server, "getHackTime")) {
return Infinity; return Infinity;
} }
@ -1935,7 +1758,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "invalid for this kind of server"); helpers.log(ctx, () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(ctx, server, "getGrowTime")) { if (helpers.failOnHacknetServer(ctx, server, "getGrowTime")) {
return Infinity; return Infinity;
} }
@ -1950,7 +1773,7 @@ const base: InternalAPI<INS> = {
helpers.log(ctx, () => "invalid for this kind of server"); helpers.log(ctx, () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(ctx, server, "getWeakenTime")) { if (helpers.failOnHacknetServer(ctx, server, "getWeakenTime")) {
return Infinity; return Infinity;
} }
@ -1969,9 +1792,9 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(fn: unknown, hostname: unknown, ...args: unknown[]): number => { (fn: unknown, hostname: unknown, ...args: unknown[]): number => {
const ident = helpers.scriptIdentifier(ctx, fn, hostname, args); const ident = helpers.scriptIdentifier(ctx, fn, hostname, args);
const runningScript = getRunningScript(ctx, ident); const runningScript = helpers.getRunningScript(ctx, ident);
if (runningScript == null) { if (runningScript == null) {
helpers.log(ctx, () => getCannotFindRunningScriptErrorMessage(ident)); helpers.log(ctx, () => helpers.getCannotFindRunningScriptErrorMessage(ident));
return -1; return -1;
} }
return runningScript.onlineMoneyMade / runningScript.onlineRunningTime; return runningScript.onlineMoneyMade / runningScript.onlineRunningTime;
@ -1987,9 +1810,9 @@ const base: InternalAPI<INS> = {
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
(fn: unknown, hostname: unknown, ...args: unknown[]): number => { (fn: unknown, hostname: unknown, ...args: unknown[]): number => {
const ident = helpers.scriptIdentifier(ctx, fn, hostname, args); const ident = helpers.scriptIdentifier(ctx, fn, hostname, args);
const runningScript = getRunningScript(ctx, ident); const runningScript = helpers.getRunningScript(ctx, ident);
if (runningScript == null) { if (runningScript == null) {
helpers.log(ctx, () => getCannotFindRunningScriptErrorMessage(ident)); helpers.log(ctx, () => helpers.getCannotFindRunningScriptErrorMessage(ident));
return -1; return -1;
} }
return runningScript.onlineExpGained / runningScript.onlineRunningTime; return runningScript.onlineExpGained / runningScript.onlineRunningTime;
@ -2192,4 +2015,4 @@ const ns = {
...NetscriptExtra(), ...NetscriptExtra(),
}; };
const possibleLogs = Object.fromEntries([...getFunctionNames(ns, "")].map((a) => [a, true])); const possibleLogs = Object.fromEntries([...helpers.getFunctionNames(ns, "")].map((a) => [a, true]));

@ -6,7 +6,7 @@ import { NetscriptContext } from "../Netscript/APIWrapper";
type FlagType = StringConstructor | NumberConstructor | BooleanConstructor | StringConstructor[]; type FlagType = StringConstructor | NumberConstructor | BooleanConstructor | StringConstructor[];
type FlagsRet = { [key: string]: ScriptArg }; type FlagsRet = { [key: string]: ScriptArg };
export function Flags(ctx: NetscriptContext | string[]): (data: unknown) => FlagsRet { export function Flags(ctx: NetscriptContext | string[]): (data: unknown) => FlagsRet {
const vargs = Array.isArray(ctx) ? ctx : ctx.workerScript.args; const vargs = Array.isArray(ctx) ? ctx : ctx.workerScript.args;
return (schema: unknown): FlagsRet => { return (schema: unknown): FlagsRet => {
schema = toNative(schema); schema = toNative(schema);
if (!Array.isArray(schema)) throw new Error("flags schema passed in is invalid."); if (!Array.isArray(schema)) throw new Error("flags schema passed in is invalid.");

@ -276,7 +276,10 @@ export function NetscriptGang(): InternalAPI<IGang> {
if (!equipment) return false; if (!equipment) return false;
const res = member.buyUpgrade(equipment, player, gang); const res = member.buyUpgrade(equipment, player, gang);
if (res) { if (res) {
ctx.workerScript.log("gang.purchaseEquipment", () => `Purchased '${equipName}' for Gang member '${memberName}'`); ctx.workerScript.log(
"gang.purchaseEquipment",
() => `Purchased '${equipName}' for Gang member '${memberName}'`,
);
} else { } else {
ctx.workerScript.log( ctx.workerScript.log(
"gang.purchaseEquipment", "gang.purchaseEquipment",

@ -1,4 +1,4 @@
import { Player as player} from "../Player"; import { Player as player } from "../Player";
import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers"; import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers";
import { startWorkerScript } from "../NetscriptWorker"; import { startWorkerScript } from "../NetscriptWorker";
import { Augmentation } from "../Augmentation/Augmentation"; import { Augmentation } from "../Augmentation/Augmentation";

@ -37,6 +37,7 @@ import { Terminal } from "./Terminal";
import { IPlayer } from "./PersonObjects/IPlayer"; import { IPlayer } from "./PersonObjects/IPlayer";
import { ScriptArg } from "./Netscript/ScriptArg"; import { ScriptArg } from "./Netscript/ScriptArg";
import { helpers } from "./Netscript/NetscriptHelpers"; import { helpers } from "./Netscript/NetscriptHelpers";
import { NS } from "./ScriptEditor/NetscriptDefinitions";
// Netscript Ports are instantiated here // Netscript Ports are instantiated here
export const NetscriptPorts: IPort[] = []; export const NetscriptPorts: IPort[] = [];
@ -114,8 +115,11 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
} }
const interpreterInitialization = function (int: Interpreter, scope: unknown): void { const interpreterInitialization = function (int: Interpreter, scope: unknown): void {
interface NS1 extends NS {
[key: string]: any;
}
//Add the Netscript environment //Add the Netscript environment
const ns = NetscriptFunctions(workerScript); const ns = NetscriptFunctions(workerScript) as NS1;
for (const name of Object.keys(ns)) { for (const name of Object.keys(ns)) {
const entry = ns[name]; const entry = ns[name];
if (typeof entry === "function") { if (typeof entry === "function") {
@ -167,7 +171,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
name === "vsprintf" || name === "vsprintf" ||
name === "scp" || name === "scp" ||
name == "write" || name == "write" ||
name === "tryWrite" || name === "tryWritePort" ||
name === "run" || name === "run" ||
name === "exec" name === "exec"
) { ) {