From 0d90479097b4342f42e917780c66c5b7bd7cb60a Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Sat, 3 Jun 2017 23:56:18 -0500 Subject: [PATCH 01/16] Fixed issue with Faction page formatting. Script.reset() now re-updated RAM usage --- css/menupages.css | 5 ++--- index.html | 3 ++- src/Script.js | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/css/menupages.css b/css/menupages.css index 1318bff0b..3480cb238 100644 --- a/css/menupages.css +++ b/css/menupages.css @@ -299,7 +299,8 @@ background-color: #555; padding-left: 10px; height: 100%; margin-left: 10%; - width: 90%; + width: 99%; + overflow: auto; overflow-y: auto; } @@ -308,8 +309,6 @@ background-color: #555; margin: 6px; } - - #faction-hack-div, #faction-fieldwork-div, #faction-securitywork-div, diff --git a/index.html b/index.html index 4d087a810..4f89485d8 100644 --- a/index.html +++ b/index.html @@ -516,12 +516,13 @@

-


+
As your reputation with this faction rises, you will unlock Augmentations, which you can purchase to enhance your abilities.

Purchase Augmentations +



diff --git a/src/Script.js b/src/Script.js index 20bbd6bbd..9fa101940 100644 --- a/src/Script.js +++ b/src/Script.js @@ -150,6 +150,8 @@ Script.prototype.saveScript = function() { } Script.prototype.reset = function() { + this.updateRamUsage(); + this.offlineRunningTime = 0.01; //Seconds this.offlineMoneyMade = 0; this.offlineExpGained = 0; From beb770eaf95ae9bcf9b5b65dd67c1049649bf43c Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Sun, 4 Jun 2017 03:46:14 -0500 Subject: [PATCH 02/16] Updated constants --- src/Constants.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Constants.js b/src/Constants.js index 981f050e3..7418f768f 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -568,7 +568,11 @@ CONSTANTS = { "-Tab automcompletion will now work on commands

" + "v0.19.7
" + "-Added changelog to Options menu
" + - "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs", + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + + "", + + LatestUpdate: + "", } \ No newline at end of file From bb24c017f1c1c17eda1a289766861c8440aee0ab Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Sun, 4 Jun 2017 23:48:37 -0500 Subject: [PATCH 03/16] Refactor Netscript Interpreter --- index.html | 1 + src/Constants.js | 131 ++-- src/NetscriptEvaluator.js | 1273 +++++++++++-------------------------- src/NetscriptFunctions.js | 341 ++++++++++ 4 files changed, 777 insertions(+), 969 deletions(-) create mode 100644 src/NetscriptFunctions.js diff --git a/index.html b/index.html index 4f89485d8..f9861ac98 100644 --- a/index.html +++ b/index.html @@ -33,6 +33,7 @@ + diff --git a/src/Constants.js b/src/Constants.js index 7418f768f..e0ac99928 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -34,7 +34,7 @@ CONSTANTS = { /* Script related things */ //Time (ms) it takes to run one operation in Netscript. - CodeInstructionRunTime: 1500, + CodeInstructionRunTime: 750, //RAM Costs for differenc commands ScriptWhileRamCost: 0.4, @@ -488,61 +488,15 @@ CONSTANTS = { "RAM Upgrades on your home computer", Changelog: - "v0.15
" + - "-Slightly reduced production multiplier for Hacknet Node RAM
" + - "-Faction pages now scroll
" + - "-Slightly increased amount of money gained from hacking
" + - "-Added 'alias' command
" + - "-Added 'scan-analyze' terminal command - used to get basic hacking info about all immediate network connections
" + - "-Fixed bugs with upgradeHacknetNode() and purchaseHacknetNode() commands
" + - "-Added getNumHacknetNodes() and hasRootAccess(hostname/ip) commands to Netscript
" + - "-Increased Cost of university classes/gym
" + - "-You can now see what an Augmentation does and its price even while its locked

" + - "v0.16
" + - "-New Script Editor interface
" + - "-Rebalanced hacknet node - Increased base production but halved the multiplier from additional cores. This should boost its early-game production but nerf its late-game production
" + - "-Player now starts with 8GB of RAM on home computer
" + - "-'scan-analyze' terminal command displays RAM on servers
" + - "-Slightly buffed the amount of money the player steals when hacking servers (by about ~8%)
" + - "-Time to execute grow() now depends on hacking skill and server security, rather than taking a flat 2 minutes.
" + - "-Clicking outside of a pop-up dialog box will now close it
" + - "-BruteSSH.exe takes 33% less time to create
" + - "-'iron-gym' and 'max-hardware' servers now have 2GB of RAM
" + - "-Buffed job salaries across the board
" + - "-Updated Tutorial
" + - "-Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work

" + - "v0.17
" + - "-Greatly increased amount of money gained for crimes (by about 400% for most crimes)
" + - "-Criminal factions require slightly less negative karma to get invited to
" + - "-Increased the percentage of money stolen from servers when hacking
" + - "-Increased the starting amount of money available on beginning servers (servers with <50 required hacking))
" + - "-Increased the growth rate of servers (both naturally and manually when using the grow() command in a script)
" + - "-Added getHostname() command in Netscript that returns the hostname of the server a script is running on
" + - "-jQuery preventDefault() called when pressing ctrl+b in script editor
" + - "-The Neuroflux Governor augmentation (the one that can be repeatedly leveled up) now increases ALL multipliers by 1%. To balance it out, it's price multiplier when it levels up was increased
" + - "-Hacknet Node base production decreased from $1.75/s to $1.65/s
" + - "-Fixed issue with nested for loops in Netscript (stupid Javascript references)
" + - "-Added 'scp' command to Terminal and Netscript
" + - "-Slightly nerfed Hacknet Node Kernel DNI and Hacknet Node Core DNI Augmentations
" + - "-Increased TOR Router cost to $200k

" + - "v0.17.1
" + - "-Fixed issue with purchasing Augmentations that are 'upgrades' and require previous Augmentations to be installed
" + - "-Increased the percentage of money stolen from servers when hacking

