Initial commit for new Netscript 1 Intepreter

This commit is contained in:
danielyxie 2018-07-08 18:53:24 -05:00
parent fde2b8cbc1
commit 78c5a1b0f4
7 changed files with 6262 additions and 1383 deletions

7395
dist/engine.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -809,7 +809,7 @@
</span>
</label>
<input type ="range" max="250" min="15" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100" />
<input type ="range" max="250" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100" />
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
</fieldset>

@ -487,27 +487,10 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.39.1<br>" +
"* Bladeburner Rank gain in BN-7 is now reduced by 40% instead of 50%<br>" +
"* Quadrupled the amount of money gained from Bladeburner contracts<br>" +
"* Added joinBladeburnerDivision() Netscript function to Bladeburner API<br>" +
"* Doubled the effects of Source-File 5. Now gives 8%, 12%, and 14% increase to all hacking multipliers " +
"at levels 1, 2, and 3, respectively (increased from 4%/6%, 7%)<br>" +
"* Increased the effect of Source-File 8. It now gives a 12%, 18% and 21% to your hacking growth multiplier " +
"at levels 1, 2, and 3, respectively (increased from 8%, 12%, 14%)<br>" +
"* The effect of Source-File 12 is now additive with itself, rather than multiplicative. This means " +
"that level N of Source-File 12 now increases all multipliers by N%<br>" +
"* The setting to suppress the confirmation box when purchasing Augmentations was moved into the main Options menu (by Github user hydroflame)<br>" +
"* Bug Fix: Crime Success rates were being calculated incorrectly (by Github user hydroflame)<br>" +
"* When an Infiltration is finished, you will now return back to the company's page, rather than the city<br>" +
"* Infiltration faction reputation selector now remembers your last choice<br>" +
"* Significantly increased the amount of money gained from Infiltration<br>" +
"* Bug Fix: Copying a NetscriptJS script to another server using scp now properly takes into account " +
"the script's changes.<br>" +
"* Bug Fix: Fixed an issue where game would not load in Edge due to incompatible features<br>" +
"* travelToCity() Singularity function no longer grants Intelligence exp"
"v0.40.0<br>" +
"* Minimum Netscript execution time reduced from 15ms to 10ms (configurable in Options)<br>" +
"* HP is now reset (restored) when Augmenting<br>" +
"* Bug Fix: Infiltration buttons can no longer be clicked through NetscriptJS<br>"
}
export {CONSTANTS};

136
src/JSInterpreter.js Normal file

File diff suppressed because one or more lines are too long

