Hacknet Automation Script
user_3576964
javascript
a year ago
6.0 kB
2
Indexable
Never
/** @param {NS} ns */ export async function main(ns) { ns.disableLog('sleep'); if (!ns.args.length) { return ns.tprint('Supply a target Cluster size'); } const target = ns.args[0]; const cluster = getMaxedNodes(ns); if (cluster >= target) { ns.tprint('Cluster target is less than current cluster size'); ns.tprint(`Target: ${target} | Cluster: ${cluster}`); return; } const killMode = ns.args[1] === 'no-kill' ? false : true; if (!killMode) { ns.tprint('Starting in no-kill mode'); ns.tprint('Running until manually terminated or target reached'); } ns.print('Starting Hacknet node automation'); let maxedCluster = await checkClusterStatus(ns, target); while (!maxedCluster) { await ns.sleep(500); await automateNodes(ns, target, killMode); maxedCluster = await checkClusterStatus(ns, target); } if (maxedCluster) { ns.print(`Cluster target of ${target} reached, exiting`); } } /** @param {NS} ns @param {number} target @param {boolean} killMode @returns {Promise<void>} */ const automateNodes = async (ns, target, killMode) => { return new Promise((resolve) => { const { hacknet: hn } = ns; const { ownedNodes, maxedNodes, nextNodeCost, money } = getStats(ns); let currentNode = maxedNodes; if (maxedNodes === ownedNodes && ownedNodes < target) { if (money < nextNodeCost) { if (!killMode) { await handleNoKill(ns, resolve, money, 'New Node', nextNodeCost); return; } else { return terminate(ns); } } else { ns.print(`Upgrades finished for Node #${currentNode}`); currentNode = hn.purchaseNode(); ns.print(`Purchased New Node: #${currentNode}`); } } const { level, ram, cores } = hn.getNodeStats(currentNode); const canUpgrade = getCanUpgrade(ns, currentNode, money); if (canUpgrade.all) { upgradeNode(ns, currentNode); handleSuccess(ns, currentNode, level, ram, cores); return resolve(); } for (const component in canUpgrade) { if (component !== 'all') { if (!canUpgrade[component].isAffordable) { if (!killMode) { await handleNoKill(ns, resolve, money, component, canUpgrade[component].cost); return resolve(); } else { terminate(ns); return resolve(); } } } } return resolve(); }); }; /** @param {NS} ns @param {number} target @returns {Promise<boolean>} */ const checkClusterStatus = async (ns, target) => { return new Promise((resolve) => { const { hacknet: hn } = ns; const ownedNodes = hn.numNodes(); if (ownedNodes === target) { const maxedNodes = getMaxedNodes(ns); if (maxedNodes === target) { return resolve(true); } else { ns.print('Maxed Nodes: ', maxedNodes); } } return resolve(false); }); }; /** @param {NS} ns */ const getMaxedNodes = (ns) => { const { hacknet: hn } = ns; const ownedNodes = hn.numNodes(); let maxedNodes = 0; for (let i = 0; i < ownedNodes; i++) { const { level, cores, ram } = hn.getNodeStats(i); if (level === 200 && cores === 16 && ram === 64) { maxedNodes++; } } return maxedNodes; }; /** @param {NS} ns @param {number} currentNode */ const getUpgradeCosts = (ns, currentNode) => { const { hacknet: hn } = ns; return { levelCost: hn.getLevelUpgradeCost(currentNode), coreCost: hn.getCoreUpgradeCost(currentNode), ramCost: hn.getRamUpgradeCost(currentNode) }; }; /** @param {NS} ns @param {number} currentNode @param {number} money */ const getCanUpgrade = (ns, currentNode, money) => { let { levelCost, coreCost, ramCost } = getUpgradeCosts(ns, currentNode); const all = (money >= levelCost || levelCost === Infinity) && (money >= coreCost || coreCost === Infinity) && (money >= ramCost || ramCost === Infinity) ? true : false; return { all, level: { isAffordable: money < levelCost && levelCost !== Infinity ? false : true, cost: levelCost }, core: { isAffordable: money < coreCost && coreCost !== Infinity ? false : true, cost: coreCost }, ram: { isAffordable: money < ramCost && ramCost !== Infinity ? false : true, cost: ramCost } } } /** @param {NS} ns @param {number} currentNode */ const upgradeNode = (ns, currentNode) => { const { hacknet: hn } = ns; hn.upgradeLevel(currentNode, 10); hn.upgradeCore(currentNode); hn.upgradeRam(currentNode); }; /** @param {NS} ns */ const getStats = (ns) => { const { hacknet: hn } = ns; return { ownedNodes: hn.numNodes(), maxedNodes: getMaxedNodes(ns), nextNodeCost: hn.getPurchaseNodeCost(), money: ns.getPlayer().money }; }; /** @param {NS} ns @param {number} currentNode @param {number} level @param {number} ram @param {number} cores */ const handleSuccess = (ns, currentNode, level, ram, cores) => { ns.print(`Node #${currentNode} upgraded successfully`); ns.print(`Level: ${level} | RAM: ${ram} | Cores: ${cores}`); }; /** * @param {NS} ns * @param {Function} resolve */ const handleNoKill = async (ns, resolve, money, upgradeType, upgradeCost) => { ns.print('Not enough funds for next upgrade'); ns.print(`Funds needed for ${upgradeType}: ${ns.formatNumber(upgradeCost)}`); ns.print(`Current funds: ${ns.formatNumber(money)}`); ns.print('Running in no-kill mode, restarting in 15 seconds'); await ns.sleep(15000); return resolve(); }; /** @param {NS} ns */ const terminate = (ns) => { ns.tprint('Insufficient funds for automation, terminating manager.js'); return ns.kill(ns.pid); };