From 804e4c23e31fb3cdc163068a5f97acec9cdf8546 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sat, 30 Mar 2019 19:53:57 -0700 Subject: [PATCH] Updated Hacknet Node API documentation for the BN-9 changes. netscript functions now properly fail for Hacknet Servers --- .../hacknetnodeapi/getCacheUpgradeCost.rst | 17 +++ .../netscript/hacknetnodeapi/getNodeStats.rst | 11 +- .../netscript/hacknetnodeapi/upgradeCache.rst | 19 +++ .../netscript/netscripthacknetnodeapi.rst | 61 ++------- src/NetscriptFunctions.js | 127 ++++++++---------- 5 files changed, 117 insertions(+), 118 deletions(-) create mode 100644 doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/upgradeCache.rst diff --git a/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst new file mode 100644 index 000000000..f59bec28b --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst @@ -0,0 +1,17 @@ +getCacheUpgradeCost() Netscript Function +======================================== + +.. warning:: This page contains spoilers for the game + +.. js:function:: getCacheUpgradeCost(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade cache. Must be positive. Rounded to nearest integer + + .. note:: This function is only applicable for Hacknet Servers (the upgraded version of + a Hacknet Node). + + Returns the cost of upgrading the cache level of the specified Hacknet Server by *n*. + + If an invalid value for *n* is provided, then this function returns 0. If the + specified Hacknet Server is already at the max cache level, then Infinity is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst index 74b7de5ad..e538edc40 100644 --- a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst +++ b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst @@ -1,6 +1,8 @@ getNodeStats() Netscript Function ================================= +.. warning:: This page contains spoilers for the game + .. js:function:: getNodeStats(i) :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` @@ -12,7 +14,12 @@ getNodeStats() Netscript Function level: Node's level, ram: Node's RAM, cores: Node's number of cores, - production: Node's money earned per second, + cache: Cache level. Only applicable for Hacknet Servers + production: Node's production per second timeOnline: Number of seconds since Node has been purchased, - totalProduction: Total number of money Node has produced + totalProduction: Total amount that the Node has produced } + + .. note:: Note that for Hacknet Nodes, production refers to the amount of money the node generates. + For Hacknet Servers (the upgraded version of Hacknet Nodes), production refers to the amount + of hashes the node generates. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeCache.rst b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst new file mode 100644 index 000000000..8825d9ace --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst @@ -0,0 +1,19 @@ +upgradeCache() Netscript Function +================================= + +.. warning:: This page contains spoilers for the game + +.. js:function:: upgradeCache(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of cache levels to purchase. Must be positive. Rounded to nearest integer + + .. note:: This function is only applicable for Hacknet Servers (the upgraded version of + a Hacknet Node). + + Tries to upgrade the specified Hacknet Server's cache *n* times. + + Returns true if it successfully upgrades the Server's cache *n* times, or if + it purchases some positive amount and the Server reaches its max cache level. + + Returns false otherwise. diff --git a/doc/source/netscript/netscripthacknetnodeapi.rst b/doc/source/netscript/netscripthacknetnodeapi.rst index fde650836..1c1353d81 100644 --- a/doc/source/netscript/netscripthacknetnodeapi.rst +++ b/doc/source/netscript/netscripthacknetnodeapi.rst @@ -31,9 +31,11 @@ In :ref:`netscriptjs`:: upgradeLevel() upgradeRam() upgradeCore() + upgradeCache() getLevelUpgradeCost() getRamUpgradeCost() getCoreUpgradeCost() + getCacheUpgradeCost() .. _netscript_hacknetnodeapi_referencingahacknetnode: @@ -68,23 +70,25 @@ The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. This script attempts to purchase Hacknet Nodes until the player has a total of 8. Then -it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores:: +it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores + +.. code:: javascript function myMoney() { - return getServerMoneyAvailable("home");() - } - }() + return getServerMoneyAvailable("home"); + } + disableLog("getServerMoneyAvailable"); disableLog("sleep"); - cnt = 8; + var cnt = 8; while(hacknet.numNodes() < cnt) { res = hacknet.purchaseNode(); print("Purchased hacknet Node with index " + res); }; - for (i = 0; i < cnt; i++) { + for (var i = 0; i < cnt; i++) { while (hacknet.getNodeStats(i).level <= 80) { var cost = hacknet.getLevelUpgradeCost(i, 10); while (myMoney() < cost) { @@ -95,9 +99,9 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c }; }; - print("All nodes upgrade to level 80"); + print("All nodes upgraded to level 80"); - for (i = 0; i < cnt; i++) { + for (var i = 0; i < cnt; i++) { while (hacknet.getNodeStats(i).ram < 16) { var cost = hacknet.getRamUpgradeCost(i, 2); while (myMoney() < cost) { @@ -108,43 +112,4 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c }; }; - print("All nodes upgrade to 16GB RAM"); - - for (i = 0; i < cnt; i++) { - while (hacknet.getNodeStats(i).level <= 140) { - var cost = hacknet.getLevelUpgradeCost(i, 5); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeLevel(i, 5); - }; - }; - - print("All nodes upgrade to level 140"); - - for (i = 0; i < cnt; i++) { - while (hacknet.getNodeStats(i).ram < 64) { - var cost = hacknet.getRamUpgradeCost(i, 2); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeRam(i, 2); - }; - }; - - print("All nodes upgrade to 64GB RAM (MAX)"); - - for (i = 0; i < cnt; i++) { - while (hacknetnodes.getNodeStatsi(i).cores < 8) { - var cost = hacknet.getCoreUpgradeCost(7); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeCore(i, 7); - }; - }; - - print("All nodes upgrade to 8 cores"); + print("All nodes upgraded to 16GB RAM"); diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index afed96696..76b6dedfa 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -37,6 +37,7 @@ import { getCostOfNextHacknetNode, getCostOfNextHacknetServer, hasHacknetServers, purchaseHacknet } from "./Hacknet/HacknetHelpers"; +import { HacknetServer } from "./Hacknet/HacknetServer"; import {Locations} from "./Locations"; import { Message } from "./Message/Message"; import { Messages } from "./Message/MessageHelpers"; @@ -234,16 +235,34 @@ function NetscriptFunctions(workerScript) { * Gets the Server for a specific hostname/ip, throwing an error * if the server doesn't exist. * @param {string} Hostname or IP of the server + * @param {string} callingFnName - Name of calling function. For logging purposes * @returns {Server} The specified Server */ const safeGetServer = function(ip, callingFnName="") { var server = getServer(ip); if (server == null) { + workerScript.log(`ERROR: Invalid IP or hostname passed into ${callingFnName}()`); throw makeRuntimeRejectMsg(workerScript, `Invalid IP or hostname passed into ${callingFnName}() function`); } return server; } + /** + * Used to fail a function if the function's target is a Hacknet Server. + * This is used for functions that should run on normal Servers, but not Hacknet Servers + * @param {Server} server - Target server + * @param {string} callingFn - Name of calling function. For logging purposes + * @returns {boolean} True if the server is a Hacknet Server, false otherwise + */ + const failOnHacknetServer = function(server, callingFn="") { + if (server instanceof HacknetServer) { + workerScript.log(`ERROR: ${callingFn}() failed because it does not work on Hacknet Servers`); + return true; + } else { + return false; + } + } + // Utility function to get Hacknet Node object const getHacknetNode = function(i) { if (isNaN(i)) { @@ -1341,25 +1360,22 @@ function NetscriptFunctions(workerScript) { let copy = Object.assign({}, BitNodeMultipliers); return copy; }, - getServerMoneyAvailable : function(ip){ + getServerMoneyAvailable : function(ip) { if (workerScript.checkingRam) { return updateStaticRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip); - } + const server = safeGetServer(ip, "getServerMoneyAvailable"); + if (failOnHacknetServer(server, "getServerMoneyAvailable")) { return 0; } if (server.hostname == "home") { - //Return player's money - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) { - workerScript.scriptRef.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2)); + // Return player's money + if (workerScript.shouldLog("getServerMoneyAvailable")) { + workerScript.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2)); } return Player.money.toNumber(); } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) { - workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); + if (workerScript.shouldLog("getServerMoneyAvailable")) { + workerScript.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); } return server.moneyAvailable; }, @@ -1368,13 +1384,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerSecurityLevel == null) { - workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerSecurityLevel"); + if (failOnHacknetServer(server, "getServerSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerSecurityLevel")) { + workerScript.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); } return server.hackDifficulty; }, @@ -1383,13 +1396,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerBaseSecurityLevel == null) { - workerScript.scriptRef.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerBaseSecurityLevel"); + if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerBaseSecurityLevel")) { + workerScript.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname); } return server.baseDifficulty; }, @@ -1398,13 +1408,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMinSecurityLevel == null) { - workerScript.scriptRef.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerMinSecurityLevel"); + if (failOnHacknetServer(server, "getServerMinSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerMinSecurityLevel")) { + workerScript.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname); } return server.minDifficulty; }, @@ -1413,13 +1420,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRequiredHackingLevel == null) { - workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerRequiredHackingLevel"); + if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) { return 1; } + if (workerScript.shouldLog("getServerRequiredHackingLevel")) { + workerScript.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname); } return server.requiredHackingSkill; }, @@ -1428,13 +1432,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMaxMoney == null) { - workerScript.scriptRef.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerMaxMoney"); + if (failOnHacknetServer(server, "getServerMaxMoney")) { return 0; } + if (workerScript.shouldLog("getServerMaxMoney")) { + workerScript.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname); } return server.moneyMax; }, @@ -1443,13 +1444,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerGrowth() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerGrowth() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerGrowth == null) { - workerScript.scriptRef.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerGrowth"); + if (failOnHacknetServer(server, "getServerGrowth")) { return 1; } + if (workerScript.shouldLog("getServerGrowth")) { + workerScript.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname); } return server.serverGrowth; }, @@ -1458,13 +1456,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerNumPortsRequired == null) { - workerScript.scriptRef.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerNumPortsRequired"); + if (failOnHacknetServer(server, "getServerNumPortsRequired")) { return 5; } + if (workerScript.shouldLog("getServerNumPortsRequired")) { + workerScript.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname); } return server.numOpenPortsRequired; }, @@ -1473,13 +1468,9 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerRam", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerRam", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerRam() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerRam() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRam == null) { - workerScript.scriptRef.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]"); + const server = safeGetServer(ip, "getServerRam"); + if (workerScript.shouldLog("getServerRam")) { + workerScript.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]"); } return [server.maxRam, server.ramUsed]; }, @@ -4771,7 +4762,7 @@ function NetscriptFunctions(workerScript) { answer = String(answer); } - const serv = safeGetServer(ip, "codingcontract.attempt()"); + const serv = safeGetServer(ip, "codingcontract.attempt"); if (contract.isSolution(answer)) { const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty()); workerScript.log(`Successfully completed Coding Contract ${fn}. Reward: ${reward}`);