From 22ddbbde5df5646f30f8e51d41e89467464ebce9 Mon Sep 17 00:00:00 2001 From: Isaac Shoebottom Date: Fri, 3 Nov 2023 18:42:37 -0300 Subject: [PATCH] Reformat files --- servers/home/autoexec.ts | 8 +- servers/home/hack.ts | 33 ++-- servers/home/hackallservers.ts | 26 ++- servers/home/hacknet.ts | 203 ++++++++++++------------ servers/home/killall.ts | 15 +- servers/home/utils.ts | 281 ++++++++++++++++----------------- servers/home/watcher.ts | 31 ++-- 7 files changed, 289 insertions(+), 308 deletions(-) diff --git a/servers/home/autoexec.ts b/servers/home/autoexec.ts index 4132e04..8055e09 100644 --- a/servers/home/autoexec.ts +++ b/servers/home/autoexec.ts @@ -1,4 +1,4 @@ -export async function main(ns: NS) { - ns.run("watcher.js") - ns.run("hacknet.js") -} \ No newline at end of file +export async function main(ns: NS) { + ns.run('watcher.js') + ns.run('hacknet.js') +} diff --git a/servers/home/hack.ts b/servers/home/hack.ts index 6d5e180..753fb37 100644 --- a/servers/home/hack.ts +++ b/servers/home/hack.ts @@ -1,23 +1,10 @@ -export async function main(ns: NS) { - const server: string = ns.args[0]; - while (true) { - /* This code checks conditions that are not needed with smart scheduling - const moneyThresh: number = ns.args[1]; - const securityThresh: number = ns.args[2]; - if (ns.getServerSecurityLevel(server) > securityThresh) { - await ns.weaken(server); - } else if (ns.getServerMoneyAvailable(server) < moneyThresh) { - await ns.grow(server); - } else { - await ns.hack(server); - } - */ - - // Guide - // https://darktechnomancer.github.io/#glossary-of-terms - await ns.weaken(server); - await ns.grow(server); - await ns.weaken(server); - await ns.hack(server); - } -} \ No newline at end of file +export async function main(ns: NS) { + const server: string = ns.args[0] + while (true) { + // Guide https://darktechnomancer.github.io/#glossary-of-terms + await ns.weaken(server) + await ns.grow(server) + await ns.weaken(server) + await ns.hack(server) + } +} diff --git a/servers/home/hackallservers.ts b/servers/home/hackallservers.ts index bea3e51..625126c 100644 --- a/servers/home/hackallservers.ts +++ b/servers/home/hackallservers.ts @@ -1,15 +1,11 @@ -import {recursiveScan} from "./utils"; -import {executeScriptOnServerFromAnother} from "./utils"; -export async function main(ns: NS) { - let servers: string[] = recursiveScan(ns); - - for (const server of servers) { - // Commented out code is not needed with smart scheduling - //let moneyThresh = ns.getServerMaxMoney(server) * 0.75; - //let securityThresh = ns.getServerMinSecurityLevel(server) + 5; - let numThreads = ns.getServerMaxRam(server) / ns.getScriptRam("hack.js") - numThreads = Math.floor(numThreads); - //executeScriptOnServerFromAnother(ns, server, "hack.js", numThreads, [server, moneyThresh, securityThresh]) - executeScriptOnServerFromAnother(ns, server, "hack.js", numThreads, [server]) - } -} \ No newline at end of file +import { executeScriptOnServerFromAnother, recursiveScan } from './utils' + +export async function main(ns: NS) { + let servers: string[] = recursiveScan(ns) + + for (const server of servers) { + let numThreads = ns.getServerMaxRam(server) / ns.getScriptRam('hack.js') + numThreads = Math.floor(numThreads) + executeScriptOnServerFromAnother(ns, server, 'hack.js', numThreads, [server]) + } +} diff --git a/servers/home/hacknet.ts b/servers/home/hacknet.ts index b957165..2df655e 100644 --- a/servers/home/hacknet.ts +++ b/servers/home/hacknet.ts @@ -1,103 +1,100 @@ -/* - * TODO: - * The current solution is not optimal, as it's preferable to buy new nodes, even if upgrading is cheaper. - * TODO: - * It may be helpful to calculate the money per second of each node on average, (total mps / total nodes) and compare - * it to the time it would take to purchase the next cheapest upgrade, and if the average mps is greater than the - * negative mps of the upgrade cost, then buy a new node. - * TODO: - * Potential Ideas: - * Find a way to calculate how much mps an individual upgrade would give, and compare it to the average mps of the node. - * ns.hacknet.getNodeStats(0).production - * If the upgrade mps is greater than the average mps, then buy the upgrade. - * If the upgrade mps is less than the average mps, then buy a new node. - */ - -enum Type { - newNode = "node", - level = "level", - ram = "ram", - core = "code" -} - -export async function main(ns: NS) { - let timeout: number = ns.args[0] - - let nodes = ns.hacknet.numNodes() - let costs: {type: Type, cost: number}[] = [] - while (true) { - costs = [] - // Go through each node and get the cheapest upgrade - for (let i = 0; i < nodes; i++) { - costs.push(getCheapestCost(ns, i)) - } - // Buy the cheapest upgrade from all nodes - let cheapest = Math.min(...costs.map(c => c.cost)) - // Find the index of the cheapest cost in the list - let index = costs.findIndex(c => c.cost === cheapest) - // Wait to buy the cheapest upgrade - try { - await buy(ns, costs[index].type, costs[index].cost, index, timeout) - } catch (e) { - ns.tprint(e) - ns.exit() - } - // Make sure that the number of nodes is up-to-date - nodes = ns.hacknet.numNodes() - } -} - -/** - * Wait until the player has enough money to buy something - * @param ns Global NS object - * @param money Amount of money to wait for - * @param timeout=-1 Number of seconds to wait before timing out. - * @throws Error if the timeout is reached - * @note This function will wait forever by default - */ -async function waitUntilMoney(ns: NS, money: number, timeout: number = -1) { - while (ns.getServerMoneyAvailable("home") < money) { - await ns.sleep(1000) - if (timeout == 0) { - throw new Error("Timed out waiting for money") - } else if (timeout > -1) { - timeout--; - } - } -} - -async function buy(ns: NS, type: Type, cost: number, node: number, timeout: number) { - await waitUntilMoney(ns, cost, timeout) - switch (type) { - case Type.newNode: - ns.hacknet.purchaseNode() - break - case Type.level: - ns.hacknet.upgradeLevel(node) - break - case Type.ram: - ns.hacknet.upgradeRam(node) - break - case Type.core: - ns.hacknet.upgradeCore(node) - break - } -} - -function getCheapestCost(ns: NS, node: number) { - let nodeCost = ns.hacknet.getPurchaseNodeCost() - let levelCost = ns.hacknet.getLevelUpgradeCost(node) - let ramCost = ns.hacknet.getRamUpgradeCost(node) - let coreCost = ns.hacknet.getCoreUpgradeCost(node) - let cheapest = Math.min(nodeCost, levelCost, ramCost, coreCost) - switch (cheapest) { - case nodeCost: - return {type: Type.newNode, cost: nodeCost} - case levelCost: - return {type: Type.level, cost: levelCost} - case ramCost: - return {type: Type.ram, cost: ramCost} - case coreCost: - return {type: Type.core, cost: coreCost} - } -} \ No newline at end of file +/* + * TODO: + * The current solution is not optimal, as it's preferable to buy new nodes, even if upgrading is cheaper. + * TODO: + * It may be helpful to calculate the money per second of each node on average, (total mps / total nodes) and compare + * it to the time it would take to purchase the next cheapest upgrade, and if the average mps is greater than the + * negative mps of the upgrade cost, then buy a new node. + * TODO: + * Potential Ideas: + * Find a way to calculate how much mps an individual upgrade would give, and compare it to the average mps of the node. + * ns.hacknet.getNodeStats(0).production + * If the upgrade mps is greater than the average mps, then buy the upgrade. + * If the upgrade mps is less than the average mps, then buy a new node. + */ + +enum Type { + newNode = 'node', level = 'level', ram = 'ram', core = 'code', +} + +export async function main(ns: NS) { + let timeout: number = ns.args[0] + + let nodes = ns.hacknet.numNodes() + let costs: { type: Type, cost: number }[] = [] + while (true) { + costs = [] + // Go through each node and get the cheapest upgrade + for (let i = 0; i < nodes; i++) { + costs.push(getCheapestCost(ns, i)) + } + // Buy the cheapest upgrade from all nodes + let cheapest = Math.min(...costs.map(c => c.cost)) + // Find the index of the cheapest cost in the list + let index = costs.findIndex(c => c.cost === cheapest) + // Wait to buy the cheapest upgrade + try { + await buy(ns, costs[index].type, costs[index].cost, index, timeout) + } catch (e) { + ns.tprint(e) + ns.exit() + } + // Make sure that the number of nodes is up-to-date + nodes = ns.hacknet.numNodes() + } +} + +/** + * Wait until the player has enough money to buy something + * @param ns Global NS object + * @param money Amount of money to wait for + * @param timeout=-1 Number of seconds to wait before timing out. + * @throws Error if the timeout is reached + * @note This function will wait forever by default + */ +async function waitUntilMoney(ns: NS, money: number, timeout: number = -1) { + while (ns.getServerMoneyAvailable('home') < money) { + await ns.sleep(1000) + if (timeout == 0) { + throw new Error('Timed out waiting for money') + } else if (timeout > -1) { + timeout-- + } + } +} + +async function buy(ns: NS, type: Type, cost: number, node: number, timeout: number) { + await waitUntilMoney(ns, cost, timeout) + switch (type) { + case Type.newNode: + ns.hacknet.purchaseNode() + break + case Type.level: + ns.hacknet.upgradeLevel(node) + break + case Type.ram: + ns.hacknet.upgradeRam(node) + break + case Type.core: + ns.hacknet.upgradeCore(node) + break + } +} + +function getCheapestCost(ns: NS, node: number) { + let nodeCost = ns.hacknet.getPurchaseNodeCost() + let levelCost = ns.hacknet.getLevelUpgradeCost(node) + let ramCost = ns.hacknet.getRamUpgradeCost(node) + let coreCost = ns.hacknet.getCoreUpgradeCost(node) + let cheapest = Math.min(nodeCost, levelCost, ramCost, coreCost) + switch (cheapest) { + case nodeCost: + return { type: Type.newNode, cost: nodeCost } + case levelCost: + return { type: Type.level, cost: levelCost } + case ramCost: + return { type: Type.ram, cost: ramCost } + case coreCost: + return { type: Type.core, cost: coreCost } + } +} diff --git a/servers/home/killall.ts b/servers/home/killall.ts index f6dcb47..7051334 100644 --- a/servers/home/killall.ts +++ b/servers/home/killall.ts @@ -1,7 +1,8 @@ -import {recursiveScan} from "./utils"; -export async function main(ns: NS) { - let servers: string[] = recursiveScan(ns) - for (const server of servers) { - ns.killall(server) - } -} \ No newline at end of file +import { recursiveScan } from './utils' + +export async function main(ns: NS) { + let servers: string[] = recursiveScan(ns) + for (const server of servers) { + ns.killall(server) + } +} diff --git a/servers/home/utils.ts b/servers/home/utils.ts index 2639e95..4391ab1 100644 --- a/servers/home/utils.ts +++ b/servers/home/utils.ts @@ -1,141 +1,140 @@ -// noinspection JSUnusedGlobalSymbols -/** - * Recursively scans all servers connected to the current server, excluding home - * @param ns global NS object - * @returns A list of all servers connected to the current server - */ -export function recursiveScan(ns: NS) { - // Starting case - let servers = ns.scan("home"); - // Add all servers to the list - let allServers: string[] = []; - while (servers.length > 0) { - let server = servers.shift(); - if(server) { - let newServers = ns.scan(server); - for (let newServer of newServers) { - if (!allServers.includes(newServer)) { - allServers.push(newServer); - servers.push(newServer); - } - } - } - } - // Remove the current server - allServers.splice(allServers.indexOf("home"), 1); - // Print all servers - return allServers; -} - -/** - * Removes files passed in from all servers - * @param ns Global NS object - * @param files The files to remove - * @returns void - * @example Removes all files from the folder "no-ports" from all servers. - * removeFilesOnAllServers(ns, ns.ls("home", "no-ports")); - * @note ns.ls() returns the full path of every file, so if the file is not in the same place in every server, - * you will need to modify each file path to match the server you are removing it from. - */ -export function removeFilesOnAllServers(ns: NS, files: string[]) { - let hosts = recursiveScan(ns); - for(const host of hosts) { - for (const file of files) { - ns.rm(file, host) - } - } -} - -/** - * Tries to gain root access to a server - * @param ns Global NS object - * @param server The server to gain root access to - * @returns The number of programs used to gain root access - */ -export function rootServer(ns: NS, server: string) { - let counter = 0; - if (ns.fileExists("BruteSSH.exe", "home")) { - ns.brutessh(server); - counter++; - } - if (ns.fileExists("FTPCrack.exe", "home")) { - ns.ftpcrack(server); - counter++; - } - if (ns.fileExists("SMTPCrack.exe", "home")) { - ns.relaysmtp(server); - counter++; - } - if (ns.fileExists("HTTPWorm.exe", "home")) { - ns.httpworm(server); - counter++; - } - if (ns.fileExists("SQLInject.exe", "home")) { - ns.sqlinject(server); - counter++; - } - ns.nuke(server) - return counter; -} - -/** - * Performs a function on a server if the player is capable of doing so, otherwise returns false - * @param ns Global NS object - * @param server The server to perform the function on - * @param func The function to perform - * @param args The arguments to pass to the function - * @returns The result of the function if it is performed or true if the function does not return anything, otherwise false - */ -export function performFunctionIfCapable(ns: NS, server: string, func: CallableFunction, args: any[]) { - if (ns.getHackingLevel() < ns.getServerRequiredHackingLevel(server)) { - return false; - } - if (ns.getServerNumPortsRequired(server) < ns.getServer(server).openPortCount) { - if (rootServer(ns, server) < ns.getServerNumPortsRequired(server)) { - return false; - } - } - if (!ns.hasRootAccess(server)) { - return false; - - } - let result = func(...args); - if (result === undefined) { - return true; - } else { - return result; - } -} - -/** - * Executes a script on a server from another server - * @param ns Global NS object - * @param server The server to execute the script on - * @param script The file path of the script to execute - * @param threads The number of threads to use - * @param args The arguments to pass to the script - */ -export function executeScriptOnServerFromAnother(ns: NS, server: string, script: string, threads: number = 1, args: any[]) { - ns.scp(script, server); - performFunctionIfCapable(ns, server, ns.exec, [script, server, threads, ...args]) - ns.atExit( - () => { - ns.rm(script, server); - } - ) -} - -/** - * Calculates the money per second the player is making - * @param ns Global NS object - * @param time=5 The number of seconds to calculate the MPS over - */ -export async function calculateMPS(ns: NS, time: number = 5) { - let start = ns.getServerMoneyAvailable("home"); - let data: number[] = []; - for (let i = 0; i < time; i++) { - await ns.sleep(1000); - data.push(ns.getServerMoneyAvailable("home") - start); - } - return data.reduce((a, b) => a + b, 0) / time; -} \ No newline at end of file +// noinspection JSUnusedGlobalSymbols + +/** + * Recursively scans all servers connected to the current server, excluding home + * @param ns global NS object + * @returns A list of all servers connected to the current server + */ +export function recursiveScan(ns: NS) { + // Starting case + let servers = ns.scan('home') + // Add all servers to the list + let allServers: string[] = [] + while (servers.length > 0) { + let server = servers.shift() + if (server) { + let newServers = ns.scan(server) + for (let newServer of newServers) { + if (!allServers.includes(newServer)) { + allServers.push(newServer) + servers.push(newServer) + } + } + } + } + // Remove the current server + allServers.splice(allServers.indexOf('home'), 1) + // Print all servers + return allServers +} + +/** + * Removes files passed in from all servers + * @param ns Global NS object + * @param files The files to remove + * @returns void + * @example Removes all files from the folder "no-ports" from all servers. + * removeFilesOnAllServers(ns, ns.ls("home", "no-ports")); + * @note ns.ls() returns the full path of every file, so if the file is not in the same place in every server, + * you will need to modify each file path to match the server you are removing it from. + */ +export function removeFilesOnAllServers(ns: NS, files: string[]) { + let hosts = recursiveScan(ns) + for (const host of hosts) { + for (const file of files) { + ns.rm(file, host) + } + } +} + +/** + * Tries to gain root access to a server + * @param ns Global NS object + * @param server The server to gain root access to + * @returns The number of programs used to gain root access + */ +export function rootServer(ns: NS, server: string) { + let counter = 0 + if (ns.fileExists('BruteSSH.exe', 'home')) { + ns.brutessh(server) + counter++ + } + if (ns.fileExists('FTPCrack.exe', 'home')) { + ns.ftpcrack(server) + counter++ + } + if (ns.fileExists('SMTPCrack.exe', 'home')) { + ns.relaysmtp(server) + counter++ + } + if (ns.fileExists('HTTPWorm.exe', 'home')) { + ns.httpworm(server) + counter++ + } + if (ns.fileExists('SQLInject.exe', 'home')) { + ns.sqlinject(server) + counter++ + } + ns.nuke(server) + return counter +} + +/** + * Performs a function on a server if the player is capable of doing so, otherwise returns false + * @param ns Global NS object + * @param server The server to perform the function on + * @param func The function to perform + * @param args The arguments to pass to the function + * @returns The result of the function if it is performed or true if the function does not return anything, otherwise false + */ +export function performFunctionIfCapable(ns: NS, server: string, func: CallableFunction, args: any[]) { + if (ns.getHackingLevel() < ns.getServerRequiredHackingLevel(server)) { + return false + } + if (ns.getServerNumPortsRequired(server) < ns.getServer(server).openPortCount) { + if (rootServer(ns, server) < ns.getServerNumPortsRequired(server)) { + return false + } + } + if (!ns.hasRootAccess(server)) { + return false + + } + let result = func(...args) + if (result === undefined) { + return true + } else { + return result + } +} + +/** + * Executes a script on a server from another server + * @param ns Global NS object + * @param server The server to execute the script on + * @param script The file path of the script to execute + * @param threads The number of threads to use + * @param args The arguments to pass to the script + */ +export function executeScriptOnServerFromAnother(ns: NS, server: string, script: string, threads: number = 1, args: any[]) { + ns.scp(script, server) + performFunctionIfCapable(ns, server, ns.exec, [script, server, threads, ...args]) + ns.atExit(() => { + ns.rm(script, server) + }) +} + +/** + * Calculates the money per second the player is making + * @param ns Global NS object + * @param time=5 The number of seconds to calculate the MPS over + */ +export async function calculateMPS(ns: NS, time: number = 5) { + let start = ns.getServerMoneyAvailable('home') + let data: number[] = [] + for (let i = 0; i < time; i++) { + await ns.sleep(1000) + data.push(ns.getServerMoneyAvailable('home') - start) + } + return data.reduce((a, b) => a + b, 0) / time +} diff --git a/servers/home/watcher.ts b/servers/home/watcher.ts index 0492994..44b33a3 100644 --- a/servers/home/watcher.ts +++ b/servers/home/watcher.ts @@ -1,15 +1,16 @@ -export async function main(ns: NS) { - let hackingLevel = ns.getHackingLevel(); - while (hackingLevel < 9999) { - let oldHackingLevel = hackingLevel; - hackingLevel = ns.getHackingLevel(); - if(oldHackingLevel !== hackingLevel) { - ns.tprint(`Hacking level increased from ${oldHackingLevel} to ${hackingLevel}`); - ns.run("killall.js"); - await ns.sleep(1000) // 1 second - ns.run("hackallservers.js"); - } - // Wait 1 second before checking again - await ns.sleep(1000) - } -} \ No newline at end of file +export async function main(ns: NS) { + ns.run('hackallservers.js') + let hackingLevel = ns.getHackingLevel() + while (hackingLevel < 9999) { + let oldHackingLevel = hackingLevel + hackingLevel = ns.getHackingLevel() + if (oldHackingLevel !== hackingLevel) { + ns.tprint(`Hacking level increased from ${oldHackingLevel} to ${hackingLevel}`) + ns.run('killall.js') + await ns.sleep(1000) // 1 second + ns.run('hackallservers.js') + } + // Wait 1 second before checking again + await ns.sleep(1000) + } +}