mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-24 15:12:27 +01:00
commit
843884aec2
@ -36,6 +36,7 @@
|
|||||||
<script src="src/NetscriptEvaluator.js"></script>
|
<script src="src/NetscriptEvaluator.js"></script>
|
||||||
<script src="src/NetscriptEnvironment.js"></script>
|
<script src="src/NetscriptEnvironment.js"></script>
|
||||||
<script src="src/NetscriptFunctions.js"></script>
|
<script src="src/NetscriptFunctions.js"></script>
|
||||||
|
<script src="utils/acorn.js"></script>
|
||||||
|
|
||||||
<!-- Main game files -->
|
<!-- Main game files -->
|
||||||
<script src="src/Constants.js"></script>
|
<script src="src/Constants.js"></script>
|
||||||
|
@ -354,41 +354,7 @@ CONSTANTS = {
|
|||||||
" ==<br>" +
|
" ==<br>" +
|
||||||
" !=<br><br>" +
|
" !=<br><br>" +
|
||||||
"<u><h1> Arrays </h1></u><br>" +
|
"<u><h1> Arrays </h1></u><br>" +
|
||||||
"Arrays are special container objects. Arrays can hold many values under a single name. Each value in the array " +
|
"Netscript arrays have the same properties and functions as javascript arrays. For information see javascripts <a href=\"https://www.w3schools.com/js/js_arrays.asp\">array</a> documentation.<br><br>"+
|
||||||
"can be accessed using an index number. The following example shows how to declare an array: <br><br>" +
|
|
||||||
"thisIsAnArray = Array[1, 2, 3, 'bitburner!', false];<br><br>" +
|
|
||||||
"Note that the values in an array can be different types. To access this array we just declared, we can use the index " +
|
|
||||||
"operator on the array's name: <br><br>" +
|
|
||||||
"print(thisIsAnArray[0]); <br>" +
|
|
||||||
"thisIsAnArray[1] = 5;<br>" +
|
|
||||||
"thisIsAnArray[3] = 'string concatenation ' + 123;<br><br>" +
|
|
||||||
"Note that arrays are indexed starting at index 0. Using an index that is too large or less than 0 will result in an " +
|
|
||||||
"out of bounds runtime error. <br><br>" +
|
|
||||||
"If an element in an array is assigned to a value that includes a variable, then it holds a reference to that variable. " +
|
|
||||||
"What this means is that if the variable changes, the array element will also change accordingly. For example:<br><br>" +
|
|
||||||
"x = 10;<br>testArr = Array[x];<br>print(testArr[0]);<br>x = 20;<br>print(testArr[0]);<br><br>" +
|
|
||||||
"This code will print: <br><br>10<br>20<br><br>" +
|
|
||||||
"<strong>Array functions</strong><br>" +
|
|
||||||
"Arrays have built-in functions/properties that can be used to more easily access and manipulate the containers. <br><br>"+
|
|
||||||
"<i>length/length()</i><br>Returns the number of elements in the array.<br>" +
|
|
||||||
"The example below will print out 5:<br><br>" +
|
|
||||||
"arr = Array[1, 2, 3, 4, 5];<br>print(arr.length);<br><br>" +
|
|
||||||
"<i>clear/clear()</i><br>Removes all elements from the array.<br>" +
|
|
||||||
"The example below creates an array with three strings and then uses clear to remove all of those strings. The result is that 'arr' will be " +
|
|
||||||
"an empty array.<br><br>" +
|
|
||||||
"arr = Array['str1', 'str2', 'str3'];<br>arr.clear();<br><br>" +
|
|
||||||
"<i>push(e)</i><br>Adds the element e to the end of the array.<br>" +
|
|
||||||
"The example below will create an array holding one element: the number 1. It will then push the number 2 onto the array. The result " +
|
|
||||||
"is that 'arr' will be an array of size 2 with arr[0] == 1 and arr[1] == 2<br><br>" +
|
|
||||||
"arr = Array[1];<br>arr.push(2);<br><br>" +
|
|
||||||
"<i>insert(e)</i><br>Inserts an element e into an array at a specified index. Every element in the array that is at or after " +
|
|
||||||
"the specified index is shifted down. The array must be indexed with the [] operator when using this function.<br>" +
|
|
||||||
"The following example will insert the number 2 into index 1 of the array. The result afterwards is that 'arr' will hold the values [1, 2, 3, 4].<br><br>" +
|
|
||||||
"arr = Array[1, 3, 4];<br>arr[1].insert(2);<br><br>" +
|
|
||||||
"<i>remove()</i><br>Removes an element from a specified index. Every element in the array that is after the specified index " +
|
|
||||||
"will be shifted up. The array must be indexed with the [] operator when using this function.<br>" +
|
|
||||||
"The following example will remove the first element of the array. The result afterwards is that 'arr' will hold the values [2, 3].<br><br>" +
|
|
||||||
"arr = Array[1, 2, 3];<br>arr[0].remove();<br><br>" +
|
|
||||||
"<u><h1> Script Arguments </h1></u><br>" +
|
"<u><h1> Script Arguments </h1></u><br>" +
|
||||||
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
|
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
|
||||||
"operator. (args[0], args[1], args[2]...) <br><br>" +
|
"operator. (args[0], args[1], args[2]...) <br><br>" +
|
||||||
@ -540,51 +506,51 @@ CONSTANTS = {
|
|||||||
"<i>hacknetnodes[i].cores</i><br> Returns the number of cores on the corresponding Hacknet Node<br><br>" +
|
"<i>hacknetnodes[i].cores</i><br> Returns the number of cores on the corresponding Hacknet Node<br><br>" +
|
||||||
"<i>hacknetnodes[i].upgradeLevel(n)</i><br> Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
|
"<i>hacknetnodes[i].upgradeLevel(n)</i><br> 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 or up to the max level (200), and false otherwise.<br><br>" +
|
"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.<br><br>" +
|
||||||
"<i>hacknetnodes[i].upgradeRam()</i><br> Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
|
"<i>hacknetnodes[i].purchaseRamUpgrade()</i><br> Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
|
||||||
"RAM is successfully upgraded, and false otherwise. <br><br>" +
|
"RAM is successfully upgraded, and false otherwise. <br><br>" +
|
||||||
"<i>hacknetnodes[i].upgradeCore()</i><br> Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
|
"<i>hacknetnodes[i].purchaseCoreUpgrade()</i><br> Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
|
||||||
"additional core is successfully purchase, and false otherwise. <br><br>" +
|
"additional core is successfully purchase, and false otherwise. <br><br>" +
|
||||||
"Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " +
|
"Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " +
|
||||||
"This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " +
|
"This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " +
|
||||||
"to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.<br><br>" +
|
"to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.<br><br>" +
|
||||||
"while(hacknetnodes.length < 4) {<br>" +
|
"while(hacknetnodes.length < 4) {<br>" +
|
||||||
" purchaseHacknetNode();<br>" +
|
" purchaseHacknetNode();<br>" +
|
||||||
"};<br>" +
|
"}<br>" +
|
||||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||||
" while (hacknetnodes[i].level <= 75) {<br>" +
|
" while (hacknetnodes[i].level <= 75) {<br>" +
|
||||||
" hacknetnodes[i].upgradeLevel(5);<br>" +
|
" hacknetnodes[i].upgradeLevel(5);<br>" +
|
||||||
" sleep(10000);<br>" +
|
" sleep(10000);<br>" +
|
||||||
" };<br>" +
|
" }<br>" +
|
||||||
"};<br>" +
|
"}<br>" +
|
||||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||||
" while (hacknetnodes[i].ram < 8) {<br>" +
|
" while (hacknetnodes[i].ram < 8) {<br>" +
|
||||||
" hacknetnodes[i].upgradeRam();<br>" +
|
" hacknetnodes[i].upgradeRam();<br>" +
|
||||||
" sleep(10000);<br>" +
|
" sleep(10000);<br>" +
|
||||||
" };<br>" +
|
" }<br>" +
|
||||||
"};<br>" +
|
"}<br>" +
|
||||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||||
" while (hacknetnodes[i].cores < 2) {<br>" +
|
" while (hacknetnodes[i].cores < 2) {<br>" +
|
||||||
" hacknetnodes[i].upgradeCore();<br>" +
|
" hacknetnodes[i].upgradeCore();<br>" +
|
||||||
" sleep(10000);<br>" +
|
" sleep(10000);<br>" +
|
||||||
" };<br>" +
|
" }<br>" +
|
||||||
"};<br><br>" +
|
"}<br><br>" +
|
||||||
"<u><h1>While loops </h1></u><br>" +
|
"<u><h1>While loops </h1></u><br>" +
|
||||||
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
|
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
|
||||||
"<i>while (<i>[cond]</i>) {<br> <i>[code]</i><br>}</i><br><br>" +
|
"<i>while (<i>[cond]</i>) {<br> <i>[code]</i><br>}</i><br><br>" +
|
||||||
"As long as <i>[cond]</i> remains true, the code block <i>[code]</i> will continuously execute. Example: <br><br>" +
|
"As long as <i>[cond]</i> remains true, the code block <i>[code]</i> will continuously execute. Example: <br><br>" +
|
||||||
"<i>i = 0; <br> while (i < 10) { <br> hack('foodnstuff');<br> i = i + 1;<br> }; </i><br><br>" +
|
"<i>i = 0; <br> while (i < 10) { <br> hack('foodnstuff');<br> i = i + 1;<br> } </i><br><br>" +
|
||||||
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" +
|
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" +
|
||||||
"<i>while(true) { <br> hack('foodnstuff'); <br> }; </i><br><br> " +
|
"<i>while(true) { <br> hack('foodnstuff'); <br> }</i><br><br> " +
|
||||||
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
|
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
|
||||||
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " +
|
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " +
|
||||||
"<u><h1>For loops</h1></u><br>" +
|
"<u><h1>For loops</h1></u><br>" +
|
||||||
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " +
|
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " +
|
||||||
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br> <i>code</i> <br> }; </i><br><br>" +
|
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br> <i>code</i> <br> } </i><br><br>" +
|
||||||
"The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " +
|
"The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " +
|
||||||
"as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " +
|
"as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " +
|
||||||
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
|
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
|
||||||
" using a for loop: <br><br>" +
|
" using a for loop: <br><br>" +
|
||||||
"<i>for (i = 0; i < 10; i = i+1) { <br> hack('foodnstuff');<br>}; </i><br><br>" +
|
"<i>for (i = 0; i < 10; i = i++) { <br> hack('foodnstuff');<br>} </i><br><br>" +
|
||||||
"<u><h1> If statements </h1></u><br>" +
|
"<u><h1> If statements </h1></u><br>" +
|
||||||
"If/Elif/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
|
"If/Elif/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
|
||||||
"<i>if (condition1) {<br> code1<br>} elif (condition2) {<br> code2<br>} else {<br>" +
|
"<i>if (condition1) {<br> code1<br>} elif (condition2) {<br> code2<br>} else {<br>" +
|
||||||
@ -596,7 +562,7 @@ CONSTANTS = {
|
|||||||
"Note that a conditional statement can have any number of elif statements. <br><br>" +
|
"Note that a conditional statement can have any number of elif statements. <br><br>" +
|
||||||
"Example: <br><br>" +
|
"Example: <br><br>" +
|
||||||
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br> hack('foodnstuff');<br>" +
|
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br> hack('foodnstuff');<br>" +
|
||||||
"} else {<br> grow('foodnstuff');<br>};<br><br>" +
|
"} else {<br> grow('foodnstuff');<br>}<br><br>" +
|
||||||
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
|
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
|
||||||
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
|
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
|
||||||
"then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>",
|
"then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>",
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
/* Environment
|
/* Environment
|
||||||
* NetScript program environment
|
* NetScript program environment
|
||||||
*/
|
*/
|
||||||
function Environment(parent) {
|
function Environment(workerScript,parent) {
|
||||||
this.vars = Object.create(parent ? parent.vars : null);
|
if (parent){
|
||||||
|
this.vars = parent.vars;
|
||||||
|
} else {
|
||||||
|
this.vars = NetscriptFunctions(workerScript);
|
||||||
|
}
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.stopFlag = false;
|
this.stopFlag = false;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,162 +1,31 @@
|
|||||||
/* Netscript Functions
|
function NetscriptFunctions(workerScript) {
|
||||||
* Implementation for Netscript features */
|
return {
|
||||||
function netscriptArray(exp, workerScript) {
|
hacknetnodes : Player.hacknetNodes,
|
||||||
var env = workerScript.env;
|
scan : function(ip=workerScript.serverIp){
|
||||||
var arr = env.get(exp.value);
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
if (exp.index == null || exp.index == undefined) {
|
|
||||||
if ((exp.op.type == "call" && exp.op.func.value == "length") ||
|
|
||||||
(exp.op.type == "var" && exp.op.value == "length")) {
|
|
||||||
return resolve(arr.length);
|
|
||||||
} else if ((exp.op.type == "call" && exp.op.func.value == "clear") ||
|
|
||||||
(exp.op.type == "var" && exp.op.value == "clear")) {
|
|
||||||
arr.length = 0;
|
|
||||||
return resolve(true);
|
|
||||||
} else if (exp.op.type == "call" && exp.op.func.value == "push") {
|
|
||||||
if (exp.op.args.length == 1) {
|
|
||||||
var entry = Object.assign({}, exp.op.args[0]);
|
|
||||||
arr.push(entry);
|
|
||||||
return resolve(true);
|
|
||||||
} else {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array.push() command. Takes 1 argument"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid operation on an array"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//The array is being indexed
|
|
||||||
var indexPromise = evaluate(exp.index.value, workerScript);
|
|
||||||
indexPromise.then(function(i) {
|
|
||||||
if (isNaN(i)) {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
|
||||||
} else if (i >= arr.length || i < 0) {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
|
||||||
} else {
|
|
||||||
if (exp.op && exp.op.type == "call") {
|
|
||||||
switch(exp.op.func.value) {
|
|
||||||
case "insert":
|
|
||||||
if (exp.op.args.length == 1) {
|
|
||||||
var entry = Object.assign({}, exp.op.args[0]);
|
|
||||||
arr.splice(i, 0, entry);
|
|
||||||
return resolve(arr.length);
|
|
||||||
} else {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array insert() call. Takes 1 argument"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "remove":
|
|
||||||
if (exp.op.args.length == 0) {
|
|
||||||
return resolve(arr.splice(i, 1));
|
|
||||||
} else {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array remove() call. Takes 1 argument"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid call on array element: " + exp.op.func.value));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Return the indexed element
|
|
||||||
var resPromise = evaluate(arr[i], workerScript);
|
|
||||||
resPromise.then(function(res) {
|
|
||||||
resolve(res);
|
|
||||||
}, function(e) {
|
|
||||||
reject(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, function(e) {
|
|
||||||
reject(e);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assigning an element in an array
|
|
||||||
if (exp.left.index) {
|
|
||||||
try {
|
|
||||||
var res = env.get(exp.left.value);
|
|
||||||
if (res.constructor === Array || res instanceof Array) {
|
|
||||||
var i = 0;
|
|
||||||
var iPromise = evaluate(exp.left.index.value, workerScript);
|
|
||||||
iPromise.then(function(idx) {
|
|
||||||
if (isNaN(idx)) {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
|
||||||
} else if (idx >= res.length || idx < 0) {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
|
||||||
} else {
|
|
||||||
//Clone res to be exp.right
|
|
||||||
i = idx;
|
|
||||||
res[i] = Object.assign({}, exp.right);
|
|
||||||
return evaluate(exp.right, workerScript);
|
|
||||||
}
|
|
||||||
}).then(function(finalRes) {
|
|
||||||
resolve(finalRes);
|
|
||||||
}).catch(function(e) {
|
|
||||||
return reject(e);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator"));
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
return reject(makeRuntimeRejectMsg(workerScript, e.toString()));
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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);}
|
|
||||||
var threads = workerScript.scriptRef.threads;
|
|
||||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
|
||||||
|
|
||||||
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);
|
var server = getServer(ip);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
workerScript.scriptRef.log("hack() error. Invalid IP or hostname passed in: " + ip + ". Stopping...");
|
throw makeRuntimeRejectMsg(workerScript, 'Invalid IP or hostname passed into scan() command');
|
||||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into hack() command"));
|
}
|
||||||
|
var out = [];
|
||||||
|
for (var i = 0; i < server.serversOnNetwork.length; i++) {
|
||||||
|
var entry = server.getServerOnNetwork(i).hostname;
|
||||||
|
if (entry == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
out.push(entry);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log('scan() returned ' + server.serversOnNetwork.length + ' connections for ' + server.hostname);
|
||||||
|
return out;
|
||||||
|
},
|
||||||
|
hack : function(ip){
|
||||||
|
if (ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Hack() call has incorrect number of arguments. Takes 1 argument");
|
||||||
|
}
|
||||||
|
var threads = workerScript.scriptRef.threads;
|
||||||
|
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("hack() error. Invalid IP or hostname passed in: " + ip + ". Stopping...");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculate the hacking time
|
//Calculate the hacking time
|
||||||
@ -164,21 +33,17 @@ function netscriptHack(exp, workerScript) {
|
|||||||
|
|
||||||
//No root access or skill level too low
|
//No root access or skill level too low
|
||||||
if (server.hasAdminRights == false) {
|
if (server.hasAdminRights == false) {
|
||||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access");
|
throw 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) {
|
if (server.requiredHackingSkill > Player.hacking_skill) {
|
||||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough");
|
throw 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 (t=" + threads + ")");
|
workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")");
|
||||||
return Promise.resolve([server, hackingTime]);
|
|
||||||
}).then(function([server, hackingTime]) {
|
|
||||||
//console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds (t=" + threads + ")");
|
//console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds (t=" + threads + ")");
|
||||||
return netscriptDelay(hackingTime* 1000).then(function() {
|
return netscriptDelay(hackingTime* 1000).then(function() {
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
var hackChance = scriptCalculateHackingChance(server);
|
var hackChance = scriptCalculateHackingChance(server);
|
||||||
var rand = Math.random();
|
var rand = Math.random();
|
||||||
var expGainedOnSuccess = scriptCalculateExpGain(server) * threads;
|
var expGainedOnSuccess = scriptCalculateExpGain(server) * threads;
|
||||||
@ -214,45 +79,37 @@ function netscriptHack(exp, workerScript) {
|
|||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).then(function(res) {
|
},
|
||||||
return Promise.resolve(res);
|
sleep : function(time){
|
||||||
}).catch(function(e) {
|
if (time === undefined) {
|
||||||
return Promise.reject(e);
|
throw makeRuntimeRejectMsg(workerScript, "sleep() call has incorrect number of arguments. Takes 1 argument");
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("Sleeping for " + sleepTime + " milliseconds");
|
||||||
|
return netscriptDelay(sleepTime).then(function() {
|
||||||
|
return Promise.resolve(true);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
grow : function(ip){
|
||||||
function netscriptGrow(exp, workerScript) {
|
|
||||||
var env = workerScript.env;
|
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
|
||||||
var threads = workerScript.scriptRef.threads;
|
var threads = workerScript.scriptRef.threads;
|
||||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||||
if (exp.args.length != 1) {
|
if (ip === undefined) {
|
||||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "grow() call has incorrect number of arguments. Takes 1 argument"));
|
throw 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);
|
var server = getServer(ip);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
workerScript.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: " + ip);
|
throw 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
|
//No root access or skill level too low
|
||||||
if (server.hasAdminRights == false) {
|
if (server.hasAdminRights == false) {
|
||||||
workerScript.scriptRef.log("Cannot grow this server (" + server.hostname + ") because user does not have root access");
|
throw 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);
|
var growTime = scriptCalculateGrowTime(server);
|
||||||
//console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds")
|
//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 (t=" + threads + ")");
|
workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds (t=" + threads + ")");
|
||||||
|
|
||||||
return Promise.resolve([server, growTime]);
|
|
||||||
}).then(function([server, growTime]) {
|
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
|
||||||
return netscriptDelay(growTime).then(function() {
|
return netscriptDelay(growTime).then(function() {
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
|
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
|
||||||
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
|
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
|
||||||
workerScript.scriptRef.recordGrow(server.ip, threads);
|
workerScript.scriptRef.recordGrow(server.ip, threads);
|
||||||
@ -267,46 +124,29 @@ function netscriptGrow(exp, workerScript) {
|
|||||||
Player.gainHackingExp(expGain);
|
Player.gainHackingExp(expGain);
|
||||||
return Promise.resolve(growthPercentage);
|
return Promise.resolve(growthPercentage);
|
||||||
});
|
});
|
||||||
}).then(function(res) {
|
},
|
||||||
return Promise.resolve(res);
|
weaken : function(ip){
|
||||||
}).catch(function(e) {
|
|
||||||
return Promise.reject(e);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function netscriptWeaken(exp, workerScript) {
|
|
||||||
var env = workerScript.env;
|
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
|
||||||
var threads = workerScript.scriptRef.threads;
|
var threads = workerScript.scriptRef.threads;
|
||||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||||
if (exp.args.length != 1) {
|
if (ip === undefined) {
|
||||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "weaken() call has incorrect number of arguments. Takes 1 argument"));
|
throw 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);
|
var server = getServer(ip);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
workerScript.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: " + ip);
|
throw 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
|
//No root access or skill level too low
|
||||||
if (server.hasAdminRights == false) {
|
if (server.hasAdminRights == false) {
|
||||||
workerScript.scriptRef.log("Cannot weaken this server (" + server.hostname + ") because user does not have root access");
|
throw 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);
|
var weakenTime = scriptCalculateWeakenTime(server);
|
||||||
//console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds")
|
//console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds")
|
||||||
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
|
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
|
||||||
formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")");
|
formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")");
|
||||||
|
|
||||||
return Promise.resolve([server, weakenTime]);
|
|
||||||
}).then(function([server, weakenTime]) {
|
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
|
||||||
return netscriptDelay(weakenTime).then(function() {
|
return netscriptDelay(weakenTime).then(function() {
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
||||||
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
||||||
var expGain = scriptCalculateExpGain(server) * threads;
|
var expGain = scriptCalculateExpGain(server) * threads;
|
||||||
@ -316,67 +156,23 @@ function netscriptWeaken(exp, workerScript) {
|
|||||||
Player.gainHackingExp(expGain);
|
Player.gainHackingExp(expGain);
|
||||||
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
|
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
|
||||||
});
|
});
|
||||||
}).then(function(res) {
|
},
|
||||||
return Promise.resolve(res);
|
print : function(args){
|
||||||
}).catch(function(e) {
|
if (args === undefined) {
|
||||||
return Promise.reject(e);
|
throw makeRuntimeRejectMsg(workerScript, "print() call has incorrect number of arguments. Takes 1 argument");
|
||||||
});
|
}
|
||||||
}
|
workerScript.scriptRef.log(args.toString());
|
||||||
|
},
|
||||||
function netscriptRunProgram(exp, workerScript, programName) {
|
nuke : function(ip){
|
||||||
var env = workerScript.env;
|
if (ip === undefined) {
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (exp.args.length != 1) {
|
|
||||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Program 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);
|
var server = getServer(ip);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
throw 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) {
|
if (server.openPortCount < server.numOpenPortsRequired) {
|
||||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus"));
|
throw makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus");
|
||||||
}
|
}
|
||||||
if (server.hasAdminRights) {
|
if (server.hasAdminRights) {
|
||||||
workerScript.scriptRef.log("Already have root access to " + server.hostname);
|
workerScript.scriptRef.log("Already have root access to " + server.hostname);
|
||||||
@ -384,12 +180,16 @@ function netscriptRunNukeProgram(exp, workerScript, server) {
|
|||||||
server.hasAdminRights = true;
|
server.hasAdminRights = true;
|
||||||
workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access");
|
workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access");
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
}
|
},
|
||||||
|
brutessh : function(ip){
|
||||||
function netscriptRunBrutesshProgram(exp, workerScript, server) {
|
if (ip === undefined) {
|
||||||
var env = workerScript.env;
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
if (!server.sshPortOpen) {
|
if (!server.sshPortOpen) {
|
||||||
workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)");
|
workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)");
|
||||||
server.sshPortOpen = true;
|
server.sshPortOpen = true;
|
||||||
@ -397,12 +197,16 @@ function netscriptRunBrutesshProgram(exp, workerScript, server) {
|
|||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname);
|
workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname);
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
}
|
},
|
||||||
|
ftpcrack : function(ip){
|
||||||
function netscriptRunFtpcrackProgram(exp, workerScript, server) {
|
if (ip === undefined) {
|
||||||
var env = workerScript.env;
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
if (!server.ftpPortOpen) {
|
if (!server.ftpPortOpen) {
|
||||||
workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)");
|
workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)");
|
||||||
server.ftpPortOpen = true;
|
server.ftpPortOpen = true;
|
||||||
@ -410,12 +214,16 @@ function netscriptRunFtpcrackProgram(exp, workerScript, server) {
|
|||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname);
|
workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname);
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
}
|
},
|
||||||
|
relaysmtp : function(ip){
|
||||||
function netscriptRunRelaysmtpProgram(exp, workerScript, server) {
|
if (ip === undefined) {
|
||||||
var env = workerScript.env;
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
if (!server.smtpPortOpen) {
|
if (!server.smtpPortOpen) {
|
||||||
workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)");
|
workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)");
|
||||||
server.smtpPortOpen = true;
|
server.smtpPortOpen = true;
|
||||||
@ -423,12 +231,16 @@ function netscriptRunRelaysmtpProgram(exp, workerScript, server) {
|
|||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname);
|
workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname);
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
}
|
},
|
||||||
|
httpworm : function(ip){
|
||||||
function netscriptRunHttpwormProgram(exp, workerScript, server) {
|
if (ip === undefined) {
|
||||||
var env = workerScript.env;
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
if (!server.httpPortOpen) {
|
if (!server.httpPortOpen) {
|
||||||
workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (80)");
|
workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (80)");
|
||||||
server.httpPortOpen = true;
|
server.httpPortOpen = true;
|
||||||
@ -436,12 +248,16 @@ function netscriptRunHttpwormProgram(exp, workerScript, server) {
|
|||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname);
|
workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname);
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
}
|
},
|
||||||
|
sqlinject : function(ip){
|
||||||
function netscriptRunSqlinjectProgram(exp, workerScript, server) {
|
if (ip === undefined) {
|
||||||
var env = workerScript.env;
|
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
if (!server.sqlPortOpen) {
|
if (!server.sqlPortOpen) {
|
||||||
workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)");
|
workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)");
|
||||||
server.sqlPortOpen = true;
|
server.sqlPortOpen = true;
|
||||||
@ -449,5 +265,211 @@ function netscriptRunSqlinjectProgram(exp, workerScript, server) {
|
|||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname);
|
workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname);
|
||||||
}
|
}
|
||||||
return Promise.resolve(true);
|
return true;
|
||||||
|
},
|
||||||
|
run : function(scriptname,threads = 1,argsForNewScript=[]){
|
||||||
|
if (scriptname === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Usage: run(scriptname, [numThreads], [arg1], [arg2]...)");
|
||||||
|
}
|
||||||
|
if (isNaN(threads) || threads < 1) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0");
|
||||||
|
}
|
||||||
|
var scriptServer = getServer(workerScript.serverIp);
|
||||||
|
if (scriptServer == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
|
||||||
|
}
|
||||||
|
|
||||||
|
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
||||||
|
},
|
||||||
|
exec : function(scriptname,ip,threads = 1,argsForNewScript=[]){
|
||||||
|
if (scriptname === undefined || ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
|
||||||
|
}
|
||||||
|
if (isNaN(threads) || threads < 1) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into exec(). Must be numeric and greater than 0");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runScriptFromScript(server, scriptname, argsForNewScript, workerScript, threads);
|
||||||
|
},
|
||||||
|
kill : function(filename,ip,argsForKillTarget=[]){
|
||||||
|
if (filename === undefined || ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Usage: kill(scriptname, server, [arg1], [arg2]...)");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("kill() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
var runningScriptObj = findRunningScript(filename, argsForKillTarget, server);
|
||||||
|
if (runningScriptObj == null) {
|
||||||
|
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var res = killWorkerScript(runningScriptObj, server.ip);
|
||||||
|
if (res) {
|
||||||
|
workerScript.scriptRef.log("Killing " + filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget) + ". May take up to a few minutes for the scripts to die...");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
killall : function(ip){
|
||||||
|
if (ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "killall() call has incorrect number of arguments. Takes 1 argument");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("killall() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
for (var i = server.runningScripts.length-1; i >= 0; --i) {
|
||||||
|
killWorkerScript(server.runningScripts[i], server.ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
scp : function(scriptname,ip){
|
||||||
|
if (scriptname === undefined || ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments");
|
||||||
|
}
|
||||||
|
var destServer = getServer(ip);
|
||||||
|
if (destServer == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into scp() command: " + ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
var currServ = getServer(workerScript.serverIp);
|
||||||
|
if (currServ == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer");
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//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 true;
|
||||||
|
},
|
||||||
|
hasRootAccess : function(ip){
|
||||||
|
if (ip===undefinied){
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "hasRootAccess() call has incorrect number of arguments. Takes 1 argument");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null){
|
||||||
|
throw workerScript.scriptRef.log("hasRootAccess() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
return server.hasAdimRights;
|
||||||
|
},
|
||||||
|
getHostname : function(){
|
||||||
|
var scriptServer = getServer(workerScript.serverIp);
|
||||||
|
if (scriptServer == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
|
||||||
|
}
|
||||||
|
return scriptServer.hostname;
|
||||||
|
},
|
||||||
|
getHackingLevel : function(){
|
||||||
|
Player.updateSkillLevels();
|
||||||
|
workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill);
|
||||||
|
return Player.hacking_skill;
|
||||||
|
},
|
||||||
|
getServerMoneyAvailable : function(ip){
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname);
|
||||||
|
return server.moneyAvailable;
|
||||||
|
},
|
||||||
|
getServerSecurityLevel : function(ip){
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname);
|
||||||
|
return server.hackDifficulty;
|
||||||
|
},
|
||||||
|
getServerBaseSecurityLevel : function(ip){
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname);
|
||||||
|
return server.baseDifficulty;
|
||||||
|
},
|
||||||
|
getServerRequiredHackingLevel : function(ip){
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname);
|
||||||
|
return server.requiredHackingSkill;
|
||||||
|
},
|
||||||
|
getServerMaxMoney : function(ip){
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
workerScript.scriptRef.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname);
|
||||||
|
return server.moneyMax;
|
||||||
|
},
|
||||||
|
fileExists : function(filename,ip=workerScript.serverIp){
|
||||||
|
if (filename === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "fileExists() call has incorrect number of arguments. Usage: fileExists(scriptname, [server])");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("fileExists() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
for (var i = 0; i < server.scripts.length; ++i) {
|
||||||
|
if (filename == server.scripts[i].filename) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Player.hasProgram(filename)) {
|
||||||
|
return true; //wrong?
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
isRunning : function(filename,ip,argsForTargetScript=[]){
|
||||||
|
if (filename === undefined || ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "isRunning() call has incorrect number of arguments. Usage: isRunning(scriptname, server, [arg1], [arg2]...)");
|
||||||
|
}
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw workerScript.scriptRef.log("isRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
|
}
|
||||||
|
return findRunningScript(filename, argsForTargetScript, server) != null;
|
||||||
|
},
|
||||||
|
purchaseHacknetNode : purchaseHacknet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
/* InputStream class. Creates a "stream object" that provides operations to read
|
|
||||||
* from a string. */
|
|
||||||
function InputStream(input) {
|
|
||||||
var pos = 0, line = 1, col = 0;
|
|
||||||
return {
|
|
||||||
next : next,
|
|
||||||
peek : peek,
|
|
||||||
eof : eof,
|
|
||||||
croak : croak,
|
|
||||||
};
|
|
||||||
function next() {
|
|
||||||
var ch = input.charAt(pos++);
|
|
||||||
if (ch == "\n") line++, col = 0; else col++;
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
function peek() {
|
|
||||||
return input.charAt(pos);
|
|
||||||
}
|
|
||||||
function eof() {
|
|
||||||
return peek() == "";
|
|
||||||
}
|
|
||||||
function croak(msg) {
|
|
||||||
throw new Error(msg + " (" + line + ":" + col + ")");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,326 +0,0 @@
|
|||||||
/* Parser
|
|
||||||
* Creates Abstract Syntax Tree Nodes
|
|
||||||
* Operates on a stream of tokens from the Tokenizer
|
|
||||||
*/
|
|
||||||
|
|
||||||
var FALSE = {type: "bool", value: false};
|
|
||||||
|
|
||||||
function Parser(input) {
|
|
||||||
var PRECEDENCE = {
|
|
||||||
"=": 1,
|
|
||||||
"||": 2,
|
|
||||||
"&&": 3,
|
|
||||||
"<": 7, ">": 7, "<=": 7, ">=": 7, "==": 7, "!=": 7,
|
|
||||||
"+": 10, "-": 10,
|
|
||||||
"*": 20, "/": 20, "%": 20,
|
|
||||||
};
|
|
||||||
return parse_toplevel();
|
|
||||||
|
|
||||||
//Returns true if the next token is a punc type with value ch
|
|
||||||
function is_punc(ch) {
|
|
||||||
var tok = input.peek();
|
|
||||||
return tok && tok.type == "punc" && (!ch || tok.value == ch) && tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns true if the next token is the kw keyword
|
|
||||||
function is_kw(kw) {
|
|
||||||
var tok = input.peek();
|
|
||||||
return tok && tok.type == "kw" && (!kw || tok.value == kw) && tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns true if the next token is an op type with the given op value
|
|
||||||
function is_op(op) {
|
|
||||||
var tok = input.peek();
|
|
||||||
return tok && tok.type == "op" && (!op || tok.value == op) && tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks that the next character is the given punctuation character and throws
|
|
||||||
//an error if it's not. If it is, skips over it in the input
|
|
||||||
function checkPuncAndSkip(ch) {
|
|
||||||
if (is_punc(ch)) input.next();
|
|
||||||
else input.croak("Expecting punctuation: \"" + ch + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks that the next character is the given keyword and throws an error
|
|
||||||
//if its not. If it is, skips over it in the input
|
|
||||||
function checkKeywordAndSkip(kw) {
|
|
||||||
if (is_kw(kw)) input.next();
|
|
||||||
else input.croak("Expecting keyword: \"" + kw + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks that the next character is the given operator and throws an error
|
|
||||||
//if its not. If it is, skips over it in the input
|
|
||||||
function checkOpAndSkip(op) {
|
|
||||||
if (is_op(op)) input.next();
|
|
||||||
else input.croak("Expecting operator: \"" + op + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
function unexpected() {
|
|
||||||
input.croak("Unexpected token: " + JSON.stringify(input.peek()));
|
|
||||||
}
|
|
||||||
|
|
||||||
function maybe_binary(left, my_prec) {
|
|
||||||
var tok = is_op();
|
|
||||||
if (tok) {
|
|
||||||
var his_prec = PRECEDENCE[tok.value];
|
|
||||||
if (his_prec > my_prec) {
|
|
||||||
input.next();
|
|
||||||
return maybe_binary({
|
|
||||||
type : tok.value == "=" ? "assign" : "binary",
|
|
||||||
operator : tok.value,
|
|
||||||
left : left,
|
|
||||||
right : maybe_binary(parse_atom(), his_prec)
|
|
||||||
}, my_prec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
|
|
||||||
function delimited(start, stop, separator, parser) {
|
|
||||||
var a = [], first = true;
|
|
||||||
checkPuncAndSkip(start);
|
|
||||||
while (!input.eof()) {
|
|
||||||
if (is_punc(stop)) break;
|
|
||||||
if (first) first = false; else checkPuncAndSkip(separator);
|
|
||||||
if (is_punc(stop)) break;
|
|
||||||
a.push(parser());
|
|
||||||
}
|
|
||||||
checkPuncAndSkip(stop);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_call(func) {
|
|
||||||
return {
|
|
||||||
type: "call",
|
|
||||||
func: func,
|
|
||||||
args: delimited("(", ")", ",", parse_expression),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_varname() {
|
|
||||||
var name = input.next();
|
|
||||||
if (name.type != "var") input.croak("Expecting variable name");
|
|
||||||
return name.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* type: "if",
|
|
||||||
* cond: [ {"type": "var", "value": "cond1"}, {"type": "var", "value": "cond2"}...]
|
|
||||||
* then: [ {"type": "var", "value": "then1"}, {"type": "var", "value": "then2"}...]
|
|
||||||
* else: {"type": "var", "value": "foo"}
|
|
||||||
*/
|
|
||||||
function parse_if() {
|
|
||||||
checkKeywordAndSkip("if");
|
|
||||||
|
|
||||||
//Conditional
|
|
||||||
var cond = parse_expression();
|
|
||||||
|
|
||||||
//Body
|
|
||||||
var then = parse_expression();
|
|
||||||
var ret = {
|
|
||||||
type: "if",
|
|
||||||
cond: [],
|
|
||||||
then: [],
|
|
||||||
};
|
|
||||||
ret.cond.push(cond);
|
|
||||||
ret.then.push(then);
|
|
||||||
|
|
||||||
// Parse all elif branches
|
|
||||||
while (is_kw("elif")) {
|
|
||||||
input.next();
|
|
||||||
var cond = parse_expression();
|
|
||||||
var then = parse_expression();
|
|
||||||
ret.cond.push(cond);
|
|
||||||
ret.then.push(then);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse else branch, if it exists
|
|
||||||
if (is_kw("else")) {
|
|
||||||
input.next();
|
|
||||||
ret.else = parse_expression();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for (init, cond, postloop) {code;}
|
|
||||||
*
|
|
||||||
* type: "for",
|
|
||||||
* init: assign node,
|
|
||||||
* cond: var node,
|
|
||||||
* postloop: assign node
|
|
||||||
* code: prog node
|
|
||||||
*/
|
|
||||||
function parse_for() {
|
|
||||||
checkKeywordAndSkip("for");
|
|
||||||
|
|
||||||
temp = delimited("(", ")", ";", parse_expression);
|
|
||||||
var splitExpressions = temp.slice();
|
|
||||||
code = parse_expression();
|
|
||||||
|
|
||||||
if (splitExpressions.length != 3) {
|
|
||||||
throw new Error("for statement has incorrect number of arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO Check type of the init, cond, and postloop nodes
|
|
||||||
return {
|
|
||||||
type: "for",
|
|
||||||
init: splitExpressions[0],
|
|
||||||
cond: splitExpressions[1],
|
|
||||||
postloop: splitExpressions[2],
|
|
||||||
code: code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* while (cond) {}
|
|
||||||
*
|
|
||||||
* type: "while",
|
|
||||||
* cond: var node
|
|
||||||
* code: prog node
|
|
||||||
*/
|
|
||||||
function parse_while() {
|
|
||||||
checkKeywordAndSkip("while");
|
|
||||||
|
|
||||||
var cond = parse_expression();
|
|
||||||
var code = parse_expression();
|
|
||||||
return {
|
|
||||||
type: "while",
|
|
||||||
cond: cond,
|
|
||||||
code: code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hacknetnodes[i].operator
|
|
||||||
*/
|
|
||||||
function parse_hacknetnodes() {
|
|
||||||
var index = null;
|
|
||||||
if (is_punc("[")) {
|
|
||||||
index = parse_expression();
|
|
||||||
if (index.type != "index") {
|
|
||||||
unexpected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_punc(".")) {
|
|
||||||
checkPuncAndSkip(".");
|
|
||||||
var op = maybe_call(function() {
|
|
||||||
var tok = input.next();
|
|
||||||
return tok;
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
type: "var",
|
|
||||||
value: "hacknetnodes",
|
|
||||||
index: index,
|
|
||||||
op: op,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
unexpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Declaring a new array with Array[1,2,3]
|
|
||||||
function parse_arraydecl() {
|
|
||||||
var array = delimited("[", "]", ",", parse_expression);
|
|
||||||
return {type: "var",
|
|
||||||
value: "array",
|
|
||||||
array: array
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//Parsing an operation on an array, such as accessing, push(), etc.
|
|
||||||
//tok is a reference to a token of type var
|
|
||||||
function parse_arrayop(tok) {
|
|
||||||
//Returns a variable node except with an extra "index" field so
|
|
||||||
//we can identify it as an index
|
|
||||||
if (is_punc("[")) {
|
|
||||||
var index = parse_arrayindex();
|
|
||||||
if (index.type != "index") {
|
|
||||||
unexpected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = null;
|
|
||||||
if (is_punc(".")) {
|
|
||||||
checkPuncAndSkip(".");
|
|
||||||
op = maybe_call(function() {
|
|
||||||
var callTok = input.next();
|
|
||||||
return callTok;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tok.index = index;
|
|
||||||
tok.op = op; //Will be null if no operation
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_arrayindex() {
|
|
||||||
var index = delimited("[", "]", ";", parse_expression);
|
|
||||||
var val = 0;
|
|
||||||
if (index.length == 1) {
|
|
||||||
val = index[0];
|
|
||||||
} else {
|
|
||||||
unexpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
return { type: "index", value: val };
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_bool() {
|
|
||||||
return {
|
|
||||||
type : "bool",
|
|
||||||
value : input.next().value == "true"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function maybe_call(expr) {
|
|
||||||
expr = expr();
|
|
||||||
return is_punc("(") ? parse_call(expr) : expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_atom() {
|
|
||||||
return maybe_call(function(){
|
|
||||||
if (is_punc("(")) {
|
|
||||||
input.next();
|
|
||||||
var exp = parse_expression();
|
|
||||||
checkPuncAndSkip(")");
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
if (is_punc("{")) return parse_prog();
|
|
||||||
if (is_punc("[")) return parse_arrayindex();
|
|
||||||
if (is_kw("if")) return parse_if();
|
|
||||||
if (is_kw("for")) return parse_for();
|
|
||||||
if (is_kw("while")) return parse_while();
|
|
||||||
if (is_kw("true") || is_kw("false")) return parse_bool();
|
|
||||||
|
|
||||||
var tok = input.next();
|
|
||||||
if (tok.type == "var" && tok.value == "hacknetnodes") return parse_hacknetnodes();
|
|
||||||
if (tok.type == "var" && tok.value == "Array") return parse_arraydecl();
|
|
||||||
if (tok.type == "var" && (is_punc("[") || is_punc("."))) {
|
|
||||||
return parse_arrayop(tok);
|
|
||||||
}
|
|
||||||
if (tok.type == "var" || tok.type == "num" || tok.type == "str")
|
|
||||||
return tok;
|
|
||||||
unexpected();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_toplevel() {
|
|
||||||
var prog = [];
|
|
||||||
while (!input.eof()) {
|
|
||||||
prog.push(parse_expression());
|
|
||||||
if (!input.eof()) checkPuncAndSkip(";");
|
|
||||||
}
|
|
||||||
//Return the top level Abstract Syntax Tree, where the top node is a "prog" node
|
|
||||||
return { type: "prog", prog: prog };
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_prog() {
|
|
||||||
var prog = delimited("{", "}", ";", parse_expression);
|
|
||||||
if (prog.length == 0) return FALSE;
|
|
||||||
if (prog.length == 1) return prog[0];
|
|
||||||
return { type: "prog", prog: prog };
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_expression() {
|
|
||||||
return maybe_call(function(){
|
|
||||||
return maybe_binary(parse_atom(), 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
/* Tokenizer
|
|
||||||
* Acts on top of the InputStream class. Takes in a character input stream and and parses it into tokens.
|
|
||||||
* Tokens can be accessed with peek() and next().
|
|
||||||
*
|
|
||||||
* Token types:
|
|
||||||
* {type: "punc", value: "(" } // punctuation: parens, comma, semicolon etc.
|
|
||||||
* {type: "num", value: 5 } // numbers (including floats)
|
|
||||||
* {type: "str", value: "Hello World!" } // strings
|
|
||||||
* {type: "kw", value: "for/if/..." } // keywords, see defs below
|
|
||||||
* {type: "var", value: "a" } // identifiers/variables
|
|
||||||
* {type: "op", value: "!=" } // operator characters
|
|
||||||
* {type: "bool", value: "true" } // Booleans
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
function Tokenizer(input) {
|
|
||||||
var current = null;
|
|
||||||
var keywords = " if elif else true false while for ";
|
|
||||||
|
|
||||||
return {
|
|
||||||
next : next,
|
|
||||||
peek : peek,
|
|
||||||
eof : eof,
|
|
||||||
croak : input.croak
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_keyword(x) {
|
|
||||||
return keywords.indexOf(" " + x + " ") >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_digit(ch) {
|
|
||||||
return /[0-9]/i.test(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
//An identifier can start with any letter or an underscore
|
|
||||||
function is_id_start(ch) {
|
|
||||||
return /[a-z_]/i.test(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_id(ch) {
|
|
||||||
return is_id_start(ch) || "?!-<>=0123456789".indexOf(ch) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_op_char(ch) {
|
|
||||||
return "+-*/%=&|<>!".indexOf(ch) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_punc(ch) {
|
|
||||||
return ",;(){}[].".indexOf(ch) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_whitespace(ch) {
|
|
||||||
return " \t\n".indexOf(ch) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_while(predicate) {
|
|
||||||
var str = "";
|
|
||||||
while (!input.eof() && predicate(input.peek()))
|
|
||||||
str += input.next();
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_number() {
|
|
||||||
var has_dot = false;
|
|
||||||
//Reads the number from the input. Checks for only a single decimal point
|
|
||||||
var number = read_while(function(ch){
|
|
||||||
if (ch == ".") {
|
|
||||||
if (has_dot) return false;
|
|
||||||
has_dot = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return is_digit(ch);
|
|
||||||
});
|
|
||||||
return { type: "num", value: parseFloat(number) };
|
|
||||||
}
|
|
||||||
|
|
||||||
//This function also checks the identifier against a list of known keywords (defined at the top)
|
|
||||||
//and will return a kw object rather than identifier if it is one
|
|
||||||
function read_ident() {
|
|
||||||
//Identifier must start with a letter or underscore..and can contain anything from ?!-<>=0123456789
|
|
||||||
var id = read_while(is_id);
|
|
||||||
return {
|
|
||||||
type : is_keyword(id) ? "kw" : "var",
|
|
||||||
value : id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_escaped(end) {
|
|
||||||
var escaped = false, str = "";
|
|
||||||
input.next(); //Skip the quotation mark
|
|
||||||
while (!input.eof()) {
|
|
||||||
var ch = input.next();
|
|
||||||
if (escaped) {
|
|
||||||
str += ch;
|
|
||||||
escaped = false;
|
|
||||||
} else if (ch == "\\") {
|
|
||||||
escaped = true;
|
|
||||||
} else if (ch == end) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
str += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_string(ch) {
|
|
||||||
if (ch == '"') {
|
|
||||||
return { type: "str", value: read_escaped('"') };
|
|
||||||
} else if (ch == '\'') {
|
|
||||||
return { type: "str", value: read_escaped('\'') };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Only supports single-line comments right now
|
|
||||||
function skip_comment() {
|
|
||||||
read_while(function(ch){ return ch != "\n" });
|
|
||||||
input.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Gets the next token
|
|
||||||
function read_next() {
|
|
||||||
//Skip over whitespace
|
|
||||||
read_while(is_whitespace);
|
|
||||||
|
|
||||||
if (input.eof()) return null;
|
|
||||||
|
|
||||||
//Peek the next character and decide what to do based on what that
|
|
||||||
//next character is
|
|
||||||
var ch = input.peek();
|
|
||||||
|
|
||||||
if (ch == "//") {
|
|
||||||
skip_comment();
|
|
||||||
return read_next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == '"' || ch == '\'') return read_string(ch);
|
|
||||||
if (is_digit(ch)) return read_number();
|
|
||||||
if (is_id_start(ch)) return read_ident();
|
|
||||||
if (is_punc(ch)) return {
|
|
||||||
type : "punc",
|
|
||||||
value : input.next()
|
|
||||||
}
|
|
||||||
if (is_op_char(ch)) return {
|
|
||||||
type : "op",
|
|
||||||
value : read_while(is_op_char)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function peek() {
|
|
||||||
//Returns current token, unless its null in which case it grabs the next one
|
|
||||||
//and returns it
|
|
||||||
return current || (current = read_next());
|
|
||||||
}
|
|
||||||
|
|
||||||
function next() {
|
|
||||||
//The token might have been peaked already, in which case read_next() was already
|
|
||||||
//called so just return current
|
|
||||||
var tok = current;
|
|
||||||
current = null;
|
|
||||||
return tok || read_next();
|
|
||||||
}
|
|
||||||
|
|
||||||
function eof() {
|
|
||||||
return peek() == null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,8 @@ function WorkerScript(runningScriptObj) {
|
|||||||
this.running = false;
|
this.running = false;
|
||||||
this.serverIp = null;
|
this.serverIp = null;
|
||||||
this.code = runningScriptObj.scriptRef.code;
|
this.code = runningScriptObj.scriptRef.code;
|
||||||
this.env = new Environment();
|
this.env = new Environment(this);
|
||||||
|
this.env.set("args", runningScriptObj.args);
|
||||||
this.output = "";
|
this.output = "";
|
||||||
this.ramUsage = 0;
|
this.ramUsage = 0;
|
||||||
this.scriptRef = runningScriptObj;
|
this.scriptRef = runningScriptObj;
|
||||||
@ -31,7 +32,7 @@ function runScriptsLoop() {
|
|||||||
//If it isn't running, start the script
|
//If it isn't running, start the script
|
||||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
||||||
try {
|
try {
|
||||||
var ast = Parser(Tokenizer(InputStream(workerScripts[i].code)));
|
var ast = acorn.parse(workerScripts[i].code);
|
||||||
//console.log(ast);
|
//console.log(ast);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing script: " + workerScripts[i].name);
|
console.log("Error parsing script: " + workerScripts[i].name);
|
||||||
|
3606
utils/acorn.js
Normal file
3606
utils/acorn.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user