workerscript log takes a function now, hopefully this will increase performance.

This commit is contained in:
Olivier Gagnon 2021-11-26 18:30:58 -05:00
parent fe3aa5a357
commit c05518e162
14 changed files with 376 additions and 316 deletions

@ -2026,7 +2026,7 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.startAction", errorLogText); workerScript.log("bladeburner.startAction", () => errorLogText);
return false; return false;
} }
@ -2038,13 +2038,13 @@ export class Bladeburner implements IBladeburner {
if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`); if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`);
//const blackOp = (action as BlackOperation); //const blackOp = (action as BlackOperation);
if (action.reqdRank > this.rank) { if (action.reqdRank > this.rank) {
workerScript.log("bladeburner.startAction", `Insufficient rank to start Black Op '${actionId.name}'.`); workerScript.log("bladeburner.startAction", () => `Insufficient rank to start Black Op '${actionId.name}'.`);
return false; return false;
} }
// Can't start a BlackOp if its already been done // Can't start a BlackOp if its already been done
if (this.blackops[actionId.name] != null) { if (this.blackops[actionId.name] != null) {
workerScript.log("bladeburner.startAction", `Black Op ${actionId.name} has already been completed.`); workerScript.log("bladeburner.startAction", () => `Black Op ${actionId.name} has already been completed.`);
return false; return false;
} }
@ -2061,14 +2061,14 @@ export class Bladeburner implements IBladeburner {
const i = blackops.indexOf(actionId.name); const i = blackops.indexOf(actionId.name);
if (i === -1) { if (i === -1) {
workerScript.log("bladeburner.startAction", `Invalid Black Op: '${name}'`); workerScript.log("bladeburner.startAction", () => `Invalid Black Op: '${name}'`);
return false; return false;
} }
if (i > 0 && this.blackops[blackops[i - 1]] == null) { if (i > 0 && this.blackops[blackops[i - 1]] == null) {
workerScript.log( workerScript.log(
"bladeburner.startAction", "bladeburner.startAction",
`Preceding Black Op must be completed before starting '${actionId.name}'.`, () => `Preceding Black Op must be completed before starting '${actionId.name}'.`,
); );
return false; return false;
} }
@ -2076,11 +2076,14 @@ export class Bladeburner implements IBladeburner {
try { try {
this.startAction(player, actionId); this.startAction(player, actionId);
workerScript.log("bladeburner.startAction", `Starting bladeburner action with type '${type}' and name ${name}"`); workerScript.log(
"bladeburner.startAction",
() => `Starting bladeburner action with type '${type}' and name ${name}"`,
);
return true; return true;
} catch (e: any) { } catch (e: any) {
this.resetAction(); this.resetAction();
workerScript.log("bladeburner.startAction", errorLogText); workerScript.log("bladeburner.startAction", () => errorLogText);
return false; return false;
} }
} }
@ -2089,13 +2092,13 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.getActionTime", errorLogText); workerScript.log("bladeburner.getActionTime", () => errorLogText);
return -1; return -1;
} }
const actionObj = this.getActionObject(actionId); const actionObj = this.getActionObject(actionId);
if (actionObj == null) { if (actionObj == null) {
workerScript.log("bladeburner.getActionTime", errorLogText); workerScript.log("bladeburner.getActionTime", () => errorLogText);
return -1; return -1;
} }
@ -2116,7 +2119,7 @@ export class Bladeburner implements IBladeburner {
case ActionTypes["Incite Violence"]: case ActionTypes["Incite Violence"]:
return 60000; return 60000;
default: default:
workerScript.log("bladeburner.getActionTime", errorLogText); workerScript.log("bladeburner.getActionTime", () => errorLogText);
return -1; return -1;
} }
} }
@ -2130,13 +2133,13 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
return [-1, -1]; return [-1, -1];
} }
const actionObj = this.getActionObject(actionId); const actionObj = this.getActionObject(actionId);
if (actionObj == null) { if (actionObj == null) {
workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
return [-1, -1]; return [-1, -1];
} }
@ -2158,7 +2161,7 @@ export class Bladeburner implements IBladeburner {
return [recChance, recChance]; return [recChance, recChance];
} }
default: default:
workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
return [-1, -1]; return [-1, -1];
} }
} }
@ -2167,13 +2170,13 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.getActionCountRemaining", errorLogText); workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
return -1; return -1;
} }
const actionObj = this.getActionObject(actionId); const actionObj = this.getActionObject(actionId);
if (actionObj == null) { if (actionObj == null) {
workerScript.log("bladeburner.getActionCountRemaining", errorLogText); workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
return -1; return -1;
} }
@ -2197,14 +2200,14 @@ export class Bladeburner implements IBladeburner {
case ActionTypes["Incite Violence"]: case ActionTypes["Incite Violence"]:
return Infinity; return Infinity;
default: default:
workerScript.log("bladeburner.getActionCountRemaining", errorLogText); workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
return -1; return -1;
} }
} }
getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number { getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number {
if (skillName === "" || !Skills.hasOwnProperty(skillName)) { if (skillName === "" || !Skills.hasOwnProperty(skillName)) {
workerScript.log("bladeburner.getSkillLevel", `Invalid skill: '${skillName}'`); workerScript.log("bladeburner.getSkillLevel", () => `Invalid skill: '${skillName}'`);
return -1; return -1;
} }
@ -2217,7 +2220,7 @@ export class Bladeburner implements IBladeburner {
getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number { getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number {
if (skillName === "" || !Skills.hasOwnProperty(skillName)) { if (skillName === "" || !Skills.hasOwnProperty(skillName)) {
workerScript.log("bladeburner.getSkillUpgradeCost", `Invalid skill: '${skillName}'`); workerScript.log("bladeburner.getSkillUpgradeCost", () => `Invalid skill: '${skillName}'`);
return -1; return -1;
} }
@ -2232,7 +2235,7 @@ export class Bladeburner implements IBladeburner {
upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean { upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean {
const errorLogText = `Invalid skill: '${skillName}'`; const errorLogText = `Invalid skill: '${skillName}'`;
if (!Skills.hasOwnProperty(skillName)) { if (!Skills.hasOwnProperty(skillName)) {
workerScript.log("bladeburner.upgradeSkill", errorLogText); workerScript.log("bladeburner.upgradeSkill", () => errorLogText);
return false; return false;
} }
@ -2244,13 +2247,14 @@ export class Bladeburner implements IBladeburner {
const cost = skill.calculateCost(currentLevel); const cost = skill.calculateCost(currentLevel);
if (skill.maxLvl && currentLevel >= skill.maxLvl) { if (skill.maxLvl && currentLevel >= skill.maxLvl) {
workerScript.log("bladeburner.upgradeSkill", `Skill '${skillName}' is already maxed.`); workerScript.log("bladeburner.upgradeSkill", () => `Skill '${skillName}' is already maxed.`);
return false; return false;
} }
if (this.skillPoints < cost) { if (this.skillPoints < cost) {
workerScript.log( workerScript.log(
"bladeburner.upgradeSkill", "bladeburner.upgradeSkill",
() =>
`You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`, `You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`,
); );
return false; return false;
@ -2258,7 +2262,7 @@ export class Bladeburner implements IBladeburner {
this.skillPoints -= cost; this.skillPoints -= cost;
this.upgradeSkill(skill); this.upgradeSkill(skill);
workerScript.log("bladeburner.upgradeSkill", `'${skillName}' upgraded to level ${this.skills[skillName]}`); workerScript.log("bladeburner.upgradeSkill", () => `'${skillName}' upgraded to level ${this.skills[skillName]}`);
return true; return true;
} }
@ -2270,13 +2274,13 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.getTeamSize", errorLogText); workerScript.log("bladeburner.getTeamSize", () => errorLogText);
return -1; return -1;
} }
const actionObj = this.getActionObject(actionId); const actionObj = this.getActionObject(actionId);
if (actionObj == null) { if (actionObj == null) {
workerScript.log("bladeburner.getTeamSize", errorLogText); workerScript.log("bladeburner.getTeamSize", () => errorLogText);
return -1; return -1;
} }
@ -2295,7 +2299,7 @@ export class Bladeburner implements IBladeburner {
const errorLogText = `Invalid action: type='${type}' name='${name}'`; const errorLogText = `Invalid action: type='${type}' name='${name}'`;
const actionId = this.getActionIdFromTypeAndName(type, name); const actionId = this.getActionIdFromTypeAndName(type, name);
if (actionId == null) { if (actionId == null) {
workerScript.log("bladeburner.setTeamSize", errorLogText); workerScript.log("bladeburner.setTeamSize", () => errorLogText);
return -1; return -1;
} }
@ -2304,26 +2308,26 @@ export class Bladeburner implements IBladeburner {
actionId.type !== ActionTypes["BlackOp"] && actionId.type !== ActionTypes["BlackOp"] &&
actionId.type !== ActionTypes["BlackOperation"] actionId.type !== ActionTypes["BlackOperation"]
) { ) {
workerScript.log("bladeburner.setTeamSize", "Only valid for 'Operations' and 'BlackOps'"); workerScript.log("bladeburner.setTeamSize", () => "Only valid for 'Operations' and 'BlackOps'");
return -1; return -1;
} }
const actionObj = this.getActionObject(actionId); const actionObj = this.getActionObject(actionId);
if (actionObj == null) { if (actionObj == null) {
workerScript.log("bladeburner.setTeamSize", errorLogText); workerScript.log("bladeburner.setTeamSize", () => errorLogText);
return -1; return -1;
} }
let sanitizedSize = Math.round(size); let sanitizedSize = Math.round(size);
if (isNaN(sanitizedSize) || sanitizedSize < 0) { if (isNaN(sanitizedSize) || sanitizedSize < 0) {
workerScript.log("bladeburner.setTeamSize", `Invalid size: ${size}`); workerScript.log("bladeburner.setTeamSize", () => `Invalid size: ${size}`);
return -1; return -1;
} }
if (this.teamSize < sanitizedSize) { if (this.teamSize < sanitizedSize) {
sanitizedSize = this.teamSize; sanitizedSize = this.teamSize;
} }
actionObj.teamCount = sanitizedSize; actionObj.teamCount = sanitizedSize;
workerScript.log("bladeburner.setTeamSize", `Team size for '${name}' set to ${sanitizedSize}.`); workerScript.log("bladeburner.setTeamSize", () => `Team size for '${name}' set to ${sanitizedSize}.`);
return sanitizedSize; return sanitizedSize;
} }
@ -2333,12 +2337,12 @@ export class Bladeburner implements IBladeburner {
return true; return true;
} else if (this.rank >= BladeburnerConstants.RankNeededForFaction) { } else if (this.rank >= BladeburnerConstants.RankNeededForFaction) {
joinFaction(bladeburnerFac); joinFaction(bladeburnerFac);
workerScript.log("bladeburner.joinBladeburnerFaction", "Joined Bladeburners faction."); workerScript.log("bladeburner.joinBladeburnerFaction", () => "Joined Bladeburners faction.");
return true; return true;
} else { } else {
workerScript.log( workerScript.log(
"bladeburner.joinBladeburnerFaction", "bladeburner.joinBladeburnerFaction",
`You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`, () => `You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`,
); );
return false; return false;
} }

@ -349,7 +349,7 @@ export class Gang {
const res = member.ascend(); const res = member.ascend();
this.respect = Math.max(1, this.respect - res.respect); this.respect = Math.max(1, this.respect - res.respect);
if (workerScript) { if (workerScript) {
workerScript.log("ascend", `Ascended Gang member ${member.name}`); workerScript.log("ascend", () => `Ascended Gang member ${member.name}`);
} }
return res; return res;
} catch (e: any) { } catch (e: any) {

@ -195,14 +195,14 @@ export class WorkerScript {
return this.disableLogs[fn] == null; return this.disableLogs[fn] == null;
} }
log(func: string, txt: string): void { log(func: string, txt: () => string): void {
if (this.shouldLog(func)) { if (this.shouldLog(func)) {
if (func && txt) { if (func && txt) {
this.scriptRef.log(`${func}: ${txt}`); this.scriptRef.log(`${func}: ${txt()}`);
} else if (func) { } else if (func) {
this.scriptRef.log(func); this.scriptRef.log(func);
} else { } else {
this.scriptRef.log(txt); this.scriptRef.log(txt());
} }
} }
} }

@ -213,7 +213,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
*/ */
const failOnHacknetServer = function (server: any, callingFn: any = ""): boolean { const failOnHacknetServer = function (server: any, callingFn: any = ""): boolean {
if (server instanceof HacknetServer) { if (server instanceof HacknetServer) {
workerScript.log(callingFn, `Does not work on Hacknet Servers`); workerScript.log(callingFn, () => `Does not work on Hacknet Servers`);
return true; return true;
} else { } else {
return false; return false;
@ -282,7 +282,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
userstack.push(`${filename}:L${call.line}@${call.func}`); userstack.push(`${filename}:L${call.line}@${call.func}`);
} }
workerScript.log(caller, msg); workerScript.log(caller, () => msg);
let rejectMsg = `${caller}: ${msg}`; let rejectMsg = `${caller}: ${msg}`;
if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`; if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`;
return makeRuntimeRejectMsg(workerScript, rejectMsg); return makeRuntimeRejectMsg(workerScript, rejectMsg);
@ -317,6 +317,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
workerScript.log( workerScript.log(
"hack", "hack",
() =>
`Executing ${hostname} in ${convertTimeMsToTimeElapsedString( `Executing ${hostname} in ${convertTimeMsToTimeElapsedString(
hackingTime * 1000, hackingTime * 1000,
true, true,
@ -366,6 +367,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess; workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
workerScript.log( workerScript.log(
"hack", "hack",
() =>
`Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney( `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(
moneyGained, moneyGained,
)} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`, )} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`,
@ -384,6 +386,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
workerScript.scriptRef.onlineExpGained += expGainedOnFailure; workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
workerScript.log( workerScript.log(
"hack", "hack",
() =>
`Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp( `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(
expGainedOnFailure, expGainedOnFailure,
)} exp (t=${numeralWrapper.formatThreads(threads)})`, )} exp (t=${numeralWrapper.formatThreads(threads)})`,
@ -460,7 +463,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (entry === null) continue; if (entry === null) continue;
out.push(entry); out.push(entry);
} }
workerScript.log("scan", `returned ${server.serversOnNetwork.length} connections for ${server.hostname}`); workerScript.log("scan", () => `returned ${server.serversOnNetwork.length} connections for ${server.hostname}`);
return out; return out;
}, },
hack: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any { hack: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any {
@ -473,7 +476,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
// Check argument validity // Check argument validity
const server = safeGetServer(hostname, "hackAnalyzeThreads"); const server = safeGetServer(hostname, "hackAnalyzeThreads");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("hackAnalyzeThreads", "Cannot be executed on this server."); workerScript.log("hackAnalyzeThreads", () => "Cannot be executed on this server.");
return -1; return -1;
} }
if (isNaN(hackAmount)) { if (isNaN(hackAmount)) {
@ -496,7 +499,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const server = safeGetServer(hostname, "hackAnalyze"); const server = safeGetServer(hostname, "hackAnalyze");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("hackAnalyze", "Cannot be executed on this server."); workerScript.log("hackAnalyze", () => "Cannot be executed on this server.");
return false; return false;
} }
@ -510,7 +513,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const server = safeGetServer(hostname, "hackAnalyzeChance"); const server = safeGetServer(hostname, "hackAnalyzeChance");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("hackAnalyzeChance", "Cannot be executed on this server."); workerScript.log("hackAnalyzeChance", () => "Cannot be executed on this server.");
return false; return false;
} }
@ -520,7 +523,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (time === undefined) { if (time === undefined) {
throw makeRuntimeErrorMsg("sleep", "Takes 1 argument."); throw makeRuntimeErrorMsg("sleep", "Takes 1 argument.");
} }
workerScript.log("sleep", `Sleeping for ${time} milliseconds`); workerScript.log("sleep", () => `Sleeping for ${time} milliseconds`);
return netscriptDelay(time, workerScript).then(function () { return netscriptDelay(time, workerScript).then(function () {
return Promise.resolve(true); return Promise.resolve(true);
}); });
@ -529,7 +532,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (time === undefined) { if (time === undefined) {
throw makeRuntimeErrorMsg("asleep", "Takes 1 argument."); throw makeRuntimeErrorMsg("asleep", "Takes 1 argument.");
} }
workerScript.log("asleep", `Sleeping for ${time} milliseconds`); workerScript.log("asleep", () => `Sleeping for ${time} milliseconds`);
return netscriptDelay(time, workerScript).then(function () { return netscriptDelay(time, workerScript).then(function () {
return Promise.resolve(true); return Promise.resolve(true);
}); });
@ -542,7 +545,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "grow"); const server = safeGetServer(hostname, "grow");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("grow", "Cannot be executed on this server."); workerScript.log("grow", () => "Cannot be executed on this server.");
return false; return false;
} }
@ -560,6 +563,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const growTime = calculateGrowTime(server, Player); const growTime = calculateGrowTime(server, Player);
workerScript.log( workerScript.log(
"grow", "grow",
() =>
`Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString( `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
growTime * 1000, growTime * 1000,
true, true,
@ -577,6 +581,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const logGrowPercent = moneyAfter / moneyBefore - 1; const logGrowPercent = moneyAfter / moneyBefore - 1;
workerScript.log( workerScript.log(
"grow", "grow",
() =>
`Available money on '${server.hostname}' grown by ${numeralWrapper.formatPercentage( `Available money on '${server.hostname}' grown by ${numeralWrapper.formatPercentage(
logGrowPercent, logGrowPercent,
6, 6,
@ -596,7 +601,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
// Check argument validity // Check argument validity
const server = safeGetServer(hostname, "growthAnalyze"); const server = safeGetServer(hostname, "growthAnalyze");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("growthAnalyze", "Cannot be executed on this server."); workerScript.log("growthAnalyze", () => "Cannot be executed on this server.");
return false; return false;
} }
if (typeof growth !== "number" || isNaN(growth) || growth < 1 || !isFinite(growth)) { if (typeof growth !== "number" || isNaN(growth) || growth < 1 || !isFinite(growth)) {
@ -616,7 +621,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "weaken"); const server = safeGetServer(hostname, "weaken");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("weaken", "Cannot be executed on this server."); workerScript.log("weaken", () => "Cannot be executed on this server.");
return false; return false;
} }
@ -629,6 +634,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const weakenTime = calculateWeakenTime(server, Player); const weakenTime = calculateWeakenTime(server, Player);
workerScript.log( workerScript.log(
"weaken", "weaken",
() =>
`Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString( `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
weakenTime * 1000, weakenTime * 1000,
true, true,
@ -638,7 +644,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (workerScript.env.stopFlag) return Promise.reject(workerScript); if (workerScript.env.stopFlag) return Promise.reject(workerScript);
const host = GetServer(workerScript.hostname); const host = GetServer(workerScript.hostname);
if (host === null) { if (host === null) {
workerScript.log("weaken", "Server is null, did it die?"); workerScript.log("weaken", () => "Server is null, did it die?");
return Promise.resolve(0); return Promise.resolve(0);
} }
const coreBonus = 1 + (host.cpuCores - 1) / 16; const coreBonus = 1 + (host.cpuCores - 1) / 16;
@ -647,9 +653,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const expGain = calculateHackingExpGain(server, Player) * threads; const expGain = calculateHackingExpGain(server, Player) * threads;
workerScript.log( workerScript.log(
"weaken", "weaken",
`'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp( () =>
expGain, `'${server.hostname}' security level weakened to ${
)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`, server.hackDifficulty
}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
); );
workerScript.scriptRef.onlineExpGained += expGain; workerScript.scriptRef.onlineExpGained += expGain;
Player.gainHackingExp(expGain); Player.gainHackingExp(expGain);
@ -721,12 +728,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
for (fn in possibleLogs) { for (fn in possibleLogs) {
workerScript.disableLogs[fn] = true; workerScript.disableLogs[fn] = true;
} }
workerScript.log("disableLog", `Disabled logging for all functions`); workerScript.log("disableLog", () => `Disabled logging for all functions`);
} else if (possibleLogs[fn] === undefined) { } else if (possibleLogs[fn] === undefined) {
throw makeRuntimeErrorMsg("disableLog", `Invalid argument: ${fn}.`); throw makeRuntimeErrorMsg("disableLog", `Invalid argument: ${fn}.`);
} else { } else {
workerScript.disableLogs[fn] = true; workerScript.disableLogs[fn] = true;
workerScript.log("disableLog", `Disabled logging for ${fn}`); workerScript.log("disableLog", () => `Disabled logging for ${fn}`);
} }
}, },
enableLog: function (fn: any): any { enableLog: function (fn: any): any {
@ -734,7 +741,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("enableLog", `Invalid argument: ${fn}.`); throw makeRuntimeErrorMsg("enableLog", `Invalid argument: ${fn}.`);
} }
delete workerScript.disableLogs[fn]; delete workerScript.disableLogs[fn];
workerScript.log("enableLog", `Enabled logging for ${fn}`); workerScript.log("enableLog", () => `Enabled logging for ${fn}`);
}, },
isLogEnabled: function (fn: any): any { isLogEnabled: function (fn: any): any {
if (possibleLogs[fn] === undefined) { if (possibleLogs[fn] === undefined) {
@ -745,7 +752,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
getScriptLogs: function (fn: any, hostname: any, ...scriptArgs: any): any { getScriptLogs: function (fn: any, hostname: any, ...scriptArgs: any): any {
const runningScriptObj = getRunningScript(fn, hostname, "getScriptLogs", scriptArgs); const runningScriptObj = getRunningScript(fn, hostname, "getScriptLogs", scriptArgs);
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log("getScriptLogs", getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs)); workerScript.log("getScriptLogs", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
return ""; return "";
} }
@ -761,7 +768,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
runningScriptObj = getRunningScript(fn, hostname, "tail", scriptArgs); runningScriptObj = getRunningScript(fn, hostname, "tail", scriptArgs);
} }
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log("tail", getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs)); workerScript.log("tail", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
return; return;
} }
@ -774,7 +781,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "nuke"); const server = safeGetServer(hostname, "nuke");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("nuke", "Cannot be executed on this server."); workerScript.log("nuke", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.NukeProgram.name)) { if (!Player.hasProgram(Programs.NukeProgram.name)) {
@ -784,10 +791,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("nuke", "Not enough ports opened to use NUKE.exe virus."); throw makeRuntimeErrorMsg("nuke", "Not enough ports opened to use NUKE.exe virus.");
} }
if (server.hasAdminRights) { if (server.hasAdminRights) {
workerScript.log("nuke", `Already have root access to '${server.hostname}'.`); workerScript.log("nuke", () => `Already have root access to '${server.hostname}'.`);
} else { } else {
server.hasAdminRights = true; server.hasAdminRights = true;
workerScript.log("nuke", `Executed NUKE.exe virus on '${server.hostname}' to gain root access.`); workerScript.log("nuke", () => `Executed NUKE.exe virus on '${server.hostname}' to gain root access.`);
} }
return true; return true;
}, },
@ -798,18 +805,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "brutessh"); const server = safeGetServer(hostname, "brutessh");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("brutessh", "Cannot be executed on this server."); workerScript.log("brutessh", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.BruteSSHProgram.name)) { if (!Player.hasProgram(Programs.BruteSSHProgram.name)) {
throw makeRuntimeErrorMsg("brutessh", "You do not have the BruteSSH.exe program!"); throw makeRuntimeErrorMsg("brutessh", "You do not have the BruteSSH.exe program!");
} }
if (!server.sshPortOpen) { if (!server.sshPortOpen) {
workerScript.log("brutessh", `Executed BruteSSH.exe on '${server.hostname}' to open SSH port (22).`); workerScript.log("brutessh", () => `Executed BruteSSH.exe on '${server.hostname}' to open SSH port (22).`);
server.sshPortOpen = true; server.sshPortOpen = true;
++server.openPortCount; ++server.openPortCount;
} else { } else {
workerScript.log("brutessh", `SSH Port (22) already opened on '${server.hostname}'.`); workerScript.log("brutessh", () => `SSH Port (22) already opened on '${server.hostname}'.`);
} }
return true; return true;
}, },
@ -820,18 +827,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "ftpcrack"); const server = safeGetServer(hostname, "ftpcrack");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("ftpcrack", "Cannot be executed on this server."); workerScript.log("ftpcrack", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.FTPCrackProgram.name)) { if (!Player.hasProgram(Programs.FTPCrackProgram.name)) {
throw makeRuntimeErrorMsg("ftpcrack", "You do not have the FTPCrack.exe program!"); throw makeRuntimeErrorMsg("ftpcrack", "You do not have the FTPCrack.exe program!");
} }
if (!server.ftpPortOpen) { if (!server.ftpPortOpen) {
workerScript.log("ftpcrack", `Executed FTPCrack.exe on '${server.hostname}' to open FTP port (21).`); workerScript.log("ftpcrack", () => `Executed FTPCrack.exe on '${server.hostname}' to open FTP port (21).`);
server.ftpPortOpen = true; server.ftpPortOpen = true;
++server.openPortCount; ++server.openPortCount;
} else { } else {
workerScript.log("ftpcrack", `FTP Port (21) already opened on '${server.hostname}'.`); workerScript.log("ftpcrack", () => `FTP Port (21) already opened on '${server.hostname}'.`);
} }
return true; return true;
}, },
@ -842,18 +849,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "relaysmtp"); const server = safeGetServer(hostname, "relaysmtp");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("relaysmtp", "Cannot be executed on this server."); workerScript.log("relaysmtp", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.RelaySMTPProgram.name)) { if (!Player.hasProgram(Programs.RelaySMTPProgram.name)) {
throw makeRuntimeErrorMsg("relaysmtp", "You do not have the relaySMTP.exe program!"); throw makeRuntimeErrorMsg("relaysmtp", "You do not have the relaySMTP.exe program!");
} }
if (!server.smtpPortOpen) { if (!server.smtpPortOpen) {
workerScript.log("relaysmtp", `Executed relaySMTP.exe on '${server.hostname}' to open SMTP port (25).`); workerScript.log("relaysmtp", () => `Executed relaySMTP.exe on '${server.hostname}' to open SMTP port (25).`);
server.smtpPortOpen = true; server.smtpPortOpen = true;
++server.openPortCount; ++server.openPortCount;
} else { } else {
workerScript.log("relaysmtp", `SMTP Port (25) already opened on '${server.hostname}'.`); workerScript.log("relaysmtp", () => `SMTP Port (25) already opened on '${server.hostname}'.`);
} }
return true; return true;
}, },
@ -864,18 +871,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "httpworm"); const server = safeGetServer(hostname, "httpworm");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("httpworm", "Cannot be executed on this server."); workerScript.log("httpworm", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.HTTPWormProgram.name)) { if (!Player.hasProgram(Programs.HTTPWormProgram.name)) {
throw makeRuntimeErrorMsg("httpworm", "You do not have the HTTPWorm.exe program!"); throw makeRuntimeErrorMsg("httpworm", "You do not have the HTTPWorm.exe program!");
} }
if (!server.httpPortOpen) { if (!server.httpPortOpen) {
workerScript.log("httpworm", `Executed HTTPWorm.exe on '${server.hostname}' to open HTTP port (80).`); workerScript.log("httpworm", () => `Executed HTTPWorm.exe on '${server.hostname}' to open HTTP port (80).`);
server.httpPortOpen = true; server.httpPortOpen = true;
++server.openPortCount; ++server.openPortCount;
} else { } else {
workerScript.log("httpworm", `HTTP Port (80) already opened on '${server.hostname}'.`); workerScript.log("httpworm", () => `HTTP Port (80) already opened on '${server.hostname}'.`);
} }
return true; return true;
}, },
@ -886,18 +893,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const server = safeGetServer(hostname, "sqlinject"); const server = safeGetServer(hostname, "sqlinject");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("sqlinject", "Cannot be executed on this server."); workerScript.log("sqlinject", () => "Cannot be executed on this server.");
return false; return false;
} }
if (!Player.hasProgram(Programs.SQLInjectProgram.name)) { if (!Player.hasProgram(Programs.SQLInjectProgram.name)) {
throw makeRuntimeErrorMsg("sqlinject", "You do not have the SQLInject.exe program!"); throw makeRuntimeErrorMsg("sqlinject", "You do not have the SQLInject.exe program!");
} }
if (!server.sqlPortOpen) { if (!server.sqlPortOpen) {
workerScript.log("sqlinject", `Executed SQLInject.exe on '${server.hostname}' to open SQL port (1433).`); workerScript.log("sqlinject", () => `Executed SQLInject.exe on '${server.hostname}' to open SQL port (1433).`);
server.sqlPortOpen = true; server.sqlPortOpen = true;
++server.openPortCount; ++server.openPortCount;
} else { } else {
workerScript.log("sqlinject", `SQL Port (1433) already opened on '${server.hostname}'.`); workerScript.log("sqlinject", () => `SQL Port (1433) already opened on '${server.hostname}'.`);
} }
return true; return true;
}, },
@ -946,11 +953,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return runScriptFromScript("spawn", scriptServer, scriptname, args, workerScript, threads); return runScriptFromScript("spawn", scriptServer, scriptname, args, workerScript, threads);
}, spawnDelay * 1e3); }, spawnDelay * 1e3);
workerScript.log("spawn", `Will execute '${scriptname}' in ${spawnDelay} seconds`); workerScript.log("spawn", () => `Will execute '${scriptname}' in ${spawnDelay} seconds`);
workerScript.running = false; // Prevent workerScript from "finishing execution naturally" workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
if (killWorkerScript(workerScript)) { if (killWorkerScript(workerScript)) {
workerScript.log("spawn", "Exiting..."); workerScript.log("spawn", () => "Exiting...");
} }
}, },
kill: function (filename: any, hostname: any, ...scriptArgs: any): any { kill: function (filename: any, hostname: any, ...scriptArgs: any): any {
@ -970,7 +977,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const server = safeGetServer(hostname, "kill"); const server = safeGetServer(hostname, "kill");
const runningScriptObj = getRunningScript(filename, hostname, "kill", scriptArgs); const runningScriptObj = getRunningScript(filename, hostname, "kill", scriptArgs);
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log("kill", getCannotFindRunningScriptErrorMessage(filename, hostname, scriptArgs)); workerScript.log("kill", () => getCannotFindRunningScriptErrorMessage(filename, hostname, scriptArgs));
return false; return false;
} }
@ -979,18 +986,21 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (res) { if (res) {
if (killByPid) { if (killByPid) {
workerScript.log("kill", `Killing script with PID ${filename}`); workerScript.log("kill", () => `Killing script with PID ${filename}`);
} else { } else {
workerScript.log("kill", `Killing '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}.`); workerScript.log(
"kill",
() => `Killing '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}.`,
);
} }
return true; return true;
} else { } else {
if (killByPid) { if (killByPid) {
workerScript.log("kill", `No script with PID ${filename}`); workerScript.log("kill", () => `No script with PID ${filename}`);
} else { } else {
workerScript.log( workerScript.log(
"kill", "kill",
`No such script '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}`, () => `No such script '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}`,
); );
} }
return false; return false;
@ -1009,7 +1019,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
WorkerScriptStartStopEventEmitter.emit(); WorkerScriptStartStopEventEmitter.emit();
workerScript.log( workerScript.log(
"killall", "killall",
`Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`, () => `Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`,
); );
return scriptsRunning; return scriptsRunning;
@ -1017,9 +1027,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
exit: function (): any { exit: function (): any {
workerScript.running = false; // Prevent workerScript from "finishing execution naturally" workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
if (killWorkerScript(workerScript)) { if (killWorkerScript(workerScript)) {
workerScript.log("exit", "Exiting..."); workerScript.log("exit", () => "Exiting...");
} else { } else {
workerScript.log("exit", "Failed. This is a bug. Report to dev."); workerScript.log("exit", () => "Failed. This is a bug. Report to dev.");
} }
}, },
scp: async function (scriptname: any, hostname1: any, hostname2: any): Promise<boolean> { scp: async function (scriptname: any, hostname1: any, hostname2: any): Promise<boolean> {
@ -1086,18 +1096,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
if (!found) { if (!found) {
workerScript.log("scp", `File '${scriptname}' does not exist.`); workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
return Promise.resolve(false); return Promise.resolve(false);
} }
for (let i = 0; i < destServer.messages.length; ++i) { for (let i = 0; i < destServer.messages.length; ++i) {
if (destServer.messages[i] === scriptname) { if (destServer.messages[i] === scriptname) {
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
return Promise.resolve(true); // Already exists return Promise.resolve(true); // Already exists
} }
} }
destServer.messages.push(scriptname); destServer.messages.push(scriptname);
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
return Promise.resolve(true); return Promise.resolve(true);
} }
@ -1111,7 +1121,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
} }
if (txtFile === undefined) { if (txtFile === undefined) {
workerScript.log("scp", `File '${scriptname}' does not exist.`); workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
return Promise.resolve(false); return Promise.resolve(false);
} }
@ -1119,13 +1129,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (destServer.textFiles[i].fn === scriptname) { if (destServer.textFiles[i].fn === scriptname) {
// Overwrite // Overwrite
destServer.textFiles[i].text = txtFile.text; destServer.textFiles[i].text = txtFile.text;
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
return Promise.resolve(true); return Promise.resolve(true);
} }
} }
const newFile = new TextFile(txtFile.fn, txtFile.text); const newFile = new TextFile(txtFile.fn, txtFile.text);
destServer.textFiles.push(newFile); destServer.textFiles.push(newFile);
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
return Promise.resolve(true); return Promise.resolve(true);
} }
@ -1138,14 +1148,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
} }
if (sourceScript == null) { if (sourceScript == null) {
workerScript.log("scp", `File '${scriptname}' does not exist.`); workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
return Promise.resolve(false); return Promise.resolve(false);
} }
// Overwrite script if it already exists // Overwrite script if it already exists
for (let i = 0; i < destServer.scripts.length; ++i) { for (let i = 0; i < destServer.scripts.length; ++i) {
if (scriptname == destServer.scripts[i].filename) { if (scriptname == destServer.scripts[i].filename) {
workerScript.log("scp", `WARNING: File '${scriptname}' overwritten on '${destServer.hostname}'`); workerScript.log("scp", () => `WARNING: File '${scriptname}' overwritten on '${destServer?.hostname}'`);
const oldScript = destServer.scripts[i]; const oldScript = destServer.scripts[i];
// If it's the exact same file don't actually perform the // If it's the exact same file don't actually perform the
// copy to avoid recompiling uselessly. Players tend to scp // copy to avoid recompiling uselessly. Players tend to scp
@ -1164,7 +1174,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
newScript.ramUsage = sourceScript.ramUsage; newScript.ramUsage = sourceScript.ramUsage;
newScript.server = destServer.hostname; newScript.server = destServer.hostname;
destServer.scripts.push(newScript); destServer.scripts.push(newScript);
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
return new Promise((resolve) => { return new Promise((resolve) => {
if (destServer === null) { if (destServer === null) {
resolve(false); resolve(false);
@ -1274,7 +1284,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
getHackingLevel: function (): any { getHackingLevel: function (): any {
updateDynamicRam("getHackingLevel", getRamCost("getHackingLevel")); updateDynamicRam("getHackingLevel", getRamCost("getHackingLevel"));
Player.updateSkillLevels(); Player.updateSkillLevels();
workerScript.log("getHackingLevel", `returned ${Player.hacking}`); workerScript.log("getHackingLevel", () => `returned ${Player.hacking}`);
return Player.hacking; return Player.hacking;
}, },
getHackingMultipliers: function (): any { getHackingMultipliers: function (): any {
@ -1322,7 +1332,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerMoneyAvailable", getRamCost("getServerMoneyAvailable")); updateDynamicRam("getServerMoneyAvailable", getRamCost("getServerMoneyAvailable"));
const server = safeGetServer(hostname, "getServerMoneyAvailable"); const server = safeGetServer(hostname, "getServerMoneyAvailable");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMoneyAvailable", "Cannot be executed on this server."); workerScript.log("getServerMoneyAvailable", () => "Cannot be executed on this server.");
return 0; return 0;
} }
if (failOnHacknetServer(server, "getServerMoneyAvailable")) { if (failOnHacknetServer(server, "getServerMoneyAvailable")) {
@ -1332,13 +1342,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
// Return player's money // Return player's money
workerScript.log( workerScript.log(
"getServerMoneyAvailable", "getServerMoneyAvailable",
`returned player's money: ${numeralWrapper.formatMoney(Player.money)}`, () => `returned player's money: ${numeralWrapper.formatMoney(Player.money)}`,
); );
return Player.money; return Player.money;
} }
workerScript.log( workerScript.log(
"getServerMoneyAvailable", "getServerMoneyAvailable",
`returned ${numeralWrapper.formatMoney(server.moneyAvailable)} for '${server.hostname}'`, () => `returned ${numeralWrapper.formatMoney(server.moneyAvailable)} for '${server.hostname}'`,
); );
return server.moneyAvailable; return server.moneyAvailable;
}, },
@ -1346,7 +1356,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerSecurityLevel", getRamCost("getServerSecurityLevel")); updateDynamicRam("getServerSecurityLevel", getRamCost("getServerSecurityLevel"));
const server = safeGetServer(hostname, "getServerSecurityLevel"); const server = safeGetServer(hostname, "getServerSecurityLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerSecurityLevel", "Cannot be executed on this server."); workerScript.log("getServerSecurityLevel", () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(server, "getServerSecurityLevel")) { if (failOnHacknetServer(server, "getServerSecurityLevel")) {
@ -1354,7 +1364,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.log( workerScript.log(
"getServerSecurityLevel", "getServerSecurityLevel",
`returned ${numeralWrapper.formatServerSecurity(server.hackDifficulty)} for '${server.hostname}'`, () => `returned ${numeralWrapper.formatServerSecurity(server.hackDifficulty)} for '${server.hostname}'`,
); );
return server.hackDifficulty; return server.hackDifficulty;
}, },
@ -1362,11 +1372,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerBaseSecurityLevel", getRamCost("getServerBaseSecurityLevel")); updateDynamicRam("getServerBaseSecurityLevel", getRamCost("getServerBaseSecurityLevel"));
workerScript.log( workerScript.log(
"getServerBaseSecurityLevel", "getServerBaseSecurityLevel",
`getServerBaseSecurityLevel is deprecated because it's not useful.`, () => `getServerBaseSecurityLevel is deprecated because it's not useful.`,
); );
const server = safeGetServer(hostname, "getServerBaseSecurityLevel"); const server = safeGetServer(hostname, "getServerBaseSecurityLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerBaseSecurityLevel", "Cannot be executed on this server."); workerScript.log("getServerBaseSecurityLevel", () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) { if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) {
@ -1374,7 +1384,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.log( workerScript.log(
"getServerBaseSecurityLevel", "getServerBaseSecurityLevel",
`returned ${numeralWrapper.formatServerSecurity(server.baseDifficulty)} for '${server.hostname}'`, () => `returned ${numeralWrapper.formatServerSecurity(server.baseDifficulty)} for '${server.hostname}'`,
); );
return server.baseDifficulty; return server.baseDifficulty;
}, },
@ -1382,7 +1392,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerMinSecurityLevel", getRamCost("getServerMinSecurityLevel")); updateDynamicRam("getServerMinSecurityLevel", getRamCost("getServerMinSecurityLevel"));
const server = safeGetServer(hostname, "getServerMinSecurityLevel"); const server = safeGetServer(hostname, "getServerMinSecurityLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMinSecurityLevel", "Cannot be executed on this server."); workerScript.log("getServerMinSecurityLevel", () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(server, "getServerMinSecurityLevel")) { if (failOnHacknetServer(server, "getServerMinSecurityLevel")) {
@ -1390,7 +1400,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.log( workerScript.log(
"getServerMinSecurityLevel", "getServerMinSecurityLevel",
`returned ${numeralWrapper.formatServerSecurity(server.minDifficulty)} for ${server.hostname}`, () => `returned ${numeralWrapper.formatServerSecurity(server.minDifficulty)} for ${server.hostname}`,
); );
return server.minDifficulty; return server.minDifficulty;
}, },
@ -1398,7 +1408,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerRequiredHackingLevel", getRamCost("getServerRequiredHackingLevel")); updateDynamicRam("getServerRequiredHackingLevel", getRamCost("getServerRequiredHackingLevel"));
const server = safeGetServer(hostname, "getServerRequiredHackingLevel"); const server = safeGetServer(hostname, "getServerRequiredHackingLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerRequiredHackingLevel", "Cannot be executed on this server."); workerScript.log("getServerRequiredHackingLevel", () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) { if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) {
@ -1406,7 +1416,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.log( workerScript.log(
"getServerRequiredHackingLevel", "getServerRequiredHackingLevel",
`returned ${numeralWrapper.formatSkill(server.requiredHackingSkill)} for '${server.hostname}'`, () => `returned ${numeralWrapper.formatSkill(server.requiredHackingSkill)} for '${server.hostname}'`,
); );
return server.requiredHackingSkill; return server.requiredHackingSkill;
}, },
@ -1414,7 +1424,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerMaxMoney", getRamCost("getServerMaxMoney")); updateDynamicRam("getServerMaxMoney", getRamCost("getServerMaxMoney"));
const server = safeGetServer(hostname, "getServerMaxMoney"); const server = safeGetServer(hostname, "getServerMaxMoney");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMaxMoney", "Cannot be executed on this server."); workerScript.log("getServerMaxMoney", () => "Cannot be executed on this server.");
return 0; return 0;
} }
if (failOnHacknetServer(server, "getServerMaxMoney")) { if (failOnHacknetServer(server, "getServerMaxMoney")) {
@ -1422,7 +1432,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.log( workerScript.log(
"getServerMaxMoney", "getServerMaxMoney",
`returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`, () => `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`,
); );
return server.moneyMax; return server.moneyMax;
}, },
@ -1430,48 +1440,54 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getServerGrowth", getRamCost("getServerGrowth")); updateDynamicRam("getServerGrowth", getRamCost("getServerGrowth"));
const server = safeGetServer(hostname, "getServerGrowth"); const server = safeGetServer(hostname, "getServerGrowth");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerGrowth", "Cannot be executed on this server."); workerScript.log("getServerGrowth", () => "Cannot be executed on this server.");
return 1; return 1;
} }
if (failOnHacknetServer(server, "getServerGrowth")) { if (failOnHacknetServer(server, "getServerGrowth")) {
return 1; return 1;
} }
workerScript.log("getServerGrowth", `returned ${server.serverGrowth} for '${server.hostname}'`); workerScript.log("getServerGrowth", () => `returned ${server.serverGrowth} for '${server.hostname}'`);
return server.serverGrowth; return server.serverGrowth;
}, },
getServerNumPortsRequired: function (hostname: any): any { getServerNumPortsRequired: function (hostname: any): any {
updateDynamicRam("getServerNumPortsRequired", getRamCost("getServerNumPortsRequired")); updateDynamicRam("getServerNumPortsRequired", getRamCost("getServerNumPortsRequired"));
const server = safeGetServer(hostname, "getServerNumPortsRequired"); const server = safeGetServer(hostname, "getServerNumPortsRequired");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerNumPortsRequired", "Cannot be executed on this server."); workerScript.log("getServerNumPortsRequired", () => "Cannot be executed on this server.");
return 5; return 5;
} }
if (failOnHacknetServer(server, "getServerNumPortsRequired")) { if (failOnHacknetServer(server, "getServerNumPortsRequired")) {
return 5; return 5;
} }
workerScript.log("getServerNumPortsRequired", `returned ${server.numOpenPortsRequired} for '${server.hostname}'`); workerScript.log(
"getServerNumPortsRequired",
() => `returned ${server.numOpenPortsRequired} for '${server.hostname}'`,
);
return server.numOpenPortsRequired; return server.numOpenPortsRequired;
}, },
getServerRam: function (hostname: any): any { getServerRam: function (hostname: any): any {
updateDynamicRam("getServerRam", getRamCost("getServerRam")); updateDynamicRam("getServerRam", getRamCost("getServerRam"));
workerScript.log("getServerRam", `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`); workerScript.log(
"getServerRam",
() => `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`,
);
const server = safeGetServer(hostname, "getServerRam"); const server = safeGetServer(hostname, "getServerRam");
workerScript.log( workerScript.log(
"getServerRam", "getServerRam",
`returned [${numeralWrapper.formatRAM(server.maxRam)}, ${numeralWrapper.formatRAM(server.ramUsed)}]`, () => `returned [${numeralWrapper.formatRAM(server.maxRam)}, ${numeralWrapper.formatRAM(server.ramUsed)}]`,
); );
return [server.maxRam, server.ramUsed]; return [server.maxRam, server.ramUsed];
}, },
getServerMaxRam: function (hostname: any): any { getServerMaxRam: function (hostname: any): any {
updateDynamicRam("getServerMaxRam", getRamCost("getServerMaxRam")); updateDynamicRam("getServerMaxRam", getRamCost("getServerMaxRam"));
const server = safeGetServer(hostname, "getServerMaxRam"); const server = safeGetServer(hostname, "getServerMaxRam");
workerScript.log("getServerMaxRam", `returned ${numeralWrapper.formatRAM(server.maxRam)}`); workerScript.log("getServerMaxRam", () => `returned ${numeralWrapper.formatRAM(server.maxRam)}`);
return server.maxRam; return server.maxRam;
}, },
getServerUsedRam: function (hostname: any): any { getServerUsedRam: function (hostname: any): any {
updateDynamicRam("getServerUsedRam", getRamCost("getServerUsedRam")); updateDynamicRam("getServerUsedRam", getRamCost("getServerUsedRam"));
const server = safeGetServer(hostname, "getServerUsedRam"); const server = safeGetServer(hostname, "getServerUsedRam");
workerScript.log("getServerUsedRam", `returned ${numeralWrapper.formatRAM(server.ramUsed)}`); workerScript.log("getServerUsedRam", () => `returned ${numeralWrapper.formatRAM(server.ramUsed)}`);
return server.ramUsed; return server.ramUsed;
}, },
serverExists: function (hostname: any): any { serverExists: function (hostname: any): any {
@ -1531,7 +1547,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const cost = getPurchaseServerCost(ram); const cost = getPurchaseServerCost(ram);
if (cost === Infinity) { if (cost === Infinity) {
workerScript.log("getPurchasedServerCost", `Invalid argument: ram='${ram}'`); workerScript.log("getPurchasedServerCost", () => `Invalid argument: ram='${ram}'`);
return Infinity; return Infinity;
} }
@ -1542,13 +1558,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
let hostnameStr = String(name); let hostnameStr = String(name);
hostnameStr = hostnameStr.replace(/\s+/g, ""); hostnameStr = hostnameStr.replace(/\s+/g, "");
if (hostnameStr == "") { if (hostnameStr == "") {
workerScript.log("purchaseServer", `Invalid argument: hostname='${hostnameStr}'`); workerScript.log("purchaseServer", () => `Invalid argument: hostname='${hostnameStr}'`);
return ""; return "";
} }
if (Player.purchasedServers.length >= getPurchaseServerLimit()) { if (Player.purchasedServers.length >= getPurchaseServerLimit()) {
workerScript.log( workerScript.log(
"purchaseServer", "purchaseServer",
() =>
`You have reached the maximum limit of ${getPurchaseServerLimit()} servers. You cannot purchase any more.`, `You have reached the maximum limit of ${getPurchaseServerLimit()} servers. You cannot purchase any more.`,
); );
return ""; return "";
@ -1556,14 +1573,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const cost = getPurchaseServerCost(ram); const cost = getPurchaseServerCost(ram);
if (cost === Infinity) { if (cost === Infinity) {
workerScript.log("purchaseServer", `Invalid argument: ram='${ram}'`); workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}'`);
return ""; return "";
} }
if (Player.money < cost) { if (Player.money < cost) {
workerScript.log( workerScript.log(
"purchaseServer", "purchaseServer",
`Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`, () => `Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`,
); );
return ""; return "";
} }
@ -1585,7 +1602,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
Player.loseMoney(cost, "servers"); Player.loseMoney(cost, "servers");
workerScript.log( workerScript.log(
"purchaseServer", "purchaseServer",
`Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`, () => `Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`,
); );
return newServ.hostname; return newServ.hostname;
}, },
@ -1595,12 +1612,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
hostnameStr = hostnameStr.replace(/\s\s+/g, ""); hostnameStr = hostnameStr.replace(/\s\s+/g, "");
const server = GetServer(hostnameStr); const server = GetServer(hostnameStr);
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("deleteServer", `Invalid argument: hostname='${hostnameStr}'`); workerScript.log("deleteServer", () => `Invalid argument: hostname='${hostnameStr}'`);
return false; return false;
} }
if (!server.purchasedByPlayer || server.hostname === "home") { if (!server.purchasedByPlayer || server.hostname === "home") {
workerScript.log("deleteServer", "Cannot delete non-purchased server."); workerScript.log("deleteServer", () => "Cannot delete non-purchased server.");
return false; return false;
} }
@ -1608,19 +1625,22 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
// Can't delete server you're currently connected to // Can't delete server you're currently connected to
if (server.isConnectedTo) { if (server.isConnectedTo) {
workerScript.log("deleteServer", "You are currently connected to the server you are trying to delete."); workerScript.log("deleteServer", () => "You are currently connected to the server you are trying to delete.");
return false; return false;
} }
// A server cannot delete itself // A server cannot delete itself
if (hostname === workerScript.hostname) { if (hostname === workerScript.hostname) {
workerScript.log("deleteServer", "Cannot delete the server this script is running on."); workerScript.log("deleteServer", () => "Cannot delete the server this script is running on.");
return false; return false;
} }
// Delete all scripts running on server // Delete all scripts running on server
if (server.runningScripts.length > 0) { if (server.runningScripts.length > 0) {
workerScript.log("deleteServer", `Cannot delete server '${hostname}' because it still has scripts running.`); workerScript.log(
"deleteServer",
() => `Cannot delete server '${hostname}' because it still has scripts running.`,
);
return false; return false;
} }
@ -1637,7 +1657,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (!found) { if (!found) {
workerScript.log( workerScript.log(
"deleteServer", "deleteServer",
`Could not identify server ${hostname} as a purchased server. This is a bug. Report to dev.`, () => `Could not identify server ${hostname} as a purchased server. This is a bug. Report to dev.`,
); );
return false; return false;
} }
@ -1651,14 +1671,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
for (let i = 0; i < homeComputer.serversOnNetwork.length; ++i) { for (let i = 0; i < homeComputer.serversOnNetwork.length; ++i) {
if (hostname == homeComputer.serversOnNetwork[i]) { if (hostname == homeComputer.serversOnNetwork[i]) {
homeComputer.serversOnNetwork.splice(i, 1); homeComputer.serversOnNetwork.splice(i, 1);
workerScript.log("deleteServer", `Deleted server '${hostnameStr}`); workerScript.log("deleteServer", () => `Deleted server '${hostnameStr}`);
return true; return true;
} }
} }
// Wasn't found on home computer // Wasn't found on home computer
workerScript.log( workerScript.log(
"deleteServer", "deleteServer",
`Could not find server ${hostname} as a purchased server. This is a bug. Report to dev.`, () => `Could not find server ${hostname} as a purchased server. This is a bug. Report to dev.`,
); );
return false; return false;
}, },
@ -1896,7 +1916,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const status = s.removeFile(fn); const status = s.removeFile(fn);
if (!status.res) { if (!status.res) {
workerScript.log("rm", status.msg + ""); workerScript.log("rm", () => status.msg + "");
} }
return status.res; return status.res;
@ -1973,7 +1993,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getHackTime", getRamCost("getHackTime")); updateDynamicRam("getHackTime", getRamCost("getHackTime"));
const server = safeGetServer(hostname, "getHackTime"); const server = safeGetServer(hostname, "getHackTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getHackTime", "invalid for this kind of server"); workerScript.log("getHackTime", () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(server, "getHackTime")) { if (failOnHacknetServer(server, "getHackTime")) {
@ -1986,7 +2006,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getGrowTime", getRamCost("getGrowTime")); updateDynamicRam("getGrowTime", getRamCost("getGrowTime"));
const server = safeGetServer(hostname, "getGrowTime"); const server = safeGetServer(hostname, "getGrowTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getGrowTime", "invalid for this kind of server"); workerScript.log("getGrowTime", () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(server, "getGrowTime")) { if (failOnHacknetServer(server, "getGrowTime")) {
@ -1999,7 +2019,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime")); updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime"));
const server = safeGetServer(hostname, "getWeakenTime"); const server = safeGetServer(hostname, "getWeakenTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getWeakenTime", "invalid for this kind of server"); workerScript.log("getWeakenTime", () => "invalid for this kind of server");
return Infinity; return Infinity;
} }
if (failOnHacknetServer(server, "getWeakenTime")) { if (failOnHacknetServer(server, "getWeakenTime")) {
@ -2030,7 +2050,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log( workerScript.log(
"getScriptIncome", "getScriptIncome",
`No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`, () => `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
); );
return -1; return -1;
} }
@ -2052,7 +2072,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log( workerScript.log(
"getScriptExpGain", "getScriptExpGain",
`No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`, () => `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
); );
return -1; return -1;
} }
@ -2095,7 +2115,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}, },
wget: async function (url: any, target: any, hostname: any = workerScript.hostname): Promise<boolean> { wget: async function (url: any, target: any, hostname: any = workerScript.hostname): Promise<boolean> {
if (!isScriptFilename(target) && !target.endsWith(".txt")) { if (!isScriptFilename(target) && !target.endsWith(".txt")) {
workerScript.log("wget", `Invalid target file: '${target}'. Must be a script or text file.`); workerScript.log("wget", () => `Invalid target file: '${target}'. Must be a script or text file.`);
return Promise.resolve(false); return Promise.resolve(false);
} }
const s = safeGetServer(hostname, "wget"); const s = safeGetServer(hostname, "wget");
@ -2110,19 +2130,22 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
res = s.writeToTextFile(target, data); res = s.writeToTextFile(target, data);
} }
if (!res.success) { if (!res.success) {
workerScript.log("wget", "Failed."); workerScript.log("wget", () => "Failed.");
return resolve(false); return resolve(false);
} }
if (res.overwritten) { if (res.overwritten) {
workerScript.log("wget", `Successfully retrieved content and overwrote '${target}' on '${hostname}'`); workerScript.log(
"wget",
() => `Successfully retrieved content and overwrote '${target}' on '${hostname}'`,
);
return resolve(true); return resolve(true);
} }
workerScript.log("wget", `Successfully retrieved content to new file '${target}' on '${hostname}'`); workerScript.log("wget", () => `Successfully retrieved content to new file '${target}' on '${hostname}'`);
return resolve(true); return resolve(true);
}, },
"text", "text",
).fail(function (e) { ).fail(function (e) {
workerScript.log("wget", JSON.stringify(e)); workerScript.log("wget", () => JSON.stringify(e));
return resolve(false); return resolve(false);
}); });
}); });

