diff --git a/src/Constants.js b/src/Constants.js index 982abedda..27571077a 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: 500, + CodeInstructionRunTime: 100, //RAM Costs for different commands ScriptWhileRamCost: 0.2, @@ -258,6 +258,22 @@ CONSTANTS = { "run [script] - Run a script
" + "tail [script] - Displays a script's logs
" + "top - Displays all active scripts and their RAM usage

" + + "

Multithreading scripts


" + + "Scripts can be multithreaded. A multithreaded script runs the script's code once in each thread. The result is that " + + "every call to the hack(), grow(), and weaken() Netscript functions will have its effect multiplied by the number of scripts. " + + "For example, if a normal single-threaded script is able to hack $10,000, then running the same script with 5 threads would " + + "yield $50,000.

" + + "Each additional thread to a script will slightly increase the RAM usage for that thread. The total cost of running a script with " + + "n threads can be calculated with:
" + + "base cost * n * (1.02 ^ n)
" + + "where the base cost is the amount of RAM required to run the script with a single thread. In the terminal, you can run the " + + "'mem [scriptname] -t n' command to see how much RAM a script requires with n threads.

" + + "Every method for running a script has an option for making it multihreaded. To runa script with " + + "n threads from a Terminal:
" + + "run [scriptname] -t n

" + + "Using Netscript commands:
" + + "run('scriptname.script', m);
" + + "exec('scriptname.script, 'targetServer', n);

" + "

Notes about how scripts work offline


" + " The scripts that you write and execute are interpreted in Javascript. For this " + "reason, it is not possible for these scripts to run while offline (when the game is closed). " + @@ -301,6 +317,9 @@ CONSTANTS = { " >=
" + " ==
" + " !=

" + + "

Arrays


" + + "Arrays are special container objects. Arrays can holy many values under a single name. Each value in the array " + + "can be accessed using an index number. To declare and access" + "

Functions


" + "You can NOT define you own functions in Netscript (yet), but there are several built in functions that " + "you may use:

" + @@ -335,12 +354,17 @@ CONSTANTS = { "relaysmtp(hostname/ip)
Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer. Does NOT work while offline
Example: relaysmtp('foodnstuff');

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

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

" + - "run(script)
Run a script as a separate process. The argument that is passed in is the name of the script as a string. This function can only " + - "be used to run scripts located on the same server. Returns true if the script is successfully started, and false otherwise. Requires a significant amount " + + "run(script, [numThreads])
Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " + + "be used to run scripts located on the current server (the server running the script that calls this function). The second argument " + + "is optional, and it specifies how many threads to run the script with. If it is omitted, then the script is run single-threaded. " + + "This second argument must be a number that is greater than 0. " + + "Returns true if the script is successfully started, and false otherwise. Requires a significant amount " + "of RAM to run this command. Does NOT work while offline
Example: run('hack-foodnstuff.script');
The example above will try and launch the 'hack-foodnstuff.script' script on " + "the current server, if it exists.

" + - "exec(script, hostname/ip)
Run a script as a separate process on another server. The first argument is the name of the script as a string. The " + - "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 " + + "exec(script, hostname/ip, [numThreads])
Run a script as a separate process on another server. The first argument is the name of the script as a string. The " + + "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. " + + "The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script is run single-threaded. " + + "This argument must be a number that is greater than 0. 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. " + @@ -400,7 +424,7 @@ CONSTANTS = { "hacknetnodes[i].ram
Returns the amount of RAM on the corresponding Hacknet Node

" + "hacknetnodes[i].cores
Returns the number of cores on the corresponding Hacknet Node

" + "hacknetnodes[i].upgradeLevel(n)
Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " + - "positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times, and false otherwise.

" + + "positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times or up to the max level (200), and false otherwise.

" + "hacknetnodes[i].upgradeRam()
Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " + "RAM is successfully upgraded, and false otherwise.

" + "hacknetnodes[i].upgradeCore()
Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " + @@ -535,6 +559,14 @@ CONSTANTS = { "RAM Upgrades on your home computer", Changelog: + "v0.20.2
" + + "-Fixed several small bugs
" + + "-Added basic array functionality to Netscript
" + + "-Added ability to run scripts with multiple threads. Running a script with n threads will multiply the effects of all " + + "hack(), grow(), and weaken() commands by n. However, running a script with multiple threads has drawbacks in terms of " + + "RAM usage. A script's ram usage when it is 'multithreaded' is calculated as: base cost * numThreads * (1.02 ^ numThreads). " + + "A script can be run multithreaded using the 'run [script] -t n' Terminal command or by passing in an argument to the " + + "run() and exec() Netscript commands. See documentation.

" + "v0.20.1
" + "-Fixed bug where sometimes scripts would crash without showing the error
" + "-Added Deepscan programs to Dark Web
" + @@ -653,7 +685,13 @@ CONSTANTS = { LatestUpdate: "v0.20.2
" + - "" + "-Fixed several small bugs
" + + "-Added basic array functionality to Netscript
" + + "-Added ability to run scripts with multiple threads. Running a script with n threads will multiply the effects of all " + + "hack(), grow(), and weaken() commands by n. However, running a script with multiple threads has drawbacks in terms of " + + "RAM usage. A script's ram usage when it is 'multithreaded' is calculated as: base cost * numThreads * (1.02 ^ numThreads). " + + "A script can be run multithreaded using the 'run [script] -t n' Terminal command or by passing in an argument to the " + + "run() and exec() Netscript commands. See documentation.

" + "v0.20.1
" + "-Fixed bug where sometimes scripts would crash without showing the error
" + "-Added Deepscan programs to Dark Web
" + diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index c384f33f0..07162262a 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -40,18 +40,15 @@ function evaluate(exp, workerScript) { } try { var res = env.get(exp.value); - console.log(res); if (exp.index) { //If theres an index field, then this variable is supposed to be an array //and the user needs to be indexing it if (res.constructor === Array || res instanceof Array) { - //Do array stuff here var iPromise = evaluate(exp.index.value, workerScript); iPromise.then(function(i) { if (i >= res.length || i < 0) { return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator")); } else { - //Evaluate here return evaluate(res[i], workerScript); } }).then(function(res) { diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 4e186bd83..83d2c8384 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -9,17 +9,45 @@ function netscriptAssign(exp, workerScript) { return reject(makeRuntimeRejectMsg(workerScript, "Cannot assign to " + JSON.stringify(exp.left))); } - var expRightPromise = evaluate(exp.right, workerScript); - expRightPromise.then(function(expRight) { + //Assigning an element in an array + if (exp.left.index) { try { - env.set(exp.left.value, expRight); - } catch (e) { - return reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString())); + var res = env.get(exp.left.value); + if (res.constructor === Array || res instanceof Array) { + var iPromise = evaluate(exp.left.index.value, workerScript); + iPromise.then(function(i) { + if (i >= res.length || i < 0) { + return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator")); + } else { + res[i].type = exp.right.type; + res[i].value = exp.right.value; + return resolve(false); + } + }).then(function(res) { + return resolve(res); + }).catch(function(e) { + return reject(e); + }); + } else { + console.log("here"); + return reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator")); + } + } catch(e) { + return reject(makeRuntimeRejectMsg(workerScript, e.toString())); } - resolve(false); //Return false so this doesnt cause conditionals to evaluate - }, function(e) { - reject(e); - }); + } else { + 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); + }); + } }); }