diff --git a/src/Netscript/Environment.js b/src/Netscript/Environment.js index 09c060315..c379030c9 100644 --- a/src/Netscript/Environment.js +++ b/src/Netscript/Environment.js @@ -44,5 +44,7 @@ Environment.prototype = { //Creates (or overwrites) a variable in the current scope def: function(name, value) { return this.vars[name] = value; - } + }, + + stopFlag: false }; \ No newline at end of file diff --git a/src/Netscript/Evaluator.js b/src/Netscript/Evaluator.js index ae59ed9b3..bfb13f7f0 100644 --- a/src/Netscript/Evaluator.js +++ b/src/Netscript/Evaluator.js @@ -11,11 +11,13 @@ function evaluate(exp, workerScript) { case "str": case "bool": return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} resolve(exp.value); }); break; case "var": return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} resolve(env.get(exp.value)); }); break; @@ -23,6 +25,8 @@ function evaluate(exp, workerScript) { case "assign": console.log("Evaluating assign operation"); return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + if (exp.left.type != "var") throw new Error("Cannot assign to " + JSON.stringify(exp.left)); @@ -31,6 +35,8 @@ function evaluate(exp, workerScript) { var expRightPromise = evaluate(exp.right, workerScript); expRightPromise.then(function(expRight) { resolve(expRight); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime) }); @@ -40,17 +46,23 @@ function evaluate(exp, workerScript) { env.set(exp.left.value, expRight); console.log("Assign operation finished"); resolve("assignFinished"); + }, function() { + reject("Stopping script"); }); }); case "binary": console.log("Binary operation called"); return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + var pLeft = new Promise(function(resolve, reject) { setTimeout(function() { var promise = evaluate(exp.left, workerScript); promise.then(function(valLeft) { resolve(valLeft); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -61,6 +73,8 @@ function evaluate(exp, workerScript) { var promise = evaluate(exp.right, workerScript); promise.then(function(valRight) { resolve([valLeft, valRight]); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -68,7 +82,11 @@ function evaluate(exp, workerScript) { pRight.then(function(args) { console.log("Resolving binary operation"); resolve(apply_op(exp.operator, args[0], args[1])); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); }); break; @@ -92,12 +110,16 @@ function evaluate(exp, workerScript) { case "for": return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + console.log("for loop encountered in evaluator"); var pInit = new Promise(function(resolve, reject) { setTimeout(function() { var resInit = evaluate(exp.init, workerScript); resInit.then(function(foo) { resolve(resInit); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -106,24 +128,36 @@ function evaluate(exp, workerScript) { var pForLoop = evaluateFor(exp, workerScript); pForLoop.then(function(forLoopRes) { resolve("forLoopDone"); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); }); break; case "while": console.log("Evaluating while loop"); return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + var pEvaluateWhile = evaluateWhile(exp, workerScript); pEvaluateWhile.then(function(whileLoopRes) { resolve("whileLoopDone"); + }, function() { + reject("Stopping script"); }); }); break; case "prog": return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + var evaluateProgPromise = evaluateProg(exp, workerScript, 0); evaluateProgPromise.then(function(res) { resolve(res); + }, function() { + reject("Stopping script"); }); }); break; @@ -141,19 +175,68 @@ function evaluate(exp, workerScript) { // return evaluate(arg, env); //})); return new Promise(function(resolve, reject) { + if (env.stopFlag) {reject("Stopping script");} + setTimeout(function() { if (exp.func.value == "hack") { console.log("Execute hack()"); - resolve("hackExecuted"); + if (exp.args.length != 0) { + throw new Error("Hack() call has incorrect number of arguments. Takes no arguments");) + } + + var p = new Promise(function(resolve, reject) { + setTimeout(function() { + var hackChance = Player.calculateHackingChance(); + var rand = Math.random(); + var expGainedOnSuccess = Player.calculateExpGain(); + var expGainedOnFailure = Math.round(expGainedOnSuccess / 4); + if (rand < hackChance) { //Success! + var moneyGained = Player.calculatePercentMoneyHacked(); + moneyGained = Math.floor(Player.getCurrentServer().moneyAvailable * moneyGained); + + Player.getCurrentServer().moneyAvailable -= moneyGained; + Player.money += moneyGained; + + Player.hacking_exp += expGainedOnSuccess; + } else { + //Player only gains 25% exp for failure? TODO Can change this later to balance + Player.hacking_exp += expGainedOnFailure; + } + }, CONSTANTS.CodeInstructionRunTime); + }); + + p.then(function(res) { + resolve("hackExecuted"); + }); + } else if (exp.func.value == "sleep") { console.log("Execute sleep()"); - resolve("sleepExecuted"); + if (exp.args.length != 1) { + throw new Error("Sleep() call has incorrect number of arguments. Takes 1 argument."); + } + + var p = new Promise(function(resolve, reject) { + setTimeout(function() { + resolve("foo"); + }, exp.args[0]); + }); + + p.then(function(res) { + resolve("sleepExecuted"); + }); + } else if (exp.func.value == "print") { + if (exp.args.length != 1) { + throw new Error("Print() call has incorrect number of arguments. Takes 1 argument"); + } + var p = new Promise(function(resolve, reject) { setTimeout(function() { var evaluatePromise = evaluate(exp.args[0], workerScript); evaluatePromise.then(function(res) { resolve(res); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -162,6 +245,8 @@ function evaluate(exp, workerScript) { post(res.toString()); console.log("Print call executed"); resolve("printExecuted"); + }, function() { + reject("Stopping script"); }); } }, CONSTANTS.CodeInstructionRunTime); @@ -183,6 +268,8 @@ function evaluateFor(exp, workerScript) { evaluatePromise.then(function(resCond) { console.log("Conditional evaluated to: " + resCond); resolve(resCond); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -197,6 +284,8 @@ function evaluateFor(exp, workerScript) { evaluatePromise.then(function(resCode) { console.log("Evaluated an iteration of for loop code"); resolve(resCode); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -209,6 +298,8 @@ function evaluateFor(exp, workerScript) { evaluatePromise.then(function(foo) { console.log("Evaluated for loop postloop"); resolve("postLoopFinished"); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -217,14 +308,22 @@ function evaluateFor(exp, workerScript) { var recursiveCall = evaluateFor(exp, workerScript); recursiveCall.then(function(foo) { resolve("endForLoop"); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); } else { console.log("Cond is false, stopping for loop"); resolve("endForLoop"); //Doesn't need to resolve to any particular value } + }, function() { + reject("Stopping script"); }); }); } @@ -238,6 +337,8 @@ function evaluateWhile(exp, workerScript) { evaluatePromise.then(function(resCond) { console.log("Conditional evaluated to: " + resCond); resolve(resCond); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -251,6 +352,8 @@ function evaluateWhile(exp, workerScript) { evaluatePromise.then(function(resCode) { console.log("Evaluated an iteration of while loop code"); resolve(resCode); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -260,12 +363,18 @@ function evaluateWhile(exp, workerScript) { var recursiveCall = evaluateWhile(exp, workerScript); recursiveCall.then(function(foo) { resolve("endWhileLoop"); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); } else { console.log("Cond is false, stopping while loop"); resolve("endWhileLoop"); //Doesn't need to resolve to any particular value } + }, function() { + reject("Stopping script"); }); }); } @@ -283,6 +392,8 @@ function evaluateProg(exp, workerScript, index) { var evaluatePromise = evaluate(exp.prog[index], workerScript); evaluatePromise.then(function(evalRes) { resolve(evalRes); + }, function() { + reject("Stopping script"); }); }, CONSTANTS.CodeInstructionRunTime); }); @@ -292,7 +403,11 @@ function evaluateProg(exp, workerScript, index) { var nextLine = evaluateProg(exp, workerScript, index + 1); nextLine.then(function(nextLineRes) { resolve("progDone"); + }, function() { + reject("Stopping script"); }); + }, function() { + reject("Stopping script"); }); } }); diff --git a/src/Netscript/NetscriptWorker.js b/src/Netscript/NetscriptWorker.js index f1e4da0d3..46fd13342 100644 --- a/src/Netscript/NetscriptWorker.js +++ b/src/Netscript/NetscriptWorker.js @@ -20,7 +20,9 @@ var workerScripts = []; //Loop through workerScripts and run every script that is not currently running function runScriptsLoop() { + //Run any scripts that haven't been started for (var i = 0; i < workerScripts.length; i++) { + //If it isn't running, start the script if (workerScripts[i].running == false) { var ast = Parser(Tokenizer(InputStream(workerScripts[i].code))); @@ -29,7 +31,34 @@ function runScriptsLoop() { console.log(ast); workerScripts[i].running = true; - evaluate(ast, workerScripts[i]); + var p = evaluate(ast, workerScripts[i]); + + //Once the code finishes (either resolved or rejected, doesnt matter), set its + //running status to false + p.then(function(foo) { + workerScripts[i].running = false; + }, function() { + workerScripts[i].running = false; + }); + } + } + + //Delete any scripts that finished or have been killed. Loop backwards bc removing + //items fucks up the indexing + for (var i = workerScripts.length - 1; i >= 0; i--) { + if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) { + //Delete script from the runningScripts array on its host serverIp + var ip = workerScripts[i].serverIp; + var name = workerScripts[i].name; + for (var j = 0; j < AllServers[ip].runningScripts.length; j++) { + if (AllServers[ip].runningScripts[j] == name) { + AllServers[i].runningScripts.splice(j, 1); + break; + } + } + + //Delete script from workerScripts + workerScripts.splice(i, 1); } } diff --git a/src/Terminal.js b/src/Terminal.js index d8a0a5334..e3c460528 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -221,9 +221,9 @@ var Terminal = { break; case "free": if (commandArray.length != 1) { - post("Incorrect usage of df command. Usage: df"); return; + post("Incorrect usage of free command. Usage: free"); return; } - console.log("df terminal command called"); + console.log("free terminal command called"); post("Total: " + Player.getCurrentServer().maxRam.toString() + " GB"); post("Used: " + Player.getCurrentServer().ramUsed.toString() + " GB"); post("Available: " + (Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed).toString() + " GB"); @@ -359,7 +359,12 @@ var Terminal = { } break; case "ps": - //TODO + if (commandArray.length != 1) { + post("Incorrect usage of ps command. Usage: ps"); + } + for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) { + post(Player.getCurrentServer().runningScripts[i]); + } break; case "rm": //TODO diff --git a/src/engine.js b/src/engine.js index 648dc5421..87f9b7678 100644 --- a/src/engine.js +++ b/src/engine.js @@ -1,6 +1,3 @@ -//TODO Saving only works with stirngs.key value pairs. Think of a system to do saves -// And everything with all the things I have - //Replaces the character at an index with a new character String.prototype.replaceAt=function(index, character) { return this.substr(0, index) + character + this.substr(index+character.length); diff --git a/utils/JSONReviver.js b/utils/JSONReviver.js index 1aff041b1..18e504c50 100644 --- a/utils/JSONReviver.js +++ b/utils/JSONReviver.js @@ -36,7 +36,6 @@ Reviver.constructors = {}; // A list of constructors the smart reviver should kn function Generic_toJSON(ctorName, obj, keys) { var data, index, key; - console.log("Generic_toJSON() called"); if (!keys) { keys = Object.keys(obj); // Only "own" properties are included }