Skip to content

Commit

Permalink
Fix #375 and Fix #376 - backdoor-all-servers improvements
Browse files Browse the repository at this point in the history
- Reduced RAM footprint by using ram-dodging when connecting to servers.
- Prevent multiple instances
- Improve logging, especially of errors
  • Loading branch information
alainbryden committed Oct 17, 2024
1 parent 48cfc57 commit ce1a2e3
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions Tasks/backdoor-all-servers.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { getNsDataThroughFile, getFilePath, log } from '../helpers.js'
import { getNsDataThroughFile, getFilePath, instanceCount, log, getErrorInfo } from '../helpers.js'

const spawnDelay = 50; // Delay to allow time for `installBackdoor` to start running before a background script connects back to 'home'

/** @param {NS} ns
* Scan all servers, backdoor anything that can be backdoored, and leave a file to indicate it's been done
/** Scan all servers, backdoor anything that can be backdoored, and leave a file to indicate it's been done
* Requires: SF-4.1 **/
export let main = async ns => {
let anyConnected = false;
/** @param {NS} ns **/
export async function main(ns) {
let notAtHome = false;
try {
let servers = ["home"],
routes = { home: ["home"] },
myHackingLevel = ns.getHackingLevel();
// Prevent multiple instances of this script from being started
if (await instanceCount(ns, "home", false, false) > 1)
return log(ns, 'Another instance is already running. Shutting down...');

let servers = ["home"];
let routes = { home: ["home"] };
let myHackingLevel = ns.getHackingLevel();
// Scan all servers and keep track of the path to get to them
ns.disableLog("scan");
for (let i = 0, j; i < servers.length; i++)
for (j of ns.scan(servers[i]))
if (!servers.includes(j)) servers.push(j), routes[j] = routes[servers[i]].slice(), routes[j].push(j);

// Filter out servers that cannot or should not be hacked / backdoored
ns.disableLog("getServerRequiredHackingLevel");
let hackableServers = servers.filter(s => s != "home" && !s.includes("hacknet-") && !s.includes("daemon")) /*or whatever you name your purchased servers*/
Expand All @@ -26,15 +31,19 @@ export let main = async ns => {

let toBackdoor = await getNsDataThroughFile(ns, `ns.args.filter(s => !ns.getServer(s).backdoorInstalled)`, '/Temp/servers-to-backdoor.txt', hackableServers);
let count = toBackdoor.length;
// Early exit condition if there are no servers left to backdoor
ns.print(`${count} servers have yet to be backdoored.`);
if (count == 0) return;

// Early exit condition if there are no servers we can currently backdoor
ns.print(`${toBackdoor.filter(s => ns.hasRootAccess(s)).length} of ${count} servers to backdoor are currently rooted.`);
toBackdoor = toBackdoor.filter(s => myHackingLevel > ns.getServerRequiredHackingLevel(s));
ns.print(`${toBackdoor.length} of ${count} servers to backdoor are within our hack level (${myHackingLevel}).`);
toBackdoor = toBackdoor.filter(s => ns.hasRootAccess(s));
ns.print(`${toBackdoor.length} of ${count} servers to be backdoored are rooted and within our hack level (${myHackingLevel})`);
if (toBackdoor.length == 0) return;

// Collect information about any servers still being backdoored (from a prior run), so we can skip them
let scriptPath = getFilePath('/Tasks/backdoor-all-servers.js.backdoor-one.js');
let currentScripts = ns.ps().filter(s => s.filename == scriptPath).map(s => s.args[0]);

Expand All @@ -44,25 +53,33 @@ export let main = async ns => {
continue;
}
ns.print(`Hopping to ${server}`);
anyConnected = true;
for (let hop of routes[server])
ns.singularity.connect(hop);
notAtHome = true; // Set a flag to get us back home if we encounter an error
const success = await getNsDataThroughFile(ns,
'ns.args.reduce((success, hop) => success && ns.singularity.connect(hop), true)',
'/Temp/singularity-connect-hop-to-server.txt', routes[server]);
if (!success)
log(ns, `ERROR: Failed to hop to server ${server}. Backdoor probably won't work...`, true, 'error');
if (server === "w0r1d_d43m0n") {
ns.alert("Ready to hack w0r1d_d43m0n!");
log(ns, "INFO: Sleeping forever to avoid multiple instances navigating to w0r1d_d43m0n.");
while (true) await ns.sleep(10000); // Sleep forever so the script isn't run multiple times to create multiple overlapping alerts
}
ns.print(`Installing backdoor on "${server}"...`);
// Kick off a separate script that will run backdoor before we connect to home.
var pid = ns.run(scriptPath, 1, server);
if (pid === 0)
return ns.print(`Couldn't initiate a new backdoor of "${server}"" (insufficient RAM?). Will try again later.`);
return log(ns, `WARN: Couldn't initiate a new backdoor of "${server}" (insufficient RAM?). Will try again later.`, false, 'warning');
await ns.sleep(spawnDelay); // Wait some time for the external backdoor script to initiate its backdoor of the current connected server
ns.singularity.connect("home");
const backAtHome = await getNsDataThroughFile(ns, 'ns.singularity.connect(ns.args[0])', null, ["home"]);
if (backAtHome)
notAtHome = false;
}
} catch (err) {
ns.tprint(String(err));
}
catch (err) {
log(ns, `ERROR: ${ns.getScriptName()} Caught an unexpected error:\n${getErrorInfo(err)}`, false, 'error');
} finally {
if (anyConnected)
ns.singularity.connect("home");
// Try to clean-up by re-connecting to home before we shut down
if (notAtHome)
await getNsDataThroughFile(ns, 'ns.singularity.connect(ns.args[0])', null, ["home"]);
}
};

0 comments on commit ce1a2e3

Please sign in to comment.