diff --git a/Mizzajl/home/EveryServerRun.js b/Mizzajl/home/EveryServerRun.js index c6c50cf..e9f9481 100644 --- a/Mizzajl/home/EveryServerRun.js +++ b/Mizzajl/home/EveryServerRun.js @@ -39,7 +39,7 @@ export async function main(ns) { let nMaxRam; let nScripts; - for (const [name, entry] of Object.entries(serverList)) { + serverList.forEach(async (entry) => { //let rootAccess = ns.hasRootAccess(currentServer); //ns.tprint(entry.serverName + " sTarget = " + sTarget); @@ -49,7 +49,7 @@ export async function main(ns) { //nScriptsRAM = ns.getScriptRam(sScript, "home") + Math.max(nWeakenScriptRAM, nGrowScriptRAM, nHackScriptRAM); //ns.tprint("nScriptsRAM = " + nScriptsRAM); - if (entry.maxRam >= 64 && serverList[name].rootAccess === true) { + if (entry.maxRam >= 64 && entry.rootAccess === true) { if (sOverrideTarget !== undefined) { sTarget = sOverrideTarget; @@ -73,7 +73,7 @@ export async function main(ns) { ns.exec(sScript, entry.serverName, 1, sTarget, nFrequency, true, false); await ns.sleep(1); } - else if (entry.maxRam < 64 && entry.maxRam > 0 && serverList[name].rootAccess === true) { + else if (entry.maxRam < 64 && entry.maxRam > 0 && entry.rootAccess === true) { ns.scriptKill(sScript, entry.serverName); ns.scriptKill(sShareScript, entry.serverName); ns.scriptKill(sWeakenScript, entry.serverName); @@ -87,6 +87,6 @@ export async function main(ns) { } - } + }) //ns.exec("serverlister.js", "home", 1); } diff --git a/Mizzajl/home/Library.js b/Mizzajl/home/Library.js index fe130cf..a76e0a3 100644 --- a/Mizzajl/home/Library.js +++ b/Mizzajl/home/Library.js @@ -33,13 +33,13 @@ export function getCracks(ns) { /** @param {NS} ns */ export function scanServerList(ns) { const home = "home"; - let serverList = {}; + let serverList = []; let unscanned = []; unscanned.push(home); while (unscanned.length > 0) { let currentServer = unscanned.pop(); - if (!serverList[currentServer]) { + if (!serverList.some(obj => obj["serverName"] === currentServer)) { let maxRam = ns.getServerMaxRam(currentServer); let minPorts = ns.getServerNumPortsRequired(currentServer); let minSecLevel = ns.getServerMinSecurityLevel(currentServer); @@ -51,8 +51,7 @@ export function scanServerList(ns) { let serverOrgs = serverStats.organizationName; let serverCores = serverStats.cpuCores; - serverList[currentServer] = - { + serverList.push({ serverName: currentServer, maxRam: maxRam, maxMoney: serverMoney, @@ -64,11 +63,11 @@ export function scanServerList(ns) { serverOrgs: serverOrgs, serverCores: serverCores, serverFiles: serverFiles, - }; + }); let neighbours = ns.scan(currentServer); for (let i = 0; i < neighbours.length; i++) { let neighbour = neighbours[i]; - if (serverList[neighbour]) { + if (serverList.some(obj => obj["serverName"] === neighbour)) { continue } unscanned.push(neighbour); @@ -89,17 +88,17 @@ export function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTar bestEntry = null; let nMaxMoneyPerChance = 0; let nBestMoneyPerChance = 0; - for (const [name, entry] of Object.entries(serverList)) { + serverList.forEach((entry)=> { if (entry.minSec <= maxSec && entry.minPorts <= maxPorts && entry.minHackLvl <= currentHackLevel) { - nMaxMoneyPerChance = (entry.maxMoney * ns.hackAnalyzeChance(name)) / entry.minSec; + nMaxMoneyPerChance = (entry.maxMoney * ns.hackAnalyzeChance(entry.serverName)) / entry.minSec; if (nMaxMoneyPerChance > nBestMoneyPerChance) { nBestMoneyPerChance = nMaxMoneyPerChance; - bestEntry = name; + bestEntry = entry.serverName; } } - } + }) } - ns.write("bestTarget.txt", JSON.stringify(serverList[bestEntry]), "w"); + ns.write("bestTarget.txt", JSON.stringify(serverList.find((entry) => entry.serverName === bestEntry)), "w"); } @@ -107,24 +106,25 @@ export function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTar export function crackingAndRooting(ns, cracks) { if (!ns.fileExists("serverList.txt", "home")) scanServerList(); let serverList = JSON.parse(ns.read("serverList.txt")); - for (const [name, entry] of Object.entries(serverList)) { + let newServerList = serverList.map((entry) => { let cracked = false; - let openPorts = serverList[name].openPorts || 0; + let openPorts = entry.openPorts || 0; if (entry.minPorts === 0 || (entry.minPorts > openPorts && entry.minPorts <= Object.keys(cracks).length)) { for (let k = 0; k < entry.minPorts; k++) { - cracks[Object.keys(cracks)[k]](name); - serverList[name].openPorts = k; + cracks[Object.keys(cracks)[k]](entry.serverName); + entry.openPorts = k; } cracked = true; } - if (!ns.hasRootAccess(name) && cracked === true) { - ns.nuke(name); - if (ns.hasRootAccess(name)) { - serverList[name].rootAccess = true; + if (!ns.hasRootAccess(entry.serverName) && cracked === true) { + ns.nuke(entry.serverName); + if (ns.hasRootAccess(entry.serverName)) { + entry.rootAccess = true; } } - ns.write("serverList.txt", JSON.stringify(serverList), "w"); - } + return entry + }) + ns.write("serverList.txt", JSON.stringify(newServerList), "w"); ns.tprint("Cracking and rooting done"); } @@ -132,25 +132,26 @@ export function crackingAndRooting(ns, cracks) { /** @param {NS} ns */ export function copyAndRunScript(ns, funnyScript, currentServer) { let bestTarget = JSON.parse(ns.read("bestTarget.txt")); - let name = currentServer; let serverList = JSON.parse(ns.read("serverList.txt")); - ns.print(name); - if (serverList[name].rootAccess === true && serverList[bestTarget.serverName].rootAccess === true) { - if (name !== "home") { - ns.print("killed threads on: " + name + ns.killall(name, true)); + let bestEntry = serverList.find((entry) => entry.serverName === bestTarget.serverName) + let currentEntry = serverList.find((entry) => entry.serverName === currentServer) + + if (currentEntry.rootAccess === true && bestEntry.rootAccess === true) { + if (currentEntry.serverName !== "home") { + ns.print("killed threads on: " + currentEntry.serverName + ns.killall(currentEntry.serverName, true)); } else { - ns.print("killed threads on: " + name + ns.scriptKill(funnyScript[0], name)); + ns.print("killed threads on: " + currentEntry.serverName + ns.scriptKill(funnyScript[0], currentEntry.serverName)); }; - if (serverList[name].maxRam > 0) { - ns.scp(funnyScript, name, "home"); + if (currentEntry.maxRam > 0) { + ns.scp(funnyScript, currentEntry.serverName, "home"); let maxProcesses = 1; - if (serverList[name].maxRam >= 8) { - maxProcesses = Math.max(Math.floor((serverList[name].maxRam) / 8), 1); + if (currentEntry.maxRam >= 8) { + maxProcesses = Math.max(Math.floor((currentEntry.maxRam) / 8), 1); } else { maxProcesses = 1 }; for (let n = 1; n <= maxProcesses; n++) { - ns.exec(funnyScript[0], name, 1, bestTarget.serverName); + ns.exec(funnyScript[0], currentEntry.serverName, 1, bestTarget.serverName); } } } @@ -165,7 +166,7 @@ export async function purchaseAndUpgradeServers(ns) { let purchasedServers = []; let pServcount = listPurchasedServers(ns).length; let currentMoney = 0; - let serverList = {}; + let serverList = []; while (pServcount < maxPurchasedServers) { purchasedServers = listPurchasedServers(ns); currentMoney = ns.getServerMoneyAvailable("home"); @@ -180,7 +181,7 @@ export async function purchaseAndUpgradeServers(ns) { ns.toast("Purchased " + hostname, "info", 10000); pServcount = listPurchasedServers(ns).length; serverList = JSON.parse(ns.read("serverList.txt")); - serverList[hostname] = { + serverList.push({ serverName: hostname, maxRam: 16, maxMoney: 0, @@ -189,7 +190,7 @@ export async function purchaseAndUpgradeServers(ns) { minHackLvl: 1, rootAccess: true, openPorts: 0, - }; + }); ns.write("serverList.txt", JSON.stringify(serverList), "w"); continue } else { @@ -202,19 +203,20 @@ export async function purchaseAndUpgradeServers(ns) { purchasedServers = listPurchasedServers(ns); for (let currentServer of purchasedServers) { currentMoney = ns.getServerMoneyAvailable("home"); - if (ns.getServerMaxRam(currentServer) < targetRam && ns.getPurchasedServerUpgradeCost(currentServer, targetRam) < currentMoney) { + if (ns.getServerMaxRam(currentServer) < targetRam){ + if (ns.getPurchasedServerUpgradeCost(currentServer, targetRam) < currentMoney) { if (ns.upgradePurchasedServer(currentServer, targetRam)) { ns.print(currentServer + " upgraded to " + targetRam + " GB RAM"); serverList = JSON.parse(ns.read("serverList.txt")); - serverList[currentServer].maxRam = targetRam; - ns.write("serverList.txt", JSON.stringify(serverList), "w"); + let newServerList = serverList.map((entry) => { if (entry.serverName === currentServer){ entry.maxRam = targetRam} return entry}); + ns.write("serverList.txt", JSON.stringify(newServerList), "w"); ns.tprint(cCyan + "Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB" + cReset); ns.toast("Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB", "info", 10000); } } else { await ns.sleep(5000); continue - }; + }}; } ++i; } @@ -260,44 +262,69 @@ export function listWorkServers(ns) { const sFileName = "serverList.txt"; if (!ns.fileExists(sFileName, "home")) { ns.print(`ERROR ${sFileName} does not exist.`); return false; }; let serverList = JSON.parse(ns.read(sFileName)); - //ns.tprint(serverList); - //const oList = sortDataByNestedKey(serverList, 'serverCores'); + let sortedList = sortJsonArrayByKey(serverList, "serverCores", "maxRam").reverse(); let nTotalWorkerRAM = 0; let nTotalFreeRAM = 0; const nServerColumnWidth = 20; - const nValueColumnWidth = 8; + const nValueColumnWidth = 10; const nCoresWidth = 5; - ns.printRaw("┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓"); - ns.printRaw("┃ Server ┃ Free / Max RAM ┃ Cores ┃"); - ns.printRaw("┣━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━┫"); - for (const [name, entry] of Object.entries(serverList)) { + ns.printRaw("┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓"); + ns.printRaw("┃ Server ┃ Free / Max RAM ┃ Cores ┃"); + ns.printRaw("┣━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━┫"); + sortedList.forEach((entry) => { if (entry.rootAccess && entry.maxRam >= 1) { let sServerName = entry.serverName.padEnd(nServerColumnWidth, ' '); let nFreeRAM = entry.maxRam - ns.getServerUsedRam(entry.serverName); - let sFreeRAM = nFreeRAM.toLocaleString().padStart(nValueColumnWidth, ' '); - let sMaxRam = entry.maxRam.toLocaleString().padStart(nValueColumnWidth, ' '); - let sCores = entry.serverCores.toLocaleString().padStart(nCoresWidth, ' '); + let sFreeRAM = Math.floor(nFreeRAM).toLocaleString("en-US").padStart(nValueColumnWidth, ' '); + let sMaxRam = entry.maxRam.toLocaleString("en-US").padStart(nValueColumnWidth, ' '); + let sCores = entry.serverCores.toLocaleString("en-US").padStart(nCoresWidth, ' '); ns.printRaw(`┃ ${sServerName} ┃ ${sFreeRAM} / ${sMaxRam} ┃ ${sCores} ┃`); nTotalWorkerRAM += entry.maxRam; nTotalFreeRAM += nFreeRAM; } - } - ns.printRaw("┗━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━┛"); - ns.printRaw(`Total Free: ${nTotalFreeRAM.toLocaleString()} / ${nTotalWorkerRAM.toLocaleString()} GB`); + }); + ns.printRaw("┗━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━┛"); + ns.printRaw(`Total Free: ${Math.floor(nTotalFreeRAM).toLocaleString("en-US")} / ${nTotalWorkerRAM.toLocaleString("en-US")} GB`); } -function sortDataByNestedKey(data, key) { - return data.sort((a, b) => { - const aValue = Object.values(a)[0][key]; - const bValue = Object.values(b)[0][key]; +export function sortJsonArrayByKey(array, primaryKey, secondaryKey) { + return array.sort((a, b) => { + const xPrimary = a[primaryKey]; + const yPrimary = b[primaryKey]; - if (typeof aValue === 'string') { - return aValue.localeCompare(bValue); - } else { - return aValue - bValue; + // Handle null or undefined values for primary key + if (xPrimary === null || yPrimary === null || xPrimary === undefined || yPrimary === undefined) { + return 0; } + + // Compare primary keys + const primaryComparison = compareValues(xPrimary, yPrimary); + if (primaryComparison !== 0) { + return primaryComparison; + } + + // If primary keys are equal, compare secondary keys + const xSecondary = a[secondaryKey]; + const ySecondary = b[secondaryKey]; + + // Handle null or undefined values for secondary key + if (xSecondary === null || ySecondary === null || xSecondary === undefined || ySecondary === undefined) { + return 0; + } + + return compareValues(xSecondary, ySecondary); }); -} \ No newline at end of file + + function compareValues(x, y) { + // Handle numeric and string comparisons differently + if (typeof x === 'string' && typeof y === 'string') { + return x.localeCompare(y); // For string comparison + } else { + return x - y; // For numeric comparison + } + } +} + diff --git a/Mizzajl/home/Serverlist.js b/Mizzajl/home/Serverlist.js index d748af7..29237fd 100644 --- a/Mizzajl/home/Serverlist.js +++ b/Mizzajl/home/Serverlist.js @@ -7,7 +7,7 @@ export async function main(ns) { let maxPorts = Object.keys(cracks).length; scanServerList(ns); let manualTargetOverride = ""; - if (ns.getHackingLevel() < 50) { + if (ns.getHackingLevel() < 200) { manualTargetOverride = "n00dles"; }; findBestTarget(ns, 999, maxPorts, ns.getHackingLevel(), manualTargetOverride); diff --git a/Mizzajl/home/WorkerList.js b/Mizzajl/home/WorkerList.js index 107e501..074b4f3 100644 --- a/Mizzajl/home/WorkerList.js +++ b/Mizzajl/home/WorkerList.js @@ -4,7 +4,7 @@ import { listWorkServers } from "/Library.js"; export async function main(ns) { ns.disableLog("ALL"); ns.tail(); - ns.resizeTail(522,625); + ns.resizeTail(560,625); let nStatus = 0; let aStatus = ["─", "╲", "│", "╱"]; let bWhile = true; diff --git a/Mizzajl/home/bestTarget.txt b/Mizzajl/home/bestTarget.txt index 4041a0d..dbe4d46 100644 --- a/Mizzajl/home/bestTarget.txt +++ b/Mizzajl/home/bestTarget.txt @@ -1 +1 @@ -{"serverName":"the-hub","maxRam":32,"maxMoney":4832749575,"minSec":24,"minPorts":2,"minHackLvl":291,"rootAccess":true,"openPorts":0,"serverOrgs":"The Hub","serverCores":4,"serverFiles":[]} \ No newline at end of file +{"serverName":"the-hub","maxRam":32,"maxMoney":4832749575,"minSec":24,"minPorts":2,"minHackLvl":291,"rootAccess":true,"openPorts":0,"serverOrgs":"The Hub","serverCores":4,"serverFiles":["factionboost.js"]} \ No newline at end of file diff --git a/Mizzajl/home/game_readme.txt b/Mizzajl/home/game_readme.txt new file mode 100644 index 0000000..3523a2d --- /dev/null +++ b/Mizzajl/home/game_readme.txt @@ -0,0 +1,40 @@ +# Bitburner + +[![Join Discord](https://img.shields.io/discord/415207508303544321)](https://discord.gg/TFc3hKD) + +[![Build Status](https://github.com/bitburner-official/bitburner-src/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/bitburner-official/bitburner-src/actions/workflows/ci.yml) + +Bitburner is a programming-based [incremental game](https://en.wikipedia.org/wiki/Incremental_game) +that revolves around hacking and cyberpunk themes. +The game can be played at https://bitburner-official.github.io/ (release build), https://bitburner-official.github.io/bitburner-src/ (development build), or installed through [Steam](https://store.steampowered.com/app/1812820/Bitburner/). +The location of the release build may change in the near future. + +See the [frequently asked questions](./doc/FAQ.md) for more information . To discuss the game or get help, join the [official Discord server](https://discord.gg/TFc3hKD). + +# Documentation + +The game's official documentation can be found in-game. + +The [in-game documentation](./markdown/bitburner.md) is generated from the [TypeScript definitions](./src/ScriptEditor/NetscriptDefinitions.d.ts). + +Anyone is welcome to contribute to the documentation by editing the [source +files](/src/Documentation/doc) and then making a pull request with your contributions. +For further guidance, please refer to the "As A Documenter" section of +[CONTRIBUTING](./doc/CONTRIBUTING.md#as-a-documenter). + +# Contribution + +There are many ways to contribute to the game. It can be as simple as fixing +a typo, correcting a bug, or improving the UI. For guidance on doing so, +please refer to the [CONTRIBUTING](./doc/CONTRIBUTING.md) document. + +You will retain all ownership of the Copyright of any contributions you make, +and will have the same rights to use or license your contributions. By +submitting a pull request you agree to grant me perpetual, worldwide, +non-exclusive, transferable, royalty-free, and irrevocable rights to use, +publish, and distribute your contributions to the project. A formal +Contributor's License Agreement will be drawn up in the future. + +If you would like to make significant contributions to the project as a +collaborator, please reach out in #suggestions or #development on Discord to +help coordinate the effort. diff --git a/Mizzajl/home/killAllScripts.js b/Mizzajl/home/killAllScripts.js index cc54271..bc01291 100644 --- a/Mizzajl/home/killAllScripts.js +++ b/Mizzajl/home/killAllScripts.js @@ -1,8 +1,7 @@ /** @param {NS} ns */ export async function main(ns) { let serverList = JSON.parse(ns.read("serverList.txt")); - for (const [name, entry] of Object.entries(serverList)) { - - ns.killall(name, true) - } + serverList.forEach(entry => { + ns.killall(entry.serverName, true) + }); } diff --git a/Mizzajl/home/testdistribute.js b/Mizzajl/home/testdistribute.js index 7257181..f7686ba 100644 --- a/Mizzajl/home/testdistribute.js +++ b/Mizzajl/home/testdistribute.js @@ -7,7 +7,6 @@ export async function main(ns) { const bRepeat = ns.args[3]; // should this script loop const nMsecDelay = ns.args[4]; // MsecDelay - const sWeakenScript = "RMweaken.js"; const sGrowScript = "RMgrow.js"; const sHackScript = "RMhack.js"; @@ -17,6 +16,7 @@ export async function main(ns) { if (!ns.fileExists(sListName, "home")) { ns.print(`ERROR ${sListName} does not exist.`); return false; }; let sServerList = JSON.parse(ns.read(sListName)); + let aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam").reverse(); ns.print(sScript); ns.print(nThreads); @@ -28,32 +28,35 @@ export async function main(ns) { ns.print("nScriptSize = " + nScriptSize); ns.print("nTotalSize = " + nTotalSize); - - - - // get sorted list of most cores servers + /* + aSortedList.forEach((entry) => { + if (entry.rootAccess && entry.maxRam >= 1 && entry.serverCores > 1) { + // if cores equal to previous entry put into same array? + } + }) */ // get total free RAM per number of cores // calculate effect of cores on each server with cores > 1 // update nThreads // run weaken/grow on core servers until cores = 1 - + // get sorted list of biggest RAM servers // get total free RAM on core 1 servers // run remaining weaken/grow // run hack untill RAM on cores 1 servers run out // run remaining hacks on smallest to biggest core servers - - - - + aSortedList.forEach((entry) => { + if (entry.rootAccess && ns.getServerMaxRam() >= ns.getScriptRam(sScript, "home")) { + let sHost = entry.serverName; + ns.exec(sScript, sHost, nThreads, sTarget, bRepeat, nMsecDelay); + + } + }) /* for (i = 0; ; i++) { let sHost = ""; ns.exec(sScript, sHost, nThreads, sTarget, bRepeat, nMsecDelay); - } - */ - + } */ } \ No newline at end of file