" + - "v0.18
" + - "-Major rebalancing (sorry didn't record specifics. But in general hacking gives more money " + - "and hacknet nodes give less)
" + - "-Server growth rate (both natural and manual using grow()) doubled
" + - "-Added option to Soft Reset
" + - "-Cancelling a full time job early now only results in halved gains for reputation. Exp and money earnings are gained in full
" + - "-Added exec() Netscript command, used to run scripts on other servers.
" + - "-NEW HACKING MECHANICS: Whenever a server is hacked, its 'security level' is increased by a very small amount. " + - "The security level is denoted by a number between 1-100. A higher security level makes it harder " + - "to hack a server and also decreases the amount of money you steal from it. Two Netscript functions, " + - "weaken() and getServerSecurityLevel() level, were added. The weaken(server) function lowers a server's " + - "security level. See the Netscript documentation for more details
" + - "-When donating to factions, the base rate is now $1,000,000 for 1 reputation point. Before, it was " + - "$1,000 for 1 reputation point.
" + - "-Monetary costs for all Augmentations increased. They are now about ~3.3 - 3.75 times more expensive than before

" + + "v0.19.7
" + + "-Added changelog to Options menu
" + + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + + "v0.19.6
" + + "-Script editor now saves its state even when you change tabs
" + + "-scp() command in Terminal/script will now overwrite files at the destination
" + + "-Terminal commands are no longer case-sensitive (only the commands themselves such as 'run' or 'nano'. Filenames are " + + "still case sensitive
" + + "-Tab automcompletion will now work on commands

" + "v0.19
" + "-Hacknet Nodes have slightly higher base production, and slightly increased RAM multiplier. " + "But they are also a bit more expensive at higher levels
" + @@ -560,16 +514,61 @@ CONSTANTS = { "-Gyms and classes are now significantly more expensive
" + "-Doubled the amount by which a server's security increases when it is hacked. Now, it will " + "increase by 0.002. Calling weaken() on a server will lower the security by 0.1.

" + - "v0.19.6
" + - "-Script editor now saves its state even when you change tabs
" + - "-scp() command in Terminal/script will now overwrite files at the destination
" + - "-Terminal commands are no longer case-sensitive (only the commands themselves such as 'run' or 'nano'. Filenames are " + - "still case sensitive
" + - "-Tab automcompletion will now work on commands

" + - "v0.19.7
" + - "-Added changelog to Options menu
" + - "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + - "", + "v0.18
" + + "-Major rebalancing (sorry didn't record specifics. But in general hacking gives more money " + + "and hacknet nodes give less)
" + + "-Server growth rate (both natural and manual using grow()) doubled
" + + "-Added option to Soft Reset
" + + "-Cancelling a full time job early now only results in halved gains for reputation. Exp and money earnings are gained in full
" + + "-Added exec() Netscript command, used to run scripts on other servers.
" + + "-NEW HACKING MECHANICS: Whenever a server is hacked, its 'security level' is increased by a very small amount. " + + "The security level is denoted by a number between 1-100. A higher security level makes it harder " + + "to hack a server and also decreases the amount of money you steal from it. Two Netscript functions, " + + "weaken() and getServerSecurityLevel() level, were added. The weaken(server) function lowers a server's " + + "security level. See the Netscript documentation for more details
" + + "-When donating to factions, the base rate is now $1,000,000 for 1 reputation point. Before, it was " + + "$1,000 for 1 reputation point.
" + + "-Monetary costs for all Augmentations increased. They are now about ~3.3 - 3.75 times more expensive than before

" + + "v0.17.1
" + + "-Fixed issue with purchasing Augmentations that are 'upgrades' and require previous Augmentations to be installed
" + + "-Increased the percentage of money stolen from servers when hacking

" + + "v0.17
" + + "-Greatly increased amount of money gained for crimes (by about 400% for most crimes)
" + + "-Criminal factions require slightly less negative karma to get invited to
" + + "-Increased the percentage of money stolen from servers when hacking
" + + "-Increased the starting amount of money available on beginning servers (servers with <50 required hacking))
" + + "-Increased the growth rate of servers (both naturally and manually when using the grow() command in a script)
" + + "-Added getHostname() command in Netscript that returns the hostname of the server a script is running on
" + + "-jQuery preventDefault() called when pressing ctrl+b in script editor
" + + "-The Neuroflux Governor augmentation (the one that can be repeatedly leveled up) now increases ALL multipliers by 1%. To balance it out, it's price multiplier when it levels up was increased
" + + "-Hacknet Node base production decreased from $1.75/s to $1.65/s
" + + "-Fixed issue with nested for loops in Netscript (stupid Javascript references)
" + + "-Added 'scp' command to Terminal and Netscript
" + + "-Slightly nerfed Hacknet Node Kernel DNI and Hacknet Node Core DNI Augmentations
" + + "-Increased TOR Router cost to $200k

" + + "v0.16
" + + "-New Script Editor interface
" + + "-Rebalanced hacknet node - Increased base production but halved the multiplier from additional cores. This should boost its early-game production but nerf its late-game production
" + + "-Player now starts with 8GB of RAM on home computer
" + + "-'scan-analyze' terminal command displays RAM on servers
" + + "-Slightly buffed the amount of money the player steals when hacking servers (by about ~8%)
" + + "-Time to execute grow() now depends on hacking skill and server security, rather than taking a flat 2 minutes.
" + + "-Clicking outside of a pop-up dialog box will now close it
" + + "-BruteSSH.exe takes 33% less time to create
" + + "-'iron-gym' and 'max-hardware' servers now have 2GB of RAM
" + + "-Buffed job salaries across the board
" + + "-Updated Tutorial
" + + "-Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work

" + + "v0.15
" + + "-Slightly reduced production multiplier for Hacknet Node RAM
" + + "-Faction pages now scroll
" + + "-Slightly increased amount of money gained from hacking
" + + "-Added 'alias' command
" + + "-Added 'scan-analyze' terminal command - used to get basic hacking info about all immediate network connections
" + + "-Fixed bugs with upgradeHacknetNode() and purchaseHacknetNode() commands
" + + "-Added getNumHacknetNodes() and hasRootAccess(hostname/ip) commands to Netscript
" + + "-Increased Cost of university classes/gym
" + + "-You can now see what an Augmentation does and its price even while its locked

", LatestUpdate: "", diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index f9463adf2..949fb9f55 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -5,118 +5,56 @@ // Evaluator should return a Promise, so that any call to evaluate() can just //wait for that promise to finish before continuing function evaluate(exp, workerScript) { + return new Promise(function(resolve, reject) { var env = workerScript.env; + if (env.stopFlag) {return reject(workerScript);} if (exp == null) { - return new Promise(function(resolve, reject) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Error: NULL expression"); - }); + return reject(makeRuntimeRejectMsg(workerScript, "Error: NULL expression")); } - switch (exp.type) { - case "num": - case "str": - case "bool": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - resolve(exp.value); - }); - break; - case "var": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} + setTimeout(function() { + if (env.stopFlag) {return reject(workerScript);} + switch (exp.type) { + case "num": + case "str": + case "bool": + resolve(exp.value); + break; + case "var": if (exp.value == "hacknetnodes") { - setTimeout(function() { - var pEvaluateHacknetNode = evaluateHacknetNode(exp, workerScript); - pEvaluateHacknetNode.then(function(res) { - resolve(res); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime); + var pEvaluateHacknetNode = evaluateHacknetNode(exp, workerScript); + pEvaluateHacknetNode.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); return; } - try { - resolve(env.get(exp.value)); - } catch (e) { - throw new Error("|" + workerScript.serverIp + "|" + workerScript.name + "|" + e.toString()); - } - }); - break; - //Can currently only assign to "var"s - case "assign": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - if (exp.left.type != "var") - reject("|" + workerScript.serverIp + "|" + workerScript.name + "| Cannot assign to " + JSON.stringify(exp.left)); - - var p = new Promise(function(resolve, reject) { - setTimeout(function() { - var expRightPromise = evaluate(exp.right, workerScript); - expRightPromise.then(function(expRight) { - resolve(expRight); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime) - }); - - p.then(function(expRight) { - try { - env.set(exp.left.value, expRight); - } catch (e) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|" + e.toString()); - } - resolve(false); //Return false so this doesnt cause loops/ifs to evaluate - }, function(e) { - reject(e); - }); - }); - - case "binary": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - var pLeft = new Promise(function(resolve, reject) { - setTimeout(function() { - var promise = evaluate(exp.left, workerScript); - promise.then(function(valLeft) { - resolve(valLeft); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime); - }); - - pLeft.then(function(valLeft) { - var pRight = new Promise(function(resolve, reject) { - setTimeout(function() { - var promise = evaluate(exp.right, workerScript); - promise.then(function(valRight) { - resolve([valLeft, valRight]); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime); - }); - - pRight.then(function(args) { - try { - resolve(apply_op(exp.operator, args[0], args[1])); - } catch (e) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|" + e.toString()); - } - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - }); - break; + try { + resolve(env.get(exp.value)); + } catch (e) { + throw new Error("|" + workerScript.serverIp + "|" + workerScript.name + "|" + e.toString()); + } + break; + //Can currently only assign to "var"s + case "assign": + var p = netscriptAssign(exp, workerScript); + p.then(function(res) { + resolve(res); + }).catch(function(e) { + reject(e); + }); + break; + case "binary": + var p = netscriptBinary(exp, workerScript); + p.then(function(res) { + resolve(res); + }).catch(function(e) { + reject(e); + }); + break; - //TODO - case "if": - return new Promise(function(resolve, reject) { + //TODO + case "if": var numConds = exp.cond.length; var numThens = exp.then.length; if (numConds == 0 || numThens == 0 || numConds != numThens) { @@ -144,817 +82,340 @@ function evaluate(exp, workerScript) { }, function(e) { reject(e); }); - }); - break; - case "for": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - var pInit = new Promise(function(resolve, reject) { - setTimeout(function() { - var resInit = evaluate(exp.init, workerScript); - resInit.then(function(foo) { - resolve(foo); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime); - }); - - pInit.then(function(expInit) { - var pForLoop = evaluateFor(exp, workerScript); - pForLoop.then(function(forLoopRes) { - resolve("forLoopDone"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - }); - break; - case "while": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - var pEvaluateWhile = evaluateWhile(exp, workerScript); - pEvaluateWhile.then(function(whileLoopRes) { - resolve("whileLoopDone"); - }, function(e) { - reject(e); - }); - }); - break; - case "prog": - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - var evaluateProgPromise = evaluateProg(exp, workerScript, 0); - evaluateProgPromise.then(function(w) { - resolve(workerScript); - }, function(e) { + break; + case "for": + var pInit = evaluate(exp.init, workerScript); + pInit.then(function(expInit) { + return evaluateFor(exp, workerScript); + }).then(function(forLoopRes) { + resolve("forLoopDone"); + }).catch(function(e) { + reject(e); + }); + break; + case "while": + var pEvaluateWhile = evaluateWhile(exp, workerScript); + pEvaluateWhile.then(function(whileLoopRes) { + resolve(whileLoopRes); + }, function(e) { + reject(e); + }); + break; + case "prog": + var evaluateProgPromise = evaluateProg(exp, workerScript, 0); + evaluateProgPromise.then(function(w) { + resolve(workerScript); + }, function(e) { workerScript.errorMessage = e.toString(); - reject(workerScript); - }); - }); - break; + reject(workerScript); + }); + break; - /* Currently supported function calls: - * hack(server) - * sleep(N) - sleep N seconds - * print(x) - Prints a variable or constant - * grow(server) - * nuke(server) - * brutessh(server) - * ftpcrack(server) - * relaysmtp(server) - * httpworm(server) - * sqlinject(server) - * getHackingLevel() - * run(script)) - */ - case "call": - //Define only valid function calls here, like hack() and stuff - //var func = evaluate(exp.func, env); - //return func.apply(null, exp.args.map(function(arg){ - // return evaluate(arg, env); - //})); - return new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - - setTimeout(function() { - if (exp.func.value == "hack") { - if (env.stopFlag) {reject(workerScript); return;} - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Hack() call has incorrect number of arguments. Takes 1 argument"); - return; - } - var ipPromise = evaluate(exp.args[0], workerScript); - - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into hack() command"); - workerScript.scriptRef.log("Cannot hack(). Invalid IP or hostname passed in: " + ip + ". Stopping..."); - return; - } - - //Calculate the hacking time - var hackingTime = scriptCalculateHackingTime(server); //This is in seconds - - //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access"); - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Script crashed because it did not have root access to " + server.hostname); - return; - } - - if (server.requiredHackingSkill > Player.hacking_skill) { - workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough"); - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Script crashed because player's hacking skill is not high enough to hack " + server.hostname); - return; - } - - workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds"); - - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds."); - setTimeout(function() { - if (env.stopFlag) {reject(workerScript); return;} - var hackChance = scriptCalculateHackingChance(server); - var rand = Math.random(); - var expGainedOnSuccess = scriptCalculateExpGain(server); - var expGainedOnFailure = (expGainedOnSuccess / 4); - if (rand < hackChance) { //Success! - if (env.stopFlag) {reject(workerScript); return;} - var moneyGained = scriptCalculatePercentMoneyHacked(server); - moneyGained = Math.floor(server.moneyAvailable * moneyGained); - - //Safety check - if (moneyGained <= 0) {moneyGained = 0;} - - server.moneyAvailable -= moneyGained; - Player.gainMoney(moneyGained); - workerScript.scriptRef.onlineMoneyMade += moneyGained; - workerScript.scriptRef.recordHack(server.ip, moneyGained); - - Player.gainHackingExp(expGainedOnSuccess); - workerScript.scriptRef.onlineExpGained += expGainedOnSuccess; - console.log("Script successfully hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); - workerScript.scriptRef.log("Script SUCCESSFULLY hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); - server.fortify(CONSTANTS.ServerFortifyAmount); - resolve("Hack success"); - } else { - if (env.stopFlag) {reject(workerScript); return;} - //Player only gains 25% exp for failure? TODO Can change this later to balance - Player.gainHackingExp(expGainedOnFailure); - workerScript.scriptRef.onlineExpGained += expGainedOnFailure; - - console.log("Script unsuccessful to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); - workerScript.scriptRef.log("Script FAILED to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); - resolve("Hack failure"); - } - }, hackingTime * 1000); - }); - - p.then(function(res) { - resolve("hackExecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - - } else if (exp.func.value == "sleep") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|sleep() call has incorrect number of arguments. Takes 1 argument."); - return; - } - var sleepTimePromise = evaluate(exp.args[0], workerScript); - sleepTimePromise.then(function(sleepTime) { - workerScript.scriptRef.log("Sleeping for " + sleepTime + " milliseconds"); - var p = new Promise(function(resolve, reject) { - setTimeout(function() { - resolve("foo"); - }, sleepTime); - }); - - p.then(function(res) { - resolve("sleepExecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e) - }); - } else if (exp.func.value == "print") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|print() call has incorrect number of arguments. Takes 1 argument"); - return; - } - - var p = new Promise(function(resolve, reject) { - setTimeout(function() { - var evaluatePromise = evaluate(exp.args[0], workerScript); - evaluatePromise.then(function(res) { - resolve(res); - }, function(e) { - reject(e); - }); - }, CONSTANTS.CodeInstructionRunTime); - }); - - p.then(function(res) { - workerScript.scriptRef.log(res.toString()); - resolve("printExecuted"); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "grow") { - if (env.stopFlag) {reject(workerScript); return;} - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|grow() call has incorrect number of arguments. Takes 1 argument"); - return; + /* Currently supported function calls: + * hack(server) + * sleep(N) - sleep N seconds + * print(x) - Prints a variable or constant + * grow(server) + * nuke(server) + * brutessh(server) + * ftpcrack(server) + * relaysmtp(server) + * httpworm(server) + * sqlinject(server) + * getHackingLevel() + * run(script)) + */ + case "call": + if (exp.func.value == "hack") { + var p = netscriptHack(exp, workerScript); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "sleep") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "sleep() call has incorrect number of arguments. Takes 1 argument.")); + } + var sleepTimePromise = evaluate(exp.args[0], workerScript); + sleepTimePromise.then(function(sleepTime) { + workerScript.scriptRef.log("Sleeping for " + sleepTime + " milliseconds"); + setTimeout(function() { + return Promise.resolve(true); + }, sleepTime); + }).then(function(res) { + resolve(true); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "print") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "print() call has incorrect number of arguments. Takes 1 argument")); + } + + var evaluatePromise = evaluate(exp.args[0], workerScript); + evaluatePromise.then(function(res) { + workerScript.scriptRef.log(res.toString()); + resolve(true); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "grow") { + var p = netscriptGrow(exp, workerScript); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "weaken") { + var p = netscriptWeaken(exp, workerScript); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "nuke") { + var p = netscriptRunProgram(exp, workerScript, Programs.NukeProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "brutessh") { + var p = netscriptRunProgram(exp, workerScript, Programs.BruteSSHProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "ftpcrack") { + var p = netscriptRunProgram(exp, workerScript, Programs.FTPCrackProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "relaysmtp") { + var p = netscriptRunProgram(exp, workerScript, Programs.RelaySMTPProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "httpworm") { + var p = netscriptRunProgram(exp, workerScript, Programs.HTTPWormProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "sqlinject") { + var p = netscriptRunProgram(exp, workerScript, Programs.SQLInjectProgram); + p.then(function(res) { + resolve(res); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "hasRootAccess") { + if (env.stopFlag) {return reject(workerScript);} + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "hasRootAccess() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + if (env.stopFlag) {return reject(workerScript);} + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("hasRootAccess() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into hasRootAccess() command")); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into grow() command"); - workerScript.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: " + ip); - return; - } - - //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot grow this server (" + server.hostname + ") because user does not have root access"); - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Script crashed because it did not have root access to " + server.hostname); - return; - } - - var growTime = scriptCalculateGrowTime(server); - console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds") - workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds"); - - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - server.moneyAvailable += 1; //It can be grown even if it has no money - var growthPercentage = processSingleServerGrowth(server, 450); - workerScript.scriptRef.recordGrow(server.ip); - resolve(growthPercentage); - }, growTime); - }); - - p.then(function(growthPercentage) { - resolve("hackExecuted"); - workerScript.scriptRef.log("Using grow(), the money available on " + server.hostname + " was grown by " + (growthPercentage*100 - 100).toFixed(6) + "%. Gained 1 hacking exp"); - Player.gainHackingExp(1); - workerScript.scriptRef.onlineExpGained += 1; - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "weaken") { - if (env.stopFlag) {reject(workerScript); return;} - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|weaken() call has incorrect number of arguments. Takes 1 argument"); - return; + workerScript.scriptRef.log("hasRootAccess() returned " + server.hasAdminRights); + resolve(server.hasAdminRights); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "run") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Takes 1 argument")); + } + var scriptNamePromise = evaluate(exp.args[0], workerScript); + scriptNamePromise.then(function(scriptname) { + if (env.stopFlag) {return reject(workerScript);} + var scriptServer = getServer(workerScript.serverIp); + if (scriptServer == null) { + return reject(makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev")); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into weaken() command"); - workerScript.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: " + ip); - return; - } - - //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot weaken this server (" + server.hostname + ") because user does not have root access"); - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Script crashed because it did not have root access to " + server.hostname); - return; - } - - var weakenTime = scriptCalculateWeakenTime(server); - console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds") - workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds"); - - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - server.weaken(CONSTANTS.ServerWeakenAmount); - workerScript.scriptRef.recordWeaken(server.ip); - resolve(CONSTANTS.ServerWeakenAmount); - }, weakenTime); - }); - - p.then(function(amt) { - workerScript.scriptRef.log("Using weaken(), " + server.hostname + "'s security level was decreased by " + amt + ". Gained 5 hacking exp"); - Player.gainHackingExp(5); - workerScript.scriptRef.onlineExpGained += 5; - resolve("hackExecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "nuke") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|nuke() call has incorrect number of arguments. Takes 1 argument"); - return; + + var runScriptPromise = runScriptFromScript(scriptServer, scriptname, workerScript); + }).then(function(res) { + resolve(res); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "exec") { + if (exp.args.length != 2) { + return reject(makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Takes 2 arguments")); + } + var argPromises = exp.args.map(function(arg) { + return evaluate(arg, workerScript); + }); + + Promise.all(argPromises).then(function(args) { + if (env.stopFlag) {return reject(workerScript);} + var server = getServer(args[1]); + if (server == null) { + return reject(makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + args[1])); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into nuke() command"); - workerScript.scriptRef.log("Cannot nuke(). Invalid IP or hostname passed in: " + ip); - return; - } - - if (!Player.hasProgram(Programs.NukeProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have NUKE program on home computer"); - return; - } - - if (server.openPortCount < server.numOpenPortsRequired) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Not enough ports opened to use NUKE.exe virus"); - return; - } - - workerScript.scriptRef.log("Running NUKE.exe on server " + server.hostname + " in 5 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (server.hasAdminRights) { - workerScript.scriptRef.log("Already have root access to " + server.hostname); - } else { - server.hasAdminRights = true; - workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access"); - } - resolve("nuke done"); - }, 5 * 1000); - }); - - p.then(function(res) { - resolve("nukeExecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "brutessh") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|brutessh() call has incorrect number of arguments. Takes 1 argument"); - return; + + return runScriptFromScript(server, args[0], workerScript); + }).then(function(res) { + resolve(res); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "scp") { + if (exp.args.length != 2) { + return reject(makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments")); + } + + var argPromises = exp.args.map(function(arg) { + return evaluate(arg, workerScript); + }); + + Promise.all(argPromises).then(function(args) { + if (env.stopFlag) {return reject(workerScript);} + var scriptname = args[0]; + var ip = args[1]; + var destServer = getServer(ip); + if (destServer == null) { + return reject(makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into scp() command: " + ip)); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into brutessh() command"); - workerScript.scriptRef.log("Cannot brutessh(). Invalid IP or hostname passed in: " + ip); - return; - } - - if (!Player.hasProgram(Programs.BruteSSHProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have BruteSSH.exe program on home computer"); - return; - } - - workerScript.scriptRef.log("Running BruteSSH.exe on server " + server.hostname + " in 10 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (!server.sshPortOpen) { - workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)"); - server.sshPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname); - } - resolve("brutessh done"); - }, 10 * 1000); - }); - - p.then(function(res) { - resolve("bruteSSHExecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "ftpcrack") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|ftpcrack() call has incorrect number of arguments. Takes 1 argument"); - return; + + var currServ = getServer(workerScript.serverIp); + if (currServ == null) { + return reject(makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer")); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into ftpcrack() command"); - workerScript.scriptRef.log("Cannot ftpcrack(). Invalid IP or hostname passed in: " + ip); - return; + + var sourceScript = null; + for (var i = 0; i < currServ.scripts.length; ++i) { + if (scriptname == currServ.scripts[i].filename) { + sourceScript = currServ.scripts[i]; + break; } - - if (!Player.hasProgram(Programs.FTPCrackProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have FTPCrack.exe program on home computer"); - return; - } - - workerScript.scriptRef.log("Running FTPCrack.exe on server " + server.hostname + " in 15 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (!server.ftpPortOpen) { - workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)"); - server.ftpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname); - } - resolve("ftpcrack done"); - }, 15 * 1000); - }); - - p.then(function(res) { - resolve("ftpcrackexecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "relaysmtp") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|relaysmtp() call has incorrect number of arguments. Takes 1 argument"); - return; } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command"); - workerScript.scriptRef.log("Cannot relaysmtp(). Invalid IP or hostname passed in: " + ip); - return; - } - - if (!Player.hasProgram(Programs.RelaySMTPProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have relaySMTP.exe program on home computer"); - return; - } - - workerScript.scriptRef.log("Running relaySMTP.exe on server " + server.hostname + " in 20 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (!server.smtpPortOpen) { - workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)"); - server.smtpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname); - } - resolve("relaysmtp done"); - }, 20 * 1000); - }); - - p.then(function(res) { - resolve("relaysmtpexecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "httpworm") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|httpworm() call has incorrect number of arguments. Takes 1 argument"); - return; + if (sourceScript == null) { + workerScript.scriptRef.log(scriptname + " does not exist. scp() failed"); + return resolve(false); } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command"); - workerScript.scriptRef.log("Cannot httpworm(). Invalid IP or hostname passed in: " + ip); - return; - } - - if (!Player.hasProgram(Programs.HTTPWormProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have HTTPWorm.exe program on home computer"); - return; - } - - workerScript.scriptRef.log("Running HTTPWorm.exe on server " + server.hostname + " in 25 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (!server.httpPortOpen) { - workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)"); - server.httpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname); - } - resolve("httpworm done"); - }, 25 * 1000); - }); - - p.then(function(res) { - resolve("HTTPWormexecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "sqlinject") { - if (exp.args.length != 1) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|sqlinject() call has incorrect number of arguments. Takes 1 argument"); - return; - } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into sqlinject() command"); - workerScript.scriptRef.log("Cannot sqlinject(). Invalid IP or hostname passed in: " + ip); - return; - } - - if (!Player.hasProgram(Programs.SQLInjectProgram)) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have SQLInject.exe program on home computer"); - return; - } - - workerScript.scriptRef.log("Running SQLInject.exe on server " + server.hostname + " in 30 seconds"); - var p = new Promise(function(resolve, reject) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - if (!server.sqlPortOpen) { - workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)"); - server.sqlPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname); - } - resolve("sqlinject done"); - }, 30 * 1000); - }); - - p.then(function(res) { - resolve("sqlinjectexecuted"); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "hasRootAccess") { - if (exp.args.length != 1) { - reject(makeRuntimeRejectMsg(workerScript, "hasRootAccess() call has incorrect number of arguments. Takes 1 argument")); - return; - } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - setTimeout(function() { - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into hasRootAccess() command"); - workerScript.scriptRef.log("Cannot hasRootAccess(). Invalid IP or hostname passed in: " + ip); - return; - } - workerScript.scriptRef.log("hasRootAccess() returned " + server.hasAdminRights); - resolve(server.hasAdminRights); - }, CONSTANTS.CodeInstructionRunTime); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "run") { - if (exp.args.length != 1) { - reject(makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Takes 1 argument")); - return; - } - var scriptNamePromise = evaluate(exp.args[0], workerScript); - scriptNamePromise.then(function(scriptname) { - if (env.stopFlag) {reject(workerScript); return;} - var scriptServer = getServer(workerScript.serverIp); - if (scriptServer == null) { - reject("|"+workerScript.serverIp+"|"+workerScript.name+"|Could not find server. This is a bug in the game. Report to game dev"); - return; - } - - var runScriptPromise = runScriptFromScript(scriptServer, scriptname, workerScript); - runScriptPromise.then(function(res) { - resolve(res); - }, function(e) { - reject(e); - }); - - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "exec") { - if (exp.args.length != 2) { - reject(makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Takes 2 arguments")); - return; - } - var scriptNamePromise = evaluate(exp.args[0], workerScript); - scriptNamePromise.then(function(scriptname) { - if (env.stopFlag) {reject(workerScript); return;} - var ipPromise = evaluate(exp.args[1], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var server = getServer(ip); - if (server == null) { - reject(makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + ip)); - return; - } - - var runScriptPromise = runScriptFromScript(server, scriptname, workerScript); - runScriptPromise.then(function(res) { - resolve(res); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "scp") { - if (exp.args.length != 2) { - reject(makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments")); - return; - } - var scriptNamePromise = evaluate(exp.args[0], workerScript); - scriptNamePromise.then(function(scriptname) { - if (env.stopFlag) {reject(workerScript); return;} - var ipPromise = evaluate(exp.args[1], workerScript); - ipPromise.then(function(ip) { - if (env.stopFlag) {reject(workerScript); return;} - var destServer = getServer(ip); - if (destServer == null) { - reject(makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into scp() command: " + ip)); - return; - } - - var currServ = getServer(workerScript.serverIp); - if (currServ == null) { - reject(makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer")); - return; - } - - var sourceScript = null; - for (var i = 0; i < currServ.scripts.length; ++i) { - if (scriptname == currServ.scripts[i].filename) { - sourceScript = currServ.scripts[i]; - break; - } - } - if (sourceScript == null) { - workerScript.scriptRef.log(scriptname + " does not exist. scp() failed"); - resolve(false); - return; - } - - //Overwrite script if it already exists - for (var i = 0; i < destServer.scripts.length; ++i) { - if (scriptname == destServer.scripts[i].filename) { - workerScript.scriptRef.log("WARNING: " + scriptname + " already exists on " + destServer.hostname + " and it will be overwritten."); - workerScript.scriptRef.log(scriptname + " overwritten on " + destServer.hostname); - var oldScript = destServer.scripts[i]; - oldScript.code = sourceScript.code; - oldScript.ramUsage = sourceScript.ramUsage; - resolve(true); - return; - } - } - - //Create new script if it does not already exist - var newScript = new Script(); - newScript.filename = scriptname; - newScript.code = sourceScript.code; - newScript.ramUsage = sourceScript.ramUsage; - newScript.server = destServer.ip; - destServer.scripts.push(newScript); - workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname); + + //Overwrite script if it already exists + for (var i = 0; i < destServer.scripts.length; ++i) { + if (scriptname == destServer.scripts[i].filename) { + workerScript.scriptRef.log("WARNING: " + scriptname + " already exists on " + destServer.hostname + " and it will be overwritten."); + workerScript.scriptRef.log(scriptname + " overwritten on " + destServer.hostname); + var oldScript = destServer.scripts[i]; + oldScript.code = sourceScript.code; + oldScript.ramUsage = sourceScript.ramUsage; resolve(true); return; - }, function(e) { - reject(e); - }); - }, function(e) { - reject(e); - }); + } + } + + //Create new script if it does not already exist + var newScript = new Script(); + newScript.filename = scriptname; + newScript.code = sourceScript.code; + newScript.ramUsage = sourceScript.ramUsage; + newScript.server = destServer.ip; + destServer.scripts.push(newScript); + workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname); + return resolve(true); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "getHostname") { + if (exp.args.length != 0) { + return reject(makeRuntimeRejectMsg(workerScript, "getHostname() call has incorrect number of arguments. Takes 0 arguments")); + } + var scriptServer = getServer(workerScript.serverIp); + if (scriptServer == null) { + return reject(makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev")); + } + resolve(scriptServer.hostname); + } else if (exp.func.value == "getHackingLevel") { + if (exp.args.length != 0) { + return reject(makeRuntimeRejectMsg(workerScript, "getHackingLevel() call has incorrect number of arguments. Takes 0 arguments")); + } + Player.updateSkillLevels(); + workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill); + resolve(Player.hacking_skill); + } else if (exp.func.value == "getServerMoneyAvailable") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "getServerMoneyAvailable() call has incorrect number of arguments. Takes 1 arguments")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerMoneyAvailable() command")); + } + workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); + resolve(server.moneyAvailable); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "getServerSecurityLevel") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() call has incorrect number of arguments. Takes 1 arguments")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("Cannot getServerSecurityLevel(). Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerSecurityLevel() command"));; + } + workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); + resolve(server.hackDifficulty); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "purchaseHacknetNode") { + if (exp.args.length != 0) { + return reject(makeRuntimeRejectMsg(workerScript, "purchaseHacknetNode() call has incorrect number of arguments. Takes 0 arguments")); + } + var cost = getCostOfNextHacknetNode(); + if (isNaN(cost)) { + return reject(makeRuntimeRejectMsg(workerScript, "Could not calculate cost in purchaseHacknetNode(). This is a bug please report to game dev")); + } + if (cost > Player.money) { + workerScript.scriptRef.log("Could not afford to purchase new Hacknet Node"); + return resolve(false); + } - } else if (exp.func.value == "getHostname") { - if (env.stopFlag) {reject(workerScript); return;} - if (exp.args.length != 0) { - reject(makeRuntimeRejectMsg(workerScript, "getHostname() call has incorrect number of arguments. Takes 0 arguments")); - return; - } - setTimeout(function() { - if (env.stopFlag) {reject(workerScript); return;} - var scriptServer = getServer(workerScript.serverIp); - if (scriptServer == null) { - reject(makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev")); - return; - } - resolve(scriptServer.hostname); - }, CONSTANTS.CodeInstructionRunTime); - } else if (exp.func.value == "getHackingLevel") { - if (exp.args.length != 0) { - reject("|"+workerScript.serverIp+"|"+workerScript.name+"|getHackingLevel() call has incorrect number of arguments. Takes 0 arguments"); - return; - } - setTimeout(function() { - if (env.stopFlag) {reject(workerScript); return;} - Player.updateSkillLevels(); - workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill); - resolve(Player.hacking_skill); - }, CONSTANTS.CodeInstructionRunTime); - } else if (exp.func.value == "getServerMoneyAvailable") { - if (exp.args.length != 1) { - reject("|"+workerScript.serverIp+"|"+workerScript.name+"|getServerMoneyAvailable() call has incorrect number of arguments. Takes 1 arguments"); - return; - } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - setTimeout(function() { - var server = getServer(ip); - if (server == null) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into getServerMoneyAvailable() command"); - workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip); - return; - } - workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); - resolve(server.moneyAvailable); - }, CONSTANTS.CodeInstructionRunTime); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "getServerSecurityLevel") { - if (exp.args.length != 1) { - reject(makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() call has incorrect number of arguments. Takes 1 arguments")); - return; - } - var ipPromise = evaluate(exp.args[0], workerScript); - ipPromise.then(function(ip) { - setTimeout(function() { - var server = getServer(ip); - if (server == null) { - reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerSecurityLevel() command")); - workerScript.scriptRef.log("Cannot getServerSecurityLevel(). Invalid IP or hostname passed in: " + ip); - return; - } - workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); - resolve(server.hackDifficulty); - }, CONSTANTS.CodeInstructionRunTime); - }, function(e) { - reject(e); - }); - } else if (exp.func.value == "purchaseHacknetNode") { - if (exp.args.length != 0) { - reject(makeRuntimeRejectMsg(workerScript, "purchaseHacknetNode() call has incorrect number of arguments. Takes 0 arguments")); - return; - } - setTimeout(function() { - var cost = getCostOfNextHacknetNode(); - if (isNaN(cost)) { - reject(makeRuntimeRejectMsg(workerScript, "Could not calculate cost in purchaseHacknetNode(). This is a bug please report to game dev")); - return; - } - if (cost > Player.money) { - workerScript.scriptRef.log("Could not afford to purchase new Hacknet Node"); - resolve(false); - return; - } - - //Auto generate a name for the node for now...TODO - var numOwned = Player.hacknetNodes.length; - var name = "hacknet-node-" + numOwned; - var node = new HacknetNode(name); - node.updateMoneyGainRate(); - - Player.loseMoney(cost); - Player.hacknetNodes.push(node); - displayHacknetNodesContent(); - workerScript.scriptRef.log("Purchased new Hacknet Node with name: " + name); - resolve(numOwned); - }, CONSTANTS.CodeInstructionRunTime); - } else { - reject(makeRuntimeRejectMsg(workerScript, "Invalid function: " + exp.func.value)); - } - }, CONSTANTS.CodeInstructionRunTime); - }); - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Unrecognized function call"); - break; - default: - break; - } + //Auto generate a name for the node for now...TODO + var numOwned = Player.hacknetNodes.length; + var name = "hacknet-node-" + numOwned; + var node = new HacknetNode(name); + node.updateMoneyGainRate(); + + Player.loseMoney(cost); + Player.hacknetNodes.push(node); + displayHacknetNodesContent(); + workerScript.scriptRef.log("Purchased new Hacknet Node with name: " + name); + resolve(numOwned); + } else { + reject(makeRuntimeRejectMsg(workerScript, "Invalid function: " + exp.func.value)); + } + break; + default: + reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". This is a bug please report to game developer")); + break; + } //End switch + }, CONSTANTS.CodeInstructionRunTime); //End setTimeout, the Netscript operation run time + + }); // End Promise } //Returns true if any of the if statements evaluated, false otherwise. Therefore, the else statement @@ -1252,6 +713,12 @@ function evaluateProg(exp, workerScript, index) { }); } +function netscriptDelay(time) { + return new Promise(function(resolve) { + setTimeout(resolve, time); + }); +} + function makeRuntimeRejectMsg(workerScript, msg) { return "|"+workerScript.serverIp+"|"+workerScript.name+"|" + msg; } diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js new file mode 100644 index 000000000..582871536 --- /dev/null +++ b/src/NetscriptFunctions.js @@ -0,0 +1,341 @@ +/* Netscript Functions + * Implementation for Netscript functions */ +function netscriptAssign(exp, workerScript) { + var env = workerScript.env; + return new Promise(function(resolve, reject) { + if (env.stopFlag) {return reject(workerScript);} + + if (exp.left.type != "var") { + return reject(makeRuntimeRejectMsg(workerScript, "Cannot assign to " + JSON.stringify(exp.left))); + } + + var expRightPromise = evaluate(exp.right, workerScript); + expRightPromise.then(function(expRight) { + try { + env.set(exp.left.value, expRight); + } catch (e) { + return reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString())); + } + resolve(false); //Return false so this doesnt cause conditionals to evaluate + }, function(e) { + reject(e); + }); + }); +} + +function netscriptBinary(exp, workerScript) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + + var opPromises = [evaluate(exp.left, workerScript), evaluate(exp.right, workerScript)]; + return Promise.all(opPromises).then(function (ops) { + try { + var result = apply_op(exp.operator, ops[0], ops[1]); + return Promise.resolve(result); + } catch(e) { + return Promise.reject(e); + } + }).catch(function(e) { + return Promise.reject(e); + }); +} + +function netscriptHack(exp, workerScript) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + + if (exp.args.length != 1) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Hack() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + return ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("hack() error. Invalid IP or hostname passed in: " + ip + ". Stopping..."); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into hack() command")); + } + + //Calculate the hacking time + var hackingTime = scriptCalculateHackingTime(server); //This is in seconds + + //No root access or skill level too low + if (server.hasAdminRights == false) { + workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access"); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname)); + } + + if (server.requiredHackingSkill > Player.hacking_skill) { + workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough"); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because player's hacking skill is not high enough to hack " + server.hostname)); + } + + workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds"); + return Promise.resolve([server, hackingTime]); + }).then(function([server, hackingTime]) { + console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds."); + return netscriptDelay(hackingTime* 1000).then(function() { + if (env.stopFlag) {return Promise.reject(workerScript);} + var hackChance = scriptCalculateHackingChance(server); + var rand = Math.random(); + var expGainedOnSuccess = scriptCalculateExpGain(server); + var expGainedOnFailure = (expGainedOnSuccess / 4); + if (rand < hackChance) { //Success! + var moneyGained = scriptCalculatePercentMoneyHacked(server); + moneyGained = Math.floor(server.moneyAvailable * moneyGained); + + //Safety check + if (moneyGained <= 0) {moneyGained = 0;} + + server.moneyAvailable -= moneyGained; + Player.gainMoney(moneyGained); + workerScript.scriptRef.onlineMoneyMade += moneyGained; + workerScript.scriptRef.recordHack(server.ip, moneyGained); + + Player.gainHackingExp(expGainedOnSuccess); + workerScript.scriptRef.onlineExpGained += expGainedOnSuccess; + console.log("Script successfully hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); + workerScript.scriptRef.log("Script SUCCESSFULLY hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); + server.fortify(CONSTANTS.ServerFortifyAmount); + return Promise.resolve(true); + } else { + //Player only gains 25% exp for failure? TODO Can change this later to balance + Player.gainHackingExp(expGainedOnFailure); + workerScript.scriptRef.onlineExpGained += expGainedOnFailure; + + console.log("Script unsuccessful to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); + workerScript.scriptRef.log("Script FAILED to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); + return Promise.resolve(false); + } + }); + }).then(function(res) { + return Promise.resolve(res); + }).catch(function(e) { + return Promise.reject(e); + }); +} + +function netscriptGrow(exp, workerScript) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + if (exp.args.length != 1) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "grow() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + return ipPromise.then(function(ip) { + if (env.stopFlag) {return Promise.reject(workerScript);} + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: " + ip); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into grow() command")); + } + + //No root access or skill level too low + if (server.hasAdminRights == false) { + workerScript.scriptRef.log("Cannot grow this server (" + server.hostname + ") because user does not have root access"); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname)); + } + + var growTime = scriptCalculateGrowTime(server); + console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds") + workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds"); + + return Promise.resolve([server, growTime]); + }).then(function([server, growTime]) { + if (env.stopFlag) {return Promise.reject(workerScript);} + return netscriptDelay(growTime).then(function() { + if (env.stopFlag) {return Promise.reject(workerScript);} + server.moneyAvailable += 1; //It can be grown even if it has no money + var growthPercentage = processSingleServerGrowth(server, 450); + workerScript.scriptRef.recordGrow(server.ip); + return Promise.resolve(growthPercentage); + }); + }).then(function(res) { + return Promise.resolve(res); + }).catch(function(e) { + return Promise.reject(e); + }) +} + +function netscriptWeaken(exp, workerScript) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + if (exp.args.length != 1) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "weaken() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + return ipPromise.then(function(ip) { + if (env.stopFlag) {return Promise.reject(workerScript);} + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: " + ip); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into weaken() command")); + } + + //No root access or skill level too low + if (server.hasAdminRights == false) { + workerScript.scriptRef.log("Cannot weaken this server (" + server.hostname + ") because user does not have root access"); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname)); + } + + var weakenTime = scriptCalculateWeakenTime(server); + console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds") + workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds"); + + return Promise.resolve([server, weakenTime]); + }).then(function([server, weakenTime]) { + if (env.stopFlag) {return Promise.reject(workerScript);} + return netscriptDelay(weakenTime).then(function() { + if (env.stopFlag) {return Promise.reject(workerScript);} + server.weaken(CONSTANTS.ServerWeakenAmount); + workerScript.scriptRef.recordWeaken(server.ip); + return Promise.resolve(CONSTANTS.ServerWeakenAmount); + }); + }).then(function(res) { + return Promise.resolve(res); + }).catch(function(e) { + return Promise.reject(e); + }); +} + +function netscriptRunProgram(exp, workerScript, programName) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + if (exp.args.length != 1) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "nuke() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + return ipPromise.then(function(ip) { + if (env.stopFlag) {return Promise.reject(workerScript);} + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip); + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into " + programName + " command")); + } + + if (!Player.hasProgram(programName)) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Player does not have " + programName + " on home computer")); + } + + switch(programName) { + case Programs.NukeProgram: + return netscriptRunNukeProgram(exp, workerScript, server); + break; + case Programs.BruteSSHProgram: + return netscriptRunBrutesshProgram(exp, workerScript, server); + break; + case Programs.FTPCrackProgram: + return netscriptRunFtpcrackProgram(exp, workerScript, server); + break; + case Programs.RelaySMTPProgram: + return netscriptRunRelaysmtpProgram(exp, workerScript, server); + break; + case Programs.HTTPWormProgram: + return netscriptRunHttpwormProgram(exp, workerScript, server); + break; + case Programs.SQLInjectProgram: + return netscriptRunSqlinjectProgram(exp, workerScript, server); + break; + default: + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid program. This is a bug please contact game dev")); + break; + } + }).then(function(res) { + return Promise.resolve(res); + }).catch(function(e) { + return Promise.reject(e); + }); +} + +function netscriptRunNukeProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + if (server.openPortCount < server.numOpenPortsRequired) { + return Promise.reject(makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus")); + } + + workerScript.scriptRef.log("Running NUKE.exe on server " + server.hostname + " in 5 seconds"); + setTimeout(function() { + if (server.hasAdminRights) { + workerScript.scriptRef.log("Already have root access to " + server.hostname); + } else { + server.hasAdminRights = true; + workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access"); + } + return Promise.resolve(true); + }, 5 * 1000); +} + +function netscriptRunBrutesshProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + setTimeout(function() { + if (!server.sshPortOpen) { + workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)"); + server.sshPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname); + } + return Promise.resolve(true); + }, 10 * 1000); +} + +function netscriptRunFtpcrackProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + setTimeout(function() { + if (!server.ftpPortOpen) { + workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)"); + server.ftpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname); + } + return Promise.resolve(true); + }, 15 * 1000); +} + +function netscriptRunRelaysmtpProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + setTimeout(function() { + if (!server.smtpPortOpen) { + workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)"); + server.smtpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname); + } + return Promise.resolve(true); + }, 20 * 1000); +} + +function netscriptRunHttpwormProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + setTimeout(function() { + if (!server.httpPortOpen) { + workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)"); + server.httpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname); + } + return Promise.resolve(true); + }, 25 * 1000); +} + +function netscriptRunSqlinjectProgram(exp, workerScript, server) { + var env = workerScript.env; + if (env.stopFlag) {return Promise.reject(workerScript);} + setTimeout(function() { + if (!server.sqlPortOpen) { + workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)"); + server.sqlPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname); + } + return Promise.resolve(true); + }, 30 * 1000); +} \ No newline at end of file From 71999ea2eb87c401c401332f7a5064090e8b3a8d Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 01:24:30 -0500 Subject: [PATCH 04/16] Removed time for Program netscript ocmmands (nuke, brutessh, etc) --- src/Constants.js | 5 ++ src/NetscriptFunctions.js | 108 +++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index e0ac99928..ddb4f5437 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -488,6 +488,11 @@ CONSTANTS = { "RAM Upgrades on your home computer", Changelog: + "v0.20.0
" + + "Refactor Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + + "now each one should only take 750 milliseconds).
" + + "" "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 582871536..f45ded862 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -252,90 +252,76 @@ function netscriptRunNukeProgram(exp, workerScript, server) { if (server.openPortCount < server.numOpenPortsRequired) { return Promise.reject(makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus")); } - - workerScript.scriptRef.log("Running NUKE.exe on server " + server.hostname + " in 5 seconds"); - setTimeout(function() { - if (server.hasAdminRights) { - workerScript.scriptRef.log("Already have root access to " + server.hostname); - } else { - server.hasAdminRights = true; - workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access"); - } - return Promise.resolve(true); - }, 5 * 1000); + if (server.hasAdminRights) { + workerScript.scriptRef.log("Already have root access to " + server.hostname); + } else { + server.hasAdminRights = true; + workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access"); + } + return Promise.resolve(true); } function netscriptRunBrutesshProgram(exp, workerScript, server) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} - setTimeout(function() { - if (!server.sshPortOpen) { - workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)"); - server.sshPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname); - } - return Promise.resolve(true); - }, 10 * 1000); + if (!server.sshPortOpen) { + workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)"); + server.sshPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname); + } + return Promise.resolve(true); } function netscriptRunFtpcrackProgram(exp, workerScript, server) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} - setTimeout(function() { - if (!server.ftpPortOpen) { - workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)"); - server.ftpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname); - } - return Promise.resolve(true); - }, 15 * 1000); + if (!server.ftpPortOpen) { + workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)"); + server.ftpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname); + } + return Promise.resolve(true); } function netscriptRunRelaysmtpProgram(exp, workerScript, server) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} - setTimeout(function() { - if (!server.smtpPortOpen) { - workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)"); - server.smtpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname); - } - return Promise.resolve(true); - }, 20 * 1000); + if (!server.smtpPortOpen) { + workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)"); + server.smtpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname); + } + return Promise.resolve(true); } function netscriptRunHttpwormProgram(exp, workerScript, server) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} - setTimeout(function() { - if (!server.httpPortOpen) { - workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)"); - server.httpPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname); - } - return Promise.resolve(true); - }, 25 * 1000); + if (!server.httpPortOpen) { + workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)"); + server.httpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname); + } + return Promise.resolve(true); } function netscriptRunSqlinjectProgram(exp, workerScript, server) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} - setTimeout(function() { - if (!server.sqlPortOpen) { - workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)"); - server.sqlPortOpen = true; - ++server.openPortCount; - } else { - workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname); - } - return Promise.resolve(true); - }, 30 * 1000); + if (!server.sqlPortOpen) { + workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)"); + server.sqlPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname); + } + return Promise.resolve(true); } \ No newline at end of file From 9adce1dd2f34bebae349850703f66e6b954f43ee Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 03:08:04 -0500 Subject: [PATCH 05/16] Added EXP gains to weaken() and grow() after refactoring, and rebalanced hacking mechanics: --- src/Constants.js | 9 ++++++--- src/NetscriptEvaluator.js | 6 +++--- src/NetscriptFunctions.js | 10 ++++++++++ src/Player.js | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index ddb4f5437..a685acd87 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -65,7 +65,7 @@ CONSTANTS = { ScriptHNUpgCoreRamCost: 0.8, //Server constants - ServerGrowthRate: 1.002, //Growth rate + ServerGrowthRate: 1.0015, //Growth rate ServerFortifyAmount: 0.002, //Amount by which server's security increases when its hacked ServerWeakenAmount: 0.1, //Amount by which server's security decreases when weakened @@ -489,10 +489,13 @@ CONSTANTS = { Changelog: "v0.20.0
" + - "Refactor Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + "now each one should only take 750 milliseconds).
" + - "" + "-Percentage money stolen when hacking lowered to compensate for faster script speeds
" + + "-Lowered base growth rate by 25%(which affects amount of money gained from grow())
" + + "-Hacking experience granted by grow() halved" + + "-Weaken() is now 10% faster, but only grants 3 hacking exp upon completion instead of 5
" "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 949fb9f55..3b91a827c 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -838,7 +838,7 @@ function scriptCalculateExpGain(server) { function scriptCalculatePercentMoneyHacked(server) { var difficultyMult = (100 - server.hackDifficulty) / 100; var skillMult = (Player.hacking_skill - (server.requiredHackingSkill - 1)) / Player.hacking_skill; - var percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / 150; + var percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / 200; if (percentMoneyHacked < 0) {return 0;} if (percentMoneyHacked > 1) {return 1;} return percentMoneyHacked; @@ -848,7 +848,7 @@ function scriptCalculatePercentMoneyHacked(server) { function scriptCalculateGrowTime(server) { var difficultyMult = server.requiredHackingSkill * server.hackDifficulty; var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50); - var growTime = skillFactor * Player.hacking_speed_mult * 16; //This is in seconds + var growTime = skillFactor * Player.hacking_speed_mult * 17; //This is in seconds return growTime * 1000; } @@ -856,6 +856,6 @@ function scriptCalculateGrowTime(server) { function scriptCalculateWeakenTime(server) { var difficultyMult = server.requiredHackingSkill * server.hackDifficulty; var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50); - var weakenTime = skillFactor * Player.hacking_speed_mult * 50; //This is in seconds + var weakenTime = skillFactor * Player.hacking_speed_mult * 45; //This is in seconds return weakenTime * 1000; } \ No newline at end of file diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index f45ded862..9ceab47dd 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -147,6 +147,11 @@ function netscriptGrow(exp, workerScript) { server.moneyAvailable += 1; //It can be grown even if it has no money var growthPercentage = processSingleServerGrowth(server, 450); workerScript.scriptRef.recordGrow(server.ip); + workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " + + formatNumber(growthPercentage*100 - 100, 6) + "%"); + var expGain = 0.5 * Player.hacking_exp_mult; + workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + Player.gainHackingExp(expGain); return Promise.resolve(growthPercentage); }); }).then(function(res) { @@ -188,6 +193,11 @@ function netscriptWeaken(exp, workerScript) { if (env.stopFlag) {return Promise.reject(workerScript);} server.weaken(CONSTANTS.ServerWeakenAmount); workerScript.scriptRef.recordWeaken(server.ip); + workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty); + workerScript.scriptRef.log("Gained 3 hacking experience"); + var expGain = 3 * Player.hacking_exp_mult; + workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + Player.gainHackingExp(expGain); return Promise.resolve(CONSTANTS.ServerWeakenAmount); }); }).then(function(res) { diff --git a/src/Player.js b/src/Player.js index 8497f4ad9..b74ee0357 100644 --- a/src/Player.js +++ b/src/Player.js @@ -243,7 +243,7 @@ PlayerObject.prototype.calculateHackingTime = function() { PlayerObject.prototype.calculatePercentMoneyHacked = function() { var difficultyMult = (100 - this.getCurrentServer().hackDifficulty) / 100; var skillMult = (this.hacking_skill - (this.getCurrentServer().requiredHackingSkill - 1)) / this.hacking_skill; - var percentMoneyHacked = difficultyMult * skillMult * this.hacking_money_mult / 150; + var percentMoneyHacked = difficultyMult * skillMult * this.hacking_money_mult / 200; console.log("Percent money hacked calculated to be: " + percentMoneyHacked); if (percentMoneyHacked < 0) {return 0;} if (percentMoneyHacked > 1) {return 1;} From d73a11f67862d3aaff5e6c4fa44be4a5f9527a0a Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 09:31:47 -0500 Subject: [PATCH 06/16] Rebalancing script RAM Usage. Script base RAM cost is 1.5GB, while common functions were made cheaper --- src/Constants.js | 12 ++++++------ src/NetscriptFunctions.js | 2 +- src/Script.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index a685acd87..38e779770 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -37,12 +37,12 @@ CONSTANTS = { CodeInstructionRunTime: 750, //RAM Costs for differenc commands - ScriptWhileRamCost: 0.4, - ScriptForRamCost: 0.4, + ScriptWhileRamCost: 0.15, + ScriptForRamCost: 0.15, ScriptIfRamCost: 0.1, - ScriptHackRamCost: 0.25, - ScriptGrowRamCost: 0.25, - ScriptWeakenRamCost: 0.25, + ScriptHackRamCost: 0.15, + ScriptGrowRamCost: 0.15, + ScriptWeakenRamCost: 0.15, ScriptNukeRamCost: 0.05, ScriptBrutesshRamCost: 0.05, ScriptFtpcrackRamCost: 0.05, @@ -495,7 +495,7 @@ CONSTANTS = { "-Percentage money stolen when hacking lowered to compensate for faster script speeds
" + "-Lowered base growth rate by 25%(which affects amount of money gained from grow())
" + "-Hacking experience granted by grow() halved" + - "-Weaken() is now 10% faster, but only grants 3 hacking exp upon completion instead of 5
" + "-Weaken() is now 10% faster, but only grants 3 base hacking exp upon completion instead of 5
" "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 9ceab47dd..79cd8585f 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -1,5 +1,5 @@ /* Netscript Functions - * Implementation for Netscript functions */ + * Implementation for Netscript features */ function netscriptAssign(exp, workerScript) { var env = workerScript.env; return new Promise(function(resolve, reject) { diff --git a/src/Script.js b/src/Script.js index 9fa101940..cc252a8f8 100644 --- a/src/Script.js +++ b/src/Script.js @@ -204,7 +204,7 @@ Script.prototype.reset = function() { //Updates how much RAM the script uses when it is running. Script.prototype.updateRamUsage = function() { - var baseRam = 1; //Each script requires 1GB to run regardless + var baseRam = 1.5; //Each script requires 1GB to run regardless var codeCopy = this.code.repeat(1); codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace From 8fa1eab3c69023f769bb497c68417ad04fa0cc50 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 10:31:46 -0500 Subject: [PATCH 07/16] Added fileExists() and getServerRequiredHackingLevel() Netscript commands. Updated Netscript documentation --- src/Constants.js | 38 ++++++++++++++++----- src/NetscriptEvaluator.js | 71 +++++++++++++++++++++++++++++---------- src/Player.js | 2 +- src/Script.js | 2 +- 4 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index 38e779770..b4307cca3 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -36,9 +36,9 @@ CONSTANTS = { //Time (ms) it takes to run one operation in Netscript. CodeInstructionRunTime: 750, - //RAM Costs for differenc commands - ScriptWhileRamCost: 0.15, - ScriptForRamCost: 0.15, + //RAM Costs for different commands + ScriptWhileRamCost: 0.2, + ScriptForRamCost: 0.2, ScriptIfRamCost: 0.1, ScriptHackRamCost: 0.15, ScriptGrowRamCost: 0.15, @@ -306,12 +306,16 @@ CONSTANTS = { "sleep(n)
Suspends the script for n milliseconds.
Example: sleep(5000);

" + "grow(hostname/ip)
Use your hacking skills to increase the amount of money available on a server. The argument passed in " + "must be a string with either the IP or hostname of the target server. The runtime for this command depends on your hacking level and the target server's security level. " + - "The grow() command requires root access to the target server, but " + - "there is no required hacking level to run the command. " + - "Grants 1 hacking exp when it completes. Works offline at a slower rate.
Example: grow('foodnstuff');

" + + "When grow() completes, the money available on a target server will be increased by a certain, fixed percentage. This percentage " + + "is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates.

" + + "Like hack(), grow() can be called on any server, regardless of where the script is running. " + + "The grow() command requires root access to the target server, but there is no required hacking level to run the command. " + + "It grants 1 hacking exp when it completes. Works offline at a slower rate.
Example: grow('foodnstuff');

" + "weaken(hostname/ip)
Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " + - "in must be a string with either the IP or hostname of the target server. This command requires root access to the target server, but " + - "there is no required hacking level to run the command. Grants 5 hacking exp when it completes. Works offline at a slower rate
Example: weaken('foodnstuff');

" + + "in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " + + "hacking level and the target server's security level.

Like hack() and grow(), weaken() can be called on " + + "any server, regardless of where the script is running. This command requires root access to the target server, but " + + "there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Works offline at a slower rate
Example: weaken('foodnstuff');

" + "print(x)
Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command )

" + "nuke(hostname/ip)
Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline
Example: nuke('foodnstuff');

" + "brutessh(hostname/ip)
Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline
Example: brutessh('foodnstuff');

" + @@ -339,6 +343,17 @@ CONSTANTS = { "hostname or IP of the target server. Does NOT work while offline
Example: getServerMoneyAvailable('foodnstuff');

" + "getServerSecurityLevel(hostname/ip)
Returns the security level of a server. The argument passed in must be a string with either the " + "hostname or IP of the target server. A server's security is denoted by a number between 1 and 100. Does NOT work while offline.

" + + "getServerRequiredHackingLevel(hostname/ip)
Returns the required hacking level of a server. The argument passed in must be a string with either the " + + "hostname or IP or the target server. Does NOT work while offline

" + + "fileExists(filename, [hostname/ip])
Returns a boolean (true or false) indicating whether the specified file exists on a server. " + + "The first argument must be a string with the name of the file. A file can either be a script or a program. A script name is case-sensitive, but a " + + "program is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe.

" + + "The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " + + "If it is not specified, then the function will search through the current server for the file.
" + + "Example: fileExists('foo.script', 'foodnstuff');
" + + "Example: fileExists('ftpcrack.exe');

" + + "The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " + + "return true if the current server (the server on which the script is running) contains the FTPCrack.exe program, and false otherwise.

" + "purchaseHacknetNode()
Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " + "at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " + "a new Hacknet Node then the function will return false. Does NOT work offline

" + @@ -495,7 +510,12 @@ CONSTANTS = { "-Percentage money stolen when hacking lowered to compensate for faster script speeds
" + "-Lowered base growth rate by 25%(which affects amount of money gained from grow())
" + "-Hacking experience granted by grow() halved" + - "-Weaken() is now 10% faster, but only grants 3 base hacking exp upon completion instead of 5
" + "-Weaken() is now 10% faster, but only grants 3 base hacking exp upon completion instead of 5
" + + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + + "and weaken() all cost slightly less RAM than before
" + + "-Added getServerRequiredHackingLevel(server) Netscript command.
" + + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + + "specified server
" + "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 3b91a827c..7d40e3ebf 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -52,8 +52,6 @@ function evaluate(exp, workerScript) { reject(e); }); break; - - //TODO case "if": var numConds = exp.cond.length; var numThens = exp.then.length; @@ -110,21 +108,6 @@ function evaluate(exp, workerScript) { reject(workerScript); }); break; - - /* Currently supported function calls: - * hack(server) - * sleep(N) - sleep N seconds - * print(x) - Prints a variable or constant - * grow(server) - * nuke(server) - * brutessh(server) - * ftpcrack(server) - * relaysmtp(server) - * httpworm(server) - * sqlinject(server) - * getHackingLevel() - * run(script)) - */ case "call": if (exp.func.value == "hack") { var p = netscriptHack(exp, workerScript); @@ -373,7 +356,7 @@ function evaluate(exp, workerScript) { ipPromise.then(function(ip) { var server = getServer(ip); if (server == null) { - workerScript.scriptRef.log("Cannot getServerSecurityLevel(). Invalid IP or hostname passed in: " + ip); + workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerSecurityLevel() command"));; } workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); @@ -381,6 +364,58 @@ function evaluate(exp, workerScript) { }, function(e) { reject(e); }); + } else if (exp.func.value == "getServerRequiredHackingLevel") { + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerRequiredHackingLevel() command")); + } + workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hsostname); + resolve(server.requiredHackingSkill); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "fileExists") { + if (exp.args.length != 1 && exp.args.length != 2) { + return reject(makeRuntimeRejectMsg(workerScript, "fileExists() call has incorrect number of arguments. Takes 1 or 2 arguments")); + } + var argPromises = exp.args.map(function(arg) { + return evaluate(arg, workerScript); + }); + + var filename = ""; + Promise.all(argPromises).then(function(args) { + if (env.stopFlag) {return reject(workerScript);} + filename = args[0]; + if (exp.args.length == 2) { + return Promise.resolve(workerScript.serverIp); + } else { + return evaluate(exp.args[1], workerScript); + } + }).then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("fileExists() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into fileExists() command")); + } + + for (var i = 0; i < server.scripts.length; ++i) { + if (filename == server.scripts[i].filename) { + return resolve(true); + } + } + if (Player.hasProgram(filename)) { + return resolve(true); + } + return reject(false); + }).catch(function(e) { + reject(e); + }); } else if (exp.func.value == "purchaseHacknetNode") { if (exp.args.length != 0) { return reject(makeRuntimeRejectMsg(workerScript, "purchaseHacknetNode() call has incorrect number of arguments. Takes 0 arguments")); diff --git a/src/Player.js b/src/Player.js index b74ee0357..070ec81d4 100644 --- a/src/Player.js +++ b/src/Player.js @@ -274,7 +274,7 @@ PlayerObject.prototype.analyze = function() { PlayerObject.prototype.hasProgram = function(programName) { var home = Player.getHomeComputer(); for (var i = 0; i < home.programs.length; ++i) { - if (programName == home.programs[i]) {return true;} + if (programName.toLowerCase() == home.programs[i].toLowerCase()) {return true;} } return false; } diff --git a/src/Script.js b/src/Script.js index cc252a8f8..eb96aae70 100644 --- a/src/Script.js +++ b/src/Script.js @@ -204,7 +204,7 @@ Script.prototype.reset = function() { //Updates how much RAM the script uses when it is running. Script.prototype.updateRamUsage = function() { - var baseRam = 1.5; //Each script requires 1GB to run regardless + var baseRam = 1.5; var codeCopy = this.code.repeat(1); codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace From 0dc3d56e3c0c7e7f182b0d2200c119dbdf3f8cf0 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 12:50:32 -0500 Subject: [PATCH 08/16] Added isRunning() Netscript command. Account for new commands in RAM usage --- src/Constants.js | 19 +++++++++++++++---- src/NetscriptEvaluator.js | 40 ++++++++++++++++++++++++++++++++++++--- src/Script.js | 6 ++++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index b4307cca3..8d713fbe4 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -54,9 +54,12 @@ CONSTANTS = { ScriptScpRamCost: 0.5, ScriptHasRootAccessRamCost: 0.05, ScriptGetHostnameRamCost: 0.1, - ScriptGetHackingLevelRamCost: 0.1, + ScriptGetHackingLevelRamCost: 0.05, ScriptGetServerMoneyRamCost: 0.1, - ScriptGetServerSecurityRamCost: 0.2, + ScriptGetServerSecurityRamCost: 0.1, + ScriptGetServerReqdHackRamCost: 0.1, + ScriptFileExistsRamCost: 0.1, + ScriptIsRunningRamCost: 0.1, ScriptOperatorRamCost: 0.01, ScriptPurchaseHacknetRamCost: 1.5, ScriptHacknetNodesRamCost: 1.0, //Base cost for accessing hacknet nodes array @@ -349,11 +352,19 @@ CONSTANTS = { "The first argument must be a string with the name of the file. A file can either be a script or a program. A script name is case-sensitive, but a " + "program is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe.

" + "The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " + - "If it is not specified, then the function will search through the current server for the file.
" + + "If it is omitted, then the function will search through the current server (the server running the script that calls this function) for the file.
" + "Example: fileExists('foo.script', 'foodnstuff');
" + "Example: fileExists('ftpcrack.exe');

" + "The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " + - "return true if the current server (the server on which the script is running) contains the FTPCrack.exe program, and false otherwise.

" + + "return true if the current server (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise.

" + + "isRunning(filename, [hostname/ip])
Returns a boolean (true or false) indicating whether the specified script is running on a server. " + + "The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " + + "hostname or IP of the target server. The function will check whether the script is running on that target server. The second argument is optional. " + + "If it is omitted, then the function will check if the script is running on the current server (the server running the script that calls this function).
" + + "Example: isRunning('foo.script', 'foodnstuff');
" + + "Example: isRunning('foo.script');

" + + "The first example above will return true if there is a script called 'foo.script' is running on the 'foodnstuff' server, and false otherwise. The second " + + "example above will return true if there is a script called 'foo.script' running on the current server, and false otherwise.

" + "purchaseHacknetNode()
Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " + "at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " + "a new Hacknet Node then the function will return false. Does NOT work offline

" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 7d40e3ebf..2100db5cc 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -123,9 +123,9 @@ function evaluate(exp, workerScript) { var sleepTimePromise = evaluate(exp.args[0], workerScript); sleepTimePromise.then(function(sleepTime) { workerScript.scriptRef.log("Sleeping for " + sleepTime + " milliseconds"); - setTimeout(function() { + return netscriptDelay(sleepTime).then(function() { return Promise.resolve(true); - }, sleepTime); + }); }).then(function(res) { resolve(true); }).catch(function(e) { @@ -412,7 +412,41 @@ function evaluate(exp, workerScript) { if (Player.hasProgram(filename)) { return resolve(true); } - return reject(false); + return resolve(false); + }).catch(function(e) { + reject(e); + }); + } else if (exp.func.value == "isRunning") { + if (exp.args.length != 1 && exp.args.length != 2) { + return reject(makeRuntimeRejectMsg(workerScript, "isRunning() call has incorrect number of arguments. Takes 1 or 2 arguments")); + } + var argPromises = exp.args.map(function(arg) { + return evaluate(arg, workerScript); + }); + + var filename = ""; + Promise.all(argPromises).then(function(args) { + if (env.stopFlag) {return reject(workerScript);} + filename = args[0]; + if (exp.args.length == 2) { + return Promise.resolve(workerScript.serverIp); + } else { + return evaluate(exp.args[1], workerScript); + } + }).then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("isRunning() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into isRunning() command")); + } + + for (var i = 0; i < server.runningScripts.length; ++i) { + if (filename == server.runningScripts[i]) { + return resolve(true); + } + } + + return resolve(false); }).catch(function(e) { reject(e); }); diff --git a/src/Script.js b/src/Script.js index eb96aae70..84c785732 100644 --- a/src/Script.js +++ b/src/Script.js @@ -228,6 +228,9 @@ Script.prototype.updateRamUsage = function() { var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel("); var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable("); var getServerSecurityCount = numOccurrences(codeCopy, "getServerSecurityLevel("); + var getServerReqdHackingCount = numOccurrences(codeCopy, "getServerRequiredHackingLevel("); + var fileExistsCount = numOccurrences(codeCopy, "fileExists("); + var isRunningCount = numOccurrences(codeCopy, "isRunning("); var numOperators = numNetscriptOperators(codeCopy); var purchaseHacknetCount = numOccurrences(codeCopy, "purchaseHacknetNode("); var hacknetnodesArrayCount = numOccurrences(codeCopy, "hacknetnodes["); @@ -256,6 +259,9 @@ Script.prototype.updateRamUsage = function() { (getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) + (getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) + (getServerSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) + + (getServerReqdHackingCount * CONSTANTS.ScriptGetServerReqdHackRamCost) + + (fileExistsCount * CONSTANTS.ScriptFileExistsRamCost) + + (isRunningCount * CONSTANTS.ScriptIsRunningRamCost) + (numOperators * CONSTANTS.ScriptOperatorRamCost) + (purchaseHacknetCount * CONSTANTS.ScriptPurchaseHacknetRamCost) + (hacknetnodesArrayCount * CONSTANTS.ScriptHacknetNodesRamCost) + From f7018f082c7dc4d4f9ef3323d781b2667a05f6ec Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 12:59:30 -0500 Subject: [PATCH 09/16] Added killall command to terminal --- src/Constants.js | 1 + src/NetscriptEvaluator.js | 4 ++++ src/Terminal.js | 9 ++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Constants.js b/src/Constants.js index 8d713fbe4..b4bbc6f2d 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -162,6 +162,7 @@ CONSTANTS = { "hostname Displays the hostname of the machine
" + "ifconfig Displays the IP address of the machine
" + "kill [script] Stops a script that is running on the current machine
" + + "killall Stops all running scripts on the current machine
" + "ls Displays all programs and scripts on the machine
" + "mem [script] Displays the amount of RAM the script requires to run
" + "nano [script] Text editor - Open up and edit a script
" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 2100db5cc..70085c306 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -256,6 +256,10 @@ function evaluate(exp, workerScript) { }).catch(function(e) { reject(e); }); + } else if (exp.func.value == "kill") { + + } else if (exp.func.value == "killall") { + } else if (exp.func.value == "scp") { if (exp.args.length != 2) { return reject(makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments")); diff --git a/src/Terminal.js b/src/Terminal.js index 5a35e0188..a13953b1b 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -236,7 +236,7 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) { //Autocomplete the command if (index == -1) { return ["alias", "analyze", "cat", "clear", "cls", "connect", "free", - "hack", "help", "home", "hostname", "ifconfig", "kill", + "hack", "help", "home", "hostname", "ifconfig", "kill", "killall", "ls", "mem", "nano", "ps", "rm", "run", "scan", "scan-analyze", "scp", "sudov", "tail", "top"]; } @@ -715,6 +715,13 @@ var Terminal = { } post("No such script is running. Nothing to kill"); break; + case "killall": + var s = Player.getCurrentServer(); + for (var i = s.runningScripts.length; i >= 0; --i) { + killWorkerScript(s.runningScripts[i], s.ip); + } + post("Killing all running scripts. May take up to a few minutes for the scripts to die..."); + break; case "ls": Terminal.executeListCommand(commandArray); break; From d3fa9f8c6eef99c9401c4f3f2bc3d318f7188680 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 5 Jun 2017 20:34:00 -0500 Subject: [PATCH 10/16] Slight rebalancing. Added kill() and killall() commands --- src/Constants.js | 19 +++++++++++-- src/NetscriptEvaluator.js | 58 +++++++++++++++++++++++++++++++++++++-- src/Script.js | 2 +- src/Terminal.js | 11 +++++--- src/engine.js | 2 +- 5 files changed, 81 insertions(+), 11 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index b4bbc6f2d..637bf5e5a 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -40,7 +40,7 @@ CONSTANTS = { ScriptWhileRamCost: 0.2, ScriptForRamCost: 0.2, ScriptIfRamCost: 0.1, - ScriptHackRamCost: 0.15, + ScriptHackRamCost: 0.1, ScriptGrowRamCost: 0.15, ScriptWeakenRamCost: 0.15, ScriptNukeRamCost: 0.05, @@ -53,7 +53,7 @@ CONSTANTS = { ScriptExecRamCost: 1.1, ScriptScpRamCost: 0.5, ScriptHasRootAccessRamCost: 0.05, - ScriptGetHostnameRamCost: 0.1, + ScriptGetHostnameRamCost: 0.05, ScriptGetHackingLevelRamCost: 0.05, ScriptGetServerMoneyRamCost: 0.1, ScriptGetServerSecurityRamCost: 0.1, @@ -335,6 +335,18 @@ CONSTANTS = { "second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. Returns " + "true if the script is successfully started, and false otherwise. Does NOT work while offline
" + "Example: exec('generic-hack.script', 'foodnstuff');
The example above will try to launch the script 'generic-hack.script' on the 'foodnstuff' server.

" + + "kill(script, [hostname/ip])
Kills a script on a server. The first argument must be a string with the name of the script. The name is case-sensitive. " + + "The second argument must be a string with the hostname or IP of the target server. The function will try to kill the specified script on the target server. " + + "The second argument is optional. If it is omitted, then the function will try to kill the specified script on the current server (the server running " + + "the script that calls this function). If the script is found on the specified server and is running, then it will be killed and this function " + + "will return true. Otherwise, this function will return false.
" + + "Example: kill('foo.script', 'foodnstuff');
" + + "Example: kill('foo.script');
" + + "The first example above will look for a script called 'foo.script' on the 'foodnstuff' server. If the script exists and is running, then it will " + + "be killed and the function will return true. Otherwise false will be returned. The second example above will do the same thing, except on the " + + "current server (the server running the script that calls the kill() function).

" + + "killall(hostname/ip)
Kills all running scripts on the specified server. This function takes a single argument which " + + "must be a string containing the hostname or IP of the target server. This function will always return true.

" + "scp(script, hostname/ip)
Copies a script to another server. The first argument is a string with the filename of the script " + "to be copied. The second argument is a string with the hostname or IP of the destination server. Returns true if the script is successfully " + "copied over and false otherwise.
Example: scp('hack-template.script', 'foodnstuff');

" + @@ -520,6 +532,7 @@ CONSTANTS = { "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + "now each one should only take 750 milliseconds).
" + "-Percentage money stolen when hacking lowered to compensate for faster script speeds
" + + "-Slightly lowered the runtime of weaken()
" + "-Lowered base growth rate by 25%(which affects amount of money gained from grow())
" + "-Hacking experience granted by grow() halved" + "-Weaken() is now 10% faster, but only grants 3 base hacking exp upon completion instead of 5
" + @@ -528,6 +541,8 @@ CONSTANTS = { "-Added getServerRequiredHackingLevel(server) Netscript command.
" + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + "specified server
" + + "-Added killall Terminal command. Kills all running scripts on the current machine
" + + "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
" + "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 70085c306..9a5eace83 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -257,9 +257,61 @@ function evaluate(exp, workerScript) { reject(e); }); } else if (exp.func.value == "kill") { + if (exp.args.length != 1 && exp.args.length != 2) { + return reject(makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Takes 1 or 2 arguments")); + } + var argPromises = exp.args.map(function(arg) { + return evaluate(arg, workerScript); + }); + var filename = ""; + Promise.all(argPromises).then(function(args) { + if (env.stopFlag) {return reject(workerScript);} + filename = args[0]; + if (exp.args.length == 2) { + return Promise.resolve(workerScript.serverIp); + } else { + return evaluate(exp.args[1], workerScript); + } + }).then(function(ip) { + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("kill() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into kill() command")); + } + + for (var i = 0; i < server.runningScripts.length; ++i) { + if (filename == server.runningScripts[i].filename) { + killWorkerScript(filename, server.ip); + workerScript.scriptRef.log("Killing " + scriptName + ". May take up to a few minutes for the scripts to die..."); + return resolve(true); + } + } + workerScript.scriptRef.log("kill() failed. No such script "+ scriptName + " on " + server.hostname); + return resolve(false); + }).catch(function(e) { + reject(e); + }); } else if (exp.func.value == "killall") { - + if (exp.args.length != 1) { + return reject(makeRuntimeRejectMsg(workerScript, "killall() call has incorrect number of arguments. Takes 1 argument")); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + if (env.stopFlag) {return reject(workerScript);} + var server = getServer(ip); + if (server == null) { + workerScript.scriptRef.log("killall() failed. Invalid IP or hostname passed in: " + ip); + return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into killall() command")); + } + workerScript.scriptRef.log("killall(): Killing all scrips on " + server.hostname); + for (var i = server.runningScripts.length; i >= 0; --i) { + killWorkerScript(server.runningScripts[i], server.ip); + } + resolve(true); + }, function(e) { + reject(e); + }); } else if (exp.func.value == "scp") { if (exp.args.length != 2) { return reject(makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments")); @@ -921,7 +973,7 @@ function scriptCalculatePercentMoneyHacked(server) { function scriptCalculateGrowTime(server) { var difficultyMult = server.requiredHackingSkill * server.hackDifficulty; var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50); - var growTime = skillFactor * Player.hacking_speed_mult * 17; //This is in seconds + var growTime = skillFactor * Player.hacking_speed_mult * 16; //This is in seconds return growTime * 1000; } @@ -929,6 +981,6 @@ function scriptCalculateGrowTime(server) { function scriptCalculateWeakenTime(server) { var difficultyMult = server.requiredHackingSkill * server.hackDifficulty; var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50); - var weakenTime = skillFactor * Player.hacking_speed_mult * 45; //This is in seconds + var weakenTime = skillFactor * Player.hacking_speed_mult * 40; //This is in seconds return weakenTime * 1000; } \ No newline at end of file diff --git a/src/Script.js b/src/Script.js index 84c785732..e25905e99 100644 --- a/src/Script.js +++ b/src/Script.js @@ -204,7 +204,7 @@ Script.prototype.reset = function() { //Updates how much RAM the script uses when it is running. Script.prototype.updateRamUsage = function() { - var baseRam = 1.5; + var baseRam = 1.4; var codeCopy = this.code.repeat(1); codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace diff --git a/src/Terminal.js b/src/Terminal.js index a13953b1b..143a9796f 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -412,11 +412,14 @@ var Terminal = { //Replace all extra whitespace in command with a single space command = command.replace(/\s\s+/g, ' '); - Terminal.commandHistory.push(command); - if (Terminal.commandHistory.length > 50) { - Terminal.commandHistory.splice(0, 1); + + if (Terminal.commandHistory[Terminal.commandHistory.length-1] != command) { + Terminal.commandHistory.push(command); + if (Terminal.commandHistory.length > 50) { + Terminal.commandHistory.splice(0, 1); + } + Terminal.commandHistoryIndex = Terminal.commandHistory.length; } - Terminal.commandHistoryIndex = Terminal.commandHistory.length; //Process any aliases command = substituteAliases(command); diff --git a/src/engine.js b/src/engine.js index 7fe9248a7..bdf07f116 100644 --- a/src/engine.js +++ b/src/engine.js @@ -1042,7 +1042,7 @@ var Engine = { return false; }); relaySmtpALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.RelaySMTPProgram. CONSTANTS.MillisecondsPer2Hours, 250); + Player.startCreateProgramWork(Programs.RelaySMTPProgram, CONSTANTS.MillisecondsPer2Hours, 250); return false; }); httpWormALink.addEventListener("click", function() { From 1a7a247b4d375925e91b96245bd490bbeb99e767 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 16:22:57 -0500 Subject: [PATCH 11/16] Re-designed Active Scripts tab. Re-designed growth mechanic to depend on server security. Server growth no longer occurss manually. Bug fixes --- css/menupages.css | 114 +++++++++++++++++++++++++++++---- index.html | 6 +- src/Constants.js | 40 ++++++++---- src/Faction.js | 2 +- src/NetscriptEvaluator.js | 1 + src/NetscriptFunctions.js | 2 + src/NetscriptWorker.js | 8 +-- src/Server.js | 41 +++--------- src/ServerPurchases.js | 1 + src/Terminal.js | 4 +- src/engine.js | 107 +------------------------------ utils/PurchaseRamForHomeBox.js | 2 +- 12 files changed, 154 insertions(+), 174 deletions(-) diff --git a/css/menupages.css b/css/menupages.css index 3480cb238..2284324b0 100644 --- a/css/menupages.css +++ b/css/menupages.css @@ -144,27 +144,113 @@ background-color: #555; padding: 4px; } -.active-scripts-list > li { - margin: 6px; - width: 70%; +.active-scripts-server-header { + background-color: #444; + font-size: 20px; + color: white; + margin: 6px 6px 0px 6px; + padding: 6px; + cursor: pointer; + width: 60%; + text-align: left; + border: none; + outline: none; } -.active-scripts-list>li h2{ +.active-scripts-server-header.active, +.active-scripts-server-header:hover { + background-color: #555; +} + +.active-scripts-server-header.active:hover { + background-color: #666; +} + +.active-scripts-server-header:after { + content: '\02795'; /* "plus" sign (+) */ + font-size: 13px; + color: white; + float: right; + margin-left: 5px; +} + +.active-scripts-server-header.active:after { + content: "\2796"; /* "minus" sign (-) */ + font-size: 13px; + color: white; + float: right; + margin-left: 5px; +} + +.active-scripts-server-panel { + margin: 0px 6px 6px 6px; + padding: 6px; + width: 55%; + margin-left: 5%; + display: none; +} + +.active-scripts-server-panel div, +.active-scripts-server-panel ul, +.active-scripts-server-panel ul > li { + background-color: #555; +} + +.active-scripts-script-header { + background-color: #555; color: #66ff33; - padding-top: 10px; - padding-left: 10px; - background-color: #333; - text-decoration: none; + padding: 4px; + padding-left: 10px; + cursor: pointer; + width: auto; + text-align: left; + border: none; + outline: none; } -.active-scripts-list>li p { - color: #66ff33; - padding: 10px; - padding-left: 40px; - background-color: #333; - text-decoration: none; +.active-scripts-script-header:hover, +.active-scripts-script-header.active:hover { + background-color: #666; } +.active-scripts-script-header.active { + background-color: #555; +} + +.active-scripts-script-header:after { + content: '\02795'; /* "plus" sign (+) */ + font-size: 13px; + color: #66ff33; + float: right; + margin-left: 5px; +} + +.active-scripts-script-header.active:after { + content: "\2796"; /* "minus" sign (-) */ + font-size: 13px; + color: #66ff33; + float: right; + margin-left: 5px; +} + +.active-scripts-script-panel { + padding: 0 18px; + background-color: #555; + width: auto; + display: none; +} + +.active-scripts-script-panel p, +.active-scripts-script-panel h2, +.active-scripts-script-panel ul, +.active-scripts-script-panel li { + background-color: #555; + width: auto; + color: white; + margin-left: 5%; +} + + /* Hacknet Nodes */ #hacknet-nodes-container { position: fixed; diff --git a/index.html b/index.html index f9861ac98..5067e3572 100644 --- a/index.html +++ b/index.html @@ -59,6 +59,7 @@ + @@ -164,8 +165,9 @@
-

This page displays a list of all scripts that are currently running across every machine. It also gives - information about their production

+

This page displays a list of all of your scripts that are currently running across every machine. It also + provides information about each script's production. The scripts are categorized by the hostname of the servers on which + they are running.

Total online production rate:

diff --git a/src/Constants.js b/src/Constants.js index 637bf5e5a..065c107fc 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -11,14 +11,14 @@ CONSTANTS = { /* Base costs */ BaseCostFor1GBOfRamHome: 40000, - BaseCostFor1GBOfRamServer: 35000, //1 GB of RAM + BaseCostFor1GBOfRamServer: 50000, //1 GB of RAM BaseCostFor1GBOfRamHacknetNode: 30000, BaseCostForHacknetNode: 1000, BaseCostForHacknetNodeCore: 500000, /* Hacknet Node constants */ - HacknetNodeMoneyGainPerLevel: 1.6, + HacknetNodeMoneyGainPerLevel: 1.55, HacknetNodePurchaseNextMult: 1.42, //Multiplier when purchasing an additional hacknet node HacknetNodeUpgradeLevelMult: 1.045, //Multiplier for cost when upgrading level HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM @@ -68,9 +68,10 @@ CONSTANTS = { ScriptHNUpgCoreRamCost: 0.8, //Server constants - ServerGrowthRate: 1.0015, //Growth rate - ServerFortifyAmount: 0.002, //Amount by which server's security increases when its hacked - ServerWeakenAmount: 0.1, //Amount by which server's security decreases when weakened + ServerBaseGrowthRate: 1.02, //Unadjusted Growth rate + ServerMaxGrowthRate: 1.003, //Maximum possible growth rate (max rate accounting for server security) + ServerFortifyAmount: 0.002, //Amount by which server's security increases when its hacked/grown + ServerWeakenAmount: 0.1, //Amount by which server's security decreases when weakened //Augmentation Constants AugmentationCostMultiplier: 4.5, //Used for balancing costs without having to readjust every Augmentation cost @@ -220,8 +221,8 @@ CONSTANTS = { "When you successfully hack a server. You steal a certain percentage of that server's total money. This " + "percentage is determined by the server's security and your hacking skill level. The amount of money " + "on a server is not limitless. So, if you constantly hack a server and deplete its money, then you will " + - "encounter diminishing returns in your hacking (since you are only hacking a certain percentage). A server " + - "will regain money at a slow rate over time.

" + + "encounter diminishing returns in your hacking (since you are only hacking a certain percentage). You can " + + "increase the amount of money on a server using a script and the grow() function in Netscript.

" + "

Server Security


" + "Each server has a security level, which is denoted by a number between 1 and 100. A higher number means " + "the server has stronger security. As mentioned above, a server's security level is an important factor " + @@ -229,7 +230,8 @@ CONSTANTS = { "only gives an estimate (with 5% uncertainty). You can also check a server's security in a script, using the " + "getServerSecurityLevel(server) function in Netscript. See the Netscript documentation for more details. " + "This function will give you an exact value for a server's security.

" + - "Whenever a server is hacked manually or through a script, its security level increases by a small amount. This will " + + "Whenever a server is hacked manually or through a script, its security level increases by a small amount. Calling " + + "the grow() command in a script will also increase security level of the target server. These actions will " + "make it harder for you to hack the server, and decrease the amount of money you can steal. You can lower a " + "server's security level in a script using the weaken(server) function in Netscript. See the Netscript " + "documentation for more details", @@ -305,7 +307,8 @@ CONSTANTS = { "hack(hostname/ip)
Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " + "either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " + " A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " + - "For example, you can create a script that hacks the 'foodnstuff' server and run it on your home computer.
" + + "For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. Calling hack() on " + + "a server will raise that server's security level by " + this.ServerFortifyAmount + ".
" + "Examples: hack('foodnstuff'); or hack('148.192.0.12');

" + "sleep(n)
Suspends the script for n milliseconds.
Example: sleep(5000);

" + "grow(hostname/ip)
Use your hacking skills to increase the amount of money available on a server. The argument passed in " + @@ -314,10 +317,12 @@ CONSTANTS = { "is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates.

" + "Like hack(), grow() can be called on any server, regardless of where the script is running. " + "The grow() command requires root access to the target server, but there is no required hacking level to run the command. " + - "It grants 1 hacking exp when it completes. Works offline at a slower rate.
Example: grow('foodnstuff');

" + + "It grants 0.5 hacking exp when it completes. It also raises the security level of the target server by " + (2 * this.ServerFortifyAmount) + ". " + + "Works offline at a slower rate.
Example: grow('foodnstuff');

" + "weaken(hostname/ip)
Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " + "in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " + - "hacking level and the target server's security level.

Like hack() and grow(), weaken() can be called on " + + "hacking level and the target server's security level. This function lowers the security level of the target server by " + + this.ServerWeakenAmount + ".

Like hack() and grow(), weaken() can be called on " + "any server, regardless of where the script is running. This command requires root access to the target server, but " + "there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Works offline at a slower rate
Example: weaken('foodnstuff');

" + "print(x)
Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command )

" + @@ -532,17 +537,24 @@ CONSTANTS = { "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + "now each one should only take 750 milliseconds).
" + "-Percentage money stolen when hacking lowered to compensate for faster script speeds
" + - "-Slightly lowered the runtime of weaken()
" + - "-Lowered base growth rate by 25%(which affects amount of money gained from grow())
" + "-Hacking experience granted by grow() halved" + - "-Weaken() is now 10% faster, but only grants 3 base hacking exp upon completion instead of 5
" + + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5
" + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + "and weaken() all cost slightly less RAM than before
" + "-Added getServerRequiredHackingLevel(server) Netscript command.
" + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + "specified server
" + + "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
" + "-Added killall Terminal command. Kills all running scripts on the current machine
" + "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
" + + "-Re-designed 'Active Scripts' tab
" + + "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
" + + "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
" + + "-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " + + "will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " + + "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + + "it will have approximately the same growth rate as before.
" + + "-Server growth no longer happens naturally
" + "v0.19.7
" + "-Added changelog to Options menu
" + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

" + diff --git a/src/Faction.js b/src/Faction.js index eb8f775b0..2dbe9f982 100644 --- a/src/Faction.js +++ b/src/Faction.js @@ -814,7 +814,7 @@ displayFactionAugmentations = function(factionName) { pElem.innerHTML = "UNLOCKED - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2); } else { aElem.setAttribute("class", "a-link-button-inactive"); - pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 4) + " faction reputation) - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2); + pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2); pElem.style.color = "red"; } aElem.style.display = "inline"; diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 9a5eace83..3865252c5 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -754,6 +754,7 @@ function evaluateHacknetNode(exp, workerScript) { reject(makeRuntimeRejectMsg(workerScript, "Invalid argument passed into upgradeLevel()")); return; } + arg = Math.round(arg); var res = nodeObj.purchaseLevelUpgrade(arg); if (res) { workerScript.scriptRef.log("Upgraded " + nodeObj.name + " " + arg + " times to level " + nodeObj.level); diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 79cd8585f..3add329cc 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -151,6 +151,7 @@ function netscriptGrow(exp, workerScript) { + formatNumber(growthPercentage*100 - 100, 6) + "%"); var expGain = 0.5 * Player.hacking_exp_mult; workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); return Promise.resolve(growthPercentage); }); @@ -197,6 +198,7 @@ function netscriptWeaken(exp, workerScript) { workerScript.scriptRef.log("Gained 3 hacking experience"); var expGain = 3 * Player.hacking_exp_mult; workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); return Promise.resolve(CONSTANTS.ServerWeakenAmount); }); diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js index 601442d07..fc0c9aeb0 100644 --- a/src/NetscriptWorker.js +++ b/src/NetscriptWorker.js @@ -133,12 +133,12 @@ function runScriptsLoop() { //Free RAM AllServers[ip].ramUsed -= workerScripts[i].ramUsage; + + //Delete script from Active Scripts + deleteActiveScriptsItem(workerScripts[i]); //Delete script from workerScripts workerScripts.splice(i, 1); - - //Delete script from Active Scripts - Engine.deleteActiveScriptsItem(i); } } @@ -171,7 +171,7 @@ function addWorkerScript(script, server) { s.ramUsage = script.ramUsage; //Add the WorkerScript to the Active Scripts list - Engine.addActiveScriptsItem(s); + addActiveScriptsItem(s); //Add the WorkerScript workerScripts.push(s); diff --git a/src/Server.js b/src/Server.js index a2891e299..3038a6718 100644 --- a/src/Server.js +++ b/src/Server.js @@ -675,52 +675,29 @@ initForeignServers = function() { } } - -//Server growth -processServerGrowth = function(numCycles) { - //Server growth processed once every 450 game cycles - var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0); - - for (var ip in AllServers) { - if (AllServers.hasOwnProperty(ip)) { - var server = AllServers[ip]; - - //Get the number of server growth cycles that will be applied based on the - //server's serverGrowth property - var serverGrowthPercentage = server.serverGrowth / 100; - var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage; - - //Apply serverGrowth for the calculated number of growth cycles - var serverGrowth = Math.pow(CONSTANTS.ServerGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult) ; - if (serverGrowth < 1) { - console.log("WARN: serverGrowth calculated to be less than 1"); - serverGrowth = 1; - } - //console.log("serverGrowth ratio: " + serverGrowth); - server.moneyAvailable *= serverGrowth; - } - } - console.log("Server growth processed for " + numServerGrowthCycles + " cycles"); -} - //Applied server growth for a single server. Returns the percentage growth processSingleServerGrowth = function(server, numCycles) { //Server growth processed once every 450 game cycles var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0); - //Get the number of server growth cycles that will be applied based on the - //server's serverGrowth property + //Get adjusted growth rate, which accounts for server security + var growthRate = CONSTANTS.ServerBaseGrowthRate; + var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty; + if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;} + console.log("Adjusted growth rate: " + adjGrowthRate); + + //Calculate adjusted server growth rate based on parameters var serverGrowthPercentage = server.serverGrowth / 100; var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage; //Apply serverGrowth for the calculated number of growth cycles - var serverGrowth = Math.pow(CONSTANTS.ServerGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult) ; + var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult) ; if (serverGrowth < 1) { console.log("WARN: serverGrowth calculated to be less than 1"); serverGrowth = 1; } server.moneyAvailable *= serverGrowth; - + server.fortify(2 * CONSTANTS.ServerFortifyAmount); return serverGrowth; } diff --git a/src/ServerPurchases.js b/src/ServerPurchases.js index 215fba9a1..a04785585 100644 --- a/src/ServerPurchases.js +++ b/src/ServerPurchases.js @@ -11,6 +11,7 @@ purchaseServer = function(ram, cost) { var newServ = new Server(); var hostname = document.getElementById("purchase-server-box-input").value; + hostname = hostname.replace(/\s\s+/g, ''); if (hostname == "") { dialogBoxCreate("You must enter a hostname for your new server!"); return; diff --git a/src/Terminal.js b/src/Terminal.js index 143a9796f..70cde40ae 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -412,14 +412,14 @@ var Terminal = { //Replace all extra whitespace in command with a single space command = command.replace(/\s\s+/g, ' '); - + //Terminal history if (Terminal.commandHistory[Terminal.commandHistory.length-1] != command) { Terminal.commandHistory.push(command); if (Terminal.commandHistory.length > 50) { Terminal.commandHistory.splice(0, 1); } - Terminal.commandHistoryIndex = Terminal.commandHistory.length; } + Terminal.commandHistoryIndex = Terminal.commandHistory.length; //Process any aliases command = substituteAliases(command); diff --git a/src/engine.js b/src/engine.js index bdf07f116..26a77f567 100644 --- a/src/engine.js +++ b/src/engine.js @@ -116,6 +116,7 @@ var Engine = { loadActiveScriptsContent: function() { Engine.hideAllContent(); Engine.Display.activeScriptsContent.style.visibility = "visible"; + setActiveScriptsClickHandlers(); Engine.currentPage = Engine.Page.ActiveScripts; }, @@ -334,100 +335,6 @@ var Engine = { } }, - /* Functions used to update information on the Active Scripts page */ - ActiveScriptsList: null, - - //Creates and adds the
  • object for a given workerScript - addActiveScriptsItem: function(workerscript) { - var item = document.createElement("li"); - - Engine.createActiveScriptsText(workerscript, item); - - //Add the li element onto the list - if (Engine.ActiveScriptsList == null) { - Engine.ActiveScriptsList = document.getElementById("active-scripts-list"); - } - Engine.ActiveScriptsList.appendChild(item); - }, - - deleteActiveScriptsItem: function(i) { - var list = Engine.ActiveScriptsList.querySelectorAll('#active-scripts-list li'); - if (i >= list.length) { - throw new Error("Trying to delete an out-of-range Active Scripts item"); - } - - var li = list[i]; - li.parentNode.removeChild(li); - }, - - //Update the ActiveScriptsItems array - updateActiveScriptsItems: function() { - var total = 0; - for (var i = 0; i < workerScripts.length; ++i) { - total += Engine.updateActiveScriptsItemContent(i, workerScripts[i]); - } - document.getElementById("active-scripts-total-prod").innerHTML = - "Total online production rate: $" + formatNumber(total, 2) + " / second"; - }, - - //Updates the content of the given item in the Active Scripts list - updateActiveScriptsItemContent: function(i, workerscript) { - var list = Engine.ActiveScriptsList.getElementsByTagName("li"); - if (i >= list.length) { - throw new Error("Trying to update an out-of-range Active Scripts Item"); - } - - var item = list[i]; - - //Clear the item - while (item.firstChild) { - item.removeChild(item.firstChild); - } - - //Add the updated text back. Returns the total online production rate - return Engine.createActiveScriptsText(workerscript, item); - }, - - createActiveScriptsText: function(workerscript, item) { - //Script name - var scriptName = document.createElement("h2"); - scriptName.appendChild(document.createTextNode(workerscript.name)); - item.appendChild(scriptName); - - var itemText = document.createElement("p"); - - //Server ip/hostname - var hostname = workerscript.getServer().hostname; - var serverIpHostname = "Server: " + hostname + "(" + workerscript.serverIp + ")"; - - //Online - var onlineTotalMoneyMade = "Total online production: $" + formatNumber(workerscript.scriptRef.onlineMoneyMade, 2); - var onlineTotalExpEarned = (Array(26).join(" ") + formatNumber(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " "); - - var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime; - var onlineMpsText = "Online production rate: $" + formatNumber(onlineMps, 2) + "/second"; - var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime; - var onlineEpsText = (Array(25).join(" ") + formatNumber(onlineEps, 4) + " hacking exp/second").replace( / /g, " "); - - //Offline - var offlineTotalMoneyMade = "Total offline production: $" + formatNumber(workerscript.scriptRef.offlineMoneyMade, 2); - var offlineTotalExpEarned = (Array(27).join(" ") + formatNumber(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " "); - - var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime; - var offlineMpsText = "Offline production rate: $" + formatNumber(offlineMps, 2) + "/second"; - var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime; - var offlineEpsText = (Array(26).join(" ") + formatNumber(offlineEps, 4) + " hacking exp/second").replace( / /g, " "); - - itemText.innerHTML = serverIpHostname + "
    " + onlineTotalMoneyMade + "
    " + onlineTotalExpEarned + "
    " + - onlineMpsText + "
    " + onlineEpsText + "
    " + offlineTotalMoneyMade + "
    " + offlineTotalExpEarned + "
    " + - offlineMpsText + "
    " + offlineEpsText + "
    "; - - item.appendChild(itemText); - - //Return total online production rate - return onlineMps; - }, - displayFactionsInfo: function() { var factionsList = document.getElementById("factions-list"); @@ -599,8 +506,7 @@ var Engine = { updateSkillLevelsCounter: 10, //Only update skill levels every 2 seconds. Might improve performance updateDisplays: 3, //Update displays such as Active Scripts display and character display createProgramNotifications: 10, //Checks whether any programs can be created and notifies - serverGrowth: 450, //Process server growth every minute and a half - checkFactionInvitations: 250, //Check whether you qualify for any faction invitations every 5 minutes + checkFactionInvitations: 250, //Check whether you qualify for any faction invitations every 5 minutes passiveFactionGrowth: 600, messages: 300, }, @@ -629,7 +535,7 @@ var Engine = { if (Engine.Counters.updateDisplays <= 0) { Engine.displayCharacterOverviewInfo(); if (Engine.currentPage == Engine.Page.ActiveScripts) { - Engine.updateActiveScriptsItems(); + updateActiveScriptsItems(); } else if (Engine.currentPage == Engine.Page.CharacterInfo) { Engine.displayCharacterInfo(); } else if (Engine.currentPage == Engine.Page.HacknetNodes) { @@ -654,12 +560,6 @@ var Engine = { Engine.Counters.createProgramNotifications = 10; } - if (Engine.Counters.serverGrowth <= 0) { - var numCycles = Math.floor((450 - Engine.Counters.serverGrowth)); - processServerGrowth(numCycles); - Engine.Counters.serverGrowth = 450; - } - if (Engine.Counters.checkFactionInvitations <= 0) { var invitedFactions = Player.checkForFactionInvitations(); if (invitedFactions.length > 0) { @@ -747,7 +647,6 @@ var Engine = { var numCyclesOffline = Math.floor((Engine._lastUpdate - lastUpdate) / Engine._idleSpeed); /* Process offline progress */ - processServerGrowth(numCyclesOffline); //Should be done before offline production for scripts var offlineProductionFromScripts = loadAllRunningScripts(); //This also takes care of offline production for those scripts if (Player.isWorking) { console.log("work() called in load() for " + numCyclesOffline * Engine._idleSpeed + " milliseconds"); diff --git a/utils/PurchaseRamForHomeBox.js b/utils/PurchaseRamForHomeBox.js index caed6e703..5f0bbc9b8 100644 --- a/utils/PurchaseRamForHomeBox.js +++ b/utils/PurchaseRamForHomeBox.js @@ -36,7 +36,7 @@ purchaseRamForHomeBoxCreate = function() { //Calculate cost //Have cost increase by some percentage each time RAM has been upgraded var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome; - var mult = Math.pow(1.36, numUpgrades); + var mult = Math.pow(1.40, numUpgrades); cost = cost * mult; purchaseRamForHomeBoxSetText("Would you like to purchase additional RAM for your home computer?

    " + From c331bd7add1947b6c329ce70bb05911e8098da57 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 19:04:18 -0500 Subject: [PATCH 12/16] Edit scripts that are running. Implement maximum money on server --- src/Constants.js | 14 ++++++++++---- src/NetscriptEvaluator.js | 2 +- src/Player.js | 2 +- src/SaveObject.js | 14 ++++++++++++++ src/Server.js | 11 ++++++++--- src/Terminal.js | 7 ------- src/engine.js | 3 ++- 7 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index 065c107fc..7fb1f8a13 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -307,8 +307,9 @@ CONSTANTS = { "hack(hostname/ip)
    Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " + "either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " + " A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " + - "For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. Calling hack() on " + - "a server will raise that server's security level by " + this.ServerFortifyAmount + ".
    " + + "For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. A successful hack() on " + + "a server will raise that server's security level by " + this.ServerFortifyAmount + ". Returns true if the hack is successful and " + + "false otherwise.
    " + "Examples: hack('foodnstuff'); or hack('148.192.0.12');

    " + "sleep(n)
    Suspends the script for n milliseconds.
    Example: sleep(5000);

    " + "grow(hostname/ip)
    Use your hacking skills to increase the amount of money available on a server. The argument passed in " + @@ -318,13 +319,15 @@ CONSTANTS = { "Like hack(), grow() can be called on any server, regardless of where the script is running. " + "The grow() command requires root access to the target server, but there is no required hacking level to run the command. " + "It grants 0.5 hacking exp when it completes. It also raises the security level of the target server by " + (2 * this.ServerFortifyAmount) + ". " + + "Returns the number by which the money on the server was multiplied for the growth. " + "Works offline at a slower rate.
    Example: grow('foodnstuff');

    " + "weaken(hostname/ip)
    Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " + "in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " + "hacking level and the target server's security level. This function lowers the security level of the target server by " + this.ServerWeakenAmount + ".

    Like hack() and grow(), weaken() can be called on " + "any server, regardless of where the script is running. This command requires root access to the target server, but " + - "there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Works offline at a slower rate
    Example: weaken('foodnstuff');

    " + + "there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Returns " + + this.ServerWeakenAmount + ". Works offline at a slower rate
    Example: weaken('foodnstuff');

    " + "print(x)
    Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command )

    " + "nuke(hostname/ip)
    Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline
    Example: nuke('foodnstuff');

    " + "brutessh(hostname/ip)
    Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline
    Example: brutessh('foodnstuff');

    " + @@ -537,7 +540,7 @@ CONSTANTS = { "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + "now each one should only take 750 milliseconds).
    " + "-Percentage money stolen when hacking lowered to compensate for faster script speeds
    " + - "-Hacking experience granted by grow() halved" + + "-Hacking experience granted by grow() halved
    " + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5
    " + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + "and weaken() all cost slightly less RAM than before
    " + @@ -555,6 +558,9 @@ CONSTANTS = { "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + "it will have approximately the same growth rate as before.
    " + "-Server growth no longer happens naturally
    " + + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money
    " + + "-Hacking now grants 10% less hacking experience
    " + + "-You can now edit scripts that are running
    " + "v0.19.7
    " + "-Added changelog to Options menu
    " + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

    " + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 3865252c5..249ffd88c 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -957,7 +957,7 @@ function scriptCalculateHackingTime(server) { //The same as Player's calculateExpGain() function but takes in the server as an argument function scriptCalculateExpGain(server) { - return (server.hackDifficulty * Player.hacking_exp_mult); + return (server.hackDifficulty * Player.hacking_exp_mult * 0.9); } //The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument diff --git a/src/Player.js b/src/Player.js index 070ec81d4..6b18126c9 100644 --- a/src/Player.js +++ b/src/Player.js @@ -254,7 +254,7 @@ PlayerObject.prototype.calculatePercentMoneyHacked = function() { //The formula is: // difficulty * requiredLevel * hacking_multiplier PlayerObject.prototype.calculateExpGain = function() { - return (this.getCurrentServer().hackDifficulty * this.hacking_exp_mult); + return (this.getCurrentServer().hackDifficulty * this.hacking_exp_mult * 0.9); } //Hack/Analyze a server. Return the amount of time the hack will take. This lets the Terminal object know how long to disable itself for diff --git a/src/SaveObject.js b/src/SaveObject.js index 998c4d809..585f82f6b 100644 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -12,6 +12,7 @@ function BitburnerSaveObject() { this.AugmentationsSave = ""; this.AliasesSave = ""; this.MessagesSave = ""; + this.VersionSave = ""; } BitburnerSaveObject.prototype.saveGame = function() { @@ -23,6 +24,7 @@ BitburnerSaveObject.prototype.saveGame = function() { this.AugmentationsSave = JSON.stringify(Augmentations); this.AliasesSave = JSON.stringify(Aliases); this.MessagesSave = JSON.stringify(Messages); + this.VersionSave = JSON.stringify(CONSTANTS.Version); var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this)))); window.localStorage.setItem("bitburnerSave", saveString); @@ -63,6 +65,18 @@ loadGame = function(saveObj) { } else { initMessages(); } + if (saveObj.hasOwnProperty("VersionSave")) { + try { + var ver = JSON.parse(saveObj.VersionSave, Reviver); + if (ver != CONSTANTS.Version) { + //TODO Create update pop up + } + } catch(e) { + Engine.version = CONSTANTS.Version; + } + } else { + Engine.version = CONSTANTS.Version; + } return true; } diff --git a/src/Server.js b/src/Server.js index 3038a6718..a072fa058 100644 --- a/src/Server.js +++ b/src/Server.js @@ -31,10 +31,9 @@ function Server() { //by a separate formula this.requiredHackingSkill = 1; - //Total money available on this server. How much of this you hack will be determined - //by a formula related to hacking skill. The money available on a server will steadily increase - //over time, and it will decrease when you hack it + //Total money available on this server this.moneyAvailable = 0; + this.moneyMax = 0; //Parameters used in formulas that dictate how moneyAvailable and requiredHackingSkill change. this.hackDifficulty = 1; //Affects hack success rate and how the requiredHackingSkill increases over time (1-100) @@ -79,6 +78,7 @@ Server.prototype.init = function(ip, hostname, organizationName, onlineStatus, i Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvailable, hackDifficulty, serverGrowth) { this.requiredHackingSkill = requiredHackingSkill; this.moneyAvailable = moneyAvailable; + this.moneyMax = 50 * moneyAvailable; this.hackDifficulty = hackDifficulty; this.serverGrowth = serverGrowth; } @@ -696,7 +696,12 @@ processSingleServerGrowth = function(server, numCycles) { console.log("WARN: serverGrowth calculated to be less than 1"); serverGrowth = 1; } + server.moneyAvailable *= serverGrowth; + if (server.moneyMax && server.moneyAvailable >= server.moneyMax) { + server.moneyAvailable = server.moneyMax; + return 1; + } server.fortify(2 * CONSTANTS.ServerFortifyAmount); return serverGrowth; } diff --git a/src/Terminal.js b/src/Terminal.js index 70cde40ae..e9367f6cd 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -757,13 +757,6 @@ var Terminal = { //Script name is the filename without the .script at the end var scriptname = filename.substr(0, filename.indexOf(".script")); - //Cannot edit scripts that are currently running - for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) { - if (filename == Player.getCurrentServer().runningScripts[i]) { - post("Cannot open/edit scripts that are currently running!"); return; - } - } - //Check if the script already exists for (var i = 0; i < Player.getCurrentServer().scripts.length; i++) { if (filename == Player.getCurrentServer().scripts[i].filename) { diff --git a/src/engine.js b/src/engine.js index 26a77f567..f96c399eb 100644 --- a/src/engine.js +++ b/src/engine.js @@ -1,4 +1,5 @@ var Engine = { + version: "", Debug: true, //Clickable objects @@ -698,7 +699,7 @@ var Engine = { initAugmentations(); //Start interactive tutorial - iTutorialStart(); + iTutorialStart(); } }, From 570bba2dd17cf2316b0b457fc3dae03eb2149031 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 19:28:20 -0500 Subject: [PATCH 13/16] Added new update text. Bugs with server max money. Updated to version 0.20.0 --- css/popupboxes.css | 5 ++-- src/Constants.js | 67 +++++++++++++++++++++++++++++++--------------- src/SaveObject.js | 15 ++++++++--- utils/DialogBox.js | 45 +++++++++++++++++++++++++++---- 4 files changed, 100 insertions(+), 32 deletions(-) diff --git a/css/popupboxes.css b/css/popupboxes.css index 97081d669..9a6ce8843 100644 --- a/css/popupboxes.css +++ b/css/popupboxes.css @@ -18,19 +18,20 @@ z-index: 2; width: 50%; height: auto; - top: 50%; + max-height: 40%; + top: 40%; left: 50%; margin: -10% 0 0 -25%; overflow: auto; background-color: black; background-color: rgba(0,0,0,0.4); + border: 5px solid #FFFFFF; } .dialog-box-content { z-index: 2; background-color: black; padding: 10px; - border: 5px solid #FFFFFF; } .dialog-box-close-button { diff --git a/src/Constants.js b/src/Constants.js index 7fb1f8a13..7b68ed8e4 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -1,5 +1,5 @@ CONSTANTS = { - Version: "0.19.7", + Version: "0.20.0", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then @@ -538,29 +538,29 @@ CONSTANTS = { "v0.20.0
    " + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + - "now each one should only take 750 milliseconds).
    " + - "-Percentage money stolen when hacking lowered to compensate for faster script speeds
    " + - "-Hacking experience granted by grow() halved
    " + - "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5
    " + + "now each one should only take 750 milliseconds).

    " + + "-Percentage money stolen when hacking lowered to compensate for faster script speeds

    " + + "-Hacking experience granted by grow() halved

    " + + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5

    " + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + - "and weaken() all cost slightly less RAM than before
    " + - "-Added getServerRequiredHackingLevel(server) Netscript command.
    " + + "and weaken() all cost slightly less RAM than before

    " + + "-Added getServerRequiredHackingLevel(server) Netscript command.

    " + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + - "specified server
    " + - "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
    " + - "-Added killall Terminal command. Kills all running scripts on the current machine
    " + - "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
    " + - "-Re-designed 'Active Scripts' tab
    " + - "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
    " + - "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
    " + + "specified server

    " + + "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server

    " + + "-Added killall Terminal command. Kills all running scripts on the current machine

    " + + "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation

    " + + "-Re-designed 'Active Scripts' tab

    " + + "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)

    " + + "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)

    " + "-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " + "will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " + "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + - "it will have approximately the same growth rate as before.
    " + - "-Server growth no longer happens naturally
    " + - "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money
    " + - "-Hacking now grants 10% less hacking experience
    " + - "-You can now edit scripts that are running
    " + + "it will have approximately the same growth rate as before.

    " + + "-Server growth no longer happens naturally

    " + + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + + "-Hacking now grants 10% less hacking experience

    " + + "-You can now edit scripts that are running



    " + "v0.19.7
    " + "-Added changelog to Options menu
    " + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

    " + @@ -644,7 +644,30 @@ CONSTANTS = { "-You can now see what an Augmentation does and its price even while its locked

    ", LatestUpdate: - "", - - + "v0.20.0
    " + + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + + "now each one should only take 750 milliseconds).
    " + + "-Percentage money stolen when hacking lowered to compensate for faster script speeds
    " + + "-Hacking experience granted by grow() halved
    " + + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5
    " + + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + + "and weaken() all cost slightly less RAM than before
    " + + "-Added getServerRequiredHackingLevel(server) Netscript command.
    " + + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + + "specified server
    " + + "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
    " + + "-Added killall Terminal command. Kills all running scripts on the current machine
    " + + "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
    " + + "-Re-designed 'Active Scripts' tab
    " + + "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
    " + + "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
    " + + "-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " + + "will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " + + "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + + "it will have approximately the same growth rate as before.
    " + + "-Server growth no longer happens naturally
    " + + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money
    " + + "-Hacking now grants 10% less hacking experience
    " + + "-You can now edit scripts that are running

    ", } \ No newline at end of file diff --git a/src/SaveObject.js b/src/SaveObject.js index 585f82f6b..032a10a4a 100644 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -67,15 +67,17 @@ loadGame = function(saveObj) { } if (saveObj.hasOwnProperty("VersionSave")) { try { + console.log("here"); var ver = JSON.parse(saveObj.VersionSave, Reviver); + console.log("version from save: " + ver); if (ver != CONSTANTS.Version) { - //TODO Create update pop up + createNewUpdateText(); } } catch(e) { - Engine.version = CONSTANTS.Version; + createNewUpdateText(); } } else { - Engine.version = CONSTANTS.Version; + createNewUpdateText(); } return true; @@ -88,6 +90,13 @@ BitburnerSaveObject.prototype.deleteGame = function() { Engine.createStatusText("Game deleted!"); } +createNewUpdateText = function() { + dialogBoxCreate("New update!
    " + + "Please report any bugs/issues through the github repository " + + "or the Bitburner subreddit (reddit.com/r/bitburner).

    " + + CONSTANTS.LatestUpdate); +} + BitburnerSaveObject.prototype.toJSON = function() { return Generic_toJSON("BitburnerSaveObject", this); diff --git a/utils/DialogBox.js b/utils/DialogBox.js index 9fa89cadc..50e9d72f7 100644 --- a/utils/DialogBox.js +++ b/utils/DialogBox.js @@ -1,32 +1,64 @@ /* Pop up Dialog Box */ +dialogBoxes = []; //Close dialog box when clicking outside +/* $(document).click(function(event) { if (dialogBoxOpened) { if (!$(event.target).closest('.dialog-box-container').length){ --dialogBoxCount; + dialogBoxes.splice(0, 1); $(".dialog-box-container").remove(); - if (dialogBoxCount == 0) { + + if (dialogBoxes.length == 0) { dialogBoxOpened = false; + } else { + dialogBoxes[0].style.display + + } + } + } +});*/ +$(document).click(function(event) { + if (dialogBoxOpened && dialogBoxes.length >= 1) { + if (!$(event.target).closest(dialogBoxes[0]).length){ + dialogBoxes[0].remove(); + dialogBoxes.splice(0, 1); + if (dialogBoxes.length == 0) { + dialogBoxOpened = false; + } else { + dialogBoxes[0].style.visibility = "visible"; } } } }); + //Dialog box close buttons +/* $(document).on('click', '.dialog-box-close-button', function( event ) { console.log("clicked close button"); if (dialogBoxOpened) { $(this).closest('.dialog-box-container').remove(); --dialogBoxCount; - if (dialogBoxCount == 0) { + if (dialogBoxes.length == 0) { dialogBoxOpened = false; } } }); +*/ +$(document).on('click', '.dialog-box-close-button', function( event ) { + if (dialogBoxOpened && dialogBoxes.length >= 1) { + dialogBoxes[0].remove(); + dialogBoxes.splice(0, 1); + if (dialogBoxes.length == 0) { + dialogBoxOpened = false; + } else { + dialogBoxes[0].style.visibility = "visible"; + } + } +}); var dialogBoxOpened = false; -var dialogBoxCount = 0; dialogBoxCreate = function(txt) { var container = document.createElement("div"); @@ -47,9 +79,12 @@ dialogBoxCreate = function(txt) { container.appendChild(content); document.body.appendChild(container); + if (dialogBoxes.length >= 1) { + container.style.visibility = "hidden"; + } + dialogBoxes.push(container); setTimeout(function() { dialogBoxOpened = true; - ++dialogBoxCount; - }, 500); + }, 400); } \ No newline at end of file From 47e57eb6457a14fdf0ccf7fcf4ab9827d47fda8b Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 19:37:38 -0500 Subject: [PATCH 14/16] Fixed bugs with Prestige --- src/Constants.js | 50 +++++++++++++++++++++++------------------------ src/Prestige.js | 9 ++------- src/SaveObject.js | 2 -- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/Constants.js b/src/Constants.js index 7b68ed8e4..bfbb273bb 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -308,7 +308,7 @@ CONSTANTS = { "either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " + " A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " + "For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. A successful hack() on " + - "a server will raise that server's security level by " + this.ServerFortifyAmount + ". Returns true if the hack is successful and " + + "a server will raise that server's security level by 0.002. Returns true if the hack is successful and " + "false otherwise.
    " + "Examples: hack('foodnstuff'); or hack('148.192.0.12');

    " + "sleep(n)
    Suspends the script for n milliseconds.
    Example: sleep(5000);

    " + @@ -318,16 +318,16 @@ CONSTANTS = { "is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates.

    " + "Like hack(), grow() can be called on any server, regardless of where the script is running. " + "The grow() command requires root access to the target server, but there is no required hacking level to run the command. " + - "It grants 0.5 hacking exp when it completes. It also raises the security level of the target server by " + (2 * this.ServerFortifyAmount) + ". " + + "It grants 0.5 hacking exp when it completes. It also raises the security level of the target server by 0.004. " + "Returns the number by which the money on the server was multiplied for the growth. " + "Works offline at a slower rate.
    Example: grow('foodnstuff');

    " + "weaken(hostname/ip)
    Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " + "in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " + "hacking level and the target server's security level. This function lowers the security level of the target server by " + - this.ServerWeakenAmount + ".

    Like hack() and grow(), weaken() can be called on " + + "0.1.

    Like hack() and grow(), weaken() can be called on " + "any server, regardless of where the script is running. This command requires root access to the target server, but " + "there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Returns " + - this.ServerWeakenAmount + ". Works offline at a slower rate
    Example: weaken('foodnstuff');

    " + + "0.1. Works offline at a slower rate
    Example: weaken('foodnstuff');

    " + "print(x)
    Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command )

    " + "nuke(hostname/ip)
    Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline
    Example: nuke('foodnstuff');

    " + "brutessh(hostname/ip)
    Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline
    Example: brutessh('foodnstuff');

    " + @@ -555,7 +555,7 @@ CONSTANTS = { "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)

    " + "-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " + "will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " + - "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + + "server's security level by 0.004. For reference, if a server has a security level of 10 " + "it will have approximately the same growth rate as before.

    " + "-Server growth no longer happens naturally

    " + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + @@ -644,30 +644,30 @@ CONSTANTS = { "-You can now see what an Augmentation does and its price even while its locked

    ", LatestUpdate: - "v0.20.0
    " + + "v0.20.0
    " + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + - "now each one should only take 750 milliseconds).
    " + - "-Percentage money stolen when hacking lowered to compensate for faster script speeds
    " + - "-Hacking experience granted by grow() halved
    " + - "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5
    " + + "now each one should only take 750 milliseconds).

    " + + "-Percentage money stolen when hacking lowered to compensate for faster script speeds

    " + + "-Hacking experience granted by grow() halved

    " + + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5

    " + "-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " + - "and weaken() all cost slightly less RAM than before
    " + - "-Added getServerRequiredHackingLevel(server) Netscript command.
    " + + "and weaken() all cost slightly less RAM than before

    " + + "-Added getServerRequiredHackingLevel(server) Netscript command.

    " + "-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " + - "specified server
    " + - "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
    " + - "-Added killall Terminal command. Kills all running scripts on the current machine
    " + - "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
    " + - "-Re-designed 'Active Scripts' tab
    " + - "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
    " + - "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
    " + + "specified server

    " + + "-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server

    " + + "-Added killall Terminal command. Kills all running scripts on the current machine

    " + + "-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation

    " + + "-Re-designed 'Active Scripts' tab

    " + + "-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)

    " + + "-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)

    " + "-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " + "will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " + - "server's security level by " + (2 * this.ServerFortifyAmount) + ". For reference, if a server has a security level of 10 " + - "it will have approximately the same growth rate as before.
    " + - "-Server growth no longer happens naturally
    " + - "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money
    " + - "-Hacking now grants 10% less hacking experience
    " + - "-You can now edit scripts that are running

    ", + "server's security level by 0.004. For reference, if a server has a security level of 10 " + + "it will have approximately the same growth rate as before.

    " + + "-Server growth no longer happens naturally

    " + + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + + "-Hacking now grants 10% less hacking experience

    " + + "-You can now edit scripts that are running
    ", } \ No newline at end of file diff --git a/src/Prestige.js b/src/Prestige.js index 7d642d241..0392fd640 100644 --- a/src/Prestige.js +++ b/src/Prestige.js @@ -109,8 +109,10 @@ function prestigeAugmentation() { //Delete all running scripts objects for (var i = 0; i < workerScripts.length; ++i) { + deleteActiveScriptsItem(workerScripts[i]); workerScripts[i].env.stopFlag = true; } + workerScripts.length = 0; var homeComp = Player.getHomeComputer(); //Delete all servers except home computer @@ -161,13 +163,6 @@ function prestigeAugmentation() { //Delete messages on home computer homeComp.messages.length = 0; - //Delete active scripts display elements - var list = Engine.ActiveScriptsList.querySelectorAll('#active-scripts-list li'); - for (var i = list.length-1; i >= 0; --i) { - Engine.deleteActiveScriptsItem(i); - } - workerScripts.length = 0; - //Delete Hacknet Nodes Player.hacknetNodes.length = 0; Player.totalHacknetNodeProduction = 0; diff --git a/src/SaveObject.js b/src/SaveObject.js index 032a10a4a..7bc88c30b 100644 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -67,9 +67,7 @@ loadGame = function(saveObj) { } if (saveObj.hasOwnProperty("VersionSave")) { try { - console.log("here"); var ver = JSON.parse(saveObj.VersionSave, Reviver); - console.log("version from save: " + ver); if (ver != CONSTANTS.Version) { createNewUpdateText(); } From a461491094fa828d102c5923a4f173d2273d1916 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 21:33:50 -0500 Subject: [PATCH 15/16] Fixed bugs with new Netscript functions. Adding ActiveScriptsUI.js file to git --- src/ActiveScriptsUI.js | 222 ++++++++++++++++++++++++++++++++++++++ src/Constants.js | 12 ++- src/NetscriptEvaluator.js | 6 +- src/NetscriptFunctions.js | 11 +- 4 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 src/ActiveScriptsUI.js diff --git a/src/ActiveScriptsUI.js b/src/ActiveScriptsUI.js new file mode 100644 index 000000000..12903448b --- /dev/null +++ b/src/ActiveScriptsUI.js @@ -0,0 +1,222 @@ +/* Active Scripts UI*/ + +function setActiveScriptsClickHandlers() { + //Server panel click handlers + var serverPanels = document.getElementsByClassName("active-scripts-server-header"); + if (serverPanels == null) { + console.log("ERROR: Could not find Active Scripts server panels"); + return; + } + for (i = 0; i < serverPanels.length; ++i) { + serverPanels[i].onclick = function() { + this.classList.toggle("active"); + + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + } + } + } + + //Script Panel click handlers + var scriptPanels = document.getElementsByClassName("active-scripts-script-header"); + if (scriptPanels == null) { + console.log("ERROR: Could not find Active Scripts panels for individual scripts"); + return; + } + for (var i = 0; i < scriptPanels.length; ++i) { + scriptPanels[i].onclick = function() { + this.classList.toggle("active"); + + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + } + } + } +} + +//Returns the ul element containins all script items for a specific server +function getActiveScriptsServerList(server) { + if (server == null) {return null;} + var panelname = "active-scripts-server-panel-" + server.hostname; + var item = document.getElementById(panelname + "-script-list"); + if (item == null) { + console.log("ERROR: Cannot find list for: " + server.hostname); + } + return item; +} + +function createActiveScriptsServerPanel(server) { + var panelname = "active-scripts-server-panel-" + server.hostname; + var activeScriptsList = document.getElementById("active-scripts-list"); + + //Div of entire Panel + var panelDiv = document.createElement("div"); + panelDiv.setAttribute("id", panelname); + + //Panel Header + var panelHdr = document.createElement("button"); + panelHdr.setAttribute("class", "active-scripts-server-header") + panelHdr.setAttribute("id", panelname + "-hdr"); + panelHdr.innerHTML = server.hostname; + + //Panel content + var panelContentDiv = document.createElement("div"); + panelContentDiv.setAttribute("class", "active-scripts-server-panel"); + panelContentDiv.setAttribute("id", panelname + "-content"); + + //List of scripts + var panelScriptList = document.createElement("ul"); + panelScriptList.setAttribute("id", panelname + "-script-list"); + + panelContentDiv.appendChild(panelScriptList); + panelDiv.appendChild(panelHdr); + panelDiv.appendChild(panelContentDiv); + activeScriptsList.appendChild(panelDiv); + + setActiveScriptsClickHandlers() //Reset click handlers + + return panelDiv; + //TODO Alphabetize Active Scripts list? +} + +//Deletes the info for a particular server (Dropdown header + Panel with all info) +//in the Active Scripts page if it exists +function deleteActiveScriptsServerPanel(server) { + var panelname = "active-scripts-server-panel-" + server.hostname; + var panel = document.getElementById(panelname); + if (panel == null) { + console.log("No such panel exists: " + panelname); + return; + } + + //Remove the panel if it has no elements + var scriptList = document.getElementById(panelname + "-script-list"); + if (scriptList.childNodes.length == 0) { + panel.parentNode.removeChild(panel); + } +} + +function addActiveScriptsItem(workerscript) { + //Get server panel + var server = getServer(workerscript.serverIp); + if (server == null) { + console.log("ERROR: Invalid server IP for workerscript."); + return; + } + var panelname = "active-scripts-server-panel-" + server.hostname; + + var panel = document.getElementById(panelname); + if (panel == null) { + panel = createActiveScriptsServerPanel(server); + } + + //Create the element itself. Each element is an accordion collapsible + var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name; + var item = document.createElement("li"); + item.setAttribute("id", itemName); + + var btn = document.createElement("button"); + btn.setAttribute("class", "active-scripts-script-header"); + btn.innerHTML = workerscript.name; + + var itemContentDiv = document.createElement("div"); + itemContentDiv.setAttribute("class", "active-scripts-script-panel"); + itemContentDiv.setAttribute("id", itemName + "-content"); + + item.appendChild(btn); + item.appendChild(itemContentDiv); + + createActiveScriptsText(workerscript, itemContentDiv); + + //Append element to list + var list = getActiveScriptsServerList(server); + list.appendChild(item); + + setActiveScriptsClickHandlers() //Reset click handlers +} + +function deleteActiveScriptsItem(workerscript) { + var server = getServer(workerscript.serverIp); + if (server == null) { + console.log("ERROR: Invalid server IP for workerscript."); + return; + } + var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name; + var li = document.getElementById(itemName); + if (li == null) { + console.log("could not find Active scripts li element for: " + workerscript.name); + return; + } + li.parentNode.removeChild(li); + deleteActiveScriptsServerPanel(server); +} + +//Update the ActiveScriptsItems array +function updateActiveScriptsItems() { + var total = 0; + for (var i = 0; i < workerScripts.length; ++i) { + total += updateActiveScriptsItemContent(workerScripts[i]); + } + document.getElementById("active-scripts-total-prod").innerHTML = + "Total online production rate: $" + formatNumber(total, 2) + " / second"; +} + +//Updates the content of the given item in the Active Scripts list +function updateActiveScriptsItemContent(workerscript) { + var server = getServer(workerscript.serverIp); + if (server == null) { + console.log("ERROR: Invalid server IP for workerscript."); + return; + } + var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name; + var itemContent = document.getElementById(itemName + "-content") + + //Clear the item + while (itemContent.firstChild) { + itemContent.removeChild(itemContent.firstChild); + } + + //Add the updated text back. Returns the total online production rate + return createActiveScriptsText(workerscript, itemContent); +} + +function createActiveScriptsText(workerscript, item) { + var itemText = document.createElement("p"); + + //Server ip/hostname + var hostname = workerscript.getServer().hostname; + var serverIpHostname = "Server: " + hostname + "(" + workerscript.serverIp + ")"; + + //Online + var onlineTotalMoneyMade = "Total online production: $" + formatNumber(workerscript.scriptRef.onlineMoneyMade, 2); + var onlineTotalExpEarned = (Array(26).join(" ") + formatNumber(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " "); + + var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime; + var onlineMpsText = "Online production rate: $" + formatNumber(onlineMps, 2) + "/second"; + var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime; + var onlineEpsText = (Array(25).join(" ") + formatNumber(onlineEps, 4) + " hacking exp/second").replace( / /g, " "); + + //Offline + var offlineTotalMoneyMade = "Total offline production: $" + formatNumber(workerscript.scriptRef.offlineMoneyMade, 2); + var offlineTotalExpEarned = (Array(27).join(" ") + formatNumber(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " "); + + var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime; + var offlineMpsText = "Offline production rate: $" + formatNumber(offlineMps, 2) + "/second"; + var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime; + var offlineEpsText = (Array(26).join(" ") + formatNumber(offlineEps, 4) + " hacking exp/second").replace( / /g, " "); + + itemText.innerHTML = serverIpHostname + "
    " + onlineTotalMoneyMade + "
    " + onlineTotalExpEarned + "
    " + + onlineMpsText + "
    " + onlineEpsText + "
    " + offlineTotalMoneyMade + "
    " + offlineTotalExpEarned + "
    " + + offlineMpsText + "
    " + offlineEpsText + "
    "; + + item.appendChild(itemText); + + //Return total online production rate + return onlineMps; +} \ No newline at end of file diff --git a/src/Constants.js b/src/Constants.js index bfbb273bb..b04b2479a 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -74,8 +74,8 @@ CONSTANTS = { ServerWeakenAmount: 0.1, //Amount by which server's security decreases when weakened //Augmentation Constants - AugmentationCostMultiplier: 4.5, //Used for balancing costs without having to readjust every Augmentation cost - AugmentationRepMultiplier: 1.2, //Used for balancing rep cost without having to readjust every value + AugmentationCostMultiplier: 5, //Used for balancing costs without having to readjust every Augmentation cost + AugmentationRepMultiplier: 1.5, //Used for balancing rep cost without having to readjust every value //Maximum number of log entries for a script MaxLogCapacity: 40, @@ -560,7 +560,8 @@ CONSTANTS = { "-Server growth no longer happens naturally

    " + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + "-Hacking now grants 10% less hacking experience

    " + - "-You can now edit scripts that are running



    " + + "-You can now edit scripts that are running

    + " + + "-Augmentations cost ~11% more money and 25% more faction reputation

    " + "v0.19.7
    " + "-Added changelog to Options menu
    " + "-Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs

    " + @@ -644,7 +645,7 @@ CONSTANTS = { "-You can now see what an Augmentation does and its price even while its locked

    ", LatestUpdate: - "v0.20.0
    " + + "v0.20.0
    " + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + "now each one should only take 750 milliseconds).

    " + @@ -669,5 +670,6 @@ CONSTANTS = { "-Server growth no longer happens naturally

    " + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + "-Hacking now grants 10% less hacking experience

    " + - "-You can now edit scripts that are running
    ", + "-You can now edit scripts that are running

    + " + + "-Augmentations cost ~11% more money and 25% more faction reputation

    ", } \ No newline at end of file diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 249ffd88c..78623ed88 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -268,7 +268,7 @@ function evaluate(exp, workerScript) { Promise.all(argPromises).then(function(args) { if (env.stopFlag) {return reject(workerScript);} filename = args[0]; - if (exp.args.length == 2) { + if (exp.args.length == 1) { return Promise.resolve(workerScript.serverIp); } else { return evaluate(exp.args[1], workerScript); @@ -448,7 +448,7 @@ function evaluate(exp, workerScript) { Promise.all(argPromises).then(function(args) { if (env.stopFlag) {return reject(workerScript);} filename = args[0]; - if (exp.args.length == 2) { + if (exp.args.length == 1) { return Promise.resolve(workerScript.serverIp); } else { return evaluate(exp.args[1], workerScript); @@ -484,7 +484,7 @@ function evaluate(exp, workerScript) { Promise.all(argPromises).then(function(args) { if (env.stopFlag) {return reject(workerScript);} filename = args[0]; - if (exp.args.length == 2) { + if (exp.args.length == 1) { return Promise.resolve(workerScript.serverIp); } else { return evaluate(exp.args[1], workerScript); diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 3add329cc..9f13539b5 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -147,10 +147,10 @@ function netscriptGrow(exp, workerScript) { server.moneyAvailable += 1; //It can be grown even if it has no money var growthPercentage = processSingleServerGrowth(server, 450); workerScript.scriptRef.recordGrow(server.ip); - workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " - + formatNumber(growthPercentage*100 - 100, 6) + "%"); var expGain = 0.5 * Player.hacking_exp_mult; - workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " + + formatNumber(growthPercentage*100 - 100, 6) + "%. Gained " + + formatNumber(expGain, 4) + " hacking exp"); workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); return Promise.resolve(growthPercentage); @@ -194,10 +194,9 @@ function netscriptWeaken(exp, workerScript) { if (env.stopFlag) {return Promise.reject(workerScript);} server.weaken(CONSTANTS.ServerWeakenAmount); workerScript.scriptRef.recordWeaken(server.ip); - workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty); - workerScript.scriptRef.log("Gained 3 hacking experience"); var expGain = 3 * Player.hacking_exp_mult; - workerScript.scriptRef.log("Gained " + expGain + " hacking experience"); + workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty + + ". Gained " + formatNumber(expGain, 4) + " hacking exp"); workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); return Promise.resolve(CONSTANTS.ServerWeakenAmount); From f92556e754c99d7e5d573287fba7d2ae64f45b28 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Tue, 6 Jun 2017 23:09:53 -0500 Subject: [PATCH 16/16] Fixed bugs with new Netscript commands --- css/menupages.css | 2 +- src/Constants.js | 10 +++++----- src/Message.js | 1 - src/NetscriptEvaluator.js | 31 +++++++++++++++++-------------- src/NetscriptWorker.js | 4 ++++ 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/css/menupages.css b/css/menupages.css index 2284324b0..11e198ef8 100644 --- a/css/menupages.css +++ b/css/menupages.css @@ -184,7 +184,7 @@ background-color: #555; .active-scripts-server-panel { margin: 0px 6px 6px 6px; - padding: 6px; + padding: 0px 6px 6px 6px; width: 55%; margin-left: 5%; display: none; diff --git a/src/Constants.js b/src/Constants.js index b04b2479a..538b41c93 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -34,7 +34,7 @@ CONSTANTS = { /* Script related things */ //Time (ms) it takes to run one operation in Netscript. - CodeInstructionRunTime: 750, + CodeInstructionRunTime: 500, //RAM Costs for different commands ScriptWhileRamCost: 0.2, @@ -538,7 +538,7 @@ CONSTANTS = { "v0.20.0
    " + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + - "now each one should only take 750 milliseconds).

    " + + "now each one should only take ~500 milliseconds).

    " + "-Percentage money stolen when hacking lowered to compensate for faster script speeds

    " + "-Hacking experience granted by grow() halved

    " + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5

    " + @@ -560,7 +560,7 @@ CONSTANTS = { "-Server growth no longer happens naturally

    " + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + "-Hacking now grants 10% less hacking experience

    " + - "-You can now edit scripts that are running

    + " + + "-You can now edit scripts that are running

    " + "-Augmentations cost ~11% more money and 25% more faction reputation

    " + "v0.19.7
    " + "-Added changelog to Options menu
    " + @@ -648,7 +648,7 @@ CONSTANTS = { "v0.20.0
    " + "-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " + "such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " + - "now each one should only take 750 milliseconds).

    " + + "now each one should only take ~500 milliseconds).

    " + "-Percentage money stolen when hacking lowered to compensate for faster script speeds

    " + "-Hacking experience granted by grow() halved

    " + "-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5

    " + @@ -670,6 +670,6 @@ CONSTANTS = { "-Server growth no longer happens naturally

    " + "-Servers now have a maximum limit to their money. This limit is 50 times it's starting money

    " + "-Hacking now grants 10% less hacking experience

    " + - "-You can now edit scripts that are running

    + " + + "-You can now edit scripts that are running

    " + "-Augmentations cost ~11% more money and 25% more faction reputation

    ", } \ No newline at end of file diff --git a/src/Message.js b/src/Message.js index c650e5e6a..64c1fa533 100644 --- a/src/Message.js +++ b/src/Message.js @@ -43,7 +43,6 @@ function addMessageToServer(msg, serverHostname) { //Checks if any of the 'timed' messages should be sent function checkForMessagesToSend() { - console.log("checkForMessagesToSend() called"); var jumper0 = Messages[MessageFilenames.Jumper0]; var jumper1 = Messages[MessageFilenames.Jumper1]; var jumper2 = Messages[MessageFilenames.Jumper2]; diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 78623ed88..d478a4240 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -280,15 +280,16 @@ function evaluate(exp, workerScript) { return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into kill() command")); } - for (var i = 0; i < server.runningScripts.length; ++i) { - if (filename == server.runningScripts[i].filename) { - killWorkerScript(filename, server.ip); - workerScript.scriptRef.log("Killing " + scriptName + ". May take up to a few minutes for the scripts to die..."); - return resolve(true); - } + var res = killWorkerScript(filename, server.ip); + if (res) { + workerScript.scriptRef.log("Killing " + filename + ". May take up to a few minutes for the scripts to die..."); + return Promise.resolve(true); + } else { + workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname); + return Promise.resolve(false); } - workerScript.scriptRef.log("kill() failed. No such script "+ scriptName + " on " + server.hostname); - return resolve(false); + }).then(function(res) { + resolve(res); }).catch(function(e) { reject(e); }); @@ -304,7 +305,7 @@ function evaluate(exp, workerScript) { workerScript.scriptRef.log("killall() failed. Invalid IP or hostname passed in: " + ip); return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into killall() command")); } - workerScript.scriptRef.log("killall(): Killing all scrips on " + server.hostname); + workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die"); for (var i = server.runningScripts.length; i >= 0; --i) { killWorkerScript(server.runningScripts[i], server.ip); } @@ -344,7 +345,7 @@ function evaluate(exp, workerScript) { } if (sourceScript == null) { workerScript.scriptRef.log(scriptname + " does not exist. scp() failed"); - return resolve(false); + return Promise.resolve(false); } //Overwrite script if it already exists @@ -355,8 +356,7 @@ function evaluate(exp, workerScript) { var oldScript = destServer.scripts[i]; oldScript.code = sourceScript.code; oldScript.ramUsage = sourceScript.ramUsage; - resolve(true); - return; + return Promise.resolve(true); } } @@ -368,7 +368,10 @@ function evaluate(exp, workerScript) { newScript.server = destServer.ip; destServer.scripts.push(newScript); workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname); - return resolve(true); + return Promise.resolve(true); + return; + }).then(function(res) { + resolve(res); }).catch(function(e) { reject(e); }); @@ -431,7 +434,7 @@ function evaluate(exp, workerScript) { workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into getServerRequiredHackingLevel() command")); } - workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hsostname); + workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname); resolve(server.requiredHackingSkill); }, function(e) { reject(e); diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js index fc0c9aeb0..d3fee5a5d 100644 --- a/src/NetscriptWorker.js +++ b/src/NetscriptWorker.js @@ -111,6 +111,8 @@ function runScriptsLoop() { return; } } + } else { + dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev"); } }); } @@ -152,8 +154,10 @@ function killWorkerScript(scriptName, serverIp) { for (var i = 0; i < workerScripts.length; i++) { if (workerScripts[i].name == scriptName && workerScripts[i].serverIp == serverIp) { workerScripts[i].env.stopFlag = true; + return true; } } + return false; } //Queues a script to be run