@ -44,7 +44,6 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
scriptCalculateHackingChance, scriptCalculateHackingTime,
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
scriptCalculateGrowTime, scriptCalculateWeakenTime} from "./NetscriptEvaluator";
import {Environment} from "./NetscriptEnvironment";
import {NetscriptPort} from "./NetscriptPort";
import Decimal from "decimal.js";
@ -164,10 +163,9 @@ function NetscriptFunctions(workerScript) {
};
return {
Math : Math,
Date : Date,
Number : Number,
hacknetnodes : Player.hacknetNodeWrappers,
hacknetnodes : function() {
return Player.hacknetNodeWrappers;
},
sprintf : sprintf,
vsprintf: vsprintf,
scan : function(ip=workerScript.serverIp, hostnames=true){

@ -3,10 +3,12 @@ import {addActiveScriptsItem,
updateActiveScriptsItems} from "./ActiveScriptsUI";
import {CONSTANTS} from "./Constants";
import {Engine} from "./engine";
import {Interpreter} from "./JSInterpreter";
import {Environment} from "./NetscriptEnvironment";
import {evaluate, isScriptErrorMessage,
makeRuntimeRejectMsg,
killNetscriptDelay} from "./NetscriptEvaluator";
import {NetscriptFunctions} from "./NetscriptFunctions";
import {executeJSScript} from "./NetscriptJSEvaluator";
import {NetscriptPort} from "./NetscriptPort";
import {AllServers} from "./Server";
@ -16,6 +18,7 @@ import {parse} from "../utils/acorn";
import {dialogBoxCreate} from "../utils/DialogBox";
import {compareArrays, printArray,
roundToTwo} from "../utils/HelperFunctions";
import {isString} from "../utils/StringHelperFunctions";
function WorkerScript(runningScriptObj) {
this.name = runningScriptObj.filename;
@ -85,7 +88,7 @@ function prestigeWorkerScripts() {
// JS script promises need a little massaging to have the same guarantees as netscript
// promises. This does said massaging and kicks the script off. It returns a promise
// that resolves or rejects when the corresponding worker script is done.
function startJsScript(workerScript) {
function startNetscript2Script(workerScript) {
workerScript.running = true;
// The name of the currently running netscript function, to prevent concurrent
@ -152,6 +155,73 @@ function startJsScript(workerScript) {
});
}
function startNetscript1Script(workerScript) {
var code = workerScript.code;
workerScript.running = true;
var interpreterInitialization = function(int, scope) {
//Add the Netscript environment
var ns = NetscriptFunctions(workerScript);
for (var name in ns) {
let entry = ns[name];
if (typeof entry === "function") {
//Async functions need to be wrapped. See JS-Interpreter documentation
if (name === "hack" || name === "grow" || name === "weaken" || name === "sleep" ||
name === "prompt" || name === "run" || name === "exec") {
let tempWrapper = function() {
let fnArgs = [];
for (let i = 0; i < arguments.length-1; ++i) {
fnArgs.push(arguments[i]);
}
let cb = arguments[arguments.length-1];
let fnPromise = entry.apply(null, fnArgs);
fnPromise.then(function(res) {
cb(res);
});
}
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper));
} else {
int.setProperty(scope, name, int.createNativeFunction(entry));
}
} else {
//Math, Date, Number, hacknetnodes, bladeburner
int.setProperty(scope, name, int.nativeToPseudo(entry));
}
}
//Add the arguments
int.setProperty(scope, "args", int.nativeToPseudo(workerScript.args));
}
var interpreter = new Interpreter(code, interpreterInitialization);
return new Promise(function(resolve, reject) {
function runInterpreter() {
try {
if (workerScript.env.stopFlag) {return reject(workerScript);}
if (interpreter.step()) {
window.setTimeout(runInterpreter, Settings.CodeInstructionRunTime);
} else {
resolve(workerScript);
}
} catch(e) {
if (isString(e)) {
workerScript.errorMessage = e;
return reject(workerScript);
} else if (e instanceof WorkerScript) {
return reject(e);
} else {
return reject(workerScript);
}
}
}
runInterpreter();
});
}
//Loop through workerScripts and run every script that is not currently running
function runScriptsLoop() {
var scriptDeleted = false;
@ -200,8 +270,10 @@ function runScriptsLoop() {
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
let p = null; // p is the script's result promise.
if (workerScripts[i].name.endsWith(".js") || workerScripts[i].name.endsWith(".ns")) {
p = startJsScript(workerScripts[i]);
p = startNetscript2Script(workerScripts[i]);
} else {
p = startNetscript1Script(workerScripts[i]);
/*
try {
var ast = parse(workerScripts[i].code, {sourceType:"module"});
//console.log(ast);
@ -213,6 +285,7 @@ function runScriptsLoop() {
}
workerScripts[i].running = true;
p = evaluate(ast, workerScripts[i]);
*/
}
//Once the code finishes (either resolved or rejected, doesnt matter), set its

@ -507,7 +507,7 @@ function parseOnlyRamCalculate(server, code, workerScript) {
return ram;
} catch (error) {
console.info("parse or eval error: ", error);
//console.info("parse or eval error: ", error);
// This is not unexpected. The user may be editing a script, and it may be in
// a transitory invalid state.
return -1;