实用脚本【备份】

0 点赞
Bitburner
转载

I need some place to keep my very useful scripts. Feel free to copy them! Some of the scripts are WAY too big to write here, so I needed to place them inside the Github. Smart scripts need to be inside the /smart/ directory. Basic smart code -> add to the /smart/ directory basic-grow.js /** @param {NS} ns **/ export async function main(ns) { const [target, start] = ns.args; const delay = start ? Math.max(0, start - Date.now()) : 0; await ns.sleep(delay); await ns.grow(target); } ----------------------------------------------------------------------------------------------- basic-hack.js /** @param {NS} ns **/ export async function main(ns) { const [target, start] = ns.args; const delay = start ? Math.max(0, start - Date.now()) : 0; await ns.sleep(delay); const moneyGained = await ns.hack(target); if (moneyGained > 0) { ns.writePort(1, { source: ns.getHostname(), amount: moneyGained }); } } ----------------------------------------------------------------------------------------------- basic-weaken.js /** @param {NS} ns **/ export async function main(ns) { const [target, start] = ns.args; const delay = start ? Math.max(0, start - Date.now()) : 0; await ns.sleep(delay); await ns.weaken(target); } run-smart-on-pservers.js -> This one starts the smarts WITH formula /** @param {NS} ns **/ export async function main(ns) { const servers = ns.getPurchasedServers(); for (const s of servers) { if (!s.startsWith("p-")) continue; const procs = ns.ps(s); if (procs.length > 0) continue; const target = s.slice(2); ns.exec("/smart/smartBatch.js", s, 1, target); } } run-smart-noformula-on-pservers.js -> Same smart basics but WITHOUT formula /** @param {NS} ns **/ export async function main(ns) { const servers = ns.getPurchasedServers(); const mainScript = "/smart/smartBatchNoFormula.js"; // List of dependencies required in the /smart/ folder of each server const dependencies = [ "/smart/basic-hack.js", "/smart/basic-grow.js", "/smart/basic-weaken.js" ]; ns.tprint(`--- Starting batch deployer for ${servers.length} servers ---`); for (const server of servers) { if (!server.startsWith("p-")) { ns.print(`Skipping ${server}: does not start with 'p-'`); continue; } const procs = ns.ps(server); if (procs.length > 0) { ns.print(`Skipping ${server}: already has ${procs.length} processes running.`); continue; } const target = server.slice(2); if (!ns.serverExists(target)) { ns.tprint(`❌ ERROR: Target '${target}' extracted from server '${server}' does not exist.`); continue; } // Copy the main script if (!ns.fileExists(mainScript, server)) { ns.tprint(`Copying main script to ${server}...`); await ns.scp(mainScript, server, "home"); } // Copy all dependencies to the target p-server for (const dep of dependencies) { if (!ns.fileExists(dep, server)) { ns.print(`Copying dependency ${dep} to ${server}...`); await ns.scp(dep, server, "home"); } } const scriptRam = ns.getScriptRam(mainScript); const freeRam = ns.getServerMaxRam(server) - ns.getServerUsedRam(server); if (freeRam < scriptRam) { ns.tprint(`❌ ERROR: Not enough RAM on ${server}. Need ${ns.formatRam(scriptRam)}`); continue; } const pid = ns.exec(mainScript, server, 1, target); if (pid > 0) { ns.tprint(`✅ SUCCESS: Started ${mainScript} on ${server} targeting ${target} (PID: ${pid})`); } else { ns.tprint(`❌ ERROR: ns.exec failed on ${server} for target ${target}.`); } } } smartBatch.js -> Manage the smart scripts with Formula. Can't fit here. Here is a link to github https://github.com/vianna77/BitBurner/blob/main/smartBatch.js Add it to directory smart smartBatchNoFormula.js -> Same as smartBatch but WITHOUT formula /** * Smart Batch No Formula (V1.1) * Executa sequencialmente Hack, Grow e Weaken monitorando o término dos PIDs. * * @param {NS} ns */ export function autocomplete(data, args) { if (args.length === 1) return data.servers; return []; } const HACK_PATH = "/smart/basic-hack.js"; const WEAKEN_PATH = "/smart/basic-weaken.js"; const GROW_PATH = "/smart/basic-grow.js"; /** @param {NS} ns **/ export async function main(ns) { ns.disableLog("ALL"); if (ns.args.length === 0) { ns.tprint("USAGE: smartBatchNoFormula.js <target>"); return; } const target = String(ns.args[0]); const thisServer = ns.getHostname(); const t = () => { const date = new Date(); return `[${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}]`; }; // --- FILE CHECK --- if (!ns.fileExists(HACK_PATH) || !ns.fileExists(WEAKEN_PATH) || !ns.fileExists(GROW_PATH)) { ns.tprint(`${t()} ❌ FATAL ERROR: Missing scripts in /smart/ directory.`); return; } const weakenRam = ns.getScriptRam(WEAKEN_PATH); const growRam = ns.getScriptRam(GROW_PATH); const hackRam = ns.getScriptRam(HACK_PATH); // --- HELPER FUNCTIONS --- const getS = () => ns.getServer(target); async function waitProcess(pid) { if (pid === 0) return; while (ns.isRunning(pid)) { await ns.sleep(500); } } async function runMaxThreads(path, ramUsage, label) { const freeRam = ns.getServerMaxRam(thisServer) - ns.getServerUsedRam(thisServer); let threads = Math.floor(freeRam / ramUsage); // REDUCE THREADS BY 1 threads = Math.max(0, threads - 1); if (threads > 0) { ns.print(`${t()} [${label}] Executing with ${threads} threads.`); const pid = ns.exec(path, thisServer, threads, target, 0); return pid; } return 0; } ns.tprint(`${t()} Starting SmartBatchNoFormula on ${target}`); while (true) { const s = getS(); const money = s.moneyAvailable; const maxMoney = s.moneyMax; const sec = s.hackDifficulty; const minSec = s.minDifficulty; // 1. PRIORIDADE: SECURITY (WEAKEN) if (sec > minSec + 0.05) { ns.print(`${t()} [WEAKEN] Sec: ${sec.toFixed(3)} > Min: ${minSec.toFixed(3)}. Reason: High Security.`); const pid = await runMaxThreads(WEAKEN_PATH, weakenRam, "WEAKEN-EXEC"); if (pid === 0) { ns.print(`${t()} [WAIT] Low RAM for Weaken.`); await ns.sleep(2000); } else { await waitProcess(pid); } continue; } // 2. PRIORIDADE: MONEY (GROW) if (money < maxMoney) { ns.print(`${t()} [GROW] Money: ${ns.formatNumber(money)} < Max: ${ns.formatNumber(maxMoney)}. Reason: Target not saturated.`); const pid = await runMaxThreads(GROW_PATH, growRam, "GROW-EXEC"); if (pid === 0) { ns.print(`${t()} [WAIT] Low RAM for Grow.`); await ns.sleep(2000); } else { await waitProcess(pid); } continue; } // 3. EXECUÇÃO: HACK const freeRam = ns.getServerMaxRam(thisServer) - ns.getServerUsedRam(thisServer); let threads = Math.floor(freeRam / hackRam); // REDUCE THREADS BY 1 threads = Math.max(0, threads - 1); if (threads > 0) { ns.print(`${t()} [HACK] Money/Sec OK. Executing Hack with ${threads} threads.`); const pid = ns.exec(HACK_PATH, thisServer, threads, target, 0); if (pid === 0) { ns.print(`${t()} [WAIT] Low RAM for Hack.`); await ns.sleep(2000); } else { await waitProcess(pid); } } else { ns.print(`${t()} [WAIT] Low RAM for Hack.`); await ns.sleep(2000); } await ns.sleep(100); } } moneyManager.js -> receives the basicHack.js events and table the data /** @param {NS} ns **/ export async function main(ns) { ns.disableLog("ALL"); ns.ui.openTail(); const serverStats = {}; // Stores { total: n, count: n, last: n, firstSeen: ms } const startTime = Date.now(); while (true) { let portData = ns.readPort(1); let hasNewData = false; while (portData !== "NULL PORT DATA") { const { source, amount } = portData; if (!serverStats[source]) { serverStats[source] = { total: 0, count: 0, last: 0, firstSeen: Date.now() }; } serverStats[source].total += amount; serverStats[source].count += 1; serverStats[source].last = amount; hasNewData = true; portData = ns.readPort(1); } if (hasNewData) { ns.clearLog(); ns.print(`--- INDIVIDUAL SERVER PERFORMANCE ---`); ns.print(`Runtime: ${ns.tFormat(Date.now() - startTime)}`); ns.print(`----------------------------------------------------------------------------------`); ns.print(`${"SERVER".padEnd(20)} | ${"LAST".padEnd(10)} | ${"AVG/HACK".padEnd(10)} | ${"AVG/SEC".padEnd(10)} | ${"TOTAL".padEnd(12)} | COUNT`); ns.print(`----------------------------------------------------------------------------------`); // Convert to array and sort by AVG/SEC ascending const sortedEntries = Object.entries(serverStats).sort(([, a], [, b]) => { const avgSecA = a.total / ((Date.now() - a.firstSeen) / 1000 || 1); const avgSecB = b.total / ((Date.now() - b.firstSeen) / 1000 || 1); return avgSecA - avgSecB; // Ascending order }); for (const [name, stats] of sortedEntries) { const avgPerHack = stats.total / stats.count; const elapsedServerSec = (Date.now() - stats.firstSeen) / 1000; const avgPerSec = stats.total / (elapsedServerSec || 1); ns.print( `${name.padEnd(20)} | ` + `${ns.formatNumber(stats.last).padEnd(10)} | ` + `${ns.formatNumber(avgPerHack).padEnd(10)} | ` + `${ns.formatNumber(avgPerSec).padEnd(10)} | ` + `$${ns.formatNumber(stats.total).padEnd(11)} | ${stats.count}` ); } } await ns.sleep(1000); } }

stock-trader-pro.js - Do stocks /** * PRO STOCK TRADER — REGIME AWARE + SCORE WEIGHTED (v3.0) * INTEGRATED WITH INDIVIDUAL MONITOR * * USAGE: run proTrader.js MAX_CAP ENABLE_SHORT AGGRESSION * EXAMPLE: run proTrader.js 1e12 true 0.7 * * @param {NS} ns */ export async function main(ns) { ns.disableLog("ALL"); // ============================================================ // 1) PARAMETER VALIDATION // ============================================================ if (ns.args.length !== 3) { ns.tprint("ERROR: Invalid arguments."); ns.tprint("USAGE: run proTrader.js MAX_CAP ENABLE_SHORT AGGRESSION"); ns.tprint("EXAMPLE: run proTrader.js 1e12 true 0.7"); return; } const MAX_CAP = Number(ns.args[0]); const ENABLE_SHORT = ns.args[1] === true || ns.args[1] === "true"; const AGGRESSION = Number(ns.args[2]); if (!Number.isFinite(MAX_CAP) || MAX_CAP <= 0) { ns.tprint("ERROR: MAX_CAP must be a positive number."); return; } if (!Number.isFinite(AGGRESSION) || AGGRESSION < 0 || AGGRESSION > 1) { ns.tprint("ERROR: AGGRESSION must be between 0.0 and 1.0."); return; } if (!ns.stock.hasWSEAccount() || !ns.stock.has4SData()) { ns.tprint("ERROR: Requires WSE account and 4S Data."); return; } ns.ui.openTail(); // ============================================================ // 2) AGGRESSION MAPPING // ============================================================ const BUY_THRESHOLD = 0.72 - AGGRESSION * 0.12; const SELL_THRESHOLD = 0.55 - AGGRESSION * 0.08; const SHORT_THRESHOLD = 0.30 + AGGRESSION * 0.10; const BASE_MAX_POSITIONS = Math.round(10 - AGGRESSION * 4); const BASE_EXPOSURE = 0.55 + AGGRESSION * 0.35; const MAX_VOL = 0.15 + AGGRESSION * 0.20; const CYCLE_TIME = Math.round(9000 - AGGRESSION * 4000); // ============================================================ // 3) STARTUP SUMMARY // ============================================================ ns.tprint("================================================="); ns.tprint("PRO STOCK TRADER v3.0 — REGIME AWARE"); ns.tprint(`MAX_CAP: ${ns.formatNumber(MAX_CAP)}`); ns.tprint(`AGGRESSION: ${AGGRESSION.toFixed(2)}`); ns.tprint(`BUY / SELL / SHORT: ${BUY_THRESHOLD.toFixed(3)} / ${SELL_THRESHOLD.toFixed(3)} / ${SHORT_THRESHOLD.toFixed(3)}`); ns.tprint(`BASE EXPOSURE: ${(BASE_EXPOSURE * 100).toFixed(1)}%`); ns.tprint(`BASE MAX POSITIONS: ${BASE_MAX_POSITIONS}`); ns.tprint("================================================="); // ============================================================ // 4) HELPERS // ============================================================ const symbols = ns.stock.getSymbols(); function cash() { return ns.getServerMoneyAvailable("home"); } function getScore(sym) { const f = ns.stock.getForecast(sym); const v = ns.stock.getVolatility(sym); if (v <= 0) return 0; return (f - 0.5) / v; } function getPosition(sym) { const [l, lAvg, s, sAvg] = ns.stock.getPosition(sym); return { l, lAvg, s, sAvg }; } function unrealized(sym) { const p = getPosition(sym); const price = ns.stock.getPrice(sym); let u = 0; if (p.l > 0) u += (price - p.lAvg) * p.l; if (ENABLE_SHORT && p.s > 0) u += (p.sAvg - price) * p.s; return u; } // ============================================================ // 5) REGIME DETECTION // ============================================================ function detectRegime(ranked) { if (ranked.length === 0) return "NO_EDGE"; const strong = ranked.filter(r => r.forecast >= BUY_THRESHOLD).length; const weak = ranked.filter(r => r.forecast <= SELL_THRESHOLD).length; if (strong >= 4) return "BULL"; if (weak >= 4) return "BEAR"; return "NEUTRAL"; } function regimeParams(regime) { if (regime === "BULL") { return { exposure: BASE_EXPOSURE, maxPos: BASE_MAX_POSITIONS }; } if (regime === "NEUTRAL") { return { exposure: BASE_EXPOSURE * 0.4, maxPos: Math.max(2, Math.floor(BASE_MAX_POSITIONS * 0.4)) }; } return { exposure: 0, maxPos: 0 }; } // ============================================================ // 6) MAIN LOOP // ============================================================ while (true) { const ranked = symbols .map(sym => ({ sym, forecast: ns.stock.getForecast(sym), vol: ns.stock.getVolatility(sym), score: getScore(sym), pos: getPosition(sym) })) .filter(o => o.vol > 0 && o.vol <= MAX_VOL) .sort((a, b) => b.score - a.score); const regime = detectRegime(ranked); const params = regimeParams(regime); let actions = []; // ---------- LIQUIDATION + MONITOR SEND ---------- for (const o of ranked) { const f = o.forecast; const price = ns.stock.getPrice(o.sym); if (o.pos.l > 0 && f < SELL_THRESHOLD) { const saleAmount = price * o.pos.l; ns.stock.sellStock(o.sym, o.pos.l); ns.writePort(1, { source: "STOCK", amount: saleAmount }); actions.push(`SELL ${o.sym} | Amount: ${ns.formatNumber(saleAmount)}`); } if (ENABLE_SHORT && o.pos.s > 0 && f > SELL_THRESHOLD) { const saleAmount = o.pos.sAvg * o.pos.s + (o.pos.sAvg - price) * o.pos.s; ns.stock.sellShort(o.sym, o.pos.s); ns.writePort(1, { source: "STOCK", amount: saleAmount }); actions.push(`COVER ${o.sym} | Amount: ${ns.formatNumber(saleAmount)}`); } } // ---------- ENTRY (LOG RESTORED) ---------- if (params.exposure === 0) { ns.print(`[REGIME] ${regime} — Trading disabled`); } else { const budget = Math.min(cash() * params.exposure, MAX_CAP); const candidates = ranked .filter(o => o.forecast > BUY_THRESHOLD && o.pos.l === 0) .slice(0, params.maxPos); const totalScore = candidates.reduce((a, c) => a + Math.max(c.score, 0.001), 0); for (const c of candidates) { const weight = c.score / totalScore; const alloc = budget * weight; const price = ns.stock.getPrice(c.sym); const shares = Math.floor(alloc / price); if (shares <= 0) continue; ns.stock.buyStock(c.sym, shares); actions.push(`BUY ${c.sym} | w=${weight.toFixed(2)}`); } } // ---------- LOG ---------- const unreal = symbols.reduce((a, s) => a + unrealized(s), 0); ns.print("================================================="); ns.print(`[REGIME] ${regime}`); actions.forEach(a => ns.print(a)); ns.print(`[EXPOSURE] ${(params.exposure * 100).toFixed(1)}% | MaxPos ${params.maxPos}`); ns.print(`[PnL] Unrealized ${ns.formatNumber(unreal)}`); ns.print("================================================="); await ns.sleep(CYCLE_TIME); } } goto.js -> brings you to any server you want to go. /** @param {NS} ns **/ export function autocomplete(data, args) { // Provides autocomplete for server names in the terminal return data.servers; } /** @param {NS} ns **/ export async function main(ns) { // --- SCRIPT SUMMARY AND INTENTION --- ns.tprint("======================================="); ns.tprint("🚀 Goto Script (v1.2)"); ns.tprint("---------------------------------------"); ns.tprint("Intention: Find path from home, auto-connect and propagate."); ns.tprint("Parameters: [target_server]"); ns.tprint("======================================="); if (ns.args.length === 0) { ns.tprint("❌ ERROR: No target server specified."); return; } const target = String(ns.args[0]); const scriptName = ns.getScriptName(); const currentServer = ns.getHostname(); const visited = new Set(); const queue = [["home"]]; // --- PATHFINDING LOGIC (Always starts from home) --- let finalPath = null; while (queue.length) { const path = queue.shift(); const host = path[path.length - 1]; if (host === target) { finalPath = path; break; } for (const next of ns.scan(host)) { if (!visited.has(next)) { visited.add(next); queue.push([...path, next]); } } } // --- EXECUTION --- if (finalPath) { ns.tprint(`✅ Path found: ${finalPath.join(" -> ")}`); // NEW: If not on home, connect to home first to reset navigation context if (currentServer !== "home") { ns.tprint("Resetting connection to 'home' before starting path..."); const backHome = ns.singularity.connect("home"); if (!backHome) { ns.tprint("❌ ERROR: Could not connect back to home."); return; } } // Navigate through the path for (const node of finalPath) { // Propagation logic: Copy script to next node if it doesn't exist there if (node !== "home" && !ns.fileExists(scriptName, node)) { await ns.scp(scriptName, node, "home"); ns.tprint(`Testing propagation: ${scriptName} copied to ${node}`); } const success = ns.singularity.connect(node); if (!success) { ns.tprint(`❌ ERROR: Failed to connect to ${node}.`); return; } } ns.tprint(`🏁 Successfully connected to ${target}.`); } else { ns.tprint(`❌ Target server '${target}' not found in the network.`); } } availableThreads.js -> Check how many threads a script needs to execute /** @param {NS} ns **/ export async function main(ns) { const script = String(ns.args[0]); // file name of script const host = ns.args[1] || ns.getHostname(); const scriptRam = ns.getScriptRam(script, host); const maxRam = ns.getServerMaxRam(host); const usedRam = ns.getServerUsedRam(host); const freeRam = maxRam - usedRam; const threads = Math.floor(freeRam / scriptRam); ns.tprint("Script RAM: " + scriptRam); ns.tprint("Free RAM: " + freeRam); ns.tprint("Threads: " + threads); } /** Autocomplete all scripts in the directory */ export function autocomplete(data, args) { return data.scripts; } buy-custom-server-by-money-available.js -> Buy servers based on money available in them. /** @param {NS} ns */ export async function main(ns) { ns.disableLog("ALL"); // =============================================== // MANDATORY RAM ARGUMENT CHECK // =============================================== if (ns.args.length === 0) { ns.tprint("=================================================================="); ns.tprint("🚨 ERROR: RAM argument is MANDATORY."); ns.tprint(" "); ns.tprint("Usage: run comp_purchase.js [RAM_GB]"); ns.tprint(" "); ns.tprint("This script purchases Personal Servers (p-servers) with the specified RAM."); ns.tprint("RAM must be a power of 2, e.g., 8, 16, 32, 64, 128, 256, 512, 1024..."); ns.tprint(" "); ns.tprint("Example: run comp_purchase.js 256"); ns.tprint("Pairs well with run-simplehack-on-pservers.js or smart scripts."); ns.tprint("=================================================================="); return; } const TARGET_RAM = Number(ns.args[0]); // RAM validity check if (isNaN(TARGET_RAM) || TARGET_RAM < 2 || (TARGET_RAM & (TARGET_RAM - 1)) !== 0) { ns.tprint(`🚨 ERROR: Invalid RAM (${ns.args[0]}). Use a power of 2 (e.g., 128, 512, 2048).`); return; } const PREFIX = "p-"; const EXCLUDE = new Set([ ".", "CSEC", "I.I.I.I", "avmnite-02h", "darkweb", "home", "run4theh111z" ]); const cost = ns.getPurchasedServerCost(TARGET_RAM); ns.tprint(`✅ Configuration: Servers with ${ns.formatRam(TARGET_RAM)} RAM.`); ns.tprint(`💰 Cost per server: ${ns.formatNumber(cost)}`); ns.tprint("--- Starting search for eligible targets ---"); // --- discover all servers --- const seen = new Set(); const stack = ["home"]; const servers = []; while (stack.length > 0) { const host = stack.pop(); if (seen.has(host)) { continue; } seen.add(host); for (const n of ns.scan(host)) { if (!seen.has(n)) stack.push(n); } // skip personal servers if (host.startsWith(PREFIX)) { continue; } // skip excluded if (EXCLUDE.has(host)) { continue; } servers.push(host); } const level = ns.getHackingLevel(); // --- collect only servers you *can hack* --- const eligible = []; for (const server of servers) { const currentPservers = ns.getPurchasedServers(); if (currentPservers.some(ps => ps === PREFIX + server)) { continue; } const req = ns.getServerRequiredHackingLevel(server); if (req <= level) { eligible.push({ name: server, money: ns.getServerMoneyAvailable(server) }); } } // --- DESCENDING by max money --- eligible.sort((a, b) => b.money - a.money); ns.tprint(`Found ${eligible.length} targets to name new servers.`); // =============================================== // VERIFICAÇÃO DE CUSTO TOTAL E EXIBIÇÃO // =============================================== const currentServersCount = ns.getPurchasedServers().length; const numToBuy = Math.min(eligible.length, 25 - currentServersCount); const totalCost = numToBuy * cost; const playerMoney = ns.getServerMoneyAvailable("home"); ns.tprint("---------------------------------------"); ns.tprint(`📊 PURCHASE PLAN:`); ns.tprint(`Servers to buy: ${numToBuy}`); ns.tprint(`Total Cost: ${ns.formatNumber(totalCost)}`); ns.tprint(`Your Money: ${ns.formatNumber(playerMoney)}`); ns.tprint("---------------------------------------"); if (numToBuy > 0 && playerMoney < totalCost) { ns.tprint(`🚨 ABORTING: Insufficient funds for ALL ${numToBuy} servers.`); return; } else if (numToBuy === 0) { ns.tprint(`⚠️ Nothing to buy (Limit reached or no targets found).`); return; } // =============================================== ns.tprint("--- Starting purchase process ---"); // --- buy servers --- for (const server of eligible) { const currentPservers = ns.getPurchasedServers(); const count = currentPservers.length; ns.tprint(`Current personal servers: ${count}/25.`); if (count >= 25) { ns.tprint("🚫 Maximum limit reached (25 servers)."); break; } const name = PREFIX + server.name; if (currentPservers.some(ps => ps === name)) { ns.tprint(`✅ Already own ${name}. Skipping.`); await ns.sleep(1000); continue; } ns.tprint(`[${count + 1}/25] Attempting to buy ${name}...`); if (ns.getServerMoneyAvailable("home") < cost) { ns.tprint(`💸 Insufficient funds. Need ${ns.formatNumber(cost - ns.getServerMoneyAvailable("home"))} more.`); break; } const ok = ns.purchaseServer(name, TARGET_RAM); if (!ok) { ns.tprint(`❌ Purchase failed for ${name}. Proceeding.`); await ns.sleep(1000); continue; } ns.tprint(`🎉 PURCHASED: ${name} (${ns.formatRam(TARGET_RAM)})`); // --- MODIFIED: DYNAMIC SCRIPT COPYING --- const scriptsToCopy = ns.ls("home").filter(file => file.endsWith(".js")); if (scriptsToCopy.length > 0) { const success = await ns.scp(scriptsToCopy, name, "home"); if (success) { ns.print(`✅ Copied ${scriptsToCopy.length} .js files to ${name}.`); } else { ns.print(`⚠️ Failed to copy some scripts to ${name}.`); } } } ns.tprint("--- Purchase process finished ---"); } buySingleCustomServer.js -> Purchase a single custom server. Params: Name size . If no size added, use 1Tb. /** * Script for purchasing and initializing a server. * @param {NS} ns * @param {import(".").NS} ns **/ // --- NEW: AUTOCOMPLETE FUNCTION --- // Allows Bitburner to suggest purchasable server names when typing export function autocomplete(data, args) { // Returns the names of all servers you already know return data.servers; } export async function main(ns) { // Capture arguments const baseName = String(ns.args[0]); // --- HELP BLOCK --- if (baseName === "undefined" || baseName === "null" || baseName.trim() === "" || !ns.args.length) { ns.tprint("-------------------------------------------------------"); ns.tprint(" 💰 HELP: PURCHASE SERVER 💰 "); ns.tprint("-------------------------------------------------------"); ns.tprint(`Usage: run ${ns.getScriptName()} [Base Name] [RAM (optional)]`); ns.tprint("-------------------------------------------------------"); ns.tprint("EXPECTED PARAMETERS:"); ns.tprint(" 1. Base Name (string): The base name of the server (the prefix 'p-' will be added automatically)."); ns.tprint(" Example: 'run ${ns.getScriptName()} server-01'"); ns.tprint(""); ns.tprint(" 2. RAM (number, optional): The amount of RAM in GB for the server."); ns.tprint(" If omitted, the default value is 1024 GB (1 TB)."); ns.tprint("-------------------------------------------------------"); return; } // --- NEW: ADDS THE PREFIX 'p-' TO AVOID CONFLICTS --- const finalName = `p-${baseName}`; // If args[1] exists, use it. Otherwise, default = 1024 GB (1 TB) const TARGET_RAM = ns.args[1] ? Number(ns.args[1]) : 1024; const cost = ns.getPurchasedServerCost(TARGET_RAM); if (ns.getServerMoneyAvailable("home") < cost) { ns.tprint(`❌ Insufficient funds. Required: ${ns.formatNumber(cost, "0.00a")}`); return; } // Pass the finalName (with prefix) to the purchase function const hostname = ns.purchaseServer(finalName, TARGET_RAM); if (!hostname) { ns.tprint("❌ ERROR: Could not purchase the server. Check if the name already exists or if the RAM is invalid."); return; } ns.tprint(`✅ Server Purchased: ${hostname} with ${TARGET_RAM}GB RAM.`); // --- MODIFIED: DYNAMIC FILE LISTING --- // Lists all files on home, filtering for those ending in .js const allFiles = ns.ls("home"); const scriptsToCopy = allFiles.filter(file => file.endsWith(".js")); if (scriptsToCopy.length > 0) { await ns.scp(scriptsToCopy, hostname, "home"); ns.tprint(`📁 Copied ${scriptsToCopy.length} .js files (including directories) to ${hostname}.`); } else { ns.tprint(`⚠️ No .js files found on home to copy.`); } } deleteServer.js /** @param {NS} ns **/ export async function main(ns) { if (ns.args.length === 0 || ns.args[0] === "-h") { ns.tprint("USAGE: deleteServer.js <servername1> <servername2> ..."); return; } const purchased = ns.getPurchasedServers(); for (const raw of ns.args) { const name = String(raw); if (!ns.serverExists(name)) { ns.tprint(`ERROR: server does not exist: ${name}`); continue; } if (!purchased.includes(name)) { ns.tprint(`ERROR: ${name} is NOT a purchased server.`); continue; } ns.killall(name); if (ns.deleteServer(name)) { ns.tprint(`Server deleted: ${name}`); } else { ns.tprint(`ERROR: failed to delete ${name} (still running processes?).`); } } } /** Autocomplete uses (data, args) **/ export function autocomplete(data, args) { return data.servers; } find.js -> Find the path to a server /** @param {NS} ns **/ export function autocomplete(data, args) { if (args.length === 1) return data.servers; return []; } /** @param {NS} ns **/ export async function main(ns) { const target = String(ns.args[0]); const visited = new Set(); const queue = [["home"]]; while (queue.length) { const path = queue.shift(); const host = path[path.length - 1]; if (host === target) { ns.tprint("Path: " + path.join(" -> ")); return; } for (const next of ns.scan(host)) { if (!visited.has(next)) { visited.add(next); queue.push([...path, next]); } } } ns.tprint("Target not found."); } gang-manager.js Apprarently there is no way to put a large amount of text here, so I'm adding my github link to the file. https://github.com/vianna77/BitBurner/blob/main/gang_manager.js heart.js -> Check current karma /** @param {NS} ns */ export async function main(ns) { ns.tprint(ns.heart.break()); } invester.js -> Same as Weaken but with Gain /** @param {NS} ns **/ export function autocomplete(data, args) { if (args.length === 1) return data.servers; return []; } /** @param {NS} ns **/ export async function main(ns) { const target = String(ns.args[0]); let count = 0; ns.disableLog("ALL"); ns.tprint("Starting grow on " + target); while (true) { const time = ns.getGrowTime(target); // milliseconds const below10min = time < 10 * 60 * 1000; // boolean: under 10 min await ns.grow(target); count++; const money = ns.getServerMoneyAvailable(target); const moneyFmt = ns.formatNumber(money); // formats as 1.2m, 3.4b, etc. const timeMin = (time / 60000).toFixed(1); // minutes, one decimal const msg = `Target: ${target} — Grow #${count} | MONEY:${moneyFmt} | ${timeMin}min`; if (below10min) { ns.print(msg); } else { ns.toast(msg, "info", 10000); ns.print(msg); } } } listHackedByMoney.js -> List all the hacked servers by money available and if they are being hacked. /** @param {NS} ns **/ export function autocomplete(data, args) { return data.servers; } /** @param {NS} ns **/ export async function main(ns) { // Preload purchased servers for hacking detection const purchased = ns.getPurchasedServers(); // 1 — get all servers reachable const servers = scanAll(ns); // 2 — filter only servers where we have root AND have max money > 0 const hacked = servers .filter(s => ns.hasRootAccess(s)) .map(s => ({ name: s, money: ns.getServerMoneyAvailable(s) })); // 3 — sort by current money ascending hacked.sort((a, b) => a.money - b.money); // 4 — print to terminal ns.tprint("Servers sorted by current money (low → high):"); for (const s of hacked) { if (s.name.startsWith("p-")) continue; const flag = purchased.some(p => p.includes(s.name)) ? " ➡ [OK] ✔ hacking!" : ""; ns.tprint(`${s.name}: $${ns.formatNumber(s.money)}${flag}`); } } // helper: full-depth recursive scan function scanAll(ns) { const visited = new Set(["home"]); const stack = ["home"]; while (stack.length > 0) { const host = stack.pop(); for (const next of ns.scan(host)) { if (!visited.has(next)) { visited.add(next); stack.push(next); } } } return [...visited]; } multiNuke.js -> Either nuke what user passed or Nuke everything that your hack level allow /** @param {NS} ns **/ export function autocomplete(data, args) { return data.servers; } /** @param {NS} ns **/ export async function main(ns) { let targets = []; // ============================================ // TARGET SELECTION // ============================================ if (ns.args.length > 0) { // Use user-provided targets targets = ns.args.map(x => String(x)); } else { // No arguments provided: Scan the entire network ns.tprint("No targets provided. Scanning network for hackable servers..."); targets = getAllServers(ns); } // ============================================ // CRACKING LOGIC // ============================================ for (const target of targets) { // Skip servers we already own if (ns.hasRootAccess(target)) continue; // Check hacking level requirement const playerHackLevel = ns.getHackingLevel(); const serverReqLevel = ns.getServerRequiredHackingLevel(target); if (serverReqLevel > playerHackLevel) { // If manually targeted, we print a message. If auto-scanning, we just skip quietly. if (ns.args.length > 0) ns.tprint(`SKIP ${target}: Hack level too low (${serverReqLevel}).`); continue; } // Port requirements const needed = ns.getServerNumPortsRequired(target); let have = 0; const tools = [ "BruteSSH.exe", "FTPCrack.exe", "relaySMTP.exe", "HTTPWorm.exe", "SQLInject.exe" ]; // Check which tools we own for (const tool of tools) { if (ns.fileExists(tool, "home")) have++; } if (have < needed) { if (ns.args.length > 0) ns.tprint(`SKIP ${target}: requires ${needed} ports, you have ${have}.`); continue; } // Crack ports if (ns.fileExists("BruteSSH.exe", "home")) ns.brutessh(target); if (ns.fileExists("FTPCrack.exe", "home")) ns.ftpcrack(target); if (ns.fileExists("relaySMTP.exe", "home")) ns.relaysmtp(target); if (ns.fileExists("HTTPWorm.exe", "home")) ns.httpworm(target); if (ns.fileExists("SQLInject.exe", "home")) ns.sqlinject(target); // Final NUKE ns.nuke(target); if (ns.hasRootAccess(target)) { ns.tprint(`[SUCCESS] NUKED ${target}. Ready for hacking.`); } else { ns.tprint(`[ERROR] Failed to NUKE ${target}. Check hacking level or script permissions.`); } } } /** * Helper function to find all servers in the network * @param {NS} ns **/ function getAllServers(ns) { let scanned = ["home"]; for (let i = 0; i < scanned.length; i++) { const current = scanned; const neighbors = ns.scan(current); for (const neighbor of neighbors) { if (!scanned.includes(neighbor)) { scanned.push(neighbor); } } } // Remove 'home' from the list as we don't need to nuke it return scanned.filter(s => s !== "home"); }[/code] prune-personal-servers.js /** @param {NS} ns **/ export async function main(ns) { const servers = ns.getPurchasedServers(); for (const s of servers) { ns.killall(s); await ns.sleep(50); // allow killall to finish ns.deleteServer(s); } } share.js -> Share memory to get bonus with faction. The amount of share is based on the threads (-t X) /** @param {NS} ns **/ export async function main(ns) { // Worker: perform share forever while (true) { await ns.share(); } } simpleHack.js -> A simple hack script. Keep hacking the target based on threshold. /** @param {NS} ns **/ export function autocomplete(data, args) { if (args.length === 1) return data.servers; return []; } /** @param {NS} ns **/ export async function main(ns) { ns.disableLog("ALL"); // ============================================ // SIMPLIFIED ARGUMENT VALIDATION // ============================================ if (ns.args.length === 0 || ns.args[0] === "-h") { ns.tprint("USAGE:"); ns.tprint(`./simpleHack.js <target>`); ns.tprint(""); ns.tprint("Ex: run simpleHack.js n00dles"); ns.tprint("NOTE: Execution is controlled ONLY by thresholds."); return; } const target = String(ns.args[0]); // Encapsulated Port Checking and Cracking if (!checkAndNuke(ns, target)) { return; } // ============================================ // INITIAL LOG AND THRESHOLDS // ============================================ ns.tprint("--- Configuration ---"); ns.tprint(`Target: ${target}`); ns.tprint("--------------------"); ns.tprint(`Required Hacking: ${ns.getServerRequiredHackingLevel(target)}`); ns.tprint(`Money Max: ${ns.formatNumber(ns.getServerMaxMoney(target))}`); const minSec = ns.getServerMinSecurityLevel(target); ns.tprint(`Min Sec: ${minSec}`); ns.tprint("--------------------"); // Control Thresholds const minSecTolerance = minSec + 1; // Security limit: 5 above minimum const minMoneyThreshold = ns.getServerMaxMoney(target) * 0.90; // Money limit: 90% of maximum // ============================================ // FULL LOOP (Pure Threshold Logic) // ============================================ ns.disableLog("getServerSecurityLevel"); ns.disableLog("getServerMoneyAvailable"); ns.print(`TARGET = ${target}`); let wCount = 0, gCount = 0, hCount = 0; // Global operation counters // Auxiliary log function const logState = (op, count, money, sec) => { ns.print( `${op}: ${count} | ` + `Sec: ${sec.toFixed(2)} / ${minSecTolerance} | ` + `Money: ${ns.formatNumber(money)} / ${ns.formatNumber(ns.getServerMaxMoney(target))}` ); }; while (true) { const money = ns.getServerMoneyAvailable(target); const sec = ns.getServerSecurityLevel(target); // 1. WEAKEN (Priority: High Security) // Runs in a loop until the security threshold is reached. if (sec > minSecTolerance) { ns.print(`Starting WEAKEN: Sec ${sec.toFixed(2)} > ${minSecTolerance}.`); // Inner loop that continues until the threshold is met while (ns.getServerSecurityLevel(target) > minSecTolerance) { wCount++; logState("WEAKEN", wCount, ns.getServerMoneyAvailable(target), ns.getServerSecurityLevel(target)); await ns.weaken(target); } continue; // Re-evaluate server conditions } // 2. GROW (Priority: Low Money) // Runs in a loop until the money threshold is reached. if (money < minMoneyThreshold) { ns.print(`Starting GROW: Money ${ns.formatNumber(money)} < ${ns.formatNumber(minMoneyThreshold)}.`); // Inner loop that continues until the threshold is met while (ns.getServerMoneyAvailable(target) < minMoneyThreshold) { gCount++; logState("GROW", gCount, ns.getServerMoneyAvailable(target), ns.getServerSecurityLevel(target)); await ns.grow(target); } continue; // Re-evaluate server conditions (since grow increases security) } // 3. HACK (Optimal Condition) // Runs in a loop until security rises OR money drops below the threshold. if (sec <= minSecTolerance && money >= minMoneyThreshold) { ns.print("Starting HACK: Server is ready."); // Inner loop that runs as long as optimal conditions are maintained while (ns.getServerSecurityLevel(target) <= minSecTolerance && ns.getServerMoneyAvailable(target) >= minMoneyThreshold) { hCount++; logState("HACK", hCount, ns.getServerMoneyAvailable(target), ns.getServerSecurityLevel(target)); await ns.hack(target); } } // If there's nothing to do, wait briefly to avoid unnecessary cycles. await ns.sleep(500); } } // ============================================ // CRACKING AUXILIARY FUNCTION // ============================================ function checkAndNuke(ns, target) { // Checks if the target is accessible if (ns.getServerMaxRam(target) < 0) { ns.tprint(`ERROR: Target ${target} is not a valid hacking target.`); return false; } if (ns.hasRootAccess(target)) { ns.print(`Root access already established on ${target}.`); return true; } const needed = ns.getServerNumPortsRequired(target); const crackers = [ "BruteSSH.exe", "FTPCrack.exe", "relaySMTP.exe", "HTTPWorm.exe", "SQLInject.exe" ]; const availableCrackers = crackers.filter(tool => ns.fileExists(tool, "home")); const have = availableCrackers.length; if (have < needed) { ns.tprint("ERROR: Not enough port-cracking programs."); ns.tprint(`Target ${target} requires ${needed} ports open, but you can only open ${have}.`); ns.tprint("Install more port tools before running this script."); return false; } // Crack and NUKE availableCrackers.forEach(tool => { switch (tool) { case "BruteSSH.exe": ns.brutessh(target); break; case "FTPCrack.exe": ns.ftpcrack(target); break; case "relaySMTP.exe": ns.relaysmtp(target); break; case "HTTPWorm.exe": ns.httpworm(target); break; case "SQLInject.exe": ns.sqlinject(target); break; } }); ns.nuke(target); if (!ns.hasRootAccess(target)) { ns.tprint("ERROR: NUKE failed or hacking level is too low."); return false; } return true; } utilCopySmarts.js -> Copy the smart scripts into each personal server /** @param {NS} ns **/ export function autocomplete(data, args) { return []; // no args needed anymore } /** @param {NS} ns **/ export async function main(ns) { const files = [ "basic-grow.js", "basic-hack.js", "basic-weaken.js", "smartBatch.js" ]; // collect all personal servers const allServers = ns.scan("home"); const personal = allServers.filter(s => s.startsWith("p-")); if (personal.length === 0) { ns.tprint("No personal servers found (none start with p-)."); return; } ns.tprint("Copying files to personal servers..."); for (const server of personal) { ns.tprint(`--- ${server} ---`); for (const file of files) { if (!ns.fileExists(file, "home")) { ns.tprint(`ERROR: Missing file: ${file}`); continue; } const ok = ns.scp(file, server, "home"); if (ok) ns.tprint(`Copied: ${file}`); else ns.tprint(`FAILED copying: ${file}`); } } ns.tprint("Done."); } sell-all-stocks.js -> after you finish running stock stuff and need to make some money to buy something cute, maybe? /** @param {NS} ns **/ export async function main(ns) { ns.tprint("--- Iniciando Liquidacao Total ---"); // Certifique-se de que a API II esteja disponível para usar as funcoes de venda if (!ns.stock.hasWSEAccount()) { ns.tprint("ERRO: Requer 4S Market Data Tix API II para vender posicoes. Por favor, compre o upgrade."); return; } const symbols = ns.stock.getSymbols(); let totalProfit = 0; for (const sym of symbols) { const pos = ns.stock.getPosition(sym); const sharesLong = pos[0]; const avgPriceLong = pos[1]; const sharesShort = pos[2]; const avgPriceShort = pos[3]; // Vender Posicoes LONG if (sharesLong > 0) { const salePrice = ns.stock.sellStock(sym, sharesLong); const profit = (salePrice - avgPriceLong) * sharesLong; totalProfit += profit; ns.tprint(`VENDIDO ${sym} [LONG]: Shares: ${ns.formatNumber(sharesLong)}, Lucro: ${ns.formatNumber(profit)}`); } // Cobrir Posicoes SHORT (Se a venda a descoberto for permitida/ativa) if (sharesShort > 0) { // Se o jogo permitir short, use ns.stock.sellShort (cover) const coverPrice = ns.stock.sellShort(sym, sharesShort); const profit = (avgPriceShort - coverPrice) * sharesShort; totalProfit += profit; ns.tprint(`COBERTO ${sym} [SHORT]: Shares: ${ns.formatNumber(sharesShort)}, Lucro: ${ns.formatNumber(profit)}`); } } ns.tprint("----------------------------------"); ns.tprint(`LIQUIDACAO COMPLETA. Lucro/Prejuizo total da operacao: ${ns.formatNumber(totalProfit)}`); ns.tprint("Seu capital esta totalmente disponivel."); } All my alias and reference to those scripts alias sscan=clear ; scan-analyze alias darkweb=connect darkweb alias bl=buy -l alias profile=run ServerProfiler.exe alias share=run share.js alias am=run availableThreads.js alias cripple=run crippler.js alias karma=run ./heart.js alias simpleHack=run simpleHack.js alias find=run find.js alias single=run buySingleCustomServer.js alias delete=run deleteServer.js alias multiNuke=run multiNuke.js alias nextMoney=run checkNextMoney.js alias customByMoney=run buy-custom-server-by-money-available.js alias list=run listHackedByMoney.js alias allservers=run allservers.js alias initialHack=run init-hack-into-own-server.js alias nodemanager=run manage-hacknodes.js 0 1000 12 alias stock=run stock-trader-pro.js alias gangcontroller=run gang-controller.js alias sellAllStocks=run sell-all-stocks.js alias goto=run goto.js alias pricing=run pricing.js alias startSimpleHackOnPServers=run run-simplehack-on-pservers.js alias startSmartNoFormula=run ./smart/run-smart-noformula-on-pservers.js alias listPservers=run list-all-p-servers.js