@ -344,13 +344,13 @@ export function NetscriptBladeburner(
player.agility >= 100 player.agility >= 100
) { ) {
player.bladeburner = new Bladeburner(player); player.bladeburner = new Bladeburner(player);
workerScript.log("joinBladeburnerDivision", "You have been accepted into the Bladeburner division"); workerScript.log("joinBladeburnerDivision", () => "You have been accepted into the Bladeburner division");
return true; return true;
} else { } else {
workerScript.log( workerScript.log(
"joinBladeburnerDivision", "joinBladeburnerDivision",
"You do not meet the requirements for joining the Bladeburner division", () => "You do not meet the requirements for joining the Bladeburner division",
); );
return false; return false;
} }

@ -53,17 +53,21 @@ export function NetscriptCodingContract(
const serv = helper.getServer(hostname, "codingcontract.attempt"); const serv = helper.getServer(hostname, "codingcontract.attempt");
if (contract.isSolution(answer)) { if (contract.isSolution(answer)) {
const reward = player.gainCodingContractReward(creward, contract.getDifficulty()); const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
workerScript.log("attempt", `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`); workerScript.log("attempt", () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
serv.removeContract(filename); serv.removeContract(filename);
return returnReward ? reward : true; return returnReward ? reward : true;
} else { } else {
++contract.tries; ++contract.tries;
if (contract.tries >= contract.getMaxNumTries()) { if (contract.tries >= contract.getMaxNumTries()) {
workerScript.log("attempt", `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`); workerScript.log(
"attempt",
() => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`,
);
serv.removeContract(filename); serv.removeContract(filename);
} else { } else {
workerScript.log( workerScript.log(
"attempt", "attempt",
() =>
`Coding Contract attempt '${filename}' failed. ${ `Coding Contract attempt '${filename}' failed. ${
contract.getMaxNumTries() - contract.tries contract.getMaxNumTries() - contract.tries
} attempts remaining.`, } attempts remaining.`,

@ -167,9 +167,9 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
const recruited = gang.recruitMember(name); const recruited = gang.recruitMember(name);
if (recruited) { if (recruited) {
workerScript.log("recruitMember", `Successfully recruited Gang Member '${name}'`); workerScript.log("recruitMember", () => `Successfully recruited Gang Member '${name}'`);
} else { } else {
workerScript.log("recruitMember", `Failed to recruit Gang Member '${name}'`); workerScript.log("recruitMember", () => `Failed to recruit Gang Member '${name}'`);
} }
return recruited; return recruited;
@ -189,11 +189,14 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
const member = getGangMember("setMemberTask", memberName); const member = getGangMember("setMemberTask", memberName);
const success = member.assignToTask(taskName); const success = member.assignToTask(taskName);
if (success) { if (success) {
workerScript.log("setMemberTask", `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`); workerScript.log(
"setMemberTask",
() => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
);
} else { } else {
workerScript.log( workerScript.log(
"setMemberTask", "setMemberTask",
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`, () => `Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
); );
} }
@ -248,9 +251,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
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) {
workerScript.log("purchaseEquipment", `Purchased '${equipName}' for Gang member '${memberName}'`); workerScript.log("purchaseEquipment", () => `Purchased '${equipName}' for Gang member '${memberName}'`);
} else { } else {
workerScript.log("purchaseEquipment", `Failed to purchase '${equipName}' for Gang member '${memberName}'`); workerScript.log(
"purchaseEquipment",
() => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
);
} }
return res; return res;
@ -271,10 +277,10 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
if (engage) { if (engage) {
gang.territoryWarfareEngaged = true; gang.territoryWarfareEngaged = true;
workerScript.log("setTerritoryWarfare", "Engaging in Gang Territory Warfare"); workerScript.log("setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
} else { } else {
gang.territoryWarfareEngaged = false; gang.territoryWarfareEngaged = false;
workerScript.log("setTerritoryWarfare", "Disengaging in Gang Territory Warfare"); workerScript.log("setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
} }
}, },
getChanceToWinClash: function (otherGang: any): number { getChanceToWinClash: function (otherGang: any): number {

@ -109,7 +109,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
} }
const node = getHacknetNode(i, "upgradeCache"); const node = getHacknetNode(i, "upgradeCache");
if (!(node instanceof HacknetServer)) { if (!(node instanceof HacknetServer)) {
workerScript.log("upgradeCache", "Can only be called on hacknet servers"); workerScript.log("upgradeCache", () => "Can only be called on hacknet servers");
return false; return false;
} }
const res = purchaseCacheUpgrade(player, node, n); const res = purchaseCacheUpgrade(player, node, n);
@ -136,7 +136,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
} }
const node = getHacknetNode(i, "upgradeCache"); const node = getHacknetNode(i, "upgradeCache");
if (!(node instanceof HacknetServer)) { if (!(node instanceof HacknetServer)) {
workerScript.log("getCacheUpgradeCost", "Can only be called on hacknet servers"); workerScript.log("getCacheUpgradeCost", () => "Can only be called on hacknet servers");
return -1; return -1;
} }
return node.calculateCacheUpgradeCost(n); return node.calculateCacheUpgradeCost(n);

@ -186,7 +186,10 @@ export function NetscriptSingularity(
} }
if (!augs.includes(name)) { if (!augs.includes(name)) {
workerScript.log("purchaseAugmentation", `Faction '${faction}' does not have the '${name}' augmentation.`); workerScript.log(
"purchaseAugmentation",
() => `Faction '${faction}' does not have the '${name}' augmentation.`,
);
return false; return false;
} }
@ -194,25 +197,25 @@ export function NetscriptSingularity(
if (!isNeuroflux) { if (!isNeuroflux) {
for (let j = 0; j < player.queuedAugmentations.length; ++j) { for (let j = 0; j < player.queuedAugmentations.length; ++j) {
if (player.queuedAugmentations[j].name === aug.name) { if (player.queuedAugmentations[j].name === aug.name) {
workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`); workerScript.log("purchaseAugmentation", () => `You already have the '${name}' augmentation.`);
return false; return false;
} }
} }
for (let j = 0; j < player.augmentations.length; ++j) { for (let j = 0; j < player.augmentations.length; ++j) {
if (player.augmentations[j].name === aug.name) { if (player.augmentations[j].name === aug.name) {
workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`); workerScript.log("purchaseAugmentation", () => `You already have the '${name}' augmentation.`);
return false; return false;
} }
} }
} }
if (fac.playerReputation < aug.baseRepRequirement) { if (fac.playerReputation < aug.baseRepRequirement) {
workerScript.log("purchaseAugmentation", `You do not have enough reputation with '${fac.name}'.`); workerScript.log("purchaseAugmentation", () => `You do not have enough reputation with '${fac.name}'.`);
return false; return false;
} }
const res = purchaseAugmentation(aug, fac, true); const res = purchaseAugmentation(aug, fac, true);
workerScript.log("purchaseAugmentation", res); workerScript.log("purchaseAugmentation", () => res);
if (isString(res) && res.startsWith("You purchased")) { if (isString(res) && res.startsWith("You purchased")) {
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
return true; return true;
@ -224,7 +227,7 @@ export function NetscriptSingularity(
helper.updateDynamicRam("softReset", getRamCost("softReset")); helper.updateDynamicRam("softReset", getRamCost("softReset"));
helper.checkSingularityAccess("softReset", 3); helper.checkSingularityAccess("softReset", 3);
workerScript.log("softReset", "Soft resetting. This will cause this script to be killed"); workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed");
setTimeout(() => { setTimeout(() => {
prestigeAugmentation(); prestigeAugmentation();
runAfterReset(cbScript); runAfterReset(cbScript);
@ -239,11 +242,14 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("installAugmentations", 3); helper.checkSingularityAccess("installAugmentations", 3);
if (player.queuedAugmentations.length === 0) { if (player.queuedAugmentations.length === 0) {
workerScript.log("installAugmentations", "You do not have any Augmentations to be installed."); workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed.");
return false; return false;
} }
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log("installAugmentations", "Installing Augmentations. This will cause this script to be killed"); workerScript.log(
"installAugmentations",
() => "Installing Augmentations. This will cause this script to be killed",
);
setTimeout(() => { setTimeout(() => {
installAugmentations(); installAugmentations();
runAfterReset(cbScript); runAfterReset(cbScript);
@ -258,11 +264,11 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("goToLocation", 1); helper.checkSingularityAccess("goToLocation", 1);
const location = Object.values(Locations).find((l) => l.name === locationName); const location = Object.values(Locations).find((l) => l.name === locationName);
if (!location) { if (!location) {
workerScript.log("goToLocation", `No location named ${locationName}`); workerScript.log("goToLocation", () => `No location named ${locationName}`);
return false; return false;
} }
if (player.city !== location.city) { if (player.city !== location.city) {
workerScript.log("goToLocation", `No location named ${locationName} in ${player.city}`); workerScript.log("goToLocation", () => `No location named ${locationName} in ${player.city}`);
return false; return false;
} }
Router.toLocation(location); Router.toLocation(location);
@ -274,7 +280,7 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("universityCourse", 1); helper.checkSingularityAccess("universityCourse", 1);
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("universityCourse", txt); workerScript.log("universityCourse", () => txt);
} }
let costMult, expMult; let costMult, expMult;
@ -283,7 +289,7 @@ export function NetscriptSingularity(
if (player.city != CityName.Aevum) { if (player.city != CityName.Aevum) {
workerScript.log( workerScript.log(
"universityCourse", "universityCourse",
"You cannot study at 'Summit University' because you are not in 'Aevum'.", () => "You cannot study at 'Summit University' because you are not in 'Aevum'.",
); );
return false; return false;
} }
@ -295,7 +301,7 @@ export function NetscriptSingularity(
if (player.city != CityName.Sector12) { if (player.city != CityName.Sector12) {
workerScript.log( workerScript.log(
"universityCourse", "universityCourse",
"You cannot study at 'Rothman University' because you are not in 'Sector-12'.", () => "You cannot study at 'Rothman University' because you are not in 'Sector-12'.",
); );
return false; return false;
} }
@ -307,7 +313,7 @@ export function NetscriptSingularity(
if (player.city != CityName.Volhaven) { if (player.city != CityName.Volhaven) {
workerScript.log( workerScript.log(
"universityCourse", "universityCourse",
"You cannot study at 'ZB Institute of Technology' because you are not in 'Volhaven'.", () => "You cannot study at 'ZB Institute of Technology' because you are not in 'Volhaven'.",
); );
return false; return false;
} }
@ -316,11 +322,11 @@ export function NetscriptSingularity(
expMult = 4; expMult = 4;
break; break;
default: default:
workerScript.log("universityCourse", `Invalid university name: '${universityName}'.`); workerScript.log("universityCourse", () => `Invalid university name: '${universityName}'.`);
return false; return false;
} }
let task; let task = "";
switch (className.toLowerCase()) { switch (className.toLowerCase()) {
case "Study Computer Science".toLowerCase(): case "Study Computer Science".toLowerCase():
task = CONSTANTS.ClassStudyComputerScience; task = CONSTANTS.ClassStudyComputerScience;
@ -341,11 +347,11 @@ export function NetscriptSingularity(
task = CONSTANTS.ClassLeadership; task = CONSTANTS.ClassLeadership;
break; break;
default: default:
workerScript.log("universityCourse", `Invalid class name: ${className}.`); workerScript.log("universityCourse", () => `Invalid class name: ${className}.`);
return false; return false;
} }
player.startClass(Router, costMult, expMult, task); player.startClass(Router, costMult, expMult, task);
workerScript.log("universityCourse", `Started ${task} at ${universityName}`); workerScript.log("universityCourse", () => `Started ${task} at ${universityName}`);
return true; return true;
}, },
@ -354,13 +360,16 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("gymWorkout", 1); helper.checkSingularityAccess("gymWorkout", 1);
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("gymWorkout", txt); workerScript.log("gymWorkout", () => txt);
} }
let costMult, expMult; let costMult, expMult;
switch (gymName.toLowerCase()) { switch (gymName.toLowerCase()) {
case LocationName.AevumCrushFitnessGym.toLowerCase(): case LocationName.AevumCrushFitnessGym.toLowerCase():
if (player.city != CityName.Aevum) { if (player.city != CityName.Aevum) {
workerScript.log("gymWorkout", "You cannot workout at 'Crush Fitness' because you are not in 'Aevum'."); workerScript.log(
"gymWorkout",
() => "You cannot workout at 'Crush Fitness' because you are not in 'Aevum'.",
);
return false; return false;
} }
player.location = LocationName.AevumCrushFitnessGym; player.location = LocationName.AevumCrushFitnessGym;
@ -369,7 +378,10 @@ export function NetscriptSingularity(
break; break;
case LocationName.AevumSnapFitnessGym.toLowerCase(): case LocationName.AevumSnapFitnessGym.toLowerCase():
if (player.city != CityName.Aevum) { if (player.city != CityName.Aevum) {
workerScript.log("gymWorkout", "You cannot workout at 'Snap Fitness' because you are not in 'Aevum'."); workerScript.log(
"gymWorkout",
() => "You cannot workout at 'Snap Fitness' because you are not in 'Aevum'.",
);
return false; return false;
} }
player.location = LocationName.AevumSnapFitnessGym; player.location = LocationName.AevumSnapFitnessGym;
@ -378,7 +390,10 @@ export function NetscriptSingularity(
break; break;
case LocationName.Sector12IronGym.toLowerCase(): case LocationName.Sector12IronGym.toLowerCase():
if (player.city != CityName.Sector12) { if (player.city != CityName.Sector12) {
workerScript.log("gymWorkout", "You cannot workout at 'Iron Gym' because you are not in 'Sector-12'."); workerScript.log(
"gymWorkout",
() => "You cannot workout at 'Iron Gym' because you are not in 'Sector-12'.",
);
return false; return false;
} }
player.location = LocationName.Sector12IronGym; player.location = LocationName.Sector12IronGym;
@ -389,7 +404,7 @@ export function NetscriptSingularity(
if (player.city != CityName.Sector12) { if (player.city != CityName.Sector12) {
workerScript.log( workerScript.log(
"gymWorkout", "gymWorkout",
"You cannot workout at 'Powerhouse Gym' because you are not in 'Sector-12'.", () => "You cannot workout at 'Powerhouse Gym' because you are not in 'Sector-12'.",
); );
return false; return false;
} }
@ -401,7 +416,7 @@ export function NetscriptSingularity(
if (player.city != CityName.Volhaven) { if (player.city != CityName.Volhaven) {
workerScript.log( workerScript.log(
"gymWorkout", "gymWorkout",
"You cannot workout at 'Millenium Fitness Gym' because you are not in 'Volhaven'.", () => "You cannot workout at 'Millenium Fitness Gym' because you are not in 'Volhaven'.",
); );
return false; return false;
} }
@ -410,7 +425,7 @@ export function NetscriptSingularity(
expMult = 4; expMult = 4;
break; break;
default: default:
workerScript.log("gymWorkout", `Invalid gym name: ${gymName}. gymWorkout() failed`); workerScript.log("gymWorkout", () => `Invalid gym name: ${gymName}. gymWorkout() failed`);
return false; return false;
} }
@ -432,10 +447,10 @@ export function NetscriptSingularity(
player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymAgility); player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymAgility);
break; break;
default: default:
workerScript.log("gymWorkout", `Invalid stat: ${stat}.`); workerScript.log("gymWorkout", () => `Invalid stat: ${stat}.`);
return false; return false;
} }
workerScript.log("gymWorkout", `Started training ${stat} at ${gymName}`); workerScript.log("gymWorkout", () => `Started training ${stat} at ${gymName}`);
return true; return true;
}, },
@ -455,11 +470,11 @@ export function NetscriptSingularity(
} }
player.loseMoney(CONSTANTS.TravelCost, "other"); player.loseMoney(CONSTANTS.TravelCost, "other");
player.city = cityname; player.city = cityname;
workerScript.log("travelToCity", `Traveled to ${cityname}`); workerScript.log("travelToCity", () => `Traveled to ${cityname}`);
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50);
return true; return true;
default: default:
workerScript.log("travelToCity", `Invalid city name: '${cityname}'.`); workerScript.log("travelToCity", () => `Invalid city name: '${cityname}'.`);
return false; return false;
} }
}, },
@ -469,12 +484,12 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("purchaseTor", 1); helper.checkSingularityAccess("purchaseTor", 1);
if (player.hasTorRouter()) { if (player.hasTorRouter()) {
workerScript.log("purchaseTor", "You already have a TOR router!"); workerScript.log("purchaseTor", () => "You already have a TOR router!");
return false; return false;
} }
if (player.money < CONSTANTS.TorRouterCost) { if (player.money < CONSTANTS.TorRouterCost) {
workerScript.log("purchaseTor", "You cannot afford to purchase a Tor router."); workerScript.log("purchaseTor", () => "You cannot afford to purchase a Tor router.");
return false; return false;
} }
player.loseMoney(CONSTANTS.TorRouterCost, "other"); player.loseMoney(CONSTANTS.TorRouterCost, "other");
@ -493,7 +508,7 @@ export function NetscriptSingularity(
player.getHomeComputer().serversOnNetwork.push(darkweb.hostname); player.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
darkweb.serversOnNetwork.push(player.getHomeComputer().hostname); darkweb.serversOnNetwork.push(player.getHomeComputer().hostname);
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log("purchaseTor", "You have purchased a Tor router!"); workerScript.log("purchaseTor", () => "You have purchased a Tor router!");
return true; return true;
}, },
purchaseProgram: function (programName: any): any { purchaseProgram: function (programName: any): any {
@ -501,35 +516,28 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("purchaseProgram", 1); helper.checkSingularityAccess("purchaseProgram", 1);
if (!player.hasTorRouter()) { if (!player.hasTorRouter()) {
workerScript.log("purchaseProgram", "You do not have the TOR router."); workerScript.log("purchaseProgram", () => "You do not have the TOR router.");
return false; return false;
} }
programName = programName.toLowerCase(); programName = programName.toLowerCase();
let item = null; const item = Object.values(DarkWebItems).find((i) => i.program.toLowerCase() === programName);
for (const key in DarkWebItems) {
const i = DarkWebItems[key];
if (i.program.toLowerCase() == programName) {
item = i;
}
}
if (item == null) { if (item == null) {
workerScript.log("purchaseProgram", `Invalid program name: '${programName}.`); workerScript.log("purchaseProgram", () => `Invalid program name: '${programName}.`);
return false; return false;
} }
if (player.money < item.price) { if (player.money < item.price) {
workerScript.log( workerScript.log(
"purchaseProgram", "purchaseProgram",
`Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`, () => `Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`,
); );
return false; return false;
} }
if (player.hasProgram(item.program)) { if (player.hasProgram(item.program)) {
workerScript.log("purchaseProgram", `You already have the '${item.program}' program`); workerScript.log("purchaseProgram", () => `You already have the '${item.program}' program`);
return true; return true;
} }
@ -537,7 +545,7 @@ export function NetscriptSingularity(
player.getHomeComputer().programs.push(item.program); player.getHomeComputer().programs.push(item.program);
workerScript.log( workerScript.log(
"purchaseProgram", "purchaseProgram",
`You have purchased the '${item.program}' program. The new program can be found on your home computer.`, () => `You have purchased the '${item.program}' program. The new program can be found on your home computer.`,
); );
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50);
return true; return true;
@ -593,7 +601,7 @@ export function NetscriptSingularity(
helper.checkSingularityAccess("installBackdoor", 1); helper.checkSingularityAccess("installBackdoor", 1);
const baseserver = player.getCurrentServer(); const baseserver = player.getCurrentServer();
if (!(baseserver instanceof Server)) { if (!(baseserver instanceof Server)) {
workerScript.log("installBackdoor", "cannot backdoor this kind of server"); workerScript.log("installBackdoor", () => "cannot backdoor this kind of server");
return Promise.resolve(); return Promise.resolve();
} }
const server = baseserver as Server; const server = baseserver as Server;
@ -607,14 +615,14 @@ export function NetscriptSingularity(
workerScript.log( workerScript.log(
"installBackdoor", "installBackdoor",
`Installing backdoor on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(installTime, true)}`, () => `Installing backdoor on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(installTime, true)}`,
); );
return netscriptDelay(installTime, workerScript).then(function () { return netscriptDelay(installTime, workerScript).then(function () {
if (workerScript.env.stopFlag) { if (workerScript.env.stopFlag) {
return Promise.reject(workerScript); return Promise.reject(workerScript);
} }
workerScript.log("installBackdoor", `Successfully installed backdoor on '${server.hostname}'`); workerScript.log("installBackdoor", () => `Successfully installed backdoor on '${server.hostname}'`);
server.backdoorInstalled = true; server.backdoorInstalled = true;
@ -627,7 +635,7 @@ export function NetscriptSingularity(
getStats: function (): any { getStats: function (): any {
helper.updateDynamicRam("getStats", getRamCost("getStats")); helper.updateDynamicRam("getStats", getRamCost("getStats"));
helper.checkSingularityAccess("getStats", 1); helper.checkSingularityAccess("getStats", 1);
workerScript.log("getStats", `getStats is deprecated, please use getplayer`); workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`);
return { return {
hacking: player.hacking, hacking: player.hacking,
@ -642,7 +650,7 @@ export function NetscriptSingularity(
getCharacterInformation: function (): any { getCharacterInformation: function (): any {
helper.updateDynamicRam("getCharacterInformation", getRamCost("getCharacterInformation")); helper.updateDynamicRam("getCharacterInformation", getRamCost("getCharacterInformation"));
helper.checkSingularityAccess("getCharacterInformation", 1); helper.checkSingularityAccess("getCharacterInformation", 1);
workerScript.log("getCharacterInformation", `getCharacterInformation is deprecated, please use getplayer`); workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`);
return { return {
bitnode: player.bitNodeN, bitnode: player.bitNodeN,
@ -691,7 +699,7 @@ export function NetscriptSingularity(
helper.updateDynamicRam("hospitalize", getRamCost("hospitalize")); helper.updateDynamicRam("hospitalize", getRamCost("hospitalize"));
helper.checkSingularityAccess("hospitalize", 1); helper.checkSingularityAccess("hospitalize", 1);
if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) { if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
workerScript.log("hospitalize", "Cannot go to the hospital because the player is busy."); workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy.");
return; return;
} }
return player.hospitalize(); return player.hospitalize();
@ -707,7 +715,7 @@ export function NetscriptSingularity(
if (player.isWorking) { if (player.isWorking) {
Router.toTerminal(); Router.toTerminal();
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("stopAction", txt); workerScript.log("stopAction", () => txt);
return true; return true;
} }
return false; return false;
@ -719,13 +727,16 @@ export function NetscriptSingularity(
// Check if we're at max cores // Check if we're at max cores
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
if (homeComputer.cpuCores >= 8) { if (homeComputer.cpuCores >= 8) {
workerScript.log("upgradeHomeCores", `Your home computer is at max cores.`); workerScript.log("upgradeHomeCores", () => `Your home computer is at max cores.`);
return false; return false;
} }
const cost = player.getUpgradeHomeCoresCost(); const cost = player.getUpgradeHomeCoresCost();
if (player.money < cost) { if (player.money < cost) {
workerScript.log("upgradeHomeCores", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`); workerScript.log(
"upgradeHomeCores",
() => `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`,
);
return false; return false;
} }
@ -735,7 +746,7 @@ export function NetscriptSingularity(
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log( workerScript.log(
"upgradeHomeCores", "upgradeHomeCores",
`Purchased an additional core for home computer! It now has ${homeComputer.cpuCores} cores.`, () => `Purchased an additional core for home computer! It now has ${homeComputer.cpuCores} cores.`,
); );
return true; return true;
}, },
@ -752,13 +763,16 @@ export function NetscriptSingularity(
// Check if we're at max RAM // Check if we're at max RAM
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
if (homeComputer.maxRam >= CONSTANTS.HomeComputerMaxRam) { if (homeComputer.maxRam >= CONSTANTS.HomeComputerMaxRam) {
workerScript.log("upgradeHomeRam", `Your home computer is at max RAM.`); workerScript.log("upgradeHomeRam", () => `Your home computer is at max RAM.`);
return false; return false;
} }
const cost = player.getUpgradeHomeRamCost(); const cost = player.getUpgradeHomeRamCost();
if (player.money < cost) { if (player.money < cost) {
workerScript.log("upgradeHomeRam", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`); workerScript.log(
"upgradeHomeRam",
() => `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`,
);
return false; return false;
} }
@ -768,6 +782,7 @@ export function NetscriptSingularity(
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log( workerScript.log(
"upgradeHomeRam", "upgradeHomeRam",
() =>
`Purchased additional RAM for home computer! It now has ${numeralWrapper.formatRAM( `Purchased additional RAM for home computer! It now has ${numeralWrapper.formatRAM(
homeComputer.maxRam, homeComputer.maxRam,
)} of RAM.`, )} of RAM.`,
@ -791,13 +806,13 @@ export function NetscriptSingularity(
// Make sure its a valid company // Make sure its a valid company
if (companyName == null || companyName === "" || !(Companies[companyName] instanceof Company)) { if (companyName == null || companyName === "" || !(Companies[companyName] instanceof Company)) {
workerScript.log("workForCompany", `Invalid company: '${companyName}'`); workerScript.log("workForCompany", () => `Invalid company: '${companyName}'`);
return false; return false;
} }
// Make sure player is actually employed at the comapny // Make sure player is actually employed at the comapny
if (!Object.keys(player.jobs).includes(companyName)) { if (!Object.keys(player.jobs).includes(companyName)) {
workerScript.log("workForCompany", `You do not have a job at '${companyName}'`); workerScript.log("workForCompany", () => `You do not have a job at '${companyName}'`);
return false; return false;
} }
@ -805,13 +820,13 @@ export function NetscriptSingularity(
const companyPositionName = player.jobs[companyName]; const companyPositionName = player.jobs[companyName];
const companyPosition = CompanyPositions[companyPositionName]; const companyPosition = CompanyPositions[companyPositionName];
if (companyPositionName === "" || !(companyPosition instanceof CompanyPosition)) { if (companyPositionName === "" || !(companyPosition instanceof CompanyPosition)) {
workerScript.log("workForCompany", "You do not have a job"); workerScript.log("workForCompany", () => "You do not have a job");
return false; return false;
} }
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("workForCompany", txt); workerScript.log("workForCompany", () => txt);
} }
if (companyPosition.isPartTimeJob()) { if (companyPosition.isPartTimeJob()) {
@ -819,7 +834,10 @@ export function NetscriptSingularity(
} else { } else {
player.startWork(Router, companyName); player.startWork(Router, companyName);
} }
workerScript.log("workForCompany", `Began working at '${player.companyName}' as a '${companyPositionName}'`); workerScript.log(
"workForCompany",
() => `Began working at '${player.companyName}' as a '${companyPositionName}'`,
);
return true; return true;
}, },
applyToCompany: function (companyName: any, field: any): any { applyToCompany: function (companyName: any, field: any): any {
@ -870,24 +888,24 @@ export function NetscriptSingularity(
res = player.applyForPartTimeWaiterJob(true); res = player.applyForPartTimeWaiterJob(true);
break; break;
default: default:
workerScript.log("applyToCompany", `Invalid job: '${field}'.`); workerScript.log("applyToCompany", () => `Invalid job: '${field}'.`);
return false; return false;
} }
// TODO https://github.com/danielyxie/bitburner/issues/1378 // TODO https://github.com/danielyxie/bitburner/issues/1378
// The player object's applyForJob function can return string with special error messages // The player object's applyForJob function can return string with special error messages
// if (isString(res)) { // if (isString(res)) {
// workerScript.log("applyToCompany", res); // workerScript.log("applyToCompany",()=> res);
// return false; // return false;
// } // }
if (res) { if (res) {
workerScript.log( workerScript.log(
"applyToCompany", "applyToCompany",
`You were offered a new job at '${companyName}' as a '${player.jobs[companyName]}'`, () => `You were offered a new job at '${companyName}' as a '${player.jobs[companyName]}'`,
); );
} else { } else {
workerScript.log( workerScript.log(
"applyToCompany", "applyToCompany",
`You failed to get a new job/promotion at '${companyName}' in the '${field}' field.`, () => `You failed to get a new job/promotion at '${companyName}' in the '${field}' field.`,
); );
} }
return res; return res;
@ -922,7 +940,7 @@ export function NetscriptSingularity(
getFaction("joinFaction", name); getFaction("joinFaction", name);
if (!player.factionInvitations.includes(name)) { if (!player.factionInvitations.includes(name)) {
workerScript.log("joinFaction", `You have not been invited by faction '${name}'`); workerScript.log("joinFaction", () => `You have not been invited by faction '${name}'`);
return false; return false;
} }
const fac = Factions[name]; const fac = Factions[name];
@ -936,7 +954,7 @@ export function NetscriptSingularity(
} }
} }
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log("joinFaction", `Joined the '${name}' faction.`); workerScript.log("joinFaction", () => `Joined the '${name}' faction.`);
return true; return true;
}, },
workForFaction: function (name: any, type: any): any { workForFaction: function (name: any, type: any): any {
@ -946,18 +964,18 @@ export function NetscriptSingularity(
// if the player is in a gang and the target faction is any of the gang faction, fail // if the player is in a gang and the target faction is any of the gang faction, fail
if (player.inGang() && AllGangs[name] !== undefined) { if (player.inGang() && AllGangs[name] !== undefined) {
workerScript.log("workForFaction", `Faction '${name}' does not offer work at the moment.`); workerScript.log("workForFaction", () => `Faction '${name}' does not offer work at the moment.`);
return; return;
} }
if (!player.factions.includes(name)) { if (!player.factions.includes(name)) {
workerScript.log("workForFaction", `You are not a member of '${name}'`); workerScript.log("workForFaction", () => `You are not a member of '${name}'`);
return false; return false;
} }
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("workForFaction", txt); workerScript.log("workForFaction", () => txt);
} }
const fac = Factions[name]; const fac = Factions[name];
@ -1049,34 +1067,34 @@ export function NetscriptSingularity(
case "hacking contracts": case "hacking contracts":
case "hackingcontracts": case "hackingcontracts":
if (!hackAvailable.includes(fac.name)) { if (!hackAvailable.includes(fac.name)) {
workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with hacking contracts.`); workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with hacking contracts.`);
return false; return false;
} }
player.startFactionHackWork(Router, fac); player.startFactionHackWork(Router, fac);
workerScript.log("workForFaction", `Started carrying out hacking contracts for '${fac.name}'`); workerScript.log("workForFaction", () => `Started carrying out hacking contracts for '${fac.name}'`);
return true; return true;
case "field": case "field":
case "fieldwork": case "fieldwork":
case "field work": case "field work":
if (!fdWkAvailable.includes(fac.name)) { if (!fdWkAvailable.includes(fac.name)) {
workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with field missions.`); workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with field missions.`);
return false; return false;
} }
player.startFactionFieldWork(Router, fac); player.startFactionFieldWork(Router, fac);
workerScript.log("workForFaction", `Started carrying out field missions for '${fac.name}'`); workerScript.log("workForFaction", () => `Started carrying out field missions for '${fac.name}'`);
return true; return true;
case "security": case "security":
case "securitywork": case "securitywork":
case "security work": case "security work":
if (!scWkAvailable.includes(fac.name)) { if (!scWkAvailable.includes(fac.name)) {
workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with security work.`); workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with security work.`);
return false; return false;
} }
player.startFactionSecurityWork(Router, fac); player.startFactionSecurityWork(Router, fac);
workerScript.log("workForFaction", `Started carrying out security work for '${fac.name}'`); workerScript.log("workForFaction", () => `Started carrying out security work for '${fac.name}'`);
return true; return true;
default: default:
workerScript.log("workForFaction", `Invalid work type: '${type}`); workerScript.log("workForFaction", () => `Invalid work type: '${type}`);
} }
return true; return true;
}, },
@ -1104,13 +1122,13 @@ export function NetscriptSingularity(
const faction = getFaction("donateToFaction", name); const faction = getFaction("donateToFaction", name);
if (typeof amt !== "number" || amt <= 0) { if (typeof amt !== "number" || amt <= 0) {
workerScript.log("donateToFaction", `Invalid donation amount: '${amt}'.`); workerScript.log("donateToFaction", () => `Invalid donation amount: '${amt}'.`);
return false; return false;
} }
if (player.money < amt) { if (player.money < amt) {
workerScript.log( workerScript.log(
"donateToFaction", "donateToFaction",
`You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`, () => `You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`,
); );
return false; return false;
} }
@ -1118,6 +1136,7 @@ export function NetscriptSingularity(
if (faction.favor < repNeededToDonate) { if (faction.favor < repNeededToDonate) {
workerScript.log( workerScript.log(
"donateToFaction", "donateToFaction",
() =>
`You do not have enough favor to donate to this faction. Have ${faction.favor}, need ${repNeededToDonate}`, `You do not have enough favor to donate to this faction. Have ${faction.favor}, need ${repNeededToDonate}`,
); );
return false; return false;
@ -1127,6 +1146,7 @@ export function NetscriptSingularity(
player.loseMoney(amt, "other"); player.loseMoney(amt, "other");
workerScript.log( workerScript.log(
"donateToFaction", "donateToFaction",
() =>
`${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation( `${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation(
repGain, repGain,
)} reputation`, )} reputation`,
@ -1139,41 +1159,39 @@ export function NetscriptSingularity(
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("createProgram", txt); workerScript.log("createProgram", () => txt);
} }
name = name.toLowerCase(); name = name.toLowerCase();
let p = null; const p = Object.values(Programs).find((p) => p.name.toLowerCase() === name);
for (const key in Programs) {
if (Programs[key].name.toLowerCase() == name) {
p = Programs[key];
}
}
if (p == null) { if (p == null) {
workerScript.log("createProgram", `The specified program does not exist: '${name}`); workerScript.log("createProgram", () => `The specified program does not exist: '${name}`);
return false; return false;
} }
if (player.hasProgram(p.name)) { if (player.hasProgram(p.name)) {
workerScript.log("createProgram", `You already have the '${p.name}' program`); workerScript.log("createProgram", () => `You already have the '${p.name}' program`);
return false; return false;
} }
const create = p.create; const create = p.create;
if (create === null) { if (create === null) {
workerScript.log("createProgram", `You cannot create the '${p.name}' program`); workerScript.log("createProgram", () => `You cannot create the '${p.name}' program`);
return false; return false;
} }
if (!create.req(player)) { if (!create.req(player)) {
workerScript.log("createProgram", `Hacking level is too low to create '${p.name}' (level ${create.level} req)`); workerScript.log(
"createProgram",
() => `Hacking level is too low to create '${p.name}' (level ${create.level} req)`,
);
return false; return false;
} }
player.startCreateProgramWork(Router, p.name, create.time, create.level); player.startCreateProgramWork(Router, p.name, create.time, create.level);
workerScript.log("createProgram", `Began creating program: '${name}'`); workerScript.log("createProgram", () => `Began creating program: '${name}'`);
return true; return true;
}, },
commitCrime: function (crimeRoughName: any): any { commitCrime: function (crimeRoughName: any): any {
@ -1182,7 +1200,7 @@ export function NetscriptSingularity(
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("commitCrime", txt); workerScript.log("commitCrime", () => txt);
} }
// Set Location to slums // Set Location to slums
@ -1193,7 +1211,7 @@ export function NetscriptSingularity(
// couldn't find crime // couldn't find crime
throw helper.makeRuntimeErrorMsg("commitCrime", `Invalid crime: '${crimeRoughName}'`); throw helper.makeRuntimeErrorMsg("commitCrime", `Invalid crime: '${crimeRoughName}'`);
} }
workerScript.log("commitCrime", `Attempting to commit ${crime.name}...`); workerScript.log("commitCrime", () => `Attempting to commit ${crime.name}...`);
return crime.commit(Router, player, 1, workerScript); return crime.commit(Router, player, 1, workerScript);
}, },
getCrimeChance: function (crimeRoughName: any): any { getCrimeChance: function (crimeRoughName: any): any {

@ -25,7 +25,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
const checkSleeveNumber = function (func: any, sleeveNumber: any): void { const checkSleeveNumber = function (func: any, sleeveNumber: any): void {
if (sleeveNumber >= player.sleeves.length || sleeveNumber < 0) { if (sleeveNumber >= player.sleeves.length || sleeveNumber < 0) {
const msg = `Invalid sleeve number: ${sleeveNumber}`; const msg = `Invalid sleeve number: ${sleeveNumber}`;
workerScript.log(func, msg); workerScript.log(func, () => msg);
throw helper.makeRuntimeErrorMsg(`sleeve.${func}`, msg); throw helper.makeRuntimeErrorMsg(`sleeve.${func}`, msg);
} }
}; };

@ -315,18 +315,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
checkTixApiAccess("purchase4SMarketData"); checkTixApiAccess("purchase4SMarketData");
if (player.has4SData) { if (player.has4SData) {
workerScript.log("purchase4SMarketData", "Already purchased 4S Market Data."); workerScript.log("purchase4SMarketData", () => "Already purchased 4S Market Data.");
return true; return true;
} }
if (player.money < getStockMarket4SDataCost()) { if (player.money < getStockMarket4SDataCost()) {
workerScript.log("purchase4SMarketData", "Not enough money to purchase 4S Market Data."); workerScript.log("purchase4SMarketData", () => "Not enough money to purchase 4S Market Data.");
return false; return false;
} }
player.has4SData = true; player.has4SData = true;
player.loseMoney(getStockMarket4SDataCost(), "stock"); player.loseMoney(getStockMarket4SDataCost(), "stock");
workerScript.log("purchase4SMarketData", "Purchased 4S Market Data"); workerScript.log("purchase4SMarketData", () => "Purchased 4S Market Data");
return true; return true;
}, },
purchase4SMarketDataTixApi: function () { purchase4SMarketDataTixApi: function () {
@ -334,18 +334,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
checkTixApiAccess("purchase4SMarketDataTixApi"); checkTixApiAccess("purchase4SMarketDataTixApi");
if (player.has4SDataTixApi) { if (player.has4SDataTixApi) {
workerScript.log("purchase4SMarketDataTixApi", "Already purchased 4S Market Data TIX API"); workerScript.log("purchase4SMarketDataTixApi", () => "Already purchased 4S Market Data TIX API");
return true; return true;
} }
if (player.money < getStockMarket4STixApiCost()) { if (player.money < getStockMarket4STixApiCost()) {
workerScript.log("purchase4SMarketDataTixApi", "Not enough money to purchase 4S Market Data TIX API"); workerScript.log("purchase4SMarketDataTixApi", () => "Not enough money to purchase 4S Market Data TIX API");
return false; return false;
} }
player.has4SDataTixApi = true; player.has4SDataTixApi = true;
player.loseMoney(getStockMarket4STixApiCost(), "stock"); player.loseMoney(getStockMarket4STixApiCost(), "stock");
workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API"); workerScript.log("purchase4SMarketDataTixApi", () => "Purchased 4S Market Data TIX API");
return true; return true;
}, },
}; };

@ -535,7 +535,7 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
} }
killWorkerScript(s); killWorkerScript(s);
w.log("", "Script finished running"); w.log("", () => "Script finished running");
}).catch(function (w) { }).catch(function (w) {
if (w instanceof Error) { if (w instanceof Error) {
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer"); dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
@ -561,9 +561,9 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
msg += errorMsg; msg += errorMsg;
dialogBoxCreate(msg); dialogBoxCreate(msg);
w.log("", "Script crashed with runtime error"); w.log("", () => "Script crashed with runtime error");
} else { } else {
w.log("", "Script killed"); w.log("", () => "Script killed");
return; // Already killed, so stop here return; // Already killed, so stop here
} }
w.running = false; w.running = false;
@ -645,7 +645,7 @@ export function runScriptFromScript(
} }
if (typeof scriptname !== "string" || !Array.isArray(args)) { if (typeof scriptname !== "string" || !Array.isArray(args)) {
workerScript.log(caller, `Invalid arguments: scriptname='${scriptname} args='${args}'`); workerScript.log(caller, () => `Invalid arguments: scriptname='${scriptname} args='${args}'`);
console.error(`runScriptFromScript() failed due to invalid arguments`); console.error(`runScriptFromScript() failed due to invalid arguments`);
return 0; return 0;
} }
@ -658,14 +658,14 @@ export function runScriptFromScript(
// Check if the script is already running // Check if the script is already running
const runningScriptObj = server.getRunningScript(scriptname, args); const runningScriptObj = server.getRunningScript(scriptname, args);
if (runningScriptObj != null) { if (runningScriptObj != null) {
workerScript.log(caller, `'${scriptname}' is already running on '${server.hostname}'`); workerScript.log(caller, () => `'${scriptname}' is already running on '${server.hostname}'`);
return 0; return 0;
} }
// 'null/undefined' arguments are not allowed // 'null/undefined' arguments are not allowed
for (let i = 0; i < args.length; ++i) { for (let i = 0; i < args.length; ++i) {
if (args[i] == null) { if (args[i] == null) {
workerScript.log(caller, "Cannot execute a script with null/undefined as an argument"); workerScript.log(caller, () => "Cannot execute a script with null/undefined as an argument");
return 0; return 0;
} }
} }
@ -684,11 +684,12 @@ export function runScriptFromScript(
const ramAvailable = server.maxRam - server.ramUsed; const ramAvailable = server.maxRam - server.ramUsed;
if (server.hasAdminRights == false) { if (server.hasAdminRights == false) {
workerScript.log(caller, `You do not have root access on '${server.hostname}'`); workerScript.log(caller, () => `You do not have root access on '${server.hostname}'`);
return 0; return 0;
} else if (ramUsage > ramAvailable) { } else if (ramUsage > ramAvailable) {
workerScript.log( workerScript.log(
caller, caller,
() =>
`Cannot run script '${scriptname}' (t=${threads}) on '${server.hostname}' because there is not enough available RAM!`, `Cannot run script '${scriptname}' (t=${threads}) on '${server.hostname}' because there is not enough available RAM!`,
); );
return 0; return 0;
@ -696,7 +697,7 @@ export function runScriptFromScript(
// Able to run script // Able to run script
workerScript.log( workerScript.log(
caller, caller,
`'${scriptname}' on '${server.hostname}' with ${threads} threads and args: ${arrayToString(args)}.`, () => `'${scriptname}' on '${server.hostname}' with ${threads} threads and args: ${arrayToString(args)}.`,
); );
const runningScriptObj = new RunningScript(script, args); const runningScriptObj = new RunningScript(script, args);
runningScriptObj.threads = threads; runningScriptObj.threads = threads;
@ -706,6 +707,6 @@ export function runScriptFromScript(
break; break;
} }
workerScript.log(caller, `Could not find script '${scriptname}' on '${server.hostname}'`); workerScript.log(caller, () => `Could not find script '${scriptname}' on '${server.hostname}'`);
return 0; return 0;
} }

@ -51,7 +51,7 @@ export function buyStock(
} }
if (stock == null || isNaN(shares)) { if (stock == null || isNaN(shares)) {
if (workerScript) { if (workerScript) {
workerScript.log("buyStock", `Invalid arguments: stock='${stock}' shares='${shares}'`); workerScript.log("buyStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer"); dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
} }
@ -68,6 +68,7 @@ export function buyStock(
if (workerScript) { if (workerScript) {
workerScript.log( workerScript.log(
"buyStock", "buyStock",
() =>
`You do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}.`, `You do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}.`,
); );
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
@ -86,6 +87,7 @@ export function buyStock(
if (workerScript) { if (workerScript) {
workerScript.log( workerScript.log(
"buyStock", "buyStock",
() =>
`Purchasing '${shares + stock.playerShares + stock.playerShortShares}' shares would exceed ${ `Purchasing '${shares + stock.playerShares + stock.playerShortShares}' shares would exceed ${
stock.symbol stock.symbol
}'s maximum (${stock.maxShares}) number of shares`, }'s maximum (${stock.maxShares}) number of shares`,
@ -116,7 +118,7 @@ export function buyStock(
`Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney( `Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(
totalPrice, totalPrice,
)}. ` + `Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`; )}. ` + `Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`;
workerScript.log("buyStock", resultTxt); workerScript.log("buyStock", () => resultTxt);
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
dialogBoxCreate( dialogBoxCreate(
<> <>
@ -146,7 +148,7 @@ export function sellStock(
// Sanitize/Validate arguments // Sanitize/Validate arguments
if (stock == null || shares < 0 || isNaN(shares)) { if (stock == null || shares < 0 || isNaN(shares)) {
if (workerScript) { if (workerScript) {
workerScript.log("sellStock", `Invalid arguments: stock='${stock}' shares='${shares}'`); workerScript.log("sellStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
dialogBoxCreate( dialogBoxCreate(
"Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer", "Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer",
@ -192,7 +194,7 @@ export function sellStock(
const resultTxt = const resultTxt =
`Sold ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` + `Sold ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
`After commissions, you gained a total of ${numeralWrapper.formatMoney(gains)}.`; `After commissions, you gained a total of ${numeralWrapper.formatMoney(gains)}.`;
workerScript.log("sellStock", resultTxt); workerScript.log("sellStock", () => resultTxt);
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
dialogBoxCreate( dialogBoxCreate(
<> <>
@ -226,7 +228,7 @@ export function shortStock(
} }
if (stock == null || isNaN(shares)) { if (stock == null || isNaN(shares)) {
if (workerScript) { if (workerScript) {
workerScript.log("shortStock", `Invalid arguments: stock='${stock}' shares='${shares}'`); workerScript.log("shortStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
} else if (opts.suppressDialog !== true) { } else if (opts.suppressDialog !== true) {
dialogBoxCreate( dialogBoxCreate(
"Failed to initiate a short position in a stock. This is probably " + "Failed to initiate a short position in a stock. This is probably " +
@ -245,6 +247,7 @@ export function shortStock(
if (workerScript) { if (workerScript) {
workerScript.log( workerScript.log(
"shortStock", "shortStock",
() =>
"You do not have enough " + "You do not have enough " +
"money to purchase this short position. You need " + "money to purchase this short position. You need " +
numeralWrapper.formatMoney(totalPrice), numeralWrapper.formatMoney(totalPrice),
@ -265,6 +268,7 @@ export function shortStock(
if (workerScript) { if (workerScript) {
workerScript.log( workerScript.log(
"shortStock", "shortStock",
() =>
`This '${shares + stock.playerShares + stock.playerShortShares}' short shares would exceed ${ `This '${shares + stock.playerShares + stock.playerShortShares}' short shares would exceed ${
stock.symbol stock.symbol
}'s maximum (${stock.maxShares}) number of shares.`, }'s maximum (${stock.maxShares}) number of shares.`,
@ -296,7 +300,7 @@ export function shortStock(
CONSTANTS.StockMarketCommission, CONSTANTS.StockMarketCommission,
)} ` + )} ` +
`in commission fees.`; `in commission fees.`;
workerScript.log("shortStock", resultTxt); workerScript.log("shortStock", () => resultTxt);
} else if (!opts.suppressDialog) { } else if (!opts.suppressDialog) {
dialogBoxCreate( dialogBoxCreate(
<> <>
@ -325,7 +329,7 @@ export function sellShort(
): boolean { ): boolean {
if (stock == null || isNaN(shares) || shares < 0) { if (stock == null || isNaN(shares) || shares < 0) {
if (workerScript) { if (workerScript) {
workerScript.log("sellShort", `Invalid arguments: stock='${stock}' shares='${shares}'`); workerScript.log("sellShort", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
} else if (!opts.suppressDialog) { } else if (!opts.suppressDialog) {
dialogBoxCreate( dialogBoxCreate(
"Failed to sell a short position in a stock. This is probably " + "Failed to sell a short position in a stock. This is probably " +
@ -349,7 +353,7 @@ export function sellShort(
if (workerScript) { if (workerScript) {
workerScript.log( workerScript.log(
"sellShort", "sellShort",
`Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug`, () => `Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug`,
); );
} else if (!opts.suppressDialog) { } else if (!opts.suppressDialog) {
dialogBoxCreate( dialogBoxCreate(
@ -383,7 +387,7 @@ export function sellShort(
const resultTxt = const resultTxt =
`Sold your short position of ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` + `Sold your short position of ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
`After commissions, you gained a total of ${numeralWrapper.formatMoney(totalGain)}`; `After commissions, you gained a total of ${numeralWrapper.formatMoney(totalGain)}`;
workerScript.log("sellShort", resultTxt); workerScript.log("sellShort", () => resultTxt);
} else if (!opts.suppressDialog) { } else if (!opts.suppressDialog) {
dialogBoxCreate( dialogBoxCreate(
<> <>

@ -37,7 +37,7 @@ export function placeOrder(
): boolean { ): boolean {
if (!(stock instanceof Stock)) { if (!(stock instanceof Stock)) {
if (workerScript) { if (workerScript) {
workerScript.log("placeOrder", `Invalid stock: '${stock}'`); workerScript.log("placeOrder", () => `Invalid stock: '${stock}'`);
} else { } else {
dialogBoxCreate(`ERROR: Invalid stock passed to placeOrder() function`); dialogBoxCreate(`ERROR: Invalid stock passed to placeOrder() function`);
} }
@ -45,7 +45,7 @@ export function placeOrder(
} }
if (typeof shares !== "number" || typeof price !== "number") { if (typeof shares !== "number" || typeof price !== "number") {
if (workerScript) { if (workerScript) {
workerScript.log("placeOrder", `Invalid arguments: shares='${shares}' price='${price}'`); workerScript.log("placeOrder", () => `Invalid arguments: shares='${shares}' price='${price}'`);
} else { } else {
dialogBoxCreate("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument"); dialogBoxCreate("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument");
} }