Created
May 19, 2022 02:16
-
-
Save heathkit/c9d7cab0804e39c8384ccef9ab67cff1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* TODO | |
* - job chunking | |
* - determine ideal growth factor based on resource? | |
* - determine hack amount based on resources (or as parameter) | |
*/ | |
/** @param {NS} ns */ | |
export async function main(ns) { | |
let target = ns.args[0] | |
ns.disableLog('ALL') | |
ns.enableLog('exec') | |
ns.tail() | |
let server = ns.getServer(target); | |
ns.print(`Target: ${server.hostname}, Difficulty: ${server.hackDifficulty}`) | |
ns.print(`=== WEAKEN PHASE ===`) | |
let delta = server.hackDifficulty - server.minDifficulty | |
if (delta > 1) { | |
await weakenServerToMin(ns, server) | |
} | |
// Grow the server to max | |
ns.print(`=== GROW PHASE ===`) | |
await growToMax(ns, target, 4) | |
// Exploit the server | |
ns.print(`=== EXPLOIT PHASE ===`) | |
await exploit(ns, target, 0.5) | |
} | |
/** | |
* Optimally exploit the target server. | |
* | |
* @param {NS} ns | |
* @param {string} target | |
* @param {number} hackPerc | |
*/ | |
async function exploit(ns, target, hackPerc) { | |
while(true) { | |
let server = ns.getServer(target) | |
ns.print(`## Starting Hack Loop ##`) | |
ns.print(`Money: ${server.moneyAvailable}`) | |
ns.print(`Difficulty: ${server.hackDifficulty}`) | |
await exploitLoop(ns, target, hackPerc); | |
} | |
} | |
/** | |
* Runs the inner loop for the exploit algorithm | |
* | |
* @param {NS} ns | |
* @param {string} target | |
* @param {number} hackPerc | |
*/ | |
async function exploitLoop(ns, target, hackPerc) { | |
let server = ns.getServer(target) | |
let hackThreads = hackPerc/ns.hackAnalyze(target); | |
let weakenFactor = ns.weakenAnalyze(1,1); | |
let weakenBaseThreads = (server.hackDifficulty - server.minDifficulty)/weakenFactor | |
let weakenTime = ns.getWeakenTime(target); | |
let growTime = ns.getGrowTime(target); | |
let hackTime = ns.getHackTime(target); | |
let weakenHackThreads = Math.ceil(ns.hackAnalyzeSecurity(hackThreads, target)/weakenFactor + 1); | |
let growThreads = Math.ceil(ns.growthAnalyze(target, 1/(1-hackPerc))); | |
ns.print(`Growth threads: ${growThreads}`) | |
ns.print(`Growth inc: ${ns.growthAnalyzeSecurity(growThreads, target, 1)}`) | |
let weakenGrowThreads = weakenBaseThreads + Math.ceil(ns.growthAnalyzeSecurity(growThreads, target, 1)/weakenFactor) + 1; | |
// Finish the hack just before the first weaken | |
let hackDelay = weakenTime - hackTime - 500; | |
// Finish the grow just after the first weaken | |
let growDelay = (weakenTime + 1000) - growTime - 500; | |
ns.print(`Finish hack: ${hackDelay + hackTime}`); | |
ns.print(`Finish weaken1: ${weakenTime}`); | |
ns.print(`Finish grow: ${growDelay + growTime}`); | |
ns.print(`Finish weaken2: ${weakenTime + 1000}`); | |
await runJob(ns, weakenHackThreads, target, "weaken", 0); | |
await runJob(ns, weakenGrowThreads, target, "weaken", 1000); | |
await runJob(ns, growThreads, target, "grow", growDelay); | |
await runJob(ns, hackThreads, target, "hack", hackDelay); | |
await ns.sleep(weakenTime + 2) | |
} | |
/** | |
* @param {NS} ns | |
* @param {string} target | |
* @param {number} factor | |
*/ | |
async function growToMax(ns, target, factor) { | |
ns.print(`current: ${ns.getServerMoneyAvailable(target)} max: ${ns.getServerMaxMoney(target)}`) | |
while (ns.getServerMoneyAvailable(target) < ns.getServerMaxMoney(target)) { | |
let delta = ns.getServerMaxMoney(target) - ns.getServerMoneyAvailable(target) | |
ns.print(`Delta: ${delta}`) | |
let growThreads = Math.ceil(ns.growthAnalyze(target, factor)) | |
let weakenFactor = ns.weakenAnalyze(1,1); | |
let weakenThreads = ns.growthAnalyzeSecurity(growThreads,target, 1)/weakenFactor | |
ns.print(`Threads to double: ${growThreads}`) | |
ns.print(`Time to double: ${ns.getGrowTime(target)/1000/60}`) | |
ns.print(`Threads to weaken: ${weakenThreads}`) | |
ns.print(`Time to weaken: ${ns.getWeakenTime(target)/1000/60}`) | |
// start a grow and a weaken in parallel | |
let weakenTime = ns.getWeakenTime(target) | |
let minutes = (weakenTime/1000/60).toFixed(2); | |
await runJob(ns, weakenThreads, target, "weaken", 0) | |
await runJob(ns, growThreads, target, "grow", 0) | |
ns.print(`Will finish in ${minutes} minutes`) | |
await ns.sleep(weakenTime) | |
} | |
} | |
/** | |
* @param {NS} ns | |
* @param {Server} server | |
*/ | |
async function weakenServerToMin(ns, server) { | |
// Weaken server to minimum | |
let delta = server.hackDifficulty - server.minDifficulty; | |
let weakenFactor = ns.weakenAnalyze(1,1); | |
let weakenThreads = Math.ceil(delta / weakenFactor); | |
ns.print(`Weaking server. threads:${weakenThreads} delta:${delta} factor:${weakenFactor}`); | |
await runJob(ns, weakenThreads, server.hostname, "weaken", 0); | |
let weakenTime = ns.getWeakenTime(server.hostname); | |
let minutes = (weakenTime/1000/60).toFixed(2); | |
ns.print(`Will finish in ${minutes} minutes`); | |
await ns.sleep(weakenTime); | |
} | |
// Assume the 2G HGW script | |
const RAM_COST = 2; | |
/** | |
* Search for a node to run the given job on | |
* @param {NS} ns | |
* @param {threads} number | |
* @param {target} string | |
* @param {mode} string | |
* @param {delay} number | |
*/ | |
async function runJob(ns, threads, target, mode, delay) { | |
let remoteServers = JSON.parse(ns.read('servers.txt')); | |
// Add any current pservs | |
let pservs = ns.scan('home').filter(s => s.includes('pserv')); | |
let servers = ['home'].concat(pservs) | |
let runHost; | |
for (let host of servers) { | |
let server = ns.getServer(host); | |
if (!server.hasAdminRights) continue; | |
let maxThreads = (server.maxRam - server.ramUsed)/RAM_COST; | |
if (maxThreads > threads) { | |
runHost = host; | |
break; | |
} | |
} | |
if (!runHost) { | |
throw new Error(`Unable to find host to run job with ${threads} threads`); | |
} | |
await ns.scp('hgw.js', runHost); | |
await ns.exec('hgw.js', runHost, threads, target, mode, delay); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment