From 7b393a7ffccbd5a433d8dceba21b818fe902c03f Mon Sep 17 00:00:00 2001 From: Zjamnik Date: Sat, 10 Sep 2022 20:42:31 +0200 Subject: [PATCH] grow helpers --- .vscode/default.code-snippets | 23 ++++- Bitburner.code-workspace | 2 + auto-nuke.js | 161 +++++++++++++++++++--------------- buy-grow-server.js | 20 +++++ find-csec.js | 9 +- grow-helper.js | 42 +++++++++ hacknet-bot.js | 38 ++++++-- jsconfig.json | 14 +++ kill-all-simple-hack.js | 30 ++++--- kill-nuke.js | 8 ++ simple-hack.js | 36 +++++--- start-grow-helpers.js | 9 ++ 12 files changed, 281 insertions(+), 111 deletions(-) create mode 100644 buy-grow-server.js create mode 100644 grow-helper.js create mode 100644 jsconfig.json create mode 100644 kill-nuke.js create mode 100644 start-grow-helpers.js diff --git a/.vscode/default.code-snippets b/.vscode/default.code-snippets index eaf18eb..19ffc46 100644 --- a/.vscode/default.code-snippets +++ b/.vscode/default.code-snippets @@ -31,9 +31,13 @@ "/** @param {import(\".\").NS } ns */", "", "export async function main(ns) {", - " ns.disableLog('ALL');", + " // ns.disableLog('ALL');", + "", + " async function writeLog(obj) {", + " await ns.tryWritePort($1, obj + '\\n');", + " }", " ", - " $0", + " $2", "}" ], "description": "New file template for Bitburner." @@ -42,7 +46,8 @@ "scope": "", "prefix": "print", "body": [ - "ns.print(`$0`);" + "ns.print(`$1`);", + "$2" ], "description": "NS print" }, @@ -50,8 +55,18 @@ "scope": "", "prefix": "tprint", "body": [ - "ns.tprint(`$0`);" + "ns.tprint(`$1`);", + "$2" ], "description": "NS terminal print" + }, + "log": { + "scope": "", + "prefix": "log", + "body": [ + "writeLog(`$1`);", + "$2" + ], + "description": "write log to port" } } \ No newline at end of file diff --git a/Bitburner.code-workspace b/Bitburner.code-workspace index 7a2fa71..ace18aa 100644 --- a/Bitburner.code-workspace +++ b/Bitburner.code-workspace @@ -73,8 +73,10 @@ "sml": "cd $dir && sml $fileName" }, "cSpell.words": [ + "avmnite", "brutessh", "CSEC", + "dles", "ftpcrack", "Hacknet", "httpworm", diff --git a/auto-nuke.js b/auto-nuke.js index b348021..fe742a5 100644 --- a/auto-nuke.js +++ b/auto-nuke.js @@ -2,6 +2,13 @@ export async function main(ns) { // ns.disableLog('ALL'); + async function writeLog(type, obj) { + let timestamp = ''; + await ns.tryWritePort(2, `t${timestamp}_${type} = ${obj};\n`); + + if (['ERROR', 'TERMINAL'].indexOf(type) != -1) ns.tprint(`${timestamp} ${type} = ${obj}`); + } + /** * @constant * @default @@ -23,7 +30,7 @@ export async function main(ns) { EXPLOITS.forEach(exploit => { if (ns.fileExists(exploit)) ++maxPorts; }); - // ns.tprint(`Max ports for hacking ${maxPorts}`); + // ns.tryWritePort(2, `Max ports for hacking ${maxPorts}`); return maxPorts; } @@ -48,17 +55,17 @@ export async function main(ns) { /** @function runHack * Recursively scan, try to nuke and hack servers in the network * @param {string} server server to nuke and hack - * @returns {number} exit code; if negative error, if positive hack script PID, if 0 already running + * @returns {Promise} exit code; if negative error, if positive hack script PID, if 0 already running */ - function runHack(server) { + async function runHack(server) { let script = 'simple-hack.js'; let serverStatus = analyzeServer(server); - ns.tprint(`${server}: ${JSON.stringify(serverStatus)}`); + await writeLog('ANALYZE', `{server: "${server}", status: ${JSON.stringify(serverStatus)}}`); if (!serverStatus.rootAccess) { if (serverStatus.nukeAvailable) { - ns.tprint(`Nuking ${server}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`); + await writeLog('NUKE', `"Nuking ${server}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"`); for (let i = 0; i < maxPortsToHack(); ++i) { switch (EXPLOITS[i]) { case 'BruteSSH.exe': @@ -91,8 +98,8 @@ export async function main(ns) { if (serverStatus.rootAccess) { if (!ns.fileExists(script, 'home')) { - ns.tprint(`Script '${script}' doesn't exist!`); - return -3; + await writeLog('ERROR', `"Script '${script}' doesn't exist!"`); + // return -3; } ns.scp(script, server, 'home'); @@ -105,20 +112,21 @@ export async function main(ns) { let a = ns.scriptRunning(script, server); if (!a) { if (maxThreads == 0) { - ns.tprint(`Not enough ram to run '${script}' on '${server}', ${scriptRam}/${serverFreeRam}!`); + // await writeLog('ERROR', `"Not enough ram to run '${script}' on '${server}', ${scriptRam}/${serverFreeRam}!"`); return -4; } + let execExitCode = ns.exec(script, server, maxThreads, server); - ns.tprint(`post exec ${execExitCode}`); + if (!execExitCode) { - ns.tprint(`Exec error running script '${script} on '${server}!`); + // await writeLog('ERROR', `"Exec error running script '${script} on '${server}!"`); return -5; } else { return execExitCode; } } else { - ns.tprint(`Hack already running on ${server}`); + // await writeLog('ERROR', `"Hack already running on ${server}"`); return 0; } } @@ -126,82 +134,95 @@ export async function main(ns) { return -6; } - let nukedServers = ['home', 'CSEC']; + // let nukedServers = ['home', 'CSEC', 'avmnite-02h']; + // /** + // * Recursively scan, try to nuke and hack servers in the network + // * @async + // * @param {string} server server to scan + // */ + // async function scanServer(server, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1) { + // if (depth <= maxDepth) { + // let availableServers = ns.scan(server); + + // // hack servers in current scan + // for (let i = 0; i < availableServers.length; ++i) { + // await writeLog('SCAN', `{server: "${availableServers[i]}", index: ${nukedServers.indexOf(availableServers[i])}, available: ["${availableServers.toString().replaceAll(',','","')}"]}`); + // if (nukedServers.indexOf(availableServers[i]) == -1) { + // nukedServers.push(availableServers[i]); + // await scanServer(availableServers[i], maxDepth, depth + 1); + // let hackExitCode = await runHack(availableServers[i]); + + // if (hackExitCode == 0) { + // await writeLog('HACK', `"Hack already running on ${availableServers[i]}"`); + // } if (hackExitCode == -6) { + // await writeLog('HACK', `"No root access to ${availableServers[i]}!"`); + // } else { + // if (hackExitCode < 0) { + // await writeLog('ERROR', `"Hack exec ERROR on '${availableServers[i]}': ${hackExitCode}!"`); + // } else { + // await writeLog('HACK', `"Hack started on '${availableServers[i]}'"`); + // } + // } + // } + // } + // } + // await ns.sleep(10); + // } + + let excludeServers = ['home']; + for (let index = 0; index < 25; index++) { + excludeServers.push(`home-${index}`); + } + excludeServers.push('CSEC'); + excludeServers.push('avmnite-02h'); /** - * Recursively scan, try to nuke and hack servers in the network + * Recursively kill simple-hack.js running on servers in the network * @async - * @param {string} server server to scan + * @param {string} currentServer server to scan */ - async function scanServer(server, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1) { + async function scanServer(currentServer, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1, previousServer = currentServer) { if (depth <= maxDepth) { - let availableServers = ns.scan(server); + let availableServers = ns.scan(currentServer); - // hack servers in current scan for (let i = 0; i < availableServers.length; ++i) { - ns.tprint(`${availableServers[i]} ${nukedServers.indexOf(availableServers[i])} ${nukedServers}`); - if (nukedServers.indexOf(availableServers[i]) == -1) { - nukedServers.push(availableServers[i]); - await scanServer(availableServers[i], maxDepth, depth + 1); - let hackExitCode = runHack(availableServers[i]); + let nextServer = availableServers[i]; - if (hackExitCode == 0) { - ns.tprint(`Hack already running on ${availableServers[i]}`); - } if (hackExitCode == -6) { - ns.tprint(`No root access to ${availableServers[i]}!`); - } else { - if (hackExitCode < 0) { - ns.tprint(`Hack exec ERROR on '${availableServers[i]}': ${hackExitCode}!`); + if (nextServer != currentServer && nextServer != previousServer) { + if (excludeServers.indexOf(nextServer) == -1) { + let hackExitCode = await runHack(nextServer); + + if (hackExitCode == 0) { + await writeLog('HACK', `"Hack already running on ${nextServer}"`); + } else if (hackExitCode == -6) { + await writeLog('HACK', `"No root access to ${nextServer}!"`); + } else if (hackExitCode == -4) { + await writeLog('HACK', `"Not enough RAM to run script on ${nextServer}!"`); } else { - ns.tprint(`Hack started on '${availableServers[i]}'`); + if (hackExitCode < 0) { + await writeLog('ERROR', `"Hack exec ERROR on '${nextServer}': ${hackExitCode}!"`); + } else { + await writeLog('HACK', `"Hack started on '${nextServer}'"`); + } } } + await scanServer(nextServer, maxDepth, depth + 1, currentServer); } } + + } await ns.sleep(10); } let runDepth = ns.args.length ? ns.args[0] : 1; - ns.tprint(`Running scan depth: ${runDepth}`); - await scanServer('home', ); + ns.write('nuke-log.js', '', 'w'); + if (!ns.scriptRunning('simple-hack.js', 'n00dles')) ns.write('hack-log.js', '', 'w'); + ns.tprint(`TERMINAL = "Running scan depth: ${runDepth}"`); - // let serversToNuke = {}; - // let availableServers = { "home": "home" }; - - // for (let depth = 0; depth < 2; ++depth) { - // for (const key in availableServers) { - // if (Object.hasOwnProperty.call(availableServers, key)) { - // const element = availableServers[key]; - - // ns.scan(element).forEach(elem => { - // availableServers[elem] = elem; - // }); - // } - // } - // } - - // ns.tprint(availableServers); - - // for (const element in availableServers) { - // ns.tprint(`start loop ${element}`); - - // if (element != 'home' && element != 'CSEC') { - // let hackExitCode = runHack(element); - - // if (hackExitCode == 0) { - // ns.tprint(`Hack already running on ${element}`); - // } if (hackExitCode == -6) { - // ns.tprint(`No root access to ${element}`); - // } else { - // if (hackExitCode < 0) { - // ns.tprint(`Hack exec ERROR on '${element}': ${hackExitCode}!`); - // } else { - // ns.tprint(`Hack started on '${element}'`); - // } - // } - // } - // } - - await ns.sleep(10); + while (true) { + await writeLog('INFO', `"Running scan depth: ${runDepth}"`); + await scanServer('home',); + await ns.sleep(600000); + } } diff --git a/buy-grow-server.js b/buy-grow-server.js new file mode 100644 index 0000000..183ee73 --- /dev/null +++ b/buy-grow-server.js @@ -0,0 +1,20 @@ +/** @param {import(".").NS } ns */ + +export async function main(ns) { + // ns.disableLog('ALL'); + + let serverCost = ns.getPurchasedServerCost(16); + let currentMoney = ns.getServerMoneyAvailable('home'); + + if (serverCost < 0.1 * currentMoney) { + let newServer = ns.purchaseServer('home', 16); + if (newServer != '') { + ns.tprint(`Bought a server`); + ns.scp('grow-helper.js', newServer); + let execExitCode = ns.exec('grow-helper.js', newServer, 5, 20); + ns.tprint(`Exec 'grow-helper.js' exit code: ${execExitCode}`); + } + } + + await ns.sleep(10); +} \ No newline at end of file diff --git a/find-csec.js b/find-csec.js index d30d8af..06779be 100644 --- a/find-csec.js +++ b/find-csec.js @@ -3,10 +3,9 @@ export async function main(ns) { ns.disableLog('ALL'); - - - ns.brutessh('CSEC'); - ns.nuke('CSEC'); + async function writeLog(obj) { + await ns.tryWritePort(, obj + '\n'); + } + - await ns.sleep(10); } \ No newline at end of file diff --git a/grow-helper.js b/grow-helper.js new file mode 100644 index 0000000..6d87b37 --- /dev/null +++ b/grow-helper.js @@ -0,0 +1,42 @@ +/** @param {import(".").NS } ns */ + +export async function main(ns) { + // ns.disableLog('ALL'); + + let excludeServers = ['home']; + for (let index = 0; index < 25; index++) { + excludeServers.push(`home-${index}`); + } + excludeServers.push('CSEC'); + excludeServers.push('avmnite-02h'); + + async function scanServer(currentServer, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1, previousServer = currentServer) { + if (depth <= maxDepth) { + let availableServers = ns.scan(currentServer); + + for (let i = 0; i < availableServers.length; ++i) { + let nextServer = availableServers[i]; + + if (nextServer != currentServer && nextServer != previousServer) { + if (excludeServers.indexOf(nextServer) == -1 && ns.scriptRunning('simple-hack.js', nextServer)) { + let maxMoney = ns.getServerMaxMoney(nextServer); + let currentMoney = ns.getServerMoneyAvailable(nextServer); + + if (currentMoney < 0.2 * maxMoney) { + await ns.grow(nextServer); + } + } + await scanServer(nextServer, maxDepth, depth + 1, currentServer); + } + } + } + await ns.sleep(10); + } + + while (true) { + + let runDepth = ns.args.length ? ns.args[0] : 1; + ns.tprint(`Running scan depth: ${runDepth}`); + await scanServer('home', runDepth); + } +} \ No newline at end of file diff --git a/hacknet-bot.js b/hacknet-bot.js index 7ac20f5..3dc7775 100644 --- a/hacknet-bot.js +++ b/hacknet-bot.js @@ -4,12 +4,13 @@ export async function main(ns) { ns.disableLog('ALL'); let nodeCostThreshold = ns.args.length > 0 ? ns.args[0] : 0.1; - let upgradeCostThreshold = ns.args.length > 1 ? ns.args[1] : 0.03; + let upgradeCostThreshold = ns.args.length > 1 ? ns.args[1] : 0.05; let upgradeCount = ns.args.length > 2 ? ns.args[2] : 1; + let levelCap = 150; + let ramCap = 64; + let coreCap = 4; ns.tprint(`Bot started {nodeCostThreshold: ${nodeCostThreshold}, upgradeCostThreshold: ${upgradeCostThreshold}, upgradeCount: ${upgradeCount}}`); - await ns.sleep(10000); - while (true) { let currentMoney = ns.getServerMoneyAvailable("home"); let nodePurchaseCost = ns.hacknet.getPurchaseNodeCost(); @@ -22,22 +23,43 @@ export async function main(ns) { } for (let index = 0; index < nodeCount; ++index) { - if (ns.hacknet.getLevelUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { + let nodeStats = ns.hacknet.getNodeStats(index); + + if (nodeStats.level < levelCap && ns.hacknet.getLevelUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { ns.hacknet.upgradeLevel(index, upgradeCount); currentMoney = ns.getServerMoneyAvailable("home"); } - if (ns.hacknet.getRamUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { + + if (nodeStats.ram < ramCap && ns.hacknet.getRamUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { ns.hacknet.upgradeRam(index, upgradeCount); currentMoney = ns.getServerMoneyAvailable("home"); } - if (ns.hacknet.getCoreUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { + + if (nodeStats.cores < coreCap && ns.hacknet.getCoreUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) { ns.hacknet.upgradeCore(index, upgradeCount); currentMoney = ns.getServerMoneyAvailable("home"); } } - let portData = ns.readPort(1); - if (portData != 'NULL PORT DATA') ns.write('hack-log.js', portData, 'a'); + let serverCost = ns.getPurchasedServerCost(16); + + if (serverCost < currentMoney) { + let newServer = ns.purchaseServer('home', 16); + if (newServer != '') { + ns.tprint(`Bought a server`); + ns.scp('grow-helper.js', newServer); + let execExitCode = ns.exec('grow-helper.js', newServer, 5, 20); + ns.tprint(`Exec 'grow-helper.js' exit code: ${execExitCode}`); + } + } + + let logFiles = ['hack-log.js', 'nuke-log.js']; + + for (let index = 0; index < logFiles.length; index++) { + const logFile = logFiles[index]; + let portData = ns.readPort(index + 1); + if (portData != 'NULL PORT DATA') ns.write(logFile, portData, 'a'); + } await ns.sleep(10); } diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..458cf9b --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Node", + "target": "ES2020", + "jsx": "react", + "strictNullChecks": true, + "strictFunctionTypes": true + }, + "exclude": [ + "node_modules", + "**/node_modules/*" + ] +} \ No newline at end of file diff --git a/kill-all-simple-hack.js b/kill-all-simple-hack.js index f8248c8..4c0a39b 100644 --- a/kill-all-simple-hack.js +++ b/kill-all-simple-hack.js @@ -4,32 +4,40 @@ export async function main(ns) { ns.disableLog('ALL'); - let nukedServers = ['home', 'CSEC']; + let excludeServers = ['home']; + for (let index = 0; index < 25; index++) { + excludeServers.push(`home-${index}`); + } + excludeServers.push('CSEC'); + excludeServers.push('avmnite-02h'); /** * Recursively kill simple-hack.js running on servers in the network * @async - * @param {string} server server to scan + * @param {string} currentServer server to scan */ - async function scanServer(server, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1) { + async function scanServer(currentServer, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1, previousServer = currentServer) { if (depth <= maxDepth) { - let availableServers = ns.scan(server); + let availableServers = ns.scan(currentServer); - // hack servers in current scan for (let i = 0; i < availableServers.length; ++i) { - if (nukedServers.indexOf(availableServers[i]) == -1) { - nukedServers.push(availableServers[i]); - await scanServer(availableServers[i], maxDepth, depth + 1); - ns.scriptKill('simple-hack.js', availableServers[i]); + let nextServer = availableServers[i]; + + if (nextServer != currentServer && nextServer != previousServer) { + if (excludeServers.indexOf(nextServer) == -1) ns.scriptKill('simple-hack.js', nextServer); + await scanServer(nextServer, maxDepth, depth + 1, currentServer); } } + + } await ns.sleep(10); } + let runDepth = ns.args.length ? ns.args[0] : 1; ns.tprint(`Running scan depth: ${runDepth}`); - await scanServer('home',); + await scanServer('home', runDepth); await ns.sleep(10); -} \ No newline at end of file +} diff --git a/kill-nuke.js b/kill-nuke.js new file mode 100644 index 0000000..8af3640 --- /dev/null +++ b/kill-nuke.js @@ -0,0 +1,8 @@ +/** @param {import(".").NS } ns */ + +export async function main(ns) { + ns.disableLog('ALL'); + + ns.scriptKill('auto-nuke.js', 'home'); + await ns.sleep(10); +} \ No newline at end of file diff --git a/simple-hack.js b/simple-hack.js index b483877..7f10a4b 100644 --- a/simple-hack.js +++ b/simple-hack.js @@ -3,33 +3,43 @@ export async function main(ns) { // ns.disableLog('ALL'); + async function writeLog(obj) { + await ns.tryWritePort(1, obj + '\n'); + } + let server = ns.args[0]; let maxMoney = ns.getServerMaxMoney(server); let minSecurity = ns.getServerMinSecurityLevel(server); let loop = 0; + let previousMoney = 0; - while (true) { + while (maxMoney != 0) { let currentMoney = ns.getServerMoneyAvailable(server); let currentSecurity = ns.getServerSecurityLevel(server); ns.print(`Money: ${currentMoney} / ${maxMoney}`); ns.print(`Security: ${currentSecurity} / ${minSecurity}`); - let newMoney = 'N/A'; - if (currentMoney < 0.95 * maxMoney) { - newMoney = await ns.grow(server); - } - - let newSecurity = 'N/A'; - if (currentSecurity > 2 * minSecurity) { - newSecurity = await ns.weaken(server); - } - let hackedMoney = 0; - if (currentMoney > 0.4 * maxMoney) { + if (currentMoney > 0.1 * maxMoney) { hackedMoney = await ns.hack(server); + currentMoney = ns.getServerMoneyAvailable(server); } - await ns.tryWritePort(1, `${server} = {loop: ${++loop}, hack: ${Math.floor(hackedMoney)}, money: "${Math.floor(currentMoney)} / ${Math.floor(maxMoney)} = ${((currentMoney / maxMoney) * 100).toFixed(2)}", security: "${currentSecurity.toFixed(2)} / ${Math.floor(minSecurity) } = ${((currentSecurity / minSecurity) * 100).toFixed(4)}"};\n`); + if (currentMoney < 0.9 * maxMoney) { + while (currentMoney <= previousMoney) { + await ns.grow(server); + currentMoney = ns.getServerMoneyAvailable(server); + } + } + previousMoney = currentMoney; + + if (currentSecurity > 2 * minSecurity) { + await ns.weaken(server); + currentSecurity = ns.getServerSecurityLevel(server); + } + + await writeLog(`${server.replaceAll('-', '_')} = {loop: ${++loop}, hack: ${Math.floor(hackedMoney)}, money: ${Math.floor(currentMoney)} / ${Math.floor(maxMoney)} == ${((currentMoney / maxMoney) * 100).toFixed(2)}, security: ${currentSecurity.toFixed(2)} / ${Math.floor(minSecurity)} == ${((currentSecurity / minSecurity) * 100).toFixed(4)}};`); await ns.sleep(10); } + await ns.sleep(10); } \ No newline at end of file diff --git a/start-grow-helpers.js b/start-grow-helpers.js new file mode 100644 index 0000000..9ac8062 --- /dev/null +++ b/start-grow-helpers.js @@ -0,0 +1,9 @@ +/** @param {import(".").NS } ns */ + +export async function main(ns) { + // ns.disableLog('ALL'); + + for (let server = 0; server <= ns.args[0]; server++) { + ns.exec('grow-helper.js', `home-${server}`, 5, 20); + } +} \ No newline at end of file