Skip to content

Instantly share code, notes, and snippets.

@Larkenx
Created February 23, 2023 21:01
Show Gist options
  • Save Larkenx/3bf3ffb5b1d13dc620961ecd28227806 to your computer and use it in GitHub Desktop.
Save Larkenx/3bf3ffb5b1d13dc620961ecd28227806 to your computer and use it in GitHub Desktop.
bitburner hack set up 2-23-2023
import * as utils from 'utils.js'
// Based heavily off of xsinx https://docs.google.com/document/d/1za34sQ6zpQ9lOAHoXuqrAwJFH5qJtslRXrj8FnB91d4/edit?usp=sharing
/** @param {NS} ns */
export async function main(ns) {
const pid = ns.args[1]
ns.disableLog('ALL')
const target = ns.args[0];
const moneyThresh = ns.getServerMaxMoney(target) * 0.75;
const securityThresh = ns.getServerMinSecurityLevel(target) + 5;
// Infinite loop that continuously hacks/grows/weakens the target server
while (true) {
// We recalculate times each loop, because the security will go up and down as we go, affecting those times
const hackTime = ns.getHackTime(target);
const growTime = ns.getGrowTime(target);
const weakenTime = ns.getWeakenTime(target);
// Weaken thread calculation:
const minSec = ns.getServerMinSecurityLevel(target);
const sec = ns.getServerSecurityLevel(target);
let weakenThreads = Math.ceil((sec - minSec) / ns.weakenAnalyze(1));
// Hack thread calculation:
let money = ns.getServerMoneyAvailable(target);
if (money <= 0) money = 1; // division by zero safety
let hackThreads = Math.ceil(ns.hackAnalyzeThreads(target, money));
// Grow thread calculation:
let maxMoney = ns.getServerMaxMoney(target);
let growThreads = Math.ceil(ns.growthAnalyze(target, maxMoney / money));
if (ns.getServerSecurityLevel(target) > securityThresh) {
// If the server's security level is above our threshold, weaken it
await utils.runScript(ns, "weaken.js", weakenThreads, target, pid);
await ns.sleep(weakenTime);
} else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
// If the server's money is less than our threshold, grow it
await utils.runScript(ns, "grow.js", growThreads, target, pid);
await ns.sleep(growTime);
} else {
// Otherwise, hack it
await utils.runScript(ns, "hack.js", hackThreads, target, pid);
await ns.sleep(hackTime);
}
}
}
import * as utils from 'utils.js'
/** @param {NS} ns */
export async function main(ns) {
while (true) {
ns.tprint('Spinning up hgw controllers for any newly hackable servers')
let allServs = await utils.fetchAllServers(ns)
let hackable = (await utils.filterHackableServers(ns, allServs)).map(s => s.hostname)
let concurrentHGW = ns.args[0] ? ns.args[0] : 1
for (let runtime = 0; runtime < concurrentHGW; runtime++) {
for (let s of hackable) {
ns.exec('hgw-controller.js', 'home', 1, s, runtime)
}
await ns.sleep(100)
}
await ns.sleep(1000 * 60 * 5) // every 5 minutes, check for more hackable ones because of hack lvl going up
}
}
/** @param {NS} ns */
export async function dfs(ns, mapFunction, log=false) {
let output = []
let visitedServers = []
let serversToVisit = ["home"]
while (serversToVisit.length > 0) {
let currentServer = serversToVisit.shift()
visitedServers.push(currentServer)
let servers = ns.scan(currentServer)
if (log) {
ns.tprint(currentServer,' => ', servers)
}
output.push(await mapFunction(ns, currentServer))
// visit all of connected servers if they haven't been explored yet
for (let server of servers) {
if (!visitedServers.includes(server) && !serversToVisit.includes(server)) {
serversToVisit.push(server)
}
}
}
return output
}
/** @param {NS} ns */
async function listNumOfThreads(ns, hostname) {
let runningThreads = 0
let scripts = ns.ps(hostname)
scripts.forEach(s => {
runningThreads += s.threads
})
return runningThreads
}
/** @param {NS} ns */
async function killAllScripts(ns, hostname) {
ns.killall(hostname)
}
/** @param {NS} ns */
export async function getServerInformation(ns, hostname) {
let stats = {
'hostname': hostname,
'moneyRatio': ns.getServerMoneyAvailable(hostname) / ns.getServerMaxMoney(hostname),
'moneyAvailable': ns.getServerMoneyAvailable(hostname),
'maxMoney': ns.getServerMaxMoney(hostname),
'minSecurityLevel': ns.getServerMinSecurityLevel(hostname),
'hackingLevelRequired': ns.getServerRequiredHackingLevel(hostname),
'securityLevel': ns.getServerSecurityLevel(hostname),
'maxRam': ns.getServerMaxRam(hostname),
'usedRam': ns.getServerUsedRam(hostname),
'rootAccess': ns.hasRootAccess(hostname)
}
return stats
}
export async function fetchAllServers(ns) {
return dfs(ns, getServerInformation, ns.args[1])
}
/** @param {NS} ns */
export async function filterHackableServers(ns, servers) {
let sortedByMoneyAvailable = servers
.filter(servInfo => {
return servInfo.rootAccess
&& servInfo.maxMoney > 0
&& servInfo.hackingLevelRequired <= Math.ceil(ns.getHackingLevel() / 2)
})
.sort((a, b) => b.maxMoney - a.maxMoney)
return sortedByMoneyAvailable
}
/** @param {NS} ns */
export async function runScript(ns, scriptName, threads, target, pid = 0) {
const MIN_HOME_RAM = 1024
let ramPerThread = ns.getScriptRam(scriptName);
let pservs = (await fetchAllServers(ns))
.filter(serv => serv.rootAccess && serv.maxRam > 0 && serv.hostname !== 'home')
.sort((a, b) => b.maxRam - a.maxRam)
.map(s => s.hostname)
let threadsStarted = 0
for (let serv of pservs) {
let availableRam = ns.getServerMaxRam(serv) - ns.getServerUsedRam(serv)
let possibleThreads = Math.floor(availableRam / ramPerThread)
if (serv.hostname === 'home' && availableRam <= MIN_HOME_RAM) {
continue
}
// Check if server is already at max capacity
if (possibleThreads <= 0) continue;
// Lower thread count if we are over target
if (possibleThreads > threads) possibleThreads = threads;
ns.scp(scriptName, serv);
ns.print(
`Starting script ${scriptName} on ${serv} with ${possibleThreads} threads`
);
ns.exec(scriptName, serv, possibleThreads, target, pid);
// Did we already run *all* the threads of this script?
threadsStarted += possibleThreads;
if (threadsStarted >= threads) return threadsStarted;
}
return threadsStarted
}
/** @param {NS} ns */
export async function getGlobalRam(ns) {
let servs = await fetchAllServers(ns)
let format = (n) => { return ns.nFormat(n, "00,00") }
let usedRam = servs.reduce((acc, s) => s.usedRam + acc, 0)
let maxRam = servs.reduce((acc, s) => { return s.maxRam + acc }, 0)
if (ns.args[0]) {
ns.tprint(`${ns.nFormat(usedRam / maxRam, "0.0%")} Global Ram Usage: ${format(usedRam)}gb/${format(maxRam)}gb`)
}
return maxRam - usedRam
}
/** @param {NS} ns */
async function getAccessToServ(ns, hostname) {
let portsOpened = 0
if (ns.fileExists('brutessh.exe')) {
ns.brutessh(hostname);
portsOpened++
}
if (ns.fileExists('ftpcrack.exe')) {
ns.ftpcrack(hostname);
portsOpened++
}
if (ns.fileExists('relaysmtp.exe')) {
ns.relaysmtp(hostname);
portsOpened++
}
if (ns.fileExists('sqlinject.exe')) {
ns.sqlinject(hostname);
portsOpened++
}
if (ns.fileExists('httpworm.exe')) {
ns.httpworm(hostname);
portsOpened++
}
if (ns.getServerNumPortsRequired(hostname) <= portsOpened) {
try {
ns.nuke(hostname);
ns.tprint(`SUCCESS NUKED ${hostname} Access Granted \$.`)
} catch (e) {
ns.tprint(`ERROR Unexpected failure; couldn't get root access on serv: ${hostname}`)
}
}
}
/** @param {NS} ns */
export async function getRootOnAllServers(ns) {
let allServs = await fetchAllServers(ns)
for (let serv of allServs.map(s => s.hostname)) {
if (!ns.hasRootAccess(serv)) {
await getAccessToServ(ns, serv)
}
}
}
/** @param {NS} ns */
export async function main(ns) {
let CLI = {
runScript,
filterHackableServers,
getServerInformation,
dfs,
fetchAllServers,
getGlobalRam,
getRootOnAllServers
}
let command = ns.args[0]
if (!command) {
ns.tprint('ERROR Must enter a command:')
ns.tprint(Object.keys(CLI))
} else {
await CLI[command](ns, ...ns.args.slice(1))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment