Last active
September 8, 2024 14:30
-
-
Save MolarFox/87c2dd6a7337e307ae7c328aabb4fdbe to your computer and use it in GitHub Desktop.
Bitburner Stuff
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
| // Basic Autohack v1.0 | |
| // Basic first pass dingus script. Just grows, weakens, and hacks every loop | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| const args = arguments["0"]["args"]; | |
| let tgt = args[0] | |
| while(true) { | |
| await ns.grow(tgt); | |
| await ns.weaken(tgt); | |
| await ns.hack(tgt); | |
| } | |
| } |
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
| // Bounded Hack Autohack v1.1 | |
| // Aims to get money and security to certain levels before attempting any hacking | |
| // By default - attempts to get to min security and max profit | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| let hack_count = 0 | |
| let hack_reporting_interval = 10 | |
| const args = arguments["0"]["args"]; | |
| const sv_max_money = await ns.getServerMaxMoney(tgt); | |
| const sv_min_security = await ns.getServerMinSecurityLevel(tgt); | |
| let tgt = args[0] | |
| let min_profit = typeof(args[1]) == 'undefined' ? sv_max_money : args[1]; | |
| let max_sec = typeof(args[2]) == 'undefined' ? sv_min_security : args[2]; | |
| while(true) { | |
| let current_money = await ns.getServerMoneyAvailable(tgt); | |
| let current_sec = await ns.getServerSecurityLevel(tgt); | |
| if (current_money < min_profit) { | |
| await ns.grow(tgt); | |
| continue; | |
| } | |
| if (current_sec > max_sec) { await ns.weaken(tgt) }; | |
| if (current_money >= min_profit && current_sec <= max_sec) { | |
| await ns.hack(tgt); | |
| hack_count++; | |
| if (hack_count % hack_reporting_interval == 0) { | |
| ns.alert(`Hacked ${tgt} ${hack_count} times`) | |
| } | |
| } | |
| } | |
| } |
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
| // Bubble Growth Autohack v1.0 | |
| // Aims to hack as often as possible, ensuring that money and sec are both improved since the last hack attempt | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| let hack_count = 0 | |
| let hack_reporting_interval = 10 | |
| const args = arguments["0"]["args"]; | |
| let tgt = args[0] | |
| let last_profit = await ns.getServerMoneyAvailable(tgt); | |
| let last_sec = await ns.getServerSecurityLevel(tgt); | |
| const sv_max_money = await ns.getServerMaxMoney(tgt); | |
| const sv_min_security = await ns.getServerMinSecurityLevel(tgt); | |
| while(true) { | |
| let current_money = await ns.getServerMoneyAvailable(tgt); | |
| let current_sec = await ns.getServerSecurityLevel(tgt); | |
| if (current_money < last_profit && current_money != sv_max_money) { | |
| await ns.grow(tgt); | |
| continue; | |
| } | |
| if (current_sec > last_sec && current_sec != sv_min_security) { await ns.weaken(tgt) }; | |
| if (current_money >= last_profit && current_sec <= last_sec) { | |
| await ns.hack(tgt); | |
| hack_count++; | |
| if (hack_count % hack_reporting_interval == 0) { | |
| ns.alert(`Attempted to hack ${tgt} ${hack_count} times`) | |
| } | |
| } | |
| } | |
| } |
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
| // autoroot v1.4 | |
| // Reads a CSV of enumerated hosts and attempts to backdoor all, | |
| // Then use their collective compute to mine currency off all | |
| export function autocomplete(data, _) { | |
| return [...data.txts]; | |
| } | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| const args = arguments["0"]["args"]; | |
| const file_name = args[0]; | |
| // Increase static ram estimate to factor dynamic run calls later on | |
| ns.ramOverride(2.0) | |
| let player_level = await ns.getHackingLevel() | |
| let sv_list = parseCsv(ns.read(file_name)); | |
| // Root every possible node | |
| sv_list.map(((x) => {backdoorServer(ns, x, player_level)})); | |
| ns.tprint("Finished running! Remember to update hosts CSV with nmap before rerunning") | |
| } | |
| /** | |
| * @param {String} file_data | |
| * @return {Array} Array of dicts containing info on each enumerated node | |
| * */ | |
| function parseCsv(file_data) { | |
| return file_data.split('\n').map((raw_row) => { | |
| let row = raw_row.split(','); | |
| let res = {}; | |
| res["name"] = row[0]; | |
| res["path"] = row[1]; | |
| res["root"] = (row[2] === 'true'); | |
| res["min_hack_level"] = parseInt(row[3]) || row[3]; | |
| res["max_profit"] = parseFloat(row[4]) || row[4]; | |
| res["max_ram"] = parseFloat(row[5]) || row[5]; | |
| return res; | |
| }).slice(1); // Slice out the header row | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @param {Object} node | |
| * */ | |
| async function backdoorServer(ns, node, player_level) { | |
| if (node.root) { return }; | |
| if (player_level < node.min_hack_level){ return }; | |
| ns.tprint(`Attempting to backdoor ${node.name}...`); | |
| let name = node.name; | |
| let ports_needed_count = ns.getServerNumPortsRequired(name); | |
| let available_exploits = availableExploits(ns).map((x) => x.split('.')[0].toLowerCase()); | |
| if (ports_needed_count > available_exploits.length) { | |
| ns.tprint(" [!] Not enough exploits available to enable backdoor! Skipping."); | |
| return | |
| } | |
| available_exploits.length = ports_needed_count | |
| for (const exploit of available_exploits) { | |
| ns[exploit](name); | |
| } | |
| await ns.nuke(name); | |
| await ns.tprint(`Successfully backdoored ${name}!`); | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @return {Array<String>} List of available scripts | |
| * */ | |
| function availableExploits(ns) { | |
| let script_files = [ | |
| "BruteSSH.exe", | |
| "FTPCrack.exe", | |
| "HTTPWorm.exe", | |
| "relaySMTP.exe", | |
| "SQLInject.exe", | |
| ] | |
| let res = []; | |
| for (const f of script_files) { | |
| if (ns.fileExists(f)) { | |
| res.push(f) | |
| } | |
| } | |
| return res | |
| } |
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
| // nmap v1.3 | |
| // Enumerates all servers from the current one, and produces a CSV containing a list of all found | |
| export function autocomplete(data, _) { | |
| return [...data.txts]; | |
| } | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| const args = arguments["0"]["args"]; | |
| const header_row = "name,path,root,min_hack_level,max_profit,max_ram"; | |
| const file_name = args[0]; | |
| let nodes = await dfs(ns, ns.getHostname()); | |
| // Write to CSV file | |
| ns.write(file_name, header_row, 'w'); | |
| for (let n in nodes) { | |
| let line = csvRow(nodes[n]); | |
| ns.write(file_name, line, 'a'); | |
| } | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @param {String} root | |
| * @return {Object} Dict: key<String> node name, val<Object> attributes describing a node | |
| * */ | |
| async function dfs(ns, root) { | |
| let to_visit = [root]; | |
| let visited = {}; | |
| visited[root] = await nodeData(ns, root, [root]); | |
| while (to_visit.length > 0) { | |
| let head = to_visit.shift(); | |
| // await ns.tprint(`At ${head} - ${to_visit}`); | |
| let child_nodes = await ns.scan(head); | |
| for (let n in child_nodes) { | |
| let node = child_nodes[n]; | |
| if (node in visited) { continue }; | |
| to_visit.push(node); | |
| visited[node] = await nodeData(ns, node, visited[head].path.concat(node)); | |
| } | |
| } | |
| return visited; | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @param {String} name | |
| * @param {Array<String>} path | |
| * @return {Object} Contains attributes describing a node | |
| * */ | |
| async function nodeData(ns, name, path) { | |
| return { | |
| name: name, | |
| path: path, | |
| root: await ns.hasRootAccess(name), | |
| min_hack_level: await ns.getServerRequiredHackingLevel(name), | |
| max_profit: await ns.getServerMaxMoney(name), | |
| max_ram: await ns.getServerMaxRam(name), | |
| }; | |
| } | |
| /** | |
| * @param {Object} node | |
| * @return {String} | |
| * */ | |
| function csvRow(node) { | |
| // TODO: whatever make this dynamic later | |
| return '\n' + [ | |
| node.name, | |
| node.path.join('/'), | |
| node.root, | |
| node.min_hack_level, | |
| node.max_profit, | |
| node.max_ram, | |
| ].join(','); | |
| } |
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
| // Auto Hack Orchestrator v1.2 | |
| // Reads a CSV of enumerated hosts and schedules all hosts to repeatedly hack one another | |
| export function autocomplete(data, _) { | |
| return [...data.txts, ...data.scripts]; | |
| } | |
| /** @param {NS} ns */ | |
| export async function main(ns) { | |
| const args = arguments["0"]["args"]; | |
| const nmap_file = args[0]; | |
| const hack_script = args[1]; | |
| const include_home = (typeof(args[2]) === 'undefined') ? false : Boolean(args[2]); | |
| const player_level = await ns.getHackingLevel(); | |
| let sv_list = ( | |
| parseCsv(ns.read(nmap_file)) // All servers reachable from host | |
| .filter((x) => x.root) // Which have been rooted | |
| ); | |
| sv_list = (include_home) ? sv_list : sv_list.filter((x) => x.name != "home"); | |
| let allocated = allocateAndRun(ns, sv_list, player_level, hack_script); | |
| ns.tprint(`Configured ${Object.keys(allocated).length} attacks!`) | |
| } | |
| /** | |
| * @param {String} file_data | |
| * @return {Array} Array of dicts containing info on each enumerated node | |
| * */ | |
| function parseCsv(file_data) { | |
| return file_data.split('\n').map((raw_row) => { | |
| let row = raw_row.split(','); | |
| let res = {}; | |
| res["name"] = row[0]; | |
| res["path"] = row[1]; | |
| res["root"] = (row[2] === 'true'); | |
| res["min_hack_level"] = parseInt(row[3]) || row[3]; | |
| res["max_profit"] = parseFloat(row[4]) || row[4]; | |
| res["max_ram"] = parseFloat(row[5]) || row[5]; | |
| return res; | |
| }).slice(1); // Slice out the header row | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @param {Array<Object>} nodes | |
| * @param {Int} player_level | |
| * @return {Object<String,Object>} Dict mapping each server to its target | |
| * */ | |
| function allocateAndRun(ns, nodes, player_level, hack_script) { | |
| const nodes_by_profit = ( | |
| nodes | |
| .filter((x) => x.min_hack_level <= player_level) // Player can hack | |
| .filter((x) => x.max_profit > 0) // Will yield hacking profits | |
| .toSorted((a,b) => (a.max_profit - b.max_profit)) // Sorted by max profit (asc) | |
| ); | |
| const nodes_by_ram = nodes.toSorted((a,b) => (a.max_ram - b.max_ram)); | |
| let res = {}; | |
| // ns.tprint(`--NODES BY RAM--\n${nodes_by_ram.map((x) => x.name)}\n\n--NODES BY PROFIT--\n${nodes_by_profit.map((x) => x.name)}\n\n`) | |
| while (nodes_by_profit.length > 0) { | |
| let attacker = nodes_by_ram.pop(); // Take strongest rooted server | |
| let target = nodes_by_profit.at(-1).name == attacker.name ? nodes_by_profit.splice(-2, 1)[0] : nodes_by_profit.splice(-1, 1)[0]; // Take highest profit server | |
| // Run attack | |
| scheduleAttack(ns, attacker, target, hack_script); | |
| res[attacker.name] = target; | |
| } | |
| return res; | |
| } | |
| /** | |
| * @param {NS} ns | |
| * @param {Object} node | |
| * @param {Object} target | |
| * @param {String} hack_script | |
| */ | |
| function scheduleAttack(ns, node, target, hack_script) { | |
| const hack_thread_cost = ns.getScriptRam(hack_script); | |
| const max_threads = Math.floor(node.max_ram / hack_thread_cost); | |
| ns.tprint(`Attacking ${target.name} [max profit: ${target.max_profit}] from ${node.name} [ram: ${node.max_ram}]`) | |
| ns.scp(hack_script, node.name); | |
| ns.exec(hack_script, node.name, max_threads, target.name) | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A bunch of random scripts I wrote to play Bitburner.