Skip to content

Instantly share code, notes, and snippets.

@m-sterling
Created May 16, 2025 15:57
Show Gist options
  • Select an option

  • Save m-sterling/840a05dcfc3efce879da40da5e6e236d to your computer and use it in GitHub Desktop.

Select an option

Save m-sterling/840a05dcfc3efce879da40da5e6e236d to your computer and use it in GitHub Desktop.
Morgan's Bitburner scripts
// for direct use with spreader.js
// source: https://github.com/bitburner-official/bitburner-scripts/blob/master/basic_hack.js
/** @param {NS} ns */
export async function main(ns) {
const hostname = ns.self().server
while (true) {
if (ns.getServerSecurityLevel(hostname) > ns.getServerMinSecurityLevel(hostname)) {
await ns.weaken(hostname);
} else if (ns.getServerMoneyAvailable(hostname) < ns.getServerMaxMoney(hostname)) {
await ns.grow(hostname);
} else {
await ns.hack(hostname);
}
}
}
// crawls the entire network and hacks all servers that it can
// protip: if you have enough port-hacking tools, you can nuke a server regardless of your level
// however, you can't hack/grow/weaken/backdoor it or run scripts on it until you hit the req'd level
/** @param {NS} ns */
export async function main(ns: NS) {
const start = new Date()
const args = ns.flags([['v', false], ['vv', false], ['vvv', false]])
if (args.vvv) {
args.vv = true
}
if (args.vv) {
args.v = true
}
let servers: string[] = []
let searched: string[] = []
function scan(target: string) {
for (let serverName of ns.scan(target)) {
if (servers.includes(serverName) || searched.includes(serverName))
continue
searched.push(serverName)
const server = ns.getServer(serverName)
if (!server.hasAdminRights) {
servers.push(serverName)
}
scan(serverName)
}
}
scan("")
ns.tprintf("Attempting to hack %d servers...", servers.length)
let failures = 0
let successes = 0
let lowestHackingLevelNeeded = Number.MAX_SAFE_INTEGER
let lowestHackingLevelServers = 0
let lowestOpenPortsNeeded = 5
let lowestOpenPortsServers = 0
servers.forEach(serverName => {
let server: Server = ns.getServer(serverName)
try {
ns.brutessh(serverName)
} catch (_) {}
try {
ns.ftpcrack(serverName)
} catch (_) {}
try {
ns.httpworm(serverName)
} catch (_) {}
try {
ns.sqlinject(serverName)
} catch (_) {}
try {
ns.relaysmtp(serverName)
} catch (_) {}
if (server.numOpenPortsRequired! > server.openPortCount!) {
failures++
ns.tprintf('Nuking %s failed: not enough ports open', serverName)
if (server.numOpenPortsRequired! < lowestOpenPortsNeeded) {
lowestOpenPortsNeeded = server.numOpenPortsRequired!
lowestOpenPortsServers = 0
}
lowestOpenPortsServers++
if (args.v) {
ns.tprintf(' Have: %d', server.openPortCount!)
ns.tprintf(' Need: %d', server.numOpenPortsRequired!)
if (args.vv) {
// ns.tprintf(' SSH: %s', server.sshPortOpen ? "true" : "false")
// ns.tprintf(' FTP: %s', server.ftpPortOpen ? "true" : "false")
// ns.tprintf(' HTTP: %s', server.httpPortOpen ? "true" : "false")
// ns.tprintf(' SQL: %s', server.sqlPortOpen ? "true" : "false")
// ns.tprintf(' SMTP: %s', server.smtpPortOpen ? "true" : "false")
if (args.vvv) {
ns.tprintf(' Hacking level needed: %d', server.requiredHackingSkill!)
}
}
}
} else if (ns.nuke(serverName)) {
successes++
ns.tprintf('Nuking %s succeeded!', serverName)
} else {
failures++
ns.tprintf("Nuking %s failed: hacking level too low", serverName)
if (server.requiredHackingSkill! < lowestHackingLevelNeeded) {
lowestHackingLevelNeeded = server.requiredHackingSkill!
lowestHackingLevelServers = 0
}
lowestHackingLevelServers++
if (args.v) {
ns.tprintf(' Have: %d', ns.getHackingLevel())
ns.tprintf(' Need: %d', server.requiredHackingSkill!)
if (args.vvv) {
ns.tprintf(' Ports opened: %d', server.openPortCount!)
ns.tprintf(' Ports needed: %d', server.numOpenPortsRequired!)
}
}
}
})
ns.tprintf('Successes: %d', successes)
ns.tprintf('Failures: %d', failures)
if (args.v && failures > 0) {
if (lowestHackingLevelNeeded == Number.MAX_SAFE_INTEGER) {
lowestHackingLevelNeeded = ns.getHackingLevel()
}
ns.tprintf('Hacking level needed: %d/%d (for %d server%s)', ns.getHackingLevel(), lowestHackingLevelNeeded, lowestHackingLevelServers, lowestHackingLevelServers == 1 ? '' : 's')
ns.tprintf('Open ports needed: %d/%d (for %d server%s)', [ns.fileExists('BruteSSH.exe', 'home'), ns.fileExists('FTPCrack.exe', 'home'), ns.fileExists('relaySMTP.exe', 'home'), ns.fileExists('HTTPWorm.exe', 'home'), ns.fileExists('SQLInject.exe', 'home')].filter(e => e).length, lowestOpenPortsNeeded, lowestOpenPortsServers, lowestOpenPortsServers == 1 ? '' : 's')
}
ns.toast(`${ns.self().filename} completed in ${(new Date()).getTime() - start.getTime()}ms`)
}
// for messing around with things
/** @param {NS} ns */
export async function main(ns) {
ns.ramOverride(ns.getServer(ns.self().server).maxRam - ns.getServer(ns.self().server).ramUsed)
ns.tprint(eval(ns.args.join(" ") || "'Hello world'") || '')
}
// list all servers and their features, with optional filtering
// also used in spreader.js
/** @param {NS} ns */
export async function main(ns) {
const start = new Date()
const flags = ns.flags([['help', false], ['verbose', false], ['nohacked', false], ['nounhacked', false], ['files', false], ['plain', false]])
if (flags.help) {
ns.tprintf("Usage: run %s [--verbose] [--nounhacked] [--nohacked] [--plain]", ns.self().filename)
ns.tprintf(" --verbose: Includes system information for servers")
ns.tprintf(" --nounhacked: Hides unhacked servers")
ns.tprintf(" --nohacked: Hides hacked servers")
ns.tprintf(" --files: Show the files present on the servers")
ns.tprintf(" --plain: Outputs only the server names, nothing else")
return
}
let servers = {}
function scan(target, route) {
for (let serverName of ns.scan(target)) {
if (Object.keys(servers).includes(serverName))
continue
let server = ns.getServer(serverName)
if (server.backdoorInstalled)
route = []
let curRoute = [...route, serverName]
servers[serverName] = {
hacked: server.hasAdminRights,
route: curRoute.join(' \u2192 '), // →
files: ns.ls(serverName)
}
scan(serverName, curRoute)
}
}
scan("", [])
if (!flags.plain) {
if (!flags.nohacked) {
ns.tprintf('=== HACKED SERVERS ===')
Object.keys(servers).filter(serverName => servers[serverName].hacked).sort().forEach(serverName => {
let server = ns.getServer(serverName)
ns.tprintf('- %s (%s)', serverName, servers[serverName].route)
if (flags.verbose) {
ns.tprintf('\tBackdoored: %s (lv. %d/%d)', server.backdoorInstalled ? "true" : "false", ns.getHackingLevel(), server.requiredHackingSkill)
ns.tprintf('\tRAM: %fGB/%fGB used', server.ramUsed, server.maxRam)
ns.tprintf('\tCPU: %d core%s', server.cpuCores, server.cpuCores == 1 ? '' : 's')
}
if (flags.files) {
ns.tprintf('\tFiles: "%s"', servers[serverName].files.join('", "'))
}
})
}
if (!flags.nounhacked) {
ns.tprintf('=== UNHACKED SERVERS ===')
Object.keys(servers).filter(serverName => !servers[serverName].hacked).sort().forEach(serverName => {
let server = ns.getServer(serverName)
ns.tprintf('- %s (%s)', serverName, servers[serverName].route)
if (flags.verbose) {
ns.tprintf('\tHacking skill needed: %d', server.requiredHackingSkill ?? 0)
ns.tprintf('\tPorts open: %d', server.openPortCount ?? 0)
ns.tprintf('\tPorts needed: %d', server.numOpenPortsRequired ?? 0)
}
if (flags.files) {
ns.tprintf('\tFiles: "%s"', servers[serverName].files.join('", "'))
}
})
}
} else {
let s = ""
if (!flags.nohacked) {
s += Object.keys(servers).filter(serverName => servers[serverName].hacked).sort().join("\n")
}
if (!flags.nounhacked) {
s += Object.keys(servers).filter(serverName => !(servers[serverName].hacked)).sort().join("\n")
}
ns.print(s)
}
ns.toast(`${ns.self().filename} completed in ${(new Date()).getTime() - start.getTime()}ms`)
}
// for direct use with spreader.js
/** @param {NS} ns */
export async function main(ns) {
while (true) {
await ns.share()
}
}
// script spreader
// used to auto-execute a script on all of your hacked servers
// to switch to a new script, --kill the first one before spreading the new script
/** @param {NS} ns */
export async function main(ns) {
const start = new Date()
const flags = ns.flags([['kill', false], ['singlethreaded', false]])
if (ns.args.length == 0) {
ns.tprintf("Usage: run %s [script name]", ns.self().scriptName)
return
}
let fails = 0, empty = 0
const scriptName = ns.args[0]
const servers = (await ns.getScriptLogs(await ns.run('list.js', undefined, '--plain', '--nounhacked'))).filter(line => !line.startsWith('scan:')).join('').split('\n')
for (let serverName of servers) {
let server = ns.getServer(serverName)
if (flags.kill) {
if (!await ns.scriptKill(scriptName, serverName)) {
fails++
}
} else {
if (serverName !== 'home') {
if (server.requiredHackingSkill <= ns.getHackingLevel()) {
if (server.maxRam >= ns.getScriptRam(scriptName)) {
await ns.scriptKill(scriptName, serverName)
server = ns.getServer(serverName)
await ns.scp(scriptName, serverName, 'home')
await ns.exec(scriptName, serverName, {preventDuplicates: true, threads: flags.singlethreaded ? 1 : Math.floor((server.maxRam - server.ramUsed)/ns.getScriptRam(scriptName))})
} else {
empty++
}
} else {
fails++
}
}
}
}
if (flags.kill) {
ns.tprintf("Killed %s on %d servers", scriptName, servers.length - fails)
if (fails != 0) {
ns.tprintf("Script %s not running on %d servers", scriptName, fails)
}
} else {
ns.tprintf("Copied and executed %s to %d servers", scriptName, servers.length - fails)
if (fails != 0) {
ns.tprintf("Failed to execute on %d servers due to insufficient hacking level", fails)
}
if (empty != 0) {
ns.tprintf("Failed to execute on %d servers due to a lack of RAM", empty)
}
}
ns.toast(`${ns.self().filename} completed in ${(new Date()).getTime() - start.getTime()}ms`)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment