Created
May 19, 2022 17:52
-
-
Save heathkit/117a960ac5c88fa6fbc1d9105d1349d5 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
// optimal_hack.js | |
/** | |
* TODO | |
* - split jobs to fit in available machines | |
* - 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); | |
await ns.sleep(5000); | |
} | |
} | |
/** | |
* 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 + 1000) | |
} | |
/** | |
* @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 SCRIPT = 'hgw.js'; | |
/** | |
* Search for a node to run the given job on | |
* | |
* TODO: Split job to fit into available memory | |
* | |
* @param {NS} ns | |
* @param {threads} number | |
* @param {target} string | |
* @param {mode} string | |
* @param {delay} number | |
*/ | |
async function runJob(ns, threads, target, mode, delay) { | |
let ramCost = ns.getScriptRam(SCRIPT); | |
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)/ramCost; | |
if (maxThreads > threads) { | |
runHost = host; | |
break; | |
} | |
} | |
if (!runHost) { | |
throw new Error(`Unable to find host to run job with ${threads} threads`); | |
} | |
await ns.scp(SCRIPT, runHost); | |
await ns.exec(SCRIPT, runHost, threads, target, mode, delay); | |
} | |
// hgw.js | |
/** @param {NS} ns */ | |
export async function main(ns) { | |
let host = ns.args[0]; | |
let mode = ns.args[1]; | |
if (!host || !mode) { | |
ns.toast('Must specify host and mode!'); | |
} | |
let delay = ns.args[2]; | |
if(delay) { | |
await ns.sleep(delay); | |
} | |
switch(mode) { | |
case 'weaken': | |
await ns.weaken(host); | |
break; | |
case 'grow': | |
await ns.grow(host); | |
break; | |
case 'hack': | |
await ns.hack(host); | |
break; | |
default: | |
ns.toast('Unknown mode ${mode}'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment