Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as helpers from "/apis/helpers.js"
- import * as myForms from "/apis/myFormulas.js"
- let doLog = true;
- let logLevel = 1;
- //-----GUI SETTINGS-----//
- let doGUI = true;
- let showKarma = true;
- let showScriptIncome = true;
- let showScriptExp = true;
- let showHacknetIncome = true;
- const doc = globalThis['document'];
- const hook0 = doc.getElementById('overview-extra-hook-0');
- const hook1 = doc.getElementById('overview-extra-hook-1');
- /** @param {NS} ns */
- async function updateGUI(ns) {
- try {
- const headers = [];
- const values = [];
- if (showKarma) {
- headers.push("Karma");
- values.push(ns.heart.break().toPrecision(5));
- }
- if (showScriptIncome) {
- let income = ns.getScriptIncome();
- headers.push("Script $ ");
- values.push(ns.nFormat(income[1], "(0.00 a)") + "/s");
- }
- if (showScriptExp) {
- let exp = ns.getScriptExpGain();
- headers.push("Script EXP ");
- values.push(ns.nFormat(exp, "(0.00 a)") + "/s");
- }
- if (showHacknetIncome) {
- let hnIncome = 0;
- for (let i = 0; i < ns.hacknet.numNodes(); i++) {
- hnIncome += ns.hacknet.getNodeStats(i).production;
- }
- headers.push("Hacknet $ ");
- values.push(ns.nFormat(hnIncome, "(0.00 a)") + "/s");
- }
- hook0.innerText = headers.join(" \n");
- hook1.innerText = values.join(" \n");
- } catch (err) {
- ns.print("Error updating the GUI! - " + String(err));
- }
- }
- /** @param {NS} ns @param {Server} server @param {Player} player*/
- export async function main(ns) {
- let debugMode = false;
- let debugLevel = 1;
- //get server names
- let server = ns.args[0];
- let host = ns.getHostname();
- //define scripts
- let hackScript = "/hiveCluster/hack.js"; // swZFa6Sz
- let growScript = "/hiveCluster/grow.js"; // q7KQwtij
- let weakenScript = "/hiveCluster/weaken.js"; //hg6DS4aQ
- if (!ns.fileExists(hackScript)) await ns.wget("https://pastebin.com/raw.php?i=swZFa6Sz", hackScript);
- if (!ns.fileExists(growScript)) await ns.wget("https://pastebin.com/raw.php?i=q7KQwtij", growScript);
- if (!ns.fileExists(weakenScript)) await ns.wget("https://pastebin.com/raw.php?i=hg6DS4aQ", weakenScript);
- //get ram amounts for all scripts.
- let runningScripts = ["/hiveCluster/hiveMind.js", "scanForCCT.js"];
- //GB of RAM to keep free on home server for running scripts
- var constantRam = 4;
- for (let s of runningScripts) constantRam += ns.getScriptRam(s);
- var hackscriptRam = ns.getScriptRam(hackScript);
- var growscriptRam = ns.getScriptRam(growScript);
- var weakenscriptRam = ns.getScriptRam(weakenScript);
- var maxRam = (ns.getServerMaxRam(host) - constantRam);
- var homeThreadsHack = Math.floor(maxRam / hackscriptRam);
- var homeThreadsGrow = Math.floor(maxRam / growscriptRam);
- var homeThreadsWeaken = Math.floor(maxRam / weakenscriptRam);
- //Get a list of all servers
- let filters = [host, "MyServer-"];
- let useExact = false;
- let usableServers = [];
- //Gather max hive memory and threads, starting with home values.
- let maxMemory = maxRam;
- let maxThreadsHack = homeThreadsHack;
- let maxThreadsGrow = homeThreadsGrow;
- let maxThreadsWeaken = homeThreadsWeaken;
- //filter the list of servers by usability
- async function getUsableServers() {
- let servers = await helpers.getAllServers(ns, filters, useExact);
- maxRam = (ns.getServerMaxRam(host) - constantRam);
- maxMemory = maxRam;
- homeThreadsHack = Math.floor(maxRam / hackscriptRam);
- homeThreadsGrow = Math.floor(maxRam / growscriptRam);
- homeThreadsWeaken = Math.floor(maxRam / weakenscriptRam);
- maxThreadsHack = homeThreadsHack;
- maxThreadsGrow = homeThreadsGrow;
- maxThreadsWeaken = homeThreadsWeaken;
- let list = [];
- list.push([host, homeThreadsHack, homeThreadsGrow, homeThreadsWeaken]);
- for (let server of servers) {
- if (!ns.hasRootAccess(server)) { await dropImmunity(ns, server); }
- //only use those with root
- if (ns.hasRootAccess(server)) {
- if (!ns.fileExists("refreshFiles.txt", server)) {
- await ns.scp([hackScript, weakenScript, growScript, "refreshFiles.txt"], server);
- ns.tprint("Moving files to ", server)
- }
- let mem = ns.getServerMaxRam(server);
- let thr = Math.floor(mem / hackscriptRam);
- let hackThr = Math.floor(mem / hackscriptRam);;
- let growThr = Math.floor(mem / growscriptRam);;
- let weakenThr = Math.floor(mem / weakenscriptRam);;
- //only add servers to the list if they can handle at least one thread.
- if (thr > 0) {
- //add memory and threads to max pools
- maxMemory += mem;
- //maxThreads += thr;
- maxThreadsHack += hackThr;
- maxThreadsGrow += growThr;
- maxThreadsWeaken += weakenThr;
- //add to array of usable servers
- list.push([server, hackThr, growThr, weakenThr]);
- }
- }
- }
- return helpers.sortArray(list, [[1, 1]]);
- }
- //sort the usable servers by the most possible threads, highest being first.
- usableServers = await getUsableServers();
- ns.tprint("Hive Mind Participants - ", usableServers);
- ns.tprint("Max Hack Threads Capable -" + maxThreadsHack);
- ns.tprint("Max Grow Threads Capable -" + maxThreadsGrow);
- ns.tprint("Max Weaken Threads Capable -" + maxThreadsWeaken);
- ns.tprint("Max Memory Available - " + maxMemory);
- await ns.sleep(1000);
- //------start calulations-----//
- let batchActions = [];
- let batch;
- let hackTime = ns.getHackTime(server);
- let growTime = hackTime * 3.2;
- let weakenTime = hackTime * 4;
- let tgTime;
- let twTime;
- var player = ns.getPlayer();
- var fserver = ns.getServer(server);
- var cs = ns.getServerSecurityLevel(server);
- var ms = ns.getServerMinSecurityLevel(server);
- var mm = ns.getServerMaxMoney(server);
- var ma = ns.getServerMoneyAvailable(server);
- let currentTime = performance.now();
- //check if server was drained of money.
- if (ma <= 0) {
- ns.tprint(server, " has been drained of all it's money. Attempting a full recovery. Please wait.");
- batchActions.push([maxThreadsGrow, growScript, currentTime + growTime + 1000, server, growTime + 1000, growscriptRam]);
- batch = batchSplit(ns, batchActions, usableServers);
- if (debugMode) {
- if (debugLevel >= 2) {
- ns.tprint(batch);
- }
- ns.tprint("Sleep - ", growTime + 200);
- await ns.sleep(1);
- }
- else {
- await executeBatch(ns, batch, server);
- //wait for growth
- await ns.sleep(growTime + 2000);
- }
- //get all the variables with new info.
- mm = ns.getServerMaxMoney(server);
- ma = ns.getServerMoneyAvailable(server);
- if (ma <= 0) {
- ns.tprint("Unable to recover. This server is more than likely un-hackable. Terminating program.");
- return;
- }
- player = ns.getPlayer();
- fserver = ns.getServer(server);
- cs = ns.getServerSecurityLevel(server);
- ms = ns.getServerMinSecurityLevel(server);
- hackTime = ns.getHackTime(server);
- growTime = hackTime * 3.2;
- weakenTime = hackTime * 4;
- usableServers = await getUsableServers();
- }
- //var maxGrowThreads = ((maxRam / growscriptRam) - weakenThreads);
- //let memNeeded = weakenThreads * weakenscriptRam;
- //neededGrowThreads = neededGrowThreads + (neededGrowThreads * bufferGrowPercent);
- //Can be changed to delay. Used to offset function call times potentially
- let timeDelay = 50;
- currentTime = performance.now();
- let growthRemaining;
- let weakenRemaining;
- async function startPriming(secondaryPrime = false) {
- ns.tprint("Priming Security and Money for " + server);
- let growThreadsToDouble = ns.growthAnalyze(server, 2);
- let neededMoney = mm - ma;
- ns.tprint("NeededGrowThreads - ", neededMoney, " / ", ma, " * ", growThreadsToDouble);
- let neededGrowThreads = Math.ceil(neededMoney / ma * growThreadsToDouble);
- var weakenThreads = 2000 - (ms / 0.05);
- //[threadCount, command, timeToFinish, target, executionTime, scriptRam]
- //create a batch order
- let growthRemaining = neededGrowThreads;
- let weakenRemaining = weakenThreads;
- while (growthRemaining > 0 || weakenRemaining > 0) {
- if (weakenRemaining > 0) {
- ns.tprint("Starting a Weaken Cycle.");
- batchActions = [];
- batch;
- currentTime = performance.now();
- hackTime = ns.getHackTime(server);
- weakenTime = hackTime * 4;
- twTime = weakenTime + timeDelay;
- if (weakenRemaining > maxThreadsWeaken) {
- batchActions.push([maxThreadsWeaken, weakenScript, currentTime + twTime, server, twTime, weakenscriptRam]);
- ns.tprint("Weakening with ", maxThreadsWeaken, " threads.");
- } else {
- batchActions.push([weakenRemaining, weakenScript, currentTime + twTime, server, twTime, weakenscriptRam]);
- ns.tprint("Weakening with ", weakenRemaining, " threads.");
- }
- batch = batchSplit(ns, batchActions, usableServers);
- if (batch[0] == false) {
- //ns.tprint(batch);
- ns.tprint("Something went wrong with batching - " + batch[2]);
- return;
- } else {
- weakenRemaining -= maxThreadsWeaken;
- if (debugMode) {
- if (debugLevel >= 2) {
- ns.tprint(batch);
- }
- ns.tprint("Sleep - ", twTime + 1000);
- await ns.sleep(1);
- } else {
- await executeBatch(ns, batch, server);
- await ns.sleep(twTime + 1000);
- }
- ns.tprint("Weaken Cycle Finished.");
- usableServers = await getUsableServers();
- }
- }
- if (growthRemaining > 0) {
- batchActions = [];
- batch;
- ns.tprint("Starting a Grow Cycle.");
- currentTime = performance.now();
- hackTime = ns.getHackTime(server);
- growTime = hackTime * 3.2;
- tgTime = growTime + timeDelay;
- if (growthRemaining > maxThreadsGrow) {
- ns.tprint("Growing with ", maxThreadsGrow, " threads.");
- batchActions.push([maxThreadsGrow, growScript, currentTime + tgTime, server, tgTime, growscriptRam]);
- } else {
- ns.tprint("Growing with ", growthRemaining, " threads.");
- batchActions.push([growthRemaining, growScript, currentTime + tgTime, server, tgTime, growscriptRam]);
- }
- batch = batchSplit(ns, batchActions, usableServers);
- if (batch[0] == false) {
- //ns.tprint(batch);
- ns.tprint("Something went wrong with batching - " + batch[2]);
- return;
- } else {
- growthRemaining -= maxThreadsGrow;
- if (debugMode) {
- if (debugLevel >= 2) {
- ns.tprint(batch);
- }
- ns.tprint("Sleep - ", tgTime + 1000);
- await ns.sleep(1000);
- }
- else {
- await executeBatch(ns, batch, server);
- await ns.sleep(tgTime + 1000);
- }
- ns.tprint("Grow Cycle Finished. Remaining Threads - ", growthRemaining);
- usableServers = await getUsableServers();
- }
- }
- //recheck values as they have now changed.
- mm = ns.getServerMaxMoney(server);
- ma = ns.getServerMoneyAvailable(server);
- player = ns.getPlayer();
- fserver = ns.getServer(server);
- cs = ns.getServerSecurityLevel(server);
- ms = ns.getServerMinSecurityLevel(server);
- hackTime = ns.getHackTime(server);
- growTime = hackTime * 3.2;
- weakenTime = hackTime * 4;
- growThreadsToDouble = ns.growthAnalyze(server, 2);
- neededMoney = mm - ma;
- ns.tprint("NeededGrowThreads - ", neededMoney, " / ", ma, " * ", growThreadsToDouble);
- neededGrowThreads = Math.ceil(neededMoney / ma * growThreadsToDouble);
- weakenThreads = (cs - ms) / 0.05;
- //[threadCount, command, timeToFinish, target, executionTime, scriptRam]
- //create a batch order
- growthRemaining = neededGrowThreads;
- weakenRemaining = weakenThreads;
- }
- //recheck values as they have now changed.
- mm = ns.getServerMaxMoney(server);
- ma = ns.getServerMoneyAvailable(server);
- player = ns.getPlayer();
- fserver = ns.getServer(server);
- cs = ns.getServerSecurityLevel(server);
- ms = ns.getServerMinSecurityLevel(server);
- hackTime = ns.getHackTime(server);
- growTime = hackTime * 3.2;
- weakenTime = hackTime * 4;
- usableServers = await getUsableServers();
- if ((cs > ms || ma < mm)) {
- if (!secondaryPrime) {
- await startPriming(true);
- } else {
- return false;
- }
- }
- return true;
- }
- let primed = true;
- //Priming the server. Max money and Min security must be acheived for this to work
- if (ma < mm || cs > ms) { primed = await startPriming(false); }
- if (!primed) {
- ns.tprint("Unable to prime the server. Terminating.");
- return;
- }
- ns.tprint("At Main Stage");
- ns.tprint("Current Security Level: ", cs);
- ns.tprint("Min Security Level: ", ms);
- ns.tprint("Current Money: ", ma, " / ", mm);
- let healthCheck = 120;
- let healthy = true;
- let offset = 50;
- let lastExecutionTime = performance.now();
- while (healthy) {
- while (healthy) {
- healthCheck -= 1;
- cs = ns.getServerSecurityLevel(server);
- ms = ns.getServerMinSecurityLevel(server);
- mm = ns.getServerMaxMoney(server);
- ma = ns.getServerMoneyAvailable(server);
- //check if this is a healty tick to check stats on.
- if (cs > ms || ma < mm) {
- //check how long we have been unhealthy
- //ns.tprint("HEALTH ISSUE: " + healthCheck);
- if (healthCheck <= 0) {
- //break out if unhealthy too long
- healthy = false;
- continue;
- }
- //if we havn't been unhealthy too long. wait a offset cycle
- await ns.sleep(offset);
- continue;
- }
- else {
- //set health to max since we are healthy
- healthCheck = 120;
- }
- //ns.tprint("Starting Batch Calculation.");
- //calculate stats needed
- hackTime = ns.getHackTime(server);
- growTime = hackTime * 3.2;
- weakenTime = hackTime * 4;
- currentTime = performance.now();
- usableServers = await getUsableServers();
- player = ns.getPlayer();
- let ratioData;
- let hackID = 0;
- let outOfSyncDelay = 0;
- batchActions = [];
- batch = [false, [], "No Valid Server to Batch too."];
- //Find the largest server with available RAM to handle the hack
- //ns.tprint(usableServers.length - 1);
- for (var i = usableServers.length - 1; i >= 0; i--) {
- let sName = usableServers[i][0];
- //get max threads available for this server
- let mem = ns.getServerMaxRam(sName) - ns.getServerUsedRam(sName);
- if (sName == host) mem = mem - constantRam;
- let threads = Math.floor(mem / hackscriptRam);
- //ns.tprint(sName, " threads - ", threads);
- //continue to next server if there are not enough threads
- if (threads <= 0) continue;
- //get ratio of threads. limiting to a max of 50% hack
- ratioData = getRatio(ns, ns.getServer(server), player, threads);
- //ns.tprint(ratioData);
- if (ratioData.hack > 0) {
- let thTime = hackTime + timeDelay;
- tgTime = growTime + timeDelay;
- twTime = weakenTime + timeDelay;
- let finishTime = currentTime + weakenTime;
- //check for out of sync. This can happen if hacking times get shorter.
- //we check for when the last run should finish and see if this new run will finish before it
- //this is a redundant check, but i left it in just in case.
- if (finishTime < lastExecutionTime) {
- outOfSyncDelay = lastExecutionTime - finishTime;
- batch[2] = "Out of Sync Detected. by - " + outOfSyncDelay;
- break;
- }
- batchActions.push([ratioData.weaken1, weakenScript, finishTime + offset, server, twTime, weakenscriptRam]);
- batchActions.push([ratioData.grow, growScript, finishTime + (offset * 2), server, tgTime, growscriptRam]);
- batchActions.push([ratioData.weaken2, weakenScript, finishTime + (offset * 3), server, twTime, weakenscriptRam]);
- //[server, remainingThreads, command, target, timeToFinish, executionTime, actionID++]
- batch = batchSplit(ns, batchActions, usableServers, [[sName, ratioData.hack, hackScript, server, finishTime, thTime, hackID]]);
- //ns.tprint(batch);
- hackID += 1;
- lastExecutionTime = finishTime + (offset * 4);
- }
- break;
- }
- if (batch[0] == true) {
- executeBatch(ns, batch);
- await ns.sleep(offset * 8);
- } else {
- if (batch[2] != "No Valid Server to Batch too.") {
- ns.tprint(batch[2], " Batch info - ", batch[1]);
- }
- await ns.sleep(offset * 8);
- }
- if (doGUI) await updateGUI(ns);
- }
- //check health of the node.
- if (!healthy) {
- ns.tprint("Fell out of sync somehow. Waiting for threads to end.");
- while (performance.now() < lastExecutionTime) {
- await ns.sleep(100);
- }
- //Something is out of whack here. Lets attempt a reprime
- healthy = await startPriming();
- }
- }
- ns.tprint("Ending due to not being healthy anymore.");
- cs = ns.getServerSecurityLevel(server);
- ms = ns.getServerMinSecurityLevel(server);
- mm = ns.getServerMaxMoney(server);
- ma = ns.getServerMoneyAvailable(server);
- ns.tprint("At End");
- ns.tprint("Current Security Level: ", cs);
- ns.tprint("Min Security Level: ", ms);
- ns.tprint("Current Money: ", ma, " / ", mm);
- }
- function getRatio(ns, server, player, hackThreads = 1, roundThreadsUp = true) {
- let weakenTime = myForms.weakenTime(server, player);
- //get how much money one thread of hack would get us
- let hackPercent = myForms.hackPercent(server, player);
- if (hackPercent * hackThreads > .5) hackThreads = Math.ceil(.5 / hackPercent);
- let moneyStolen = server.moneyMax * hackPercent * hackThreads;
- //figure out how many grow threads it would take to recover
- let growPercent = myForms.growPercent(server, 1, player, 1);
- let moneyGrown = (server.moneyMax - moneyStolen) * (growPercent - 1);
- //ns.tprint(moneyGrown, " = (", server.moneyMax, " - ", moneyStolen, ") * ", growPercent - 1);
- let growthThreads = moneyStolen / moneyGrown;
- //ns.tprint(growthThreads, " = ", moneyStolen, " / ", moneyGrown);
- if (roundThreadsUp) growthThreads = Math.ceil(growthThreads);
- //figure out how many weaken Threads are needed.
- let weakenThreads1 = 0;
- let weakenThreads2 = 0;
- if (roundThreadsUp) {
- weakenThreads1 = Math.ceil(hackThreads / 25);
- weakenThreads2 = Math.ceil(growthThreads / 1.25);
- }
- else {
- weakenThreads1 = hackThreads / 25;
- weakenThreads2 = growthThreads / 1.25;
- }
- let totalThreads = hackThreads + growthThreads + weakenThreads1 + weakenThreads2;
- let incomePerSecond = moneyStolen / (weakenTime / 1000);
- return { hack: hackThreads, weaken1: weakenThreads1, grow: growthThreads, weaken2: weakenThreads2, hackPercent: hackPercent, totalThreads: totalThreads, income: incomePerSecond, totalHackPercent: hackPercent * hackThreads };
- }
- //Takes an array of actions
- //An action is defined as - [threadCount, command, timeToFinish, target, executionTime, scriptRam]
- let lastActionID = 0;
- /** @param {NS} ns */
- function batchSplit(ns, actions, servers, batchServers = [], deb = false) {
- let actionID = lastActionID;
- for (let action of actions) {
- let remainingThreads = action[0];
- let command = action[1];
- let timeToFinish = action[2];
- let target = action[3];
- let executionTime = action[4];
- let scriptRam = action[5];
- lastActionID++;
- for (let tserver of servers) {
- let server = tserver[0];
- let freeThreads = Math.floor((ns.getServerMaxRam(server) - ns.getServerUsedRam(server)) / ns.getScriptRam(command));
- for (let bServer of batchServers) {
- if (bServer[0] == server) {
- freeThreads -= bServer[1];
- }
- }
- if (deb) ns.tprint(server, " - ", freeThreads);
- if (freeThreads > 0) {
- if (remainingThreads > freeThreads) {
- batchServers.push([server, freeThreads, command, target, timeToFinish, executionTime, actionID++]);
- remainingThreads -= freeThreads;
- } else {
- batchServers.push([server, remainingThreads, command, target, timeToFinish, executionTime, actionID++]);
- remainingThreads = 0;
- break;
- }
- }
- if (remainingThreads == 0) {
- break;
- }
- }
- if (remainingThreads > 0) {
- //ns.tprint("Unable to batch - ", action, batchServers);
- return [false, action, "Batch too large for the network", remainingThreads, batchServers];
- }
- }
- return [true, batchServers, "Batched Actions Successfully"];
- }
- //["n00dles",4,"/newserver/grow.js","joesguns",13529012.076642979,20249.87664293067,0]
- //target, timeToFinish, executionTime, actionID
- /** @param {NS} ns */
- async function executeBatch(ns, batch, batchDelay = 0) {
- //ns.tprint(batch);
- for (let batchOrder of batch[1]) { //target ttf execution time id
- //ns.tprint(batchOrder[0], " ordering - ",batchOrder[1] );
- ns.exec(batchOrder[2], batchOrder[0], batchOrder[1], batchOrder[3], batchOrder[4], batchOrder[5], batchOrder[6]);
- }
- }
- export function autocomplete(data, args) {
- return [...data.servers];
- }
- /** @param {NS} ns */
- async function log(ns, s, level) {
- if (doLog && level <= logLevel) ns.tprint(s);
- }
- /** @param {NS} ns */
- async function dropImmunity(ns, server) {
- // If we have the BruteSSH.exe program, use it to open the SSH Port
- // on the target server
- let portLevel = 0;
- if (ns.fileExists("BruteSSH.exe", "home") && !ns.hasRootAccess(server) && ns.getServerNumPortsRequired(server) > portLevel) {
- log(ns, "Attempting BruteSSH on " + server, 2);
- ns.brutessh(server);
- portLevel++;
- }
- if (ns.fileExists("FTPCrack.exe", "home") && !ns.hasRootAccess(server) && ns.getServerNumPortsRequired(server) > portLevel) {
- log(ns, "Attempting FTPCrack on " + server, 2);
- ns.ftpcrack(server);
- portLevel++;
- }
- if (ns.fileExists("relaySMTP.exe", "home") && !ns.hasRootAccess(server) && ns.getServerNumPortsRequired(server) > portLevel) {
- log(ns, "Attempting relaySMTP on " + server, 2);
- ns.relaysmtp(server);
- portLevel++;
- }
- if (ns.fileExists("HTTPWorm.exe", "home") && !ns.hasRootAccess(server) && ns.getServerNumPortsRequired(server) > portLevel) {
- log(ns, "Attempting HTTPWorm on " + server, 2);
- ns.httpworm(server);
- portLevel++;
- }
- if (ns.fileExists("SQLInject.exe", "home") && !ns.hasRootAccess(server) && ns.getServerNumPortsRequired(server) > portLevel) {
- log(ns, "Attempting SQLInject on " + server, 2);
- ns.sqlinject(server);
- portLevel++;
- }
- // Get root access to target server
- if (!ns.hasRootAccess(server)) {
- if (ns.getServerNumPortsRequired(server) <= portLevel) {
- ns.nuke(server);
- if (ns.hasRootAccess(server)) {
- log(ns, "Gained root access to " + server, 1);
- }
- }
- else log(ns, "Not enough open ports for " + server + " to run NUKE.exe", 2);
- }
- }
Add Comment
Please, Sign In to add comment