From e9cceb5e55094486f9bf7dae7a2f8697e6a743a0 Mon Sep 17 00:00:00 2001 From: Alain Bryden <2285037+alainbryden@users.noreply.github.com> Date: Sat, 23 Jul 2022 11:56:24 -0300 Subject: [PATCH] Remove deprecated references to singularity functions not in the singularity namespace --- Remote/manualhack-target.js | 2 +- Tasks/backdoor-all-servers.js | 6 +-- Tasks/backdoor-all-servers.js.backdoor-one.js | 2 +- Tasks/program-manager.js | 2 +- Tasks/ram-manager.js | 6 +-- Tasks/tor-manager.js | 2 +- ascend.js | 16 +++---- autopilot.js | 8 ++-- bladeburner.js | 4 +- casino.js | 4 +- crime.js | 4 +- daemon.js | 8 ++-- faction-manager.js | 26 +++++------ farm-intelligence.js | 2 +- gangs.js | 8 ++-- sleeve.js | 2 +- stanek.js | 4 +- work-for-factions.js | 44 +++++++++---------- 18 files changed, 75 insertions(+), 75 deletions(-) diff --git a/Remote/manualhack-target.js b/Remote/manualhack-target.js index 011d196b..dc038568 100644 --- a/Remote/manualhack-target.js +++ b/Remote/manualhack-target.js @@ -12,7 +12,7 @@ export async function main(ns) { if (sleepDuration > 0) await ns.sleep(sleepDuration); do { - if (!await ns.manualHack() && !disableToastWarnings) + if (!await ns.singularity.manualHack() && !disableToastWarnings) ns.toast(`Warning, hack stole 0 money. Might be a misfire. ${JSON.stringify(ns.args)}`, 'warning'); if (loop) await ns.sleep(cycleTime - expectedDuration); } while (loop); diff --git a/Tasks/backdoor-all-servers.js b/Tasks/backdoor-all-servers.js index 969803a2..893b79d7 100644 --- a/Tasks/backdoor-all-servers.js +++ b/Tasks/backdoor-all-servers.js @@ -39,7 +39,7 @@ export let main = async ns => { ns.print(`Hopping to ${server}`); anyConnected = true; for (let hop of routes[server]) - ns.connect(hop); + ns.singularity.connect(hop); if (server === "w0r1d_d43m0n") { ns.alert("Ready to hack w0r1d_d43m0n!"); while (true) await ns.sleep(10000); // Sleep forever so the script isn't run multiple times to create multiple overlapping alerts @@ -50,12 +50,12 @@ export let main = async ns => { if (pid === 0) return ns.print(`Couldn't initiate a new backdoor of "${server}"" (insufficient RAM?). Will try again later.`); await ns.sleep(spawnDelay); // Wait some time for the external backdoor script to initiate its backdoor of the current connected server - ns.connect("home"); + ns.singularity.connect("home"); } } catch (err) { ns.tprint(String(err)); } finally { if (anyConnected) - ns.connect("home"); + ns.singularity.connect("home"); } }; \ No newline at end of file diff --git a/Tasks/backdoor-all-servers.js.backdoor-one.js b/Tasks/backdoor-all-servers.js.backdoor-one.js index 49bf2222..25ab50b6 100644 --- a/Tasks/backdoor-all-servers.js.backdoor-one.js +++ b/Tasks/backdoor-all-servers.js.backdoor-one.js @@ -2,7 +2,7 @@ export async function main(ns) { let target = ns.args.length > 0 ? ns.args[0] : '(unspecified server)'; try { - await ns.installBackdoor(); + await ns.singularity.installBackdoor(); ns.toast(`Backdoored ${target}`, 'success'); } catch (err) { diff --git a/Tasks/program-manager.js b/Tasks/program-manager.js index 938d9104..45a9ceae 100644 --- a/Tasks/program-manager.js +++ b/Tasks/program-manager.js @@ -14,7 +14,7 @@ export async function main(ns) { do { let foundMissingProgram = false; for (const prog of programNames) { - if (!ns.fileExists(prog, "home") && ns.purchaseProgram(prog)) + if (!ns.fileExists(prog, "home") && ns.singularity.purchaseProgram(prog)) ns.toast(`Purchased ${prog}`, 'success'); else if (keepRunning) foundMissingProgram = true; diff --git a/Tasks/ram-manager.js b/Tasks/ram-manager.js index e1c237ea..c867e2fd 100644 --- a/Tasks/ram-manager.js +++ b/Tasks/ram-manager.js @@ -22,15 +22,15 @@ export async function main(ns) { return log(ns, `ERROR: One of the arguments could not be parsed as a number: ${JSON.stringify(options)}`, true, 'error'); // Quickly buy as many upgrades as we can within the budget do { - let cost = await getNsDataThroughFile(ns, `ns.getUpgradeHomeRamCost()`, `/Temp/getUpgradeHomeRamCost.txt`); - let currentRam = await getNsDataThroughFile(ns, `ns.getServerMaxRam(ns.args[0])`, `/Temp/getServerMaxRam.txt`, ["home"]); + let cost = await getNsDataThroughFile(ns, `ns.singularity.getUpgradeHomeRamCost()`, `/Temp/getUpgradeHomeRamCost.txt`); + let currentRam = await getNsDataThroughFile(ns, `ns.singularity.getServerMaxRam(ns.args[0])`, `/Temp/getServerMaxRam.txt`, ["home"]); if (cost >= Number.MAX_VALUE || currentRam == max_ram) return log(ns, `INFO: We're at max home RAM (${formatRam(currentRam)})`); const nextRam = currentRam * 2; const upgradeDesc = `home RAM from ${formatRam(currentRam)} to ${formatRam(nextRam)}`; if (spendable < cost) return log(ns, `Money we're allowed to spend (${formatMoney(spendable)}) is less than the cost (${formatMoney(cost)}) to upgrade ${upgradeDesc}`); - if (!(await getNsDataThroughFile(ns, `ns.upgradeHomeRam()`, `/Temp/upgradeHomeRam.txt`))) + if (!(await getNsDataThroughFile(ns, `ns.singularity.upgradeHomeRam()`, `/Temp/upgradeHomeRam.txt`))) return log(ns, `ERROR: Failed to upgrade ${upgradeDesc} thinking we could afford it ` + `(cost: ${formatMoney(cost)} cash: ${formatMoney(money)} budget: ${formatMoney(spendable)})`, true, 'error'); // Otherwise, we've successfully upgraded home ram. diff --git a/Tasks/tor-manager.js b/Tasks/tor-manager.js index e67b5db7..90887089 100644 --- a/Tasks/tor-manager.js +++ b/Tasks/tor-manager.js @@ -17,7 +17,7 @@ export async function main(ns) { ns.toast(`Purchased the Tor router!`, 'success'); break; } - ns.purchaseTor(); + ns.singularity.purchaseTor(); if (keepRunning) await ns.sleep(interval); } diff --git a/ascend.js b/ascend.js index 6a69170f..385e215e 100644 --- a/ascend.js +++ b/ascend.js @@ -41,7 +41,7 @@ export async function main(ns) { await waitForProcessToComplete(ns, pid, true); // Wait for the script to shut down, indicating it has shut down other scripts // Stop the current action so that we're no longer spending money (if training) and can collect rep earned (if working) - await getNsDataThroughFile(ns, 'ns.stopAction()', '/Temp/stop-player-action.txt'); + await getNsDataThroughFile(ns, 'ns.singularity.stopAction()', '/Temp/stop-player-action.txt'); // Clear any global reserve so that all money can be spent await ns.write(getFilePath('reserve.txt'), '0', "w"); @@ -84,8 +84,8 @@ export async function main(ns) { // Sanity check, if we are not slated to install any augmentations, ABORT // Get owned + purchased augmentations, then installed augmentations. Ensure there's a difference - let purchasedAugmentations = await getNsDataThroughFile(ns, 'ns.getOwnedAugmentations(true)', '/Temp/player-augs-purchased.txt'); - let installedAugmentations = await getNsDataThroughFile(ns, 'ns.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); + let purchasedAugmentations = await getNsDataThroughFile(ns, 'ns.singularity.getOwnedAugmentations(true)', '/Temp/player-augs-purchased.txt'); + let installedAugmentations = await getNsDataThroughFile(ns, 'ns.singularity.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); let noAugsToInstall = purchasedAugmentations.length == installedAugmentations.length; if (noAugsToInstall && !options['allow-soft-reset']) return log(ns, `ERROR: See above faction-manager.js logs - there are no new purchased augs. ` + @@ -117,13 +117,13 @@ export async function main(ns) { // STEP 7: Buy whatever home CPU upgrades we can afford log(ns, 'Try Upgrade Home Cores...', true, 'info'); - pid = await runCommand(ns, `while(ns.upgradeHomeCores()); { await ns.sleep(10); }`, '/Temp/upgrade-home-ram.js'); + pid = await runCommand(ns, `while(ns.singularity.upgradeHomeCores()); { await ns.sleep(10); }`, '/Temp/upgrade-home-ram.js'); await waitForProcessToComplete(ns, pid, true); // Wait for the script to shut down, indicating it has bought all it can. // STEP 8: Join every faction we've been invited to (gives a little INT XP) - let invites = await getNsDataThroughFile(ns, 'ns.checkFactionInvitations()', '/Temp/faction-invitations.txt'); + let invites = await getNsDataThroughFile(ns, 'ns.singularity.checkFactionInvitations()', '/Temp/faction-invitations.txt'); if (invites.length > 0) { - pid = await runCommand(ns, 'ns.args.forEach(f => ns.joinFaction(f))', '/Temp/join-factions.js', invites); + pid = await runCommand(ns, 'ns.args.forEach(f => ns.singularity.joinFaction(f))', '/Temp/join-factions.js', invites); await waitForProcessToComplete(ns, pid, true); } @@ -160,9 +160,9 @@ export async function main(ns) { // Default script (if none is specified) is stanek.js if we have it (which in turn will spawn daemon.js when done) (purchasedAugmentations.includes(`Stanek's Gift - Genesis`) ? getFilePath('stanek.js') : getFilePath('daemon.js')); if (noAugsToInstall) - await runCommand(ns, `ns.softReset(ns.args[0])`, '/Temp/soft-reset.js', [resetScript]); + await runCommand(ns, `ns.singularity.softReset(ns.args[0])`, '/Temp/soft-reset.js', [resetScript]); else - await runCommand(ns, `ns.installAugmentations(ns.args[0])`, '/Temp/install-augmentations.js', [resetScript]); + await runCommand(ns, `ns.singularity.installAugmentations(ns.args[0])`, '/Temp/install-augmentations.js', [resetScript]); } else log(ns, `SUCCESS: Ready to ascend. In the future, you can run with --reset (or --install-augmentations) ` + `to actually perform the reset automatically.`, true, 'success'); diff --git a/autopilot.js b/autopilot.js index fc54b671..73fc0aee 100644 --- a/autopilot.js +++ b/autopilot.js @@ -97,7 +97,7 @@ async function startUp(ns) { unlockedSFs = await getActiveSourceFiles(ns, true); try { installedAugmentations = !(4 in unlockedSFs) ? [] : - await getNsDataThroughFile(ns, 'ns.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); + await getNsDataThroughFile(ns, 'ns.singularity.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); if (!(4 in unlockedSFs)) log(ns, `WARNING: This script requires SF4 (singularity) functions to assess purchasable augmentations ascend automatically. ` + `Some functionality will be diabled and you'll have to manage working for factions, purchasing, and installing augmentations yourself.`, true); @@ -176,7 +176,7 @@ async function checkOnDaedalusStatus(ns, player, stocksValue) { return reserveForDaedalus = false; } if (reserveForDaedalus) { // Already waiting for a Daedalus invite, try joining them - return (4 in unlockedSFs) ? await getNsDataThroughFile(ns, 'ns.joinFaction(ns.args[0])', '/Temp/joinFaction.txt', ["Daedalus"]) : + return (4 in unlockedSFs) ? await getNsDataThroughFile(ns, 'ns.singularity.joinFaction(ns.args[0])', '/Temp/joinFaction.txt', ["Daedalus"]) : log(ns, "INFO: Please manually join the faction 'Daedalus' as soon as possible to proceed", false, 'info'); } const bitNodeMults = await tryGetBitNodeMultipliers(ns, false) || { DaedalusAugsRequirement: 1 }; @@ -432,7 +432,7 @@ async function maybeDoCasino(ns, player) { await killScript(ns, 'work-for-factions.js'); // Kill any action, in case we are studying or working out, as it might steal focus or funds before we can bet it at the casino. if (4 in unlockedSFs) // No big deal if we can't, casino.js has logic to find the stop button and click it. - await getNsDataThroughFile(ns, `ns.stopAction()`, '/Temp/stop-action.txt'); + await getNsDataThroughFile(ns, `ns.singularity.stopAction()`, '/Temp/stop-action.txt'); const pid = launchScriptHelper(ns, 'casino.js', ['--kill-all-scripts', true, '--on-completion-script', ns.getScriptName()]); if (pid) { @@ -567,7 +567,7 @@ async function shouldDelayInstall(ns, player, facmanOutput) { // enough rep, or enough money to donate for rep to buy TRP (Reminder: donations always unlocked in BN8) if (player.bitNodeN == 8 && player.factions.includes("Daedalus") && (wdHack || 0) == 0) { // Sanity check, ensure the player hasn't manually purchased (but not yet installed) TRP - const ownedAugmentations = await getNsDataThroughFile(ns, `ns.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); + const ownedAugmentations = await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); if (!facmanOutput.affordable_augs.includes("The Red Pill") && !ownedAugmentations.includes("The Red Pill")) { setStatus(ns, `Not installing until we have enough Daedalus rep to install TRP on our next reset.`) return true; diff --git a/bladeburner.js b/bladeburner.js index fda974d3..face4455 100644 --- a/bladeburner.js +++ b/bladeburner.js @@ -107,7 +107,7 @@ async function gatherBladeburnerInfo(ns) { maxRankNeeded = blackOpsRanks[remainingBlackOpsNames[remainingBlackOpsNames.length - 1]]; // Check if we have the aug that lets us do bladeburner while otherwise busy haveSimulacrum = !(4 in ownedSourceFiles) ? true : // If player doesn't have SF4, we cannot check, so hope for the best. - await getNsDataThroughFile(ns, `ns.getOwnedAugmentations().includes("${simulacrumAugName}")`, '/Temp/bladeburner-hasSimulacrum.txt'); + await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations().includes("${simulacrumAugName}")`, '/Temp/bladeburner-hasSimulacrum.txt'); // Initialize some flags that may change over time lastAssignedTask = null; lastBlackOpComplete = false; // Flag will track whether we've notified the user that the last black-op is ready @@ -404,7 +404,7 @@ let lastCanWorkCheckIdle = true; async function canDoBladeburnerWork(ns) { if (options['ignore-busy-status'] || haveSimulacrum) return true; // Check if the player is busy doing something else - const busy = await getNsDataThroughFile(ns, 'ns.isBusy()', '/Temp/isBusy.txt'); + const busy = await getNsDataThroughFile(ns, 'ns.singularity.isBusy()', '/Temp/isBusy.txt'); if (!busy) return lastCanWorkCheckIdle = true; if (lastCanWorkCheckIdle) log(ns, `WARNING: Cannot perform Bladeburner actions because the player is busy ` + diff --git a/casino.js b/casino.js index da49e601..faf1961b 100644 --- a/casino.js +++ b/casino.js @@ -44,7 +44,7 @@ export async function main(ns) { // Step 1: Go to Aevum if we aren't already there. (Must be done manually if you don't have SF4) if (ns.getPlayer().city != "Aevum") { try { - if (ns.getPlayer().money < 200000 || !(await getNsDataThroughFile(ns, 'ns.travelToCity(ns.args[0])', '/Temp/travelToCity.txt', ["Aevum"]))) + if (ns.getPlayer().money < 200000 || !(await getNsDataThroughFile(ns, 'ns.singularity.travelToCity(ns.args[0])', '/Temp/travelToCity.txt', ["Aevum"]))) return tailAndLog(ns, "ERROR: Sorry, you need at least 200k to travel to the casino."); } catch (err) { return tailAndLog(ns, "ERROR: You must manually travel to to Aevum to use this script until you get SF4"); @@ -77,7 +77,7 @@ export async function main(ns) { await click(await findRetry(ns, "//div[(@role = 'button') and (contains(., 'City'))]")); await click(await findRetry(ns, "//span[@aria-label = 'Iker Molina Casino']")); } catch { // Use SF4 as a fallback, it's more reliable. - try { await getNsDataThroughFile(ns, 'ns.goToLocation(ns.args[0])', '/Temp/goToLocation.txt', ["Iker Molina Casino"]); } + try { await getNsDataThroughFile(ns, 'ns.singularity.goToLocation(ns.args[0])', '/Temp/goToLocation.txt', ["Iker Molina Casino"]); } catch { return tailAndLog(ns, "ERROR: Failed to travel to the casino both using UI navigation and using SF4 as a fall-back."); } } // Step 2.3: Try to start the blackjack game diff --git a/crime.js b/crime.js index 06125139..fa0a1d53 100644 --- a/crime.js +++ b/crime.js @@ -22,7 +22,7 @@ async function legacyAutoCrime(ns, crime = "mug") { let interval = 100; while (true) { let maxBusyLoops = 100; - while ((await getNsDataThroughFile(ns, `ns.isBusy()`, '/Temp/isBusy.txt')) && maxBusyLoops-- > 0) { + while ((await getNsDataThroughFile(ns, `ns.singularity.isBusy()`, '/Temp/isBusy.txt')) && maxBusyLoops-- > 0) { await ns.sleep(interval); ns.print("Waiting to no longer be busy..."); } @@ -31,7 +31,7 @@ async function legacyAutoCrime(ns, crime = "mug") { return; } ns.tail(); // Force a tail window open when auto-criming, or else it's very difficult to stop if it was accidentally closed. - let wait = 10 + (await getNsDataThroughFile(ns, 'ns.commitCrime(ns.args[0])', '/Temp/commitCrime.txt', [crime])); + let wait = 10 + (await getNsDataThroughFile(ns, 'ns.singularity.commitCrime(ns.args[0])', '/Temp/commitCrime.txt', [crime])); ns.print(`Karma: ${formatNumberShort(ns.heart.break())} Committing crime \"${crime}\" and sleeping for ${formatDuration(wait)}...`); await ns.sleep(wait); } diff --git a/daemon.js b/daemon.js index 8cae7895..8c648727 100644 --- a/daemon.js +++ b/daemon.js @@ -350,14 +350,14 @@ async function kickstartHackXp(ns) { log(ns, `INFO: Studying for ${studyTime} seconds to kickstart hack XP and speed up initial cycle times. (set --initial-study-time 0 to disable this step.)`); const money = ns.getServerMoneyAvailable("home") if (money >= 200000) // If we can afford to travel, we're probably far enough along that it's worthwhile going to Volhaven where ZB university is. - await getNsDataThroughFile(ns, `ns.travelToCity("Volhaven")`, '/Temp/travel-to-city.txt'); + await getNsDataThroughFile(ns, `ns.singularity.travelToCity("Volhaven")`, '/Temp/travel-to-city.txt'); const playerInfo = await getPlayerInfo(); // Update player stats to be certain of our new location. const university = playerInfo.city == "Sector-12" ? "Rothman University" : playerInfo.city == "Aevum" ? "Summit University" : playerInfo.city == "Volhaven" ? "ZB Institute of Technology" : null; if (!university) log(ns, `INFO: Cannot study, because you are in city ${playerInfo.city} which has no known university, and you cannot afford to travel to another city.`); else { const course = playerInfo.city == "Sector-12" ? "Study Computer Science" : "Algorithms"; // Assume if we are still in Sector-12 we are poor and should only take the free course - await getNsDataThroughFile(ns, `ns.universityCourse(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/study.txt', [university, course, false]); + await getNsDataThroughFile(ns, `ns.singularity.universityCourse(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/study.txt', [university, course, false]); startedStudying = true; await ns.sleep(studyTime * 1000); // Wait for studies to affect Hack XP. This will often greatly reduce time-to-hack/grow/weaken, and avoid a slow first cycle } @@ -388,7 +388,7 @@ async function kickstartHackXp(ns) { log(ns, 'WARNING: Encountered an error while trying to kickstart hack XP (low RAM issues perhaps?)', false, 'warning'); } finally { // Ensure we stop studying (in case no other running scripts end up stealing focus, so we don't keep studying forever) - if (startedStudying) await getNsDataThroughFile(ns, `ns.stopAction()`, '/Temp/stop-action.txt'); + if (startedStudying) await getNsDataThroughFile(ns, `ns.singularity.stopAction()`, '/Temp/stop-action.txt'); studying = false; // This will allow work-for-faction to launch } } @@ -797,7 +797,7 @@ async function refreshDynamicServerData(ns, serverNames) { dictServerProfitInfo = Object.fromEntries(JSON.parse(dictServerProfitInfo).map(s => [s.hostname, s])); //ns.print(dictServerProfitInfo); if (options.i) - currentTerminalServer = getServerByName(await getNsDataThroughFile(ns, 'ns.getCurrentServer()', '/Temp/terminal-server.txt')); + currentTerminalServer = getServerByName(await getNsDataThroughFile(ns, 'ns.singularity.getCurrentServer()', '/Temp/terminal-server.txt')); } class Server { diff --git a/faction-manager.js b/faction-manager.js index c7f7e2ca..9c21059a 100644 --- a/faction-manager.js +++ b/faction-manager.js @@ -131,8 +131,8 @@ export async function main(ns) { joinedFactions = ignorePlayerData ? [] : playerData.factions; log(ns, 'In factions: ' + joinedFactions); // Get owned augmentations (whether they've been installed or not). Ignore strNF because you can always buy more. - ownedAugmentations = await getNsDataThroughFile(ns, 'ns.getOwnedAugmentations(true)', '/Temp/player-augs-purchased.txt'); - const installedAugmentations = await getNsDataThroughFile(ns, 'ns.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); + ownedAugmentations = await getNsDataThroughFile(ns, 'ns.singularity.getOwnedAugmentations(true)', '/Temp/player-augs-purchased.txt'); + const installedAugmentations = await getNsDataThroughFile(ns, 'ns.singularity.getOwnedAugmentations()', '/Temp/player-augs-installed.txt'); augsAwaitingInstall = ownedAugmentations.length - installedAugmentations.length; if (options['neuroflux-disabled']) omitAugs.push(strNF); simulatedOwnedAugmentations = ignorePlayerData ? [] : ownedAugmentations.filter(a => a != strNF); @@ -233,7 +233,7 @@ const dictCommand = (command) => `Object.fromEntries(ns.args.map(o => [o, ${comm /** @param {NS} ns **/ async function updateFactionData(ns, factionsToOmit) { // Gather a list of all faction names to collect information about. Start with any player joined and invited factions - const invitations = await getNsDataThroughFile(ns, 'ns.checkFactionInvitations()', '/Temp/checkFactionInvitations.txt'); + const invitations = await getNsDataThroughFile(ns, 'ns.singularity.checkFactionInvitations()', '/Temp/checkFactionInvitations.txt'); factionNames = joinedFactions.concat(invitations); // Add in factions the user hasn't seen. All factions by default, or a small subset of easy-access factions if --hide-locked-factions is set factionNames.push(...(options['hide-locked-factions'] ? easyAccessFactions : allFactions).filter(f => !factionNames.includes(f))); @@ -246,9 +246,9 @@ async function updateFactionData(ns, factionsToOmit) { log(ns, `We "know" about ${factionNames.length} factions, and will omit ${factionsToOmit.length} of them.`); factionNames = factionNames.filter(f => !factionsToOmit.includes(f)); - let dictFactionAugs = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationsFromFaction(o)'), '/Temp/getAugmentationsFromFactions.txt', factionNames); - let dictFactionReps = await getNsDataThroughFile(ns, dictCommand('ns.getFactionRep(o)'), '/Temp/getFactionReps.txt', factionNames); - let dictFactionFavors = await getNsDataThroughFile(ns, dictCommand('ns.getFactionFavor(o)'), '/Temp/getFactionFavors.txt', factionNames); + let dictFactionAugs = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationsFromFaction(o)'), '/Temp/getAugmentationsFromFactions.txt', factionNames); + let dictFactionReps = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getFactionRep(o)'), '/Temp/getFactionReps.txt', factionNames); + let dictFactionFavors = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getFactionFavor(o)'), '/Temp/getFactionFavors.txt', factionNames); // Need information about our gang to work around a TRP bug - gang faction appears to have it available, but it's not (outside of BN2) if (gangFaction && playerData.bitNodeN != 2) @@ -276,10 +276,10 @@ async function updateFactionData(ns, factionsToOmit) { /** @param {NS} ns **/ async function updateAugmentationData(ns, desiredAugs) { const augmentationNames = [...new Set(Object.values(factionData).flatMap(f => f.augmentations))]; // augmentations.slice(); - const dictAugRepReqs = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationRepReq(o)'), '/Temp/getAugmentationRepReqs.txt', augmentationNames); - const dictAugPrices = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationPrice(o)'), '/Temp/getAugmentationPrices.txt', augmentationNames); - const dictAugStats = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationStats(o)'), '/Temp/getAugmentationStats.txt', augmentationNames); - const dictAugPrereqs = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationPrereq(o)'), '/Temp/getAugmentationPrereqs.txt', augmentationNames); + const dictAugRepReqs = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationRepReq(o)'), '/Temp/getAugmentationRepReqs.txt', augmentationNames); + const dictAugPrices = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationPrice(o)'), '/Temp/getAugmentationPrices.txt', augmentationNames); + const dictAugStats = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationStats(o)'), '/Temp/getAugmentationStats.txt', augmentationNames); + const dictAugPrereqs = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationPrereq(o)'), '/Temp/getAugmentationPrereqs.txt', augmentationNames); augmentationData = Object.fromEntries(augmentationNames.map(aug => [aug, { name: aug, displayName: aug, @@ -370,7 +370,7 @@ async function joinFactions(ns, forceJoinFactions) { else { log(ns, `Joining faction ${faction.name} which has ${desiredAugs.length} desired augmentations: ${desiredAugs}`); let response; - if (response = await getNsDataThroughFile(ns, `ns.joinFaction(ns.args[0])`, '/Temp/join-faction.txt', [faction.name])) { + if (response = await getNsDataThroughFile(ns, `ns.singularity.joinFaction(ns.args[0])`, '/Temp/join-faction.txt', [faction.name])) { faction.joined = true; faction.augmentations.forEach(aug => accessibleAugmentations.add(aug)); joinedFactions.push(faction.name); @@ -757,7 +757,7 @@ async function purchaseDesiredAugs(ns) { `(We had ${formatMoney(startingPlayerMoney)} at startup). Will proceed with buying most of the purchase order.`, printToTerminal, 'warning'); // Donate to factions if necessary (using a ram-dodging script of course) if (Object.keys(purchaseFactionDonations).length > 0 && Object.values(purchaseFactionDonations).some(v => v > 0)) { - if (await getNsDataThroughFile(ns, 'JSON.parse(ns.args[0]).reduce((success, o) => success && ns.donateToFaction(o.faction, o.repDonation), true)', + if (await getNsDataThroughFile(ns, 'JSON.parse(ns.args[0]).reduce((success, o) => success && ns.singularity.donateToFaction(o.faction, o.repDonation), true)', '/Temp/facman-donate.txt', [JSON.stringify(Object.keys(purchaseFactionDonations).map(f => ({ faction: f, repDonation: purchaseFactionDonations[f] })))])) log(ns, `SUCCESS: Donated to ${Object.keys(purchaseFactionDonations).length} factions to gain access to desired augmentations.`, printToTerminal, 'success') else @@ -766,7 +766,7 @@ async function purchaseDesiredAugs(ns) { // Purchase desired augs (using a ram-dodging script of course) if (purchaseableAugs.length == 0) return log(ns, `INFO: Cannot afford to buy any augmentations at this time.`, printToTerminal) - const purchased = await getNsDataThroughFile(ns, 'JSON.parse(ns.args[0]).reduce((total, o) => total + (ns.purchaseAugmentation(o.faction, o.augmentation) ? 1 : 0), 0)', + const purchased = await getNsDataThroughFile(ns, 'JSON.parse(ns.args[0]).reduce((total, o) => total + (ns.singularity.purchaseAugmentation(o.faction, o.augmentation) ? 1 : 0), 0)', '/Temp/facman-purchase-augs.txt', [JSON.stringify(purchaseableAugs.map(aug => ({ faction: aug.getFromJoined(), augmentation: aug.name })))]); if (purchased == purchaseableAugs.length) log(ns, `SUCCESS: Purchased ${purchased} desired augmentations in optimal order!`, printToTerminal, 'success') diff --git a/farm-intelligence.js b/farm-intelligence.js index 4f4f1f53..434888d3 100644 --- a/farm-intelligence.js +++ b/farm-intelligence.js @@ -23,7 +23,7 @@ export async function main(ns) { const tempFile = '/Temp/farm-intelligence.js'; await ns.write(tempFile, `export async function main(ns) { ns.disableLog('ALL'); - ${JSON.stringify(ns.singularity.checkFactionInvitations())}.forEach(f => ns.joinFaction(f)); + ${JSON.stringify(ns.singularity.checkFactionInvitations())}.forEach(f => ns.singularity.joinFaction(f)); ns.singularity.softReset('${tempFile}'); }`, "w"); ns.run(tempFile) diff --git a/gangs.js b/gangs.js index e1f631d3..d2918172 100644 --- a/gangs.js +++ b/gangs.js @@ -136,9 +136,9 @@ async function initialize(ns) { if (sf4Level < 3) log(ns, `WARNING: This script makes use of singularity functions, which are quite expensive before you have SF4.3. ` + `Unless you have a lot of free RAM for temporary scripts, you may get runtime errors.`); - const augmentationNames = await getNsDataThroughFile(ns, `ns.getAugmentationsFromFaction('${myGangFaction}')`, '/Temp/gang-augs.txt'); - const ownedAugmentations = await getNsDataThroughFile(ns, `ns.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); - const dictAugRepReqs = await getDict(ns, augmentationNames, 'getAugmentationRepReq', '/Temp/aug-repreqs.txt'); + const augmentationNames = await getNsDataThroughFile(ns, `ns.singularity.getAugmentationsFromFaction('${myGangFaction}')`, '/Temp/gang-augs.txt'); + const ownedAugmentations = await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); + const dictAugRepReqs = await getDict(ns, augmentationNames, 'singularity.getAugmentationRepReq', '/Temp/aug-repreqs.txt'); // Due to a bug, gangs appear to provide "The Red Pill" even when it's unavailable (outside of BN2), so ignore this one. requiredRep = augmentationNames.filter(aug => !ownedAugmentations.includes(aug) && aug != "The Red Pill").reduce((max, aug) => Math.max(max, dictAugRepReqs[aug]), -1); log(ns, `Highest augmentation reputation cost is ${formatNumberShort(requiredRep)}`); @@ -276,7 +276,7 @@ async function optimizeGangCrime(ns, myGangInfo) { // Find out how much reputation we need, without SF4, we estimate gang faction rep based on current gang rep let factionRep = -1; if (ownedSourceFiles[4] > 0) { - try { factionRep = await getNsDataThroughFile(ns, `ns.getFactionRep(ns.args[0])`, `/Temp/getFactionRep.txt`, [myGangFaction]); } + try { factionRep = await getNsDataThroughFile(ns, `ns.singularity.getFactionRep(ns.args[0])`, `/Temp/getFactionRep.txt`, [myGangFaction]); } catch { log(ns, 'INFO: Error suppressed. Falling back to estimating current gang faction rep.'); } } if (factionRep == -1) // Estimate current gang rep based on respect. Game gives 1/75 rep / respect. This is an underestimate, because it doesn't take into account spent/lost respect on ascend/recruit/death. diff --git a/sleeve.js b/sleeve.js index 0ad0289b..d8884115 100644 --- a/sleeve.js +++ b/sleeve.js @@ -270,7 +270,7 @@ async function promptForTrainingBudget(ns) { async function calculateCrimeChance(ns, sleeve, crimeName) { // If not in the cache, retrieve this crime's stats const crimeStats = cachedCrimeStats[crimeName] ?? (cachedCrimeStats[crimeName] = (4 in ownedSourceFiles ? - await getNsDataThroughFile(ns, `ns.getCrimeStats(ns.args[0])`, '/Temp/get-crime-stats.txt', [crimeName]) : + await getNsDataThroughFile(ns, `ns.singularity.getCrimeStats(ns.args[0])`, '/Temp/get-crime-stats.txt', [crimeName]) : // Hack: To support players without SF4, hard-code values as of the current release crimeName == "homicide" ? { difficulty: 1, strength_success_weight: 2, defense_success_weight: 2, dexterity_success_weight: 0.5, agility_success_weight: 0.5 } : crimeName == "mug" ? { difficulty: 0.2, strength_success_weight: 1.5, defense_success_weight: 0.5, dexterity_success_weight: 1.5, agility_success_weight: 0.5, } : diff --git a/stanek.js b/stanek.js index d7326fb3..69d70da9 100644 --- a/stanek.js +++ b/stanek.js @@ -89,7 +89,7 @@ export async function main(ns) { if (sf4Level == 0) { log(ns, `INFO: SF4 required to get owned faction rep and augmentation info. Ignoring the --reputation-threshold setting.`); } else { - const ownedAugmentations = await getNsDataThroughFile(ns, `ns.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); + const ownedAugmentations = await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); const awakeningOwned = ownedAugmentations.includes("Stanek's Gift - Awakening"); const serenityOwned = ownedAugmentations.includes("Stanek's Gift - Serenity"); shouldContinueForAug = (currentRep) => // return true if currentRep is high enough that we should keep grinding for the next unowned aug @@ -140,7 +140,7 @@ async function getFragmentsToCharge(ns) { return undefined; } // If we have SF4, get our updated faction rep, and determine if we should continue past --max-charges to earn rep for the next augmentation - const churchRep = sf4Level ? await getNsDataThroughFile(ns, 'ns.getFactionRep("Church of the Machine God")', '/Temp/stanek-reputation.txt') : 0; + const churchRep = sf4Level ? await getNsDataThroughFile(ns, 'ns.singularity.getFactionRep("Church of the Machine God")', '/Temp/stanek-reputation.txt') : 0; const shouldContinue = shouldContinueForAug(churchRep); // Collect information about each fragment's charge status, and prepare a status update diff --git a/work-for-factions.js b/work-for-factions.js index 8fb5d291..a8b54221 100644 --- a/work-for-factions.js +++ b/work-for-factions.js @@ -179,13 +179,13 @@ async function loadStartupData(ns) { }; // Get some faction and augmentation information to decide what remains to be purchased - dictFactionFavors = await getNsDataThroughFile(ns, dictCommand('ns.getFactionFavor(o)'), '/Temp/getFactionFavors.txt', allKnownFactions); - const dictFactionAugs = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationsFromFaction(o)'), '/Temp/getAugmentationsFromFactions.txt', allKnownFactions); + dictFactionFavors = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getFactionFavor(o)'), '/Temp/getFactionFavors.txt', allKnownFactions); + const dictFactionAugs = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationsFromFaction(o)'), '/Temp/getAugmentationsFromFactions.txt', allKnownFactions); const augmentationNames = [...new Set(Object.values(dictFactionAugs).flat())]; - const dictAugRepReqs = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationRepReq(o)'), '/Temp/getAugmentationRepReqs.txt', augmentationNames); - const dictAugStats = await getNsDataThroughFile(ns, dictCommand('ns.getAugmentationStats(o)'), '/Temp/getAugmentationStats.txt', augmentationNames); - const ownedAugmentations = await getNsDataThroughFile(ns, `ns.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); - const installedAugmentations = await getNsDataThroughFile(ns, `ns.getOwnedAugmentations()`, '/Temp/player-augs-installed.txt'); + const dictAugRepReqs = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationRepReq(o)'), '/Temp/getAugmentationRepReqs.txt', augmentationNames); + const dictAugStats = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getAugmentationStats(o)'), '/Temp/getAugmentationStats.txt', augmentationNames); + const ownedAugmentations = await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations(true)`, '/Temp/player-augs-purchased.txt'); + const installedAugmentations = await getNsDataThroughFile(ns, `ns.singularity.getOwnedAugmentations()`, '/Temp/player-augs-installed.txt'); // Based on what augmentations we own, we can change our own behaviour (e.g. whether to allow work to steal focus) hasFocusPenaly = !installedAugmentations.includes("Neuroreceptor Management Implant"); // Check if we have an augmentation that lets us not have to focus at work (always nicer if we can background it) shouldFocusAtWork = !options['no-focus'] && hasFocusPenaly; // Focus at work for the best rate of rep gain, unless focus activities are disabled via command line @@ -516,8 +516,8 @@ async function earnFactionInvite(ns, factionName) { ns.print(`You must be a CO (e.g. CEO/CTO) of a company to earn an invite to ${factionName}. This may take a while!`); let factionConfig = companySpecificConfigs.find(f => f.name == factionName); // We set up Silhouette with a "company-specific-config" so that we can work for an invite like any megacorporation faction. let companyNames = preferredCompanyFactionOrder.map(f => companySpecificConfigs.find(cf => cf.name == f)?.companyName || f); - let favorByCompany = await getNsDataThroughFile(ns, dictCommand('ns.getCompanyFavor(o)'), '/Temp/getCompanyFavors.txt', companyNames); - let repByCompany = await getNsDataThroughFile(ns, dictCommand('ns.getCompanyRep(o)'), '/Temp/getCompanyReps.txt', companyNames); + let favorByCompany = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getCompanyFavor(o)'), '/Temp/getCompanyFavors.txt', companyNames); + let repByCompany = await getNsDataThroughFile(ns, dictCommand('ns.singularity.getCompanyRep(o)'), '/Temp/getCompanyReps.txt', companyNames); // Change the company to work for into whichever company we can get to CEO fastest with. Minimize needed_rep/rep_gain_rate. CEO job is at 3.2e6 rep, so (3.2e6-current_rep)/(100+favor). factionConfig.companyName = companyNames.sort((a, b) => (3.2e6 - repByCompany[a]) / (100 + favorByCompany[a]) - (3.2e6 - repByCompany[b]) / (100 + favorByCompany[b]))[0]; // Hack: We will be working indefinitely, so we rely on an external script (daemon + faction-manager) to join this faction for us, or for checkForNewPrioritiesInterval to elapse. @@ -538,7 +538,7 @@ async function goToCity(ns, cityName) { ns.print(`Already in city ${cityName}`); return true; } - if (await getNsDataThroughFile(ns, `ns.travelToCity(ns.args[0])`, '/Temp/travel.txt', [cityName])) { + if (await getNsDataThroughFile(ns, `ns.singularity.travelToCity(ns.args[0])`, '/Temp/travel.txt', [cityName])) { lastActionRestart = Date.now(); lastTravel = Date.now() announce(ns, `Travelled from ${player.city} to ${cityName}`, 'info'); @@ -565,7 +565,7 @@ export async function crimeForKillsKarmaStats(ns, reqKills, reqKarma, reqStats, let crime, lastCrime, lastStatusUpdateTime; while (forever || player.strength < reqStats || player.defense < reqStats || player.dexterity < reqStats || player.agility < reqStats || player.numPeopleKilled < reqKills || -ns.heart.break() < reqKarma) { if (!forever && breakToMainLoop()) return ns.print('INFO: Interrupting crime to check on high-level priorities.'); - let crimeChances = await getNsDataThroughFile(ns, `Object.fromEntries(ns.args.map(c => [c, ns.getCrimeChance(c)]))`, '/Temp/crime-chances.txt', bestCrimesByDifficulty); + let crimeChances = await getNsDataThroughFile(ns, `Object.fromEntries(ns.args.map(c => [c, ns.singularity.getCrimeChance(c)]))`, '/Temp/crime-chances.txt', bestCrimesByDifficulty); let needStats = player.strength < reqStats || player.defense < reqStats || player.dexterity < reqStats || player.agility < reqStats; let karma = -ns.heart.break(); crime = crimeCount < 10 ? (crimeChances["homicide"] > 0.75 ? "homicide" : "mug") : // Start with a few fast & easy crimes to boost stats if we're just starting @@ -577,7 +577,7 @@ export async function crimeForKillsKarmaStats(ns, reqKills, reqKarma, reqStats, lastStatusUpdateTime = Date.now(); } ns.tail(); // Force a tail window open when auto-criming, or else it's very difficult to stop if it was accidentally closed. - await ns.sleep(1 + (await getNsDataThroughFile(ns, 'ns.commitCrime(ns.args[0])', '/Temp/commitCrime.txt', [crime]))); + await ns.sleep(1 + (await getNsDataThroughFile(ns, 'ns.singularity.commitCrime(ns.args[0])', '/Temp/commitCrime.txt', [crime]))); while ((player = (await getPlayerInfo(ns))).crimeType == `commit ${crime}` || player.crimeType == crime) // If we woke up too early, wait a little longer for the crime to finish await ns.sleep(10); crimeCount++; @@ -604,7 +604,7 @@ async function study(ns, focus, course, university = null) { if (!university) return announce(ns, `WARNING: Could not study '${course}' because we are in city '${playerCity}' without a university.`, 'warning'); } - if (await getNsDataThroughFile(ns, `ns.universityCourse(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/study.txt', [university, course, focus])) { + if (await getNsDataThroughFile(ns, `ns.singularity.universityCourse(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/study.txt', [university, course, focus])) { lastActionRestart = Date.now(); announce(ns, `Started studying '${course}' at '${university}`, 'success'); return true; @@ -638,7 +638,7 @@ export async function waitForFactionInvite(ns, factionName, maxWaitTime = waitFo ns.print(`Waiting for invite from faction "${factionName}"...`); let waitTime = maxWaitTime; do { - var invitations = await getNsDataThroughFile(ns, 'ns.checkFactionInvitations()', '/Temp/player-faction-invites.txt'); + var invitations = checkFactionInvites(ns); var joinedFactions = (await getPlayerInfo(ns)).factions; if (invitations.includes(factionName) || joinedFactions.includes(factionName)) break; @@ -658,7 +658,7 @@ export async function tryJoinFaction(ns, factionName) { var joinedFactions = (await getPlayerInfo(ns)).factions; if (joinedFactions.includes(factionName)) return true; - if (!(await getNsDataThroughFile(ns, `ns.joinFaction(ns.args[0])`, '/Temp/join-faction.txt', [factionName]))) + if (!(await getNsDataThroughFile(ns, `ns.singularity.joinFaction(ns.args[0])`, '/Temp/join-faction.txt', [factionName]))) return false; announce(ns, `Joined faction "${factionName}"`, 'success'); return true; @@ -674,7 +674,7 @@ async function getPlayerInfo(ns) { /** @param {NS} ns * @returns {Promise} List of new faction invites */ async function checkFactionInvites(ns) { - return await getNsDataThroughFile(ns, 'ns.checkFactionInvitations()', '/Temp/checkFactionInvitations.txt'); + return await getNsDataThroughFile(ns, 'ns.singularity.checkFactionInvitations()', '/Temp/checkFactionInvitations.txt'); } /** @param {NS} ns @@ -686,19 +686,19 @@ async function getGangInfo(ns) { /** @param {NS} ns * @returns {Promise} Current reputation with the specified faction */ async function getFactionReputation(ns, factionName) { - return await getNsDataThroughFile(ns, `ns.getFactionRep(ns.args[0])`, '/Temp/getFactionRep.txt', [factionName]); + return await getNsDataThroughFile(ns, `ns.singularity.getFactionRep(ns.args[0])`, '/Temp/getFactionRep.txt', [factionName]); } /** @param {NS} ns * @returns {Promise} Current reputation with the specified company */ async function getCompanyReputation(ns, companyName) { - return await getNsDataThroughFile(ns, `ns.getCompanyRep(ns.args[0])`, '/Temp/getCompanyRep.txt', [companyName]); + return await getNsDataThroughFile(ns, `ns.singularity.getCompanyRep(ns.args[0])`, '/Temp/getCompanyRep.txt', [companyName]); } /** @param {NS} ns * @returns {Promise} Current favour with the specified faction */ async function getCurrentFactionFavour(ns, factionName) { - return await getNsDataThroughFile(ns, `ns.getFactionFavor(ns.args[0])`, '/Temp/getFactionFavor.txt', [factionName]); + return await getNsDataThroughFile(ns, `ns.singularity.getFactionFavor(ns.args[0])`, '/Temp/getFactionFavor.txt', [factionName]); } /** @param {NS} ns @@ -817,12 +817,12 @@ export async function workForSingleFaction(ns, factionName, forceUnlockDonations /** Stop whatever focus work we're currently doing * @param {NS} ns */ -async function stop(ns) { return await getNsDataThroughFile(ns, `ns.stopAction()`, '/Temp/stopAction.txt'); } +async function stop(ns) { return await getNsDataThroughFile(ns, `ns.singularity.stopAction()`, '/Temp/stopAction.txt'); } /** Start the specified faction work * @param {NS} ns */ async function startWorkForFaction(ns, factionName, work, focus) { - return await getNsDataThroughFile(ns, `ns.workForFaction(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/workForFaction.txt', [factionName, work, focus]) + return await getNsDataThroughFile(ns, `ns.singularity.workForFaction(ns.args[0], ns.args[1], ns.args[2])`, '/Temp/workForFaction.txt', [factionName, work, focus]) } /** Try all work types and see what gives the best rep gain with this faction! @@ -903,7 +903,7 @@ const serverByCompany = { "Bachman & Associates": "b-and-a", "ECorp": "ecorp", " /** Apply to the specified role at the specified company * @param {NS} ns */ async function tryApplyToCompany(ns, company, role) { - return await getNsDataThroughFile(ns, `ns.applyToCompany(ns.args[0], ns.args[1])`, '/Temp/applyToCompany.txt', [company, role]) + return await getNsDataThroughFile(ns, `ns.singularity.applyToCompany(ns.args[0], ns.args[1])`, '/Temp/applyToCompany.txt', [company, role]) } /** @param {NS} ns */ @@ -985,7 +985,7 @@ export async function workForMegacorpFactionInvite(ns, factionName, waitForInvit // TODO: If we ever get rid of the below periodic restart-work, we will need to monitor for interruptions with player.workType == e.g. "Work for Company" if (!studying && (!working || (Date.now() - lastActionRestart >= restartWorkInteval) /* We must periodically restart work to collect Rep Gains */)) { // Work for the company (assume daemon is grinding hack XP as fast as it can, so no point in studying for that) - if (await getNsDataThroughFile(ns, `ns.workForCompany(ns.args[0], ns.args[1])`, '/Temp/workForCompany.txt', [companyName, shouldFocusAtWork])) { + if (await getNsDataThroughFile(ns, `ns.singularity.workForCompany(ns.args[0], ns.args[1])`, '/Temp/workForCompany.txt', [companyName, shouldFocusAtWork])) { working = true; if (shouldFocusAtWork) ns.tail(); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep stealing focus currentReputation = await getCompanyReputation(ns, companyName); // Update to capture the reputation earned when restarting work