mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 09:43:54 +01:00
commit
26ddf99d76
800
dist/engine.bundle.js
vendored
800
dist/engine.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
800
dist/tests.bundle.js
vendored
800
dist/tests.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
BIN
doc/build/doctrees/environment.pickle
vendored
BIN
doc/build/doctrees/environment.pickle
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscript.doctree
vendored
BIN
doc/build/doctrees/netscript.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscriptjs.doctree
vendored
Normal file
BIN
doc/build/doctrees/netscriptjs.doctree
vendored
Normal file
Binary file not shown.
BIN
doc/build/doctrees/terminal.doctree
vendored
BIN
doc/build/doctrees/terminal.doctree
vendored
Binary file not shown.
1
doc/build/html/_sources/netscript.rst.txt
vendored
1
doc/build/html/_sources/netscript.rst.txt
vendored
@ -14,6 +14,7 @@ to reach out to the developer!
|
|||||||
:maxdepth: 5
|
:maxdepth: 5
|
||||||
:caption: Sections:
|
:caption: Sections:
|
||||||
|
|
||||||
|
NetscriptJS (Netscript 2.0) <netscriptjs>
|
||||||
Data Types and Variables <netscriptdatatypes>
|
Data Types and Variables <netscriptdatatypes>
|
||||||
Operators <netscriptoperators>
|
Operators <netscriptoperators>
|
||||||
Loops and Conditionals <netscriptloopsandconditionals>
|
Loops and Conditionals <netscriptloopsandconditionals>
|
||||||
|
204
doc/build/html/_sources/netscriptjs.rst.txt
vendored
Normal file
204
doc/build/html/_sources/netscriptjs.rst.txt
vendored
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
NetscriptJS (Netscript 2.0)
|
||||||
|
===========================
|
||||||
|
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||||
|
allows users to write (almost) full-fledged Javascript code in their scripts, while
|
||||||
|
still being able to access the Netscript functions.
|
||||||
|
|
||||||
|
NetscriptJS was developed primarily by `Github user jaguilar <https://github.com/jaguilar>`_
|
||||||
|
|
||||||
|
On top of having almost all of the features and capabilities of Javascript, NetscriptJS is also
|
||||||
|
significantly faster than Netscript 1.0.
|
||||||
|
|
||||||
|
This documentation will not go over any of the additional features of NetscriptJS, since
|
||||||
|
there is plenty of documentation on Javascript available on the web.
|
||||||
|
|
||||||
|
NetscriptJS in Mozilla Firefox
|
||||||
|
------------------------------
|
||||||
|
As of the time of writing this, the Mozilla Firefox browser does not support
|
||||||
|
dynamic import functionality and therefore cannot run NetscriptJS scripts.
|
||||||
|
|
||||||
|
(This may be some option/method for enabling this in Firefox, but I don't know
|
||||||
|
what is it)
|
||||||
|
|
||||||
|
How to use NetscriptJS
|
||||||
|
----------------------
|
||||||
|
Working with NetscriptJS scripts is the same as Netscript 1.0 scripts. The only difference
|
||||||
|
is that NetscriptJS scripts use the ".ns" or ".js" extension rather than ".script". E.g.::
|
||||||
|
|
||||||
|
$ nano foo.ns
|
||||||
|
$ run foo.ns -t 100 arg1 arg2 arg3
|
||||||
|
exec("foo.ns", "purchasedServer1", "100", "randomArg");
|
||||||
|
|
||||||
|
The caveat when using NetscriptJS to write scripts is that your code must be
|
||||||
|
asynchronous. Furthermore, instead of using the global scope and executing your code
|
||||||
|
sequentially, NetscriptJS uses a :code:`main()` function as an entry point.
|
||||||
|
|
||||||
|
Furthermore, the "Netscript environment" must be passed into a NetscriptJS script through
|
||||||
|
the main function. This environment includes all of the pre-defined Netscript functions
|
||||||
|
(:code:`hack()`, :code:`exec`, etc.) as well as the arguments you pass to the script.
|
||||||
|
|
||||||
|
Therefore, the signature of the :code:`main()` function must be::
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print("Starting script here");
|
||||||
|
await ns.hack("foodnstuff"); //Use Netscript hack function
|
||||||
|
ns.print(ns.args); //The script arguments must be prefaced with ns as well
|
||||||
|
}
|
||||||
|
|
||||||
|
Here is a summary of all rules you need to follow when writing Netscript JS code:
|
||||||
|
|
||||||
|
* Write :code:`await` before any call to the following Netscript functions:
|
||||||
|
|
||||||
|
* hack
|
||||||
|
* grow
|
||||||
|
* weaken
|
||||||
|
* sleep
|
||||||
|
* run
|
||||||
|
* exec
|
||||||
|
* prompt
|
||||||
|
|
||||||
|
* Any function that contains :code:`await` must be declared as :code:`async`
|
||||||
|
|
||||||
|
* Always :code:`await` any function that is marked as :code:`async`
|
||||||
|
|
||||||
|
* Any functions that you want to be visible from other scripts must be marked with :code:`export`.
|
||||||
|
|
||||||
|
* **Do not write any infinite loops without using a** :code:`sleep` **or one of the timed Netscript functions like** :code:`hack`. Doing so will crash your game.
|
||||||
|
|
||||||
|
* Any global variable declared in a NetscriptJS script is shared between all instances of that
|
||||||
|
script. For example, assume you write a script *foo.ns* and declared a global variable like so::
|
||||||
|
|
||||||
|
//foo.ns
|
||||||
|
let globalVariable;
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
globalVariable = ns.args.length;
|
||||||
|
while(true) {
|
||||||
|
ns.tprint(globalVariable);
|
||||||
|
await ns.sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Then, you ran multiple instances of *foo.ns*::
|
||||||
|
|
||||||
|
$ run foo.ns 1
|
||||||
|
$ run foo.ns 1 2 3
|
||||||
|
$ run foo.ns 1 2 3 4 5
|
||||||
|
|
||||||
|
Then all three instances of foo.ns will share the same instance of :code:`globalVariable`.
|
||||||
|
(In this example, the value of :code:`globalVariable` will be set to 5 because the
|
||||||
|
last instance of *foo.ns* to run has 5 arguments. This means that all three instances of
|
||||||
|
the script will repeatedly print the value 5).
|
||||||
|
|
||||||
|
These global variables can be thought of as `C++ static class members <https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm>`_,
|
||||||
|
where a NetscriptJS script is a class and a global variable is a static member within that class.
|
||||||
|
|
||||||
|
Warnings
|
||||||
|
--------
|
||||||
|
The NetscriptJS evaluation engine works by converting your code into a blob URL and then
|
||||||
|
using a dynamic import to load your code as a module. Every unique NetscriptJS script
|
||||||
|
is loaded as its own module. This means that
|
||||||
|
making a small edit to a NetscriptJS script results in a new module being generated.
|
||||||
|
|
||||||
|
At this point, we have been unable to find a method for deleting modules from browsers so that
|
||||||
|
they get garbage collected.
|
||||||
|
|
||||||
|
The result is that these modules from NetscriptJS scripts accumulate in your browser,
|
||||||
|
using memory that never gets released. Over time, this results in a memory-leak type
|
||||||
|
situation that can slow down your computer.
|
||||||
|
|
||||||
|
Therefore, there are two recommendations for those who decide to use NetscriptJS:
|
||||||
|
|
||||||
|
1. Every now and then, close and re-open the game. This will clear all of the modules.
|
||||||
|
To be safe, I recommend **completely** closing the game's tab and then re-opening it.
|
||||||
|
Depending on your browser, a refresh or page reload does not always clear the modules.
|
||||||
|
|
||||||
|
2. Only use NetscriptJS scripts when needed. It is very unlikely that NetscriptJS
|
||||||
|
is needed for very simple scripts. By doing this, you will reduce the number of modules
|
||||||
|
that are loaded.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
**DOM Manipulation (tprintColored.ns)**
|
||||||
|
|
||||||
|
Directly alter the game's terminal and print colored text::
|
||||||
|
|
||||||
|
export function tprintColored(txt, color) {
|
||||||
|
let terminalInput = document.getElementById("terminal-input");
|
||||||
|
let rowElement = document.createElement("tr");
|
||||||
|
let cellElement = document.createElement("td");
|
||||||
|
|
||||||
|
rowElement.classList.add("posted");
|
||||||
|
cellElement.classList.add("terminal-line");
|
||||||
|
cellElement.style.color = color;
|
||||||
|
cellElement.innerText = txt;
|
||||||
|
|
||||||
|
rowElement.appendChild(cellElement);
|
||||||
|
terminalInput.before(rowElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
tprintColored("Red Text!", "red");
|
||||||
|
tprintColored("Blue Text!", "blue");
|
||||||
|
tprintColored("Use Hex Codes!", "#3087E3");
|
||||||
|
}
|
||||||
|
|
||||||
|
**Script Scheduler (scriptScheduler.ns)**
|
||||||
|
|
||||||
|
This script shows some of the new functionality that is available in NetscriptJS,
|
||||||
|
including objects and object constructors, changing an object's prototype, and
|
||||||
|
importing other NetscriptJS scripts::
|
||||||
|
|
||||||
|
import {tprintColored} from "tprintColored.ns"; //Importing from other NetscriptJS scripts works!
|
||||||
|
|
||||||
|
function ScriptJob(params) {
|
||||||
|
if (params.fn == null) {
|
||||||
|
throw new Error("No Filename (fn) passed into ScriptJob ctor");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fn = params.fn;
|
||||||
|
this.threads = params.threads ? params.threads : 1;
|
||||||
|
this.args = params.args ? params.args : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.run = async function(ns) {
|
||||||
|
let runArgs = [this.fn, this.threads].concat(this.args);
|
||||||
|
await ns.run.apply(this, runArgs);
|
||||||
|
tprintColored("Running " + this.fn + " on " + ns.getHostname(), "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.exec = async function(ns, target) {
|
||||||
|
ns.scp(this.fn, target);
|
||||||
|
|
||||||
|
let execArgs = [this.fn, target, this.threads].concat(this.args);
|
||||||
|
await ns.exec.apply(this, execArgs);
|
||||||
|
|
||||||
|
tprintColored("Executing " + this.fn + " on " + target, "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
tprintColored("Starting scriptScheduler.ns", "red");
|
||||||
|
try {
|
||||||
|
let job = new ScriptJob({
|
||||||
|
fn: "test.js",
|
||||||
|
threads: 1,
|
||||||
|
args: ["foodnstuff"]
|
||||||
|
});
|
||||||
|
await job.run(ns);
|
||||||
|
await job.exec(ns, "foodnstuff");
|
||||||
|
} catch (e) {
|
||||||
|
ns.tprint("Exception thrown in scriptScheduler.ns: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Final Note
|
||||||
|
----------
|
||||||
|
NetscriptJS opens up a lot of possibilities when scripting. I look forward to seeing
|
||||||
|
the scripts that people come up with. Just remember that the power and capabilities of
|
||||||
|
NetscriptJS come with risks. Please backup your save if you're going to experiment with
|
||||||
|
NetscriptJS and report any serious exploits.
|
||||||
|
|
||||||
|
With great power comes great responsibility
|
||||||
|
|
||||||
|
Happy hacking
|
2
doc/build/html/_sources/terminal.rst.txt
vendored
2
doc/build/html/_sources/terminal.rst.txt
vendored
@ -266,7 +266,7 @@ nano
|
|||||||
|
|
||||||
$ nano [filename]
|
$ nano [filename]
|
||||||
|
|
||||||
Opens up the specified file in the Text Editor. Only scripts (.script) and
|
Opens up the specified file in the Text Editor. Only scripts (.script, .ns, .js) and
|
||||||
text files (.txt) can be edited. If the file does not already exist, then a new
|
text files (.txt) can be edited. If the file does not already exist, then a new
|
||||||
empty file will be created.
|
empty file will be created.
|
||||||
|
|
||||||
|
8
doc/build/html/index.html
vendored
8
doc/build/html/index.html
vendored
@ -62,6 +62,14 @@ secrets that you've been searching for.</p>
|
|||||||
<p class="caption"><span class="caption-text">Contents:</span></p>
|
<p class="caption"><span class="caption-text">Contents:</span></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="netscript.html"> Netscript</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="netscript.html"> Netscript</a><ul>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html"> NetscriptJS (Netscript 2.0)</a><ul>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="netscriptjs.html#netscriptjs-in-mozilla-firefox">NetscriptJS in Mozilla Firefox</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="netscriptjs.html#how-to-use-netscriptjs">How to use NetscriptJS</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="netscriptjs.html#warnings">Warnings</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="netscriptjs.html#examples">Examples</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="netscriptjs.html#final-note">Final Note</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a><ul>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a><ul>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="netscriptdatatypes.html#data-types">Data Types</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="netscriptdatatypes.html#data-types">Data Types</a></li>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="netscriptdatatypes.html#variables">Variables</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="netscriptdatatypes.html#variables">Variables</a></li>
|
||||||
|
15
doc/build/html/netscript.html
vendored
15
doc/build/html/netscript.html
vendored
@ -24,7 +24,7 @@
|
|||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||||
<link rel="index" title="Index" href="genindex.html" />
|
<link rel="index" title="Index" href="genindex.html" />
|
||||||
<link rel="search" title="Search" href="search.html" />
|
<link rel="search" title="Search" href="search.html" />
|
||||||
<link rel="next" title="Netscript Data Types and Variables" href="netscriptdatatypes.html" />
|
<link rel="next" title="NetscriptJS (Netscript 2.0)" href="netscriptjs.html" />
|
||||||
<link rel="prev" title="Welcome to Bitburner's documentation!" href="index.html" />
|
<link rel="prev" title="Welcome to Bitburner's documentation!" href="index.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<div class="rel" role="navigation" aria-label="related navigation">
|
<div class="rel" role="navigation" aria-label="related navigation">
|
||||||
<a href="index.html" title="Welcome to Bitburner's documentation!"
|
<a href="index.html" title="Welcome to Bitburner's documentation!"
|
||||||
accesskey="P">previous</a> |
|
accesskey="P">previous</a> |
|
||||||
<a href="netscriptdatatypes.html" title="Netscript Data Types and Variables"
|
<a href="netscriptjs.html" title="NetscriptJS (Netscript 2.0)"
|
||||||
accesskey="N">next</a> |
|
accesskey="N">next</a> |
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
accesskey="I">index</a>
|
accesskey="I">index</a>
|
||||||
@ -63,6 +63,14 @@ to reach out to the developer!</p>
|
|||||||
<div class="toctree-wrapper compound">
|
<div class="toctree-wrapper compound">
|
||||||
<p class="caption"><span class="caption-text">Sections:</span></p>
|
<p class="caption"><span class="caption-text">Sections:</span></p>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="netscriptjs.html"> NetscriptJS (Netscript 2.0)</a><ul>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html#netscriptjs-in-mozilla-firefox">NetscriptJS in Mozilla Firefox</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html#how-to-use-netscriptjs">How to use NetscriptJS</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html#warnings">Warnings</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html#examples">Examples</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html#final-note">Final Note</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html#data-types">Data Types</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html#data-types">Data Types</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html#variables">Variables</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html#variables">Variables</a></li>
|
||||||
@ -226,6 +234,7 @@ to reach out to the developer!</p>
|
|||||||
<p class="caption"><span class="caption-text">Contents:</span></p>
|
<p class="caption"><span class="caption-text">Contents:</span></p>
|
||||||
<ul class="current">
|
<ul class="current">
|
||||||
<li class="toctree-l1 current"><a class="current reference internal" href="#"> Netscript</a><ul>
|
<li class="toctree-l1 current"><a class="current reference internal" href="#"> Netscript</a><ul>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html"> NetscriptJS (Netscript 2.0)</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptoperators.html"> Operators</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptoperators.html"> Operators</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="netscriptloopsandconditionals.html"> Loops and Conditionals</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="netscriptloopsandconditionals.html"> Loops and Conditionals</a></li>
|
||||||
@ -262,7 +271,7 @@ to reach out to the developer!</p>
|
|||||||
<div role="navigation" aria-label="related navigaton">
|
<div role="navigation" aria-label="related navigaton">
|
||||||
<a href="index.html" title="Welcome to Bitburner's documentation!"
|
<a href="index.html" title="Welcome to Bitburner's documentation!"
|
||||||
>previous</a> |
|
>previous</a> |
|
||||||
<a href="netscriptdatatypes.html" title="Netscript Data Types and Variables"
|
<a href="netscriptjs.html" title="NetscriptJS (Netscript 2.0)"
|
||||||
>next</a> |
|
>next</a> |
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
>index</a>
|
>index</a>
|
||||||
|
327
doc/build/html/netscriptjs.html
vendored
Normal file
327
doc/build/html/netscriptjs.html
vendored
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="English">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>NetscriptJS (Netscript 2.0) — Bitburner 1.0 documentation</title>
|
||||||
|
<link rel="stylesheet" href="_static/agogo.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
var DOCUMENTATION_OPTIONS = {
|
||||||
|
URL_ROOT: './',
|
||||||
|
VERSION: '1.0',
|
||||||
|
COLLAPSE_INDEX: false,
|
||||||
|
FILE_SUFFIX: '.html',
|
||||||
|
HAS_SOURCE: true,
|
||||||
|
SOURCELINK_SUFFIX: '.txt'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||||
|
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||||
|
<link rel="index" title="Index" href="genindex.html" />
|
||||||
|
<link rel="search" title="Search" href="search.html" />
|
||||||
|
<link rel="next" title="Netscript Data Types and Variables" href="netscriptdatatypes.html" />
|
||||||
|
<link rel="prev" title="Netscript Documentation" href="netscript.html" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header-wrapper" role="banner">
|
||||||
|
<div class="header">
|
||||||
|
<div class="headertitle"><a
|
||||||
|
href="index.html">Bitburner 1.0 documentation</a></div>
|
||||||
|
<div class="rel" role="navigation" aria-label="related navigation">
|
||||||
|
<a href="netscript.html" title="Netscript Documentation"
|
||||||
|
accesskey="P">previous</a> |
|
||||||
|
<a href="netscriptdatatypes.html" title="Netscript Data Types and Variables"
|
||||||
|
accesskey="N">next</a> |
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
accesskey="I">index</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<div class="document">
|
||||||
|
|
||||||
|
<div class="documentwrapper">
|
||||||
|
<div class="bodywrapper">
|
||||||
|
<div class="body" role="main">
|
||||||
|
|
||||||
|
<div class="section" id="netscriptjs-netscript-2-0">
|
||||||
|
<h1>NetscriptJS (Netscript 2.0)<a class="headerlink" href="#netscriptjs-netscript-2-0" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||||
|
allows users to write (almost) full-fledged Javascript code in their scripts, while
|
||||||
|
still being able to access the Netscript functions.</p>
|
||||||
|
<p>NetscriptJS was developed primarily by <a class="reference external" href="https://github.com/jaguilar">Github user jaguilar</a></p>
|
||||||
|
<p>On top of having almost all of the features and capabilities of Javascript, NetscriptJS is also
|
||||||
|
significantly faster than Netscript 1.0.</p>
|
||||||
|
<p>This documentation will not go over any of the additional features of NetscriptJS, since
|
||||||
|
there is plenty of documentation on Javascript available on the web.</p>
|
||||||
|
<div class="section" id="netscriptjs-in-mozilla-firefox">
|
||||||
|
<h2>NetscriptJS in Mozilla Firefox<a class="headerlink" href="#netscriptjs-in-mozilla-firefox" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p>As of the time of writing this, the Mozilla Firefox browser does not support
|
||||||
|
dynamic import functionality and therefore cannot run NetscriptJS scripts.</p>
|
||||||
|
<p>(This may be some option/method for enabling this in Firefox, but I don't know
|
||||||
|
what is it)</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="how-to-use-netscriptjs">
|
||||||
|
<h2>How to use NetscriptJS<a class="headerlink" href="#how-to-use-netscriptjs" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p>Working with NetscriptJS scripts is the same as Netscript 1.0 scripts. The only difference
|
||||||
|
is that NetscriptJS scripts use the ".ns" or ".js" extension rather than ".script". E.g.:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span>$ nano foo.ns
|
||||||
|
$ run foo.ns -t 100 arg1 arg2 arg3
|
||||||
|
exec("foo.ns", "purchasedServer1", "100", "randomArg");
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p>The caveat when using NetscriptJS to write scripts is that your code must be
|
||||||
|
asynchronous. Furthermore, instead of using the global scope and executing your code
|
||||||
|
sequentially, NetscriptJS uses a <code class="code docutils literal"><span class="pre">main()</span></code> function as an entry point.</p>
|
||||||
|
<p>Furthermore, the "Netscript environment" must be passed into a NetscriptJS script through
|
||||||
|
the main function. This environment includes all of the pre-defined Netscript functions
|
||||||
|
(<code class="code docutils literal"><span class="pre">hack()</span></code>, <code class="code docutils literal"><span class="pre">exec</span></code>, etc.) as well as the arguments you pass to the script.</p>
|
||||||
|
<p>Therefore, the signature of the <code class="code docutils literal"><span class="pre">main()</span></code> function must be:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="k">async</span> <span class="n">function</span> <span class="n">main</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="n">ns</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Starting script here"</span><span class="p">);</span>
|
||||||
|
<span class="k">await</span> <span class="n">ns</span><span class="o">.</span><span class="n">hack</span><span class="p">(</span><span class="s2">"foodnstuff"</span><span class="p">);</span> <span class="o">//</span><span class="n">Use</span> <span class="n">Netscript</span> <span class="n">hack</span> <span class="n">function</span>
|
||||||
|
<span class="n">ns</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">ns</span><span class="o">.</span><span class="n">args</span><span class="p">);</span> <span class="o">//</span><span class="n">The</span> <span class="n">script</span> <span class="n">arguments</span> <span class="n">must</span> <span class="n">be</span> <span class="n">prefaced</span> <span class="k">with</span> <span class="n">ns</span> <span class="k">as</span> <span class="n">well</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p>Here is a summary of all rules you need to follow when writing Netscript JS code:</p>
|
||||||
|
<ul>
|
||||||
|
<li><p class="first">Write <code class="code docutils literal"><span class="pre">await</span></code> before any call to the following Netscript functions:</p>
|
||||||
|
<blockquote>
|
||||||
|
<div><ul class="simple">
|
||||||
|
<li>hack</li>
|
||||||
|
<li>grow</li>
|
||||||
|
<li>weaken</li>
|
||||||
|
<li>sleep</li>
|
||||||
|
<li>run</li>
|
||||||
|
<li>exec</li>
|
||||||
|
<li>prompt</li>
|
||||||
|
</ul>
|
||||||
|
</div></blockquote>
|
||||||
|
</li>
|
||||||
|
<li><p class="first">Any function that contains <code class="code docutils literal"><span class="pre">await</span></code> must be declared as <code class="code docutils literal"><span class="pre">async</span></code></p>
|
||||||
|
</li>
|
||||||
|
<li><p class="first">Always <code class="code docutils literal"><span class="pre">await</span></code> any function that is marked as <code class="code docutils literal"><span class="pre">async</span></code></p>
|
||||||
|
</li>
|
||||||
|
<li><p class="first">Any functions that you want to be visible from other scripts must be marked with <code class="code docutils literal"><span class="pre">export</span></code>.</p>
|
||||||
|
</li>
|
||||||
|
<li><p class="first"><strong>Do not write any infinite loops without using a</strong> <code class="code docutils literal"><span class="pre">sleep</span></code> <strong>or one of the timed Netscript functions like</strong> <code class="code docutils literal"><span class="pre">hack</span></code>. Doing so will crash your game.</p>
|
||||||
|
</li>
|
||||||
|
<li><p class="first">Any global variable declared in a NetscriptJS script is shared between all instances of that
|
||||||
|
script. For example, assume you write a script <em>foo.ns</em> and declared a global variable like so:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">//</span><span class="n">foo</span><span class="o">.</span><span class="n">ns</span>
|
||||||
|
<span class="n">let</span> <span class="n">globalVariable</span><span class="p">;</span>
|
||||||
|
|
||||||
|
<span class="n">export</span> <span class="k">async</span> <span class="n">function</span> <span class="n">main</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="n">globalVariable</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">length</span><span class="p">;</span>
|
||||||
|
<span class="k">while</span><span class="p">(</span><span class="n">true</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="n">ns</span><span class="o">.</span><span class="n">tprint</span><span class="p">(</span><span class="n">globalVariable</span><span class="p">);</span>
|
||||||
|
<span class="k">await</span> <span class="n">ns</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p>Then, you ran multiple instances of <em>foo.ns</em>:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span>$ run foo.ns 1
|
||||||
|
$ run foo.ns 1 2 3
|
||||||
|
$ run foo.ns 1 2 3 4 5
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p>Then all three instances of foo.ns will share the same instance of <code class="code docutils literal"><span class="pre">globalVariable</span></code>.
|
||||||
|
(In this example, the value of <code class="code docutils literal"><span class="pre">globalVariable</span></code> will be set to 5 because the
|
||||||
|
last instance of <em>foo.ns</em> to run has 5 arguments. This means that all three instances of
|
||||||
|
the script will repeatedly print the value 5).</p>
|
||||||
|
<p>These global variables can be thought of as <a class="reference external" href="https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm">C++ static class members</a>,
|
||||||
|
where a NetscriptJS script is a class and a global variable is a static member within that class.</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="warnings">
|
||||||
|
<h2>Warnings<a class="headerlink" href="#warnings" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p>The NetscriptJS evaluation engine works by converting your code into a blob URL and then
|
||||||
|
using a dynamic import to load your code as a module. Every unique NetscriptJS script
|
||||||
|
is loaded as its own module. This means that
|
||||||
|
making a small edit to a NetscriptJS script results in a new module being generated.</p>
|
||||||
|
<p>At this point, we have been unable to find a method for deleting modules from browsers so that
|
||||||
|
they get garbage collected.</p>
|
||||||
|
<p>The result is that these modules from NetscriptJS scripts accumulate in your browser,
|
||||||
|
using memory that never gets released. Over time, this results in a memory-leak type
|
||||||
|
situation that can slow down your computer.</p>
|
||||||
|
<p>Therefore, there are two recommendations for those who decide to use NetscriptJS:</p>
|
||||||
|
<p>1. Every now and then, close and re-open the game. This will clear all of the modules.
|
||||||
|
To be safe, I recommend <strong>completely</strong> closing the game's tab and then re-opening it.
|
||||||
|
Depending on your browser, a refresh or page reload does not always clear the modules.</p>
|
||||||
|
<p>2. Only use NetscriptJS scripts when needed. It is very unlikely that NetscriptJS
|
||||||
|
is needed for very simple scripts. By doing this, you will reduce the number of modules
|
||||||
|
that are loaded.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="examples">
|
||||||
|
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p><strong>DOM Manipulation (tprintColored.ns)</strong></p>
|
||||||
|
<p>Directly alter the game's terminal and print colored text:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="n">function</span> <span class="n">tprintColored</span><span class="p">(</span><span class="n">txt</span><span class="p">,</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="n">let</span> <span class="n">terminalInput</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="n">getElementById</span><span class="p">(</span><span class="s2">"terminal-input"</span><span class="p">);</span>
|
||||||
|
<span class="n">let</span> <span class="n">rowElement</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="n">createElement</span><span class="p">(</span><span class="s2">"tr"</span><span class="p">);</span>
|
||||||
|
<span class="n">let</span> <span class="n">cellElement</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="n">createElement</span><span class="p">(</span><span class="s2">"td"</span><span class="p">);</span>
|
||||||
|
|
||||||
|
<span class="n">rowElement</span><span class="o">.</span><span class="n">classList</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"posted"</span><span class="p">);</span>
|
||||||
|
<span class="n">cellElement</span><span class="o">.</span><span class="n">classList</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"terminal-line"</span><span class="p">);</span>
|
||||||
|
<span class="n">cellElement</span><span class="o">.</span><span class="n">style</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="n">color</span><span class="p">;</span>
|
||||||
|
<span class="n">cellElement</span><span class="o">.</span><span class="n">innerText</span> <span class="o">=</span> <span class="n">txt</span><span class="p">;</span>
|
||||||
|
|
||||||
|
<span class="n">rowElement</span><span class="o">.</span><span class="n">appendChild</span><span class="p">(</span><span class="n">cellElement</span><span class="p">);</span>
|
||||||
|
<span class="n">terminalInput</span><span class="o">.</span><span class="n">before</span><span class="p">(</span><span class="n">rowElement</span><span class="p">);</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
|
||||||
|
<span class="n">export</span> <span class="k">async</span> <span class="n">function</span> <span class="n">main</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span> <span class="p">{</span>
|
||||||
|
<span class="n">tprintColored</span><span class="p">(</span><span class="s2">"Red Text!"</span><span class="p">,</span> <span class="s2">"red"</span><span class="p">);</span>
|
||||||
|
<span class="n">tprintColored</span><span class="p">(</span><span class="s2">"Blue Text!"</span><span class="p">,</span> <span class="s2">"blue"</span><span class="p">);</span>
|
||||||
|
<span class="n">tprintColored</span><span class="p">(</span><span class="s2">"Use Hex Codes!"</span><span class="p">,</span> <span class="s2">"#3087E3"</span><span class="p">);</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p><strong>Script Scheduler (scriptScheduler.ns)</strong></p>
|
||||||
|
<p>This script shows some of the new functionality that is available in NetscriptJS,
|
||||||
|
including objects and object constructors, changing an object's prototype, and
|
||||||
|
importing other NetscriptJS scripts:</p>
|
||||||
|
<div class="highlight-default"><div class="highlight"><pre><span></span>import {tprintColored} from "tprintColored.ns"; //Importing from other NetscriptJS scripts works!
|
||||||
|
|
||||||
|
function ScriptJob(params) {
|
||||||
|
if (params.fn == null) {
|
||||||
|
throw new Error("No Filename (fn) passed into ScriptJob ctor");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fn = params.fn;
|
||||||
|
this.threads = params.threads ? params.threads : 1;
|
||||||
|
this.args = params.args ? params.args : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.run = async function(ns) {
|
||||||
|
let runArgs = [this.fn, this.threads].concat(this.args);
|
||||||
|
await ns.run.apply(this, runArgs);
|
||||||
|
tprintColored("Running " + this.fn + " on " + ns.getHostname(), "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.exec = async function(ns, target) {
|
||||||
|
ns.scp(this.fn, target);
|
||||||
|
|
||||||
|
let execArgs = [this.fn, target, this.threads].concat(this.args);
|
||||||
|
await ns.exec.apply(this, execArgs);
|
||||||
|
|
||||||
|
tprintColored("Executing " + this.fn + " on " + target, "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
tprintColored("Starting scriptScheduler.ns", "red");
|
||||||
|
try {
|
||||||
|
let job = new ScriptJob({
|
||||||
|
fn: "test.js",
|
||||||
|
threads: 1,
|
||||||
|
args: ["foodnstuff"]
|
||||||
|
});
|
||||||
|
await job.run(ns);
|
||||||
|
await job.exec(ns, "foodnstuff");
|
||||||
|
} catch (e) {
|
||||||
|
ns.tprint("Exception thrown in scriptScheduler.ns: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="final-note">
|
||||||
|
<h2>Final Note<a class="headerlink" href="#final-note" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p>NetscriptJS opens up a lot of possibilities when scripting. I look forward to seeing
|
||||||
|
the scripts that people come up with. Just remember that the power and capabilities of
|
||||||
|
NetscriptJS come with risks. Please backup your save if you're going to experiment with
|
||||||
|
NetscriptJS and report any serious exploits.</p>
|
||||||
|
<p>With great power comes great responsibility</p>
|
||||||
|
<p>Happy hacking</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar">
|
||||||
|
<h3>Table Of Contents</h3>
|
||||||
|
<p class="caption"><span class="caption-text">Contents:</span></p>
|
||||||
|
<ul class="current">
|
||||||
|
<li class="toctree-l1 current"><a class="reference internal" href="netscript.html"> Netscript</a><ul class="current">
|
||||||
|
<li class="toctree-l2 current"><a class="current reference internal" href="#"> NetscriptJS (Netscript 2.0)</a><ul>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="#netscriptjs-in-mozilla-firefox">NetscriptJS in Mozilla Firefox</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="#how-to-use-netscriptjs">How to use NetscriptJS</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="#warnings">Warnings</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="#examples">Examples</a></li>
|
||||||
|
<li class="toctree-l3"><a class="reference internal" href="#final-note">Final Note</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptoperators.html"> Operators</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptloopsandconditionals.html"> Loops and Conditionals</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptscriptarguments.html"> Script Arguments</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html"> Basic Functions</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptadvancedfunctions.html"> Advanced Functions</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div role="search">
|
||||||
|
<h3 style="margin-top: 1.5em;">Search</h3>
|
||||||
|
<form class="search" action="search.html" method="get">
|
||||||
|
<input type="text" name="q" />
|
||||||
|
<input type="submit" value="Go" />
|
||||||
|
<input type="hidden" name="check_keywords" value="yes" />
|
||||||
|
<input type="hidden" name="area" value="default" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clearer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-wrapper">
|
||||||
|
<div class="footer">
|
||||||
|
<div class="left">
|
||||||
|
<div role="navigation" aria-label="related navigaton">
|
||||||
|
<a href="netscript.html" title="Netscript Documentation"
|
||||||
|
>previous</a> |
|
||||||
|
<a href="netscriptdatatypes.html" title="Netscript Data Types and Variables"
|
||||||
|
>next</a> |
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
>index</a>
|
||||||
|
</div>
|
||||||
|
<div role="note" aria-label="source link">
|
||||||
|
<br/>
|
||||||
|
<a href="_sources/netscriptjs.rst.txt"
|
||||||
|
rel="nofollow">Show Source</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right">
|
||||||
|
|
||||||
|
<div class="footer" role="contentinfo">
|
||||||
|
© Copyright 2017, Bitburner.
|
||||||
|
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.4.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clearer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
doc/build/html/objects.inv
vendored
BIN
doc/build/html/objects.inv
vendored
Binary file not shown.
2
doc/build/html/searchindex.js
vendored
2
doc/build/html/searchindex.js
vendored
File diff suppressed because one or more lines are too long
2
doc/build/html/terminal.html
vendored
2
doc/build/html/terminal.html
vendored
@ -291,7 +291,7 @@ to run 'foo.script' with 50 threads.</p>
|
|||||||
<h3>nano<a class="headerlink" href="#nano" title="Permalink to this headline">¶</a></h3>
|
<h3>nano<a class="headerlink" href="#nano" title="Permalink to this headline">¶</a></h3>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<div>$ nano [filename]</div></blockquote>
|
<div>$ nano [filename]</div></blockquote>
|
||||||
<p>Opens up the specified file in the Text Editor. Only scripts (.script) and
|
<p>Opens up the specified file in the Text Editor. Only scripts (.script, .ns, .js) and
|
||||||
text files (.txt) can be edited. If the file does not already exist, then a new
|
text files (.txt) can be edited. If the file does not already exist, then a new
|
||||||
empty file will be created.</p>
|
empty file will be created.</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +14,7 @@ to reach out to the developer!
|
|||||||
:maxdepth: 5
|
:maxdepth: 5
|
||||||
:caption: Sections:
|
:caption: Sections:
|
||||||
|
|
||||||
|
NetscriptJS (Netscript 2.0) <netscriptjs>
|
||||||
Data Types and Variables <netscriptdatatypes>
|
Data Types and Variables <netscriptdatatypes>
|
||||||
Operators <netscriptoperators>
|
Operators <netscriptoperators>
|
||||||
Loops and Conditionals <netscriptloopsandconditionals>
|
Loops and Conditionals <netscriptloopsandconditionals>
|
||||||
|
204
doc/source/netscriptjs.rst
Normal file
204
doc/source/netscriptjs.rst
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
NetscriptJS (Netscript 2.0)
|
||||||
|
===========================
|
||||||
|
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||||
|
allows users to write (almost) full-fledged Javascript code in their scripts, while
|
||||||
|
still being able to access the Netscript functions.
|
||||||
|
|
||||||
|
NetscriptJS was developed primarily by `Github user jaguilar <https://github.com/jaguilar>`_
|
||||||
|
|
||||||
|
On top of having almost all of the features and capabilities of Javascript, NetscriptJS is also
|
||||||
|
significantly faster than Netscript 1.0.
|
||||||
|
|
||||||
|
This documentation will not go over any of the additional features of NetscriptJS, since
|
||||||
|
there is plenty of documentation on Javascript available on the web.
|
||||||
|
|
||||||
|
NetscriptJS in Mozilla Firefox
|
||||||
|
------------------------------
|
||||||
|
As of the time of writing this, the Mozilla Firefox browser does not support
|
||||||
|
dynamic import functionality and therefore cannot run NetscriptJS scripts.
|
||||||
|
|
||||||
|
(This may be some option/method for enabling this in Firefox, but I don't know
|
||||||
|
what is it)
|
||||||
|
|
||||||
|
How to use NetscriptJS
|
||||||
|
----------------------
|
||||||
|
Working with NetscriptJS scripts is the same as Netscript 1.0 scripts. The only difference
|
||||||
|
is that NetscriptJS scripts use the ".ns" or ".js" extension rather than ".script". E.g.::
|
||||||
|
|
||||||
|
$ nano foo.ns
|
||||||
|
$ run foo.ns -t 100 arg1 arg2 arg3
|
||||||
|
exec("foo.ns", "purchasedServer1", "100", "randomArg");
|
||||||
|
|
||||||
|
The caveat when using NetscriptJS to write scripts is that your code must be
|
||||||
|
asynchronous. Furthermore, instead of using the global scope and executing your code
|
||||||
|
sequentially, NetscriptJS uses a :code:`main()` function as an entry point.
|
||||||
|
|
||||||
|
Furthermore, the "Netscript environment" must be passed into a NetscriptJS script through
|
||||||
|
the main function. This environment includes all of the pre-defined Netscript functions
|
||||||
|
(:code:`hack()`, :code:`exec`, etc.) as well as the arguments you pass to the script.
|
||||||
|
|
||||||
|
Therefore, the signature of the :code:`main()` function must be::
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print("Starting script here");
|
||||||
|
await ns.hack("foodnstuff"); //Use Netscript hack function
|
||||||
|
ns.print(ns.args); //The script arguments must be prefaced with ns as well
|
||||||
|
}
|
||||||
|
|
||||||
|
Here is a summary of all rules you need to follow when writing Netscript JS code:
|
||||||
|
|
||||||
|
* Write :code:`await` before any call to the following Netscript functions:
|
||||||
|
|
||||||
|
* hack
|
||||||
|
* grow
|
||||||
|
* weaken
|
||||||
|
* sleep
|
||||||
|
* run
|
||||||
|
* exec
|
||||||
|
* prompt
|
||||||
|
|
||||||
|
* Any function that contains :code:`await` must be declared as :code:`async`
|
||||||
|
|
||||||
|
* Always :code:`await` any function that is marked as :code:`async`
|
||||||
|
|
||||||
|
* Any functions that you want to be visible from other scripts must be marked with :code:`export`.
|
||||||
|
|
||||||
|
* **Do not write any infinite loops without using a** :code:`sleep` **or one of the timed Netscript functions like** :code:`hack`. Doing so will crash your game.
|
||||||
|
|
||||||
|
* Any global variable declared in a NetscriptJS script is shared between all instances of that
|
||||||
|
script. For example, assume you write a script *foo.ns* and declared a global variable like so::
|
||||||
|
|
||||||
|
//foo.ns
|
||||||
|
let globalVariable;
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
globalVariable = ns.args.length;
|
||||||
|
while(true) {
|
||||||
|
ns.tprint(globalVariable);
|
||||||
|
await ns.sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Then, you ran multiple instances of *foo.ns*::
|
||||||
|
|
||||||
|
$ run foo.ns 1
|
||||||
|
$ run foo.ns 1 2 3
|
||||||
|
$ run foo.ns 1 2 3 4 5
|
||||||
|
|
||||||
|
Then all three instances of foo.ns will share the same instance of :code:`globalVariable`.
|
||||||
|
(In this example, the value of :code:`globalVariable` will be set to 5 because the
|
||||||
|
last instance of *foo.ns* to run has 5 arguments. This means that all three instances of
|
||||||
|
the script will repeatedly print the value 5).
|
||||||
|
|
||||||
|
These global variables can be thought of as `C++ static class members <https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm>`_,
|
||||||
|
where a NetscriptJS script is a class and a global variable is a static member within that class.
|
||||||
|
|
||||||
|
Warnings
|
||||||
|
--------
|
||||||
|
The NetscriptJS evaluation engine works by converting your code into a blob URL and then
|
||||||
|
using a dynamic import to load your code as a module. Every unique NetscriptJS script
|
||||||
|
is loaded as its own module. This means that
|
||||||
|
making a small edit to a NetscriptJS script results in a new module being generated.
|
||||||
|
|
||||||
|
At this point, we have been unable to find a method for deleting modules from browsers so that
|
||||||
|
they get garbage collected.
|
||||||
|
|
||||||
|
The result is that these modules from NetscriptJS scripts accumulate in your browser,
|
||||||
|
using memory that never gets released. Over time, this results in a memory-leak type
|
||||||
|
situation that can slow down your computer.
|
||||||
|
|
||||||
|
Therefore, there are two recommendations for those who decide to use NetscriptJS:
|
||||||
|
|
||||||
|
1. Every now and then, close and re-open the game. This will clear all of the modules.
|
||||||
|
To be safe, I recommend **completely** closing the game's tab and then re-opening it.
|
||||||
|
Depending on your browser, a refresh or page reload does not always clear the modules.
|
||||||
|
|
||||||
|
2. Only use NetscriptJS scripts when needed. It is very unlikely that NetscriptJS
|
||||||
|
is needed for very simple scripts. By doing this, you will reduce the number of modules
|
||||||
|
that are loaded.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
**DOM Manipulation (tprintColored.ns)**
|
||||||
|
|
||||||
|
Directly alter the game's terminal and print colored text::
|
||||||
|
|
||||||
|
export function tprintColored(txt, color) {
|
||||||
|
let terminalInput = document.getElementById("terminal-input");
|
||||||
|
let rowElement = document.createElement("tr");
|
||||||
|
let cellElement = document.createElement("td");
|
||||||
|
|
||||||
|
rowElement.classList.add("posted");
|
||||||
|
cellElement.classList.add("terminal-line");
|
||||||
|
cellElement.style.color = color;
|
||||||
|
cellElement.innerText = txt;
|
||||||
|
|
||||||
|
rowElement.appendChild(cellElement);
|
||||||
|
terminalInput.before(rowElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
tprintColored("Red Text!", "red");
|
||||||
|
tprintColored("Blue Text!", "blue");
|
||||||
|
tprintColored("Use Hex Codes!", "#3087E3");
|
||||||
|
}
|
||||||
|
|
||||||
|
**Script Scheduler (scriptScheduler.ns)**
|
||||||
|
|
||||||
|
This script shows some of the new functionality that is available in NetscriptJS,
|
||||||
|
including objects and object constructors, changing an object's prototype, and
|
||||||
|
importing other NetscriptJS scripts::
|
||||||
|
|
||||||
|
import {tprintColored} from "tprintColored.ns"; //Importing from other NetscriptJS scripts works!
|
||||||
|
|
||||||
|
function ScriptJob(params) {
|
||||||
|
if (params.fn == null) {
|
||||||
|
throw new Error("No Filename (fn) passed into ScriptJob ctor");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fn = params.fn;
|
||||||
|
this.threads = params.threads ? params.threads : 1;
|
||||||
|
this.args = params.args ? params.args : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.run = async function(ns) {
|
||||||
|
let runArgs = [this.fn, this.threads].concat(this.args);
|
||||||
|
await ns.run.apply(this, runArgs);
|
||||||
|
tprintColored("Running " + this.fn + " on " + ns.getHostname(), "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptJob.prototype.exec = async function(ns, target) {
|
||||||
|
ns.scp(this.fn, target);
|
||||||
|
|
||||||
|
let execArgs = [this.fn, target, this.threads].concat(this.args);
|
||||||
|
await ns.exec.apply(this, execArgs);
|
||||||
|
|
||||||
|
tprintColored("Executing " + this.fn + " on " + target, "blue");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
tprintColored("Starting scriptScheduler.ns", "red");
|
||||||
|
try {
|
||||||
|
let job = new ScriptJob({
|
||||||
|
fn: "test.js",
|
||||||
|
threads: 1,
|
||||||
|
args: ["foodnstuff"]
|
||||||
|
});
|
||||||
|
await job.run(ns);
|
||||||
|
await job.exec(ns, "foodnstuff");
|
||||||
|
} catch (e) {
|
||||||
|
ns.tprint("Exception thrown in scriptScheduler.ns: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Final Note
|
||||||
|
----------
|
||||||
|
NetscriptJS opens up a lot of possibilities when scripting. I look forward to seeing
|
||||||
|
the scripts that people come up with. Just remember that the power and capabilities of
|
||||||
|
NetscriptJS come with risks. Please backup your save if you're going to experiment with
|
||||||
|
NetscriptJS and report any serious exploits.
|
||||||
|
|
||||||
|
With great power comes great responsibility
|
||||||
|
|
||||||
|
Happy hacking
|
@ -266,7 +266,7 @@ nano
|
|||||||
|
|
||||||
$ nano [filename]
|
$ nano [filename]
|
||||||
|
|
||||||
Opens up the specified file in the Text Editor. Only scripts (.script) and
|
Opens up the specified file in the Text Editor. Only scripts (.script, .ns, .js) and
|
||||||
text files (.txt) can be edited. If the file does not already exist, then a new
|
text files (.txt) can be edited. If the file does not already exist, then a new
|
||||||
empty file will be created.
|
empty file will be created.
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ function deleteActiveScriptsItem(workerscript) {
|
|||||||
var server = getServer(workerscript.serverIp);
|
var server = getServer(workerscript.serverIp);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
throw new Error("ERROR: Invalid server IP for workerscript. This most likely occurred because " +
|
throw new Error("ERROR: Invalid server IP for workerscript. This most likely occurred because " +
|
||||||
"you tried to delete a large number of scripts and also purchased servers at the " +
|
"you tried to delete a large number of scripts and also deleted servers at the " +
|
||||||
"same time. It's not a big deal, just save and refresh the game.");
|
"same time. It's not a big deal, just save and refresh the game.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -506,8 +506,6 @@ Action.prototype.getSuccessChance = function(inst, params={}) {
|
|||||||
//Tests for success. Should be called when an action has completed
|
//Tests for success. Should be called when an action has completed
|
||||||
// @inst - Bladeburner Object
|
// @inst - Bladeburner Object
|
||||||
Action.prototype.attempt = function(inst) {
|
Action.prototype.attempt = function(inst) {
|
||||||
console.log("Current City Pop: " + inst.getCurrentCity().pop);
|
|
||||||
console.log("Action.attempt success chance: " + this.getSuccessChance(inst));
|
|
||||||
return (Math.random() < this.getSuccessChance(inst));
|
return (Math.random() < this.getSuccessChance(inst));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,7 +1202,9 @@ Bladeburner.prototype.completeAction = function() {
|
|||||||
return hackWorldDaemon(Player.bitNodeN);
|
return hackWorldDaemon(Player.bitNodeN);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createActionAndSkillsContent();
|
if (Engine.currentPage === Engine.Page.Bladeburner) {
|
||||||
|
this.createActionAndSkillsContent();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.logging.blackops) {
|
if (this.logging.blackops) {
|
||||||
this.log(action.name + " successful! Gained " + formatNumber(rankGain, 1) + " rank");
|
this.log(action.name + " successful! Gained " + formatNumber(rankGain, 1) + " rank");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
let CONSTANTS = {
|
let CONSTANTS = {
|
||||||
Version: "0.36.1",
|
Version: "0.37.0",
|
||||||
|
|
||||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||||
@ -1140,30 +1140,10 @@ let CONSTANTS = {
|
|||||||
"World Stock Exchange account and TIX API Access<br>",
|
"World Stock Exchange account and TIX API Access<br>",
|
||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
"v0.36.1<br>" +
|
"v0.37.0<br>" +
|
||||||
"* Bladeburner Changes: <br>" +
|
"* NetscriptJS (Netscript 2.0) released<br>" +
|
||||||
"** Bug Fix: You can no longer get Bladeburner faction reputation through Infiltration<br>" +
|
"* Running the game with the '?noScripts' query will start the game without loading any of your scripts. " +
|
||||||
"** Initial difficulty of Tracking contracts reduced<br>" +
|
"This should be used if you accidentally write a script that crashes your game<br>"
|
||||||
"** Datamancer skill effect increased from 4% per level to 5%<br>" +
|
|
||||||
"** Slightly decreased the base stamina cost of contracts/operations<br>" +
|
|
||||||
"** Slightly increased the effects of the Tracer, Digital Observer, Short Circuit, Cloak, and Blade's Intuition skills<br>" +
|
|
||||||
"** Overclock skill capped at level 95, rather than 99<br>" +
|
|
||||||
"** Training gives significantly more exp/s<br>" +
|
|
||||||
"* Crime, Infiltration, and Hacking are now slightly more profitable in BN-6<br>" +
|
|
||||||
"* Gyms are now more expensive, but give slightly more exp<br>" +
|
|
||||||
"* Added getScriptName() and getHacknetMultipliers() Netscript functions (added by Github user hydroflame)<br>" +
|
|
||||||
"* getScriptRam() Netscript function now has default value for the second argument, which is hostname/ip (implemented by Github user hydroflame)<br>" +
|
|
||||||
"* There is now a soft-cap on stock price, which means it's no longer possible for the price of a stock to reach insanely-high values<br>" +
|
|
||||||
"* The ctrl+b hotkey in the text editor should now also be triggered by command+b on OSX (I don't have OSX so I can't confirm if this works)<br>" +
|
|
||||||
"* Many servers now have additional RAM<br>" +
|
|
||||||
"* Added an option to disable hotkeys/keyboard shortcuts<br>" +
|
|
||||||
"* Refactored 'Active Scripts' UI page to optimize its performance<br>" +
|
|
||||||
"* Added a new .fconf Terminal setting: ENABLE_TIMESTAMP<br>" +
|
|
||||||
"* 'Netscript Execution Time', which can be found in the Options, now has a minimum value of 15ms rather than 25ms<br>" +
|
|
||||||
"* Bug Fix: Fixed a typo in the Fulcrum Technologies company name (Technolgies -> Technologies)<br>" +
|
|
||||||
"* Bug Fix: hacknetnodes keyword should no longer incur RAM cost if its in a comment<br>" +
|
|
||||||
"* Bug Fix: disableLog() now works for the commitCrime() Netscript function (fixed by Github user hydroflame)"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {CONSTANTS};
|
export {CONSTANTS};
|
||||||
|
@ -1031,6 +1031,14 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
|||||||
var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
|
var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
|
||||||
"purchase this one.";
|
"purchase this one.";
|
||||||
if (sing) {return txt;} else {dialogBoxCreate(txt);}
|
if (sing) {return txt;} else {dialogBoxCreate(txt);}
|
||||||
|
} else if (Player.money.lt(aug.baseCost * fac.augmentationPriceMult)) {
|
||||||
|
let txt = "You don't have enough money to purchase " + aug.name;
|
||||||
|
if (sing) {return txt;}
|
||||||
|
dialogBoxCreate(txt);
|
||||||
|
} else if (fac.playerReputation < aug.baseRepRequirement) {
|
||||||
|
let txt = "You don't have enough faction reputation to purchase " + aug.name;
|
||||||
|
if (sing) {return txt;}
|
||||||
|
dialogBoxCreate(txt);
|
||||||
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
|
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
|
||||||
if (Player.firstAugPurchased === false) {
|
if (Player.firstAugPurchased === false) {
|
||||||
Player.firstAugPurchased = true;
|
Player.firstAugPurchased = true;
|
||||||
@ -1077,11 +1085,9 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
|||||||
|
|
||||||
displayFactionAugmentations(fac.name);
|
displayFactionAugmentations(fac.name);
|
||||||
} else {
|
} else {
|
||||||
if (sing) {
|
dialogBoxCreate("Hmm, something went wrong when trying to purchase an Augmentation. " +
|
||||||
return "You don't have enough money to purchase " + aug.name;
|
"Please report this to the game developer with an explanation of how to " +
|
||||||
} else {
|
"reproduce this.");
|
||||||
dialogBoxCreate("You don't have enough money to purchase this Augmentation!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
yesNoBoxClose();
|
yesNoBoxClose();
|
||||||
}
|
}
|
||||||
|
@ -14,31 +14,40 @@ export function makeScriptBlob(code) {
|
|||||||
// (i.e. hack, grow, etc.).
|
// (i.e. hack, grow, etc.).
|
||||||
// When the promise returned by this resolves, we'll have finished
|
// When the promise returned by this resolves, we'll have finished
|
||||||
// running the main function of the script.
|
// running the main function of the script.
|
||||||
export async function executeJSScript(script, scripts = [], env = {}) {
|
export async function executeJSScript(scripts = [], workerScript) {
|
||||||
const envUuid = registerEnv(env);
|
let loadedModule;
|
||||||
const envHeader = makeEnvHeader(envUuid);
|
let urlStack = null;
|
||||||
const urlStack = _getScriptUrls(script, scripts, envHeader, []);
|
let script = workerScript.getScript();
|
||||||
|
if (script.module === "") {
|
||||||
|
// The URL at the top is the one we want to import. It will
|
||||||
|
// recursively import all the other modules in the urlStack.
|
||||||
|
//
|
||||||
|
// Webpack likes to turn the import into a require, which sort of
|
||||||
|
// but not really behaves like import. Particularly, it cannot
|
||||||
|
// load fully dynamic content. So we hide the import from webpack
|
||||||
|
// by placing it inside an eval call.
|
||||||
|
urlStack = _getScriptUrls(script, scripts, []);
|
||||||
|
script.module = await eval('import(urlStack[urlStack.length - 1])');
|
||||||
|
}
|
||||||
|
loadedModule = script.module;
|
||||||
|
|
||||||
|
let ns = workerScript.env.vars;
|
||||||
|
//ns.threads = workerScript.threads;
|
||||||
|
//ns.args = workerScript.args;
|
||||||
|
|
||||||
// The URL at the top is the one we want to import. It will
|
|
||||||
// recursively import all the other modules in the urlStack.
|
|
||||||
//
|
|
||||||
// Webpack likes to turn the import into a require, which sort of
|
|
||||||
// but not really behaves like import. Particularly, it cannot
|
|
||||||
// load fully dynamic content. So we hide the import from webpack
|
|
||||||
// by placing it inside an eval call.
|
|
||||||
try {
|
try {
|
||||||
// TODO: putting await in a non-async function yields unhelpful
|
// TODO: putting await in a non-async function yields unhelpful
|
||||||
// "SyntaxError: unexpected reserved word" with no line number information.
|
// "SyntaxError: unexpected reserved word" with no line number information.
|
||||||
const loadedModule = await eval('import(urlStack[urlStack.length - 1])');
|
|
||||||
if (!loadedModule.main) {
|
if (!loadedModule.main) {
|
||||||
throw makeRuntimeRejectMsg(script.filename +
|
throw makeRuntimeRejectMsg(script.filename +
|
||||||
" did not have a main function, cannot run it.");
|
" did not have a main function, cannot run it.");
|
||||||
}
|
}
|
||||||
return await loadedModule.main();
|
return loadedModule.main(ns);
|
||||||
} finally {
|
} finally {
|
||||||
// Revoke the generated URLs and unregister the environment.
|
// Revoke the generated URLs
|
||||||
for (const url in urlStack) URL.revokeObjectURL(url);
|
if (urlStack != null) {
|
||||||
unregisterEnv(envUuid);
|
for (const url in urlStack) URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +63,7 @@ export async function executeJSScript(script, scripts = [], env = {}) {
|
|||||||
// different parts of the tree. That hasn't presented any problem with during
|
// different parts of the tree. That hasn't presented any problem with during
|
||||||
// testing, but it might be an idea for the future. Would require a topo-sort
|
// testing, but it might be an idea for the future. Would require a topo-sort
|
||||||
// then url-izing from leaf-most to root-most.
|
// then url-izing from leaf-most to root-most.
|
||||||
function _getScriptUrls(script, scripts, envHeader, seen) {
|
function _getScriptUrls(script, scripts, seen) {
|
||||||
// Inspired by: https://stackoverflow.com/a/43834063/91401
|
// Inspired by: https://stackoverflow.com/a/43834063/91401
|
||||||
const urlStack = [];
|
const urlStack = [];
|
||||||
seen.push(script);
|
seen.push(script);
|
||||||
@ -78,19 +87,17 @@ function _getScriptUrls(script, scripts, envHeader, seen) {
|
|||||||
const [importedScript] = scripts.filter(s => s.filename == filename);
|
const [importedScript] = scripts.filter(s => s.filename == filename);
|
||||||
|
|
||||||
// Try to get a URL for the requested script and its dependencies.
|
// Try to get a URL for the requested script and its dependencies.
|
||||||
const urls = _getScriptUrls(importedScript, scripts, envHeader, seen);
|
const urls = _getScriptUrls(importedScript, scripts, seen);
|
||||||
|
|
||||||
// The top url in the stack is the replacement import file for this script.
|
// The top url in the stack is the replacement import file for this script.
|
||||||
urlStack.push(...urls);
|
urlStack.push(...urls);
|
||||||
return [prefix, urls[urls.length - 1], suffix].join('');
|
return [prefix, urls[urls.length - 1], suffix].join('');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inject the NSJS preamble at the top of the code.
|
|
||||||
const transformedCodeWithHeader = [envHeader, transformedCode].join("\n");
|
|
||||||
|
|
||||||
// If we successfully transformed the code, create a blob url for it and
|
// If we successfully transformed the code, create a blob url for it and
|
||||||
// push that URL onto the top of the stack.
|
// push that URL onto the top of the stack.
|
||||||
urlStack.push(URL.createObjectURL(makeScriptBlob(transformedCodeWithHeader)));
|
urlStack.push(URL.createObjectURL(makeScriptBlob(transformedCode)));
|
||||||
return urlStack;
|
return urlStack;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// If there is an error, we need to clean up the URLs.
|
// If there is an error, we need to clean up the URLs.
|
||||||
|
@ -40,6 +40,18 @@ WorkerScript.prototype.getServer = function() {
|
|||||||
return AllServers[this.serverIp];
|
return AllServers[this.serverIp];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Returns the Script object for the underlying script
|
||||||
|
WorkerScript.prototype.getScript = function() {
|
||||||
|
let server = this.getServer();
|
||||||
|
for (var i = 0; i < server.scripts.length; ++i) {
|
||||||
|
if (server.scripts[i].filename === this.name) {
|
||||||
|
return server.scripts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("ERROR: Failed to find underlying Script object in WorkerScript.getScript(). This probably means somethings wrong");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//Array containing all scripts that are running across all servers, to easily run them all
|
//Array containing all scripts that are running across all servers, to easily run them all
|
||||||
let workerScripts = [];
|
let workerScripts = [];
|
||||||
|
|
||||||
@ -110,9 +122,8 @@ function startJsScript(workerScript) {
|
|||||||
|
|
||||||
// Note: the environment that we pass to the JS script only needs to contain the functions visible
|
// Note: the environment that we pass to the JS script only needs to contain the functions visible
|
||||||
// to that script, which env.vars does at this point.
|
// to that script, which env.vars does at this point.
|
||||||
return executeJSScript(workerScript.scriptRef.scriptRef,
|
return executeJSScript(workerScript.getServer().scripts,
|
||||||
workerScript.getServer().scripts,
|
workerScript).then(function (mainReturnValue) {
|
||||||
workerScript.env.vars).then(function (mainReturnValue) {
|
|
||||||
if (mainReturnValue === undefined) return workerScript;
|
if (mainReturnValue === undefined) return workerScript;
|
||||||
return [mainReturnValue, workerScript];
|
return [mainReturnValue, workerScript];
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
@ -130,10 +141,12 @@ function startJsScript(workerScript) {
|
|||||||
|
|
||||||
//Loop through workerScripts and run every script that is not currently running
|
//Loop through workerScripts and run every script that is not currently running
|
||||||
function runScriptsLoop() {
|
function runScriptsLoop() {
|
||||||
//Delete any scripts that finished or have been killed. Loop backwards bc removing
|
var scriptDeleted = false;
|
||||||
//items fucks up the indexing
|
|
||||||
|
//Delete any scripts that finished or have been killed. Loop backwards bc removing items screws up indexing
|
||||||
for (var i = workerScripts.length - 1; i >= 0; i--) {
|
for (var i = workerScripts.length - 1; i >= 0; i--) {
|
||||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
|
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
|
||||||
|
scriptDeleted = true;
|
||||||
//Delete script from the runningScripts array on its host serverIp
|
//Delete script from the runningScripts array on its host serverIp
|
||||||
var ip = workerScripts[i].serverIp;
|
var ip = workerScripts[i].serverIp;
|
||||||
var name = workerScripts[i].name;
|
var name = workerScripts[i].name;
|
||||||
@ -156,13 +169,15 @@ function runScriptsLoop() {
|
|||||||
workerScripts.splice(i, 1);
|
workerScripts.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (scriptDeleted) {updateActiveScriptsItems();} //Force Update
|
||||||
|
|
||||||
|
|
||||||
//Run any scripts that haven't been started
|
//Run any scripts that haven't been started
|
||||||
for (var i = 0; i < workerScripts.length; i++) {
|
for (var i = 0; i < workerScripts.length; i++) {
|
||||||
//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) {
|
||||||
let p = null; // p is the script's result promise.
|
let p = null; // p is the script's result promise.
|
||||||
if (workerScripts[i].name.endsWith(".js")) {
|
if (workerScripts[i].name.endsWith(".js") || workerScripts[i].name.endsWith(".ns")) {
|
||||||
p = startJsScript(workerScripts[i]);
|
p = startJsScript(workerScripts[i]);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -223,6 +238,7 @@ function runScriptsLoop() {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev");
|
dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev");
|
||||||
|
console.log(w);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ var keybindings = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function isScriptFilename(f) {
|
function isScriptFilename(f) {
|
||||||
return f.endsWith(".js") || f.endsWith(".script");
|
return f.endsWith(".js") || f.endsWith(".script") || f.endsWith(".ns");
|
||||||
}
|
}
|
||||||
|
|
||||||
var scriptEditorRamCheck = null, scriptEditorRamText = null;
|
var scriptEditorRamCheck = null, scriptEditorRamText = null;
|
||||||
@ -326,6 +326,7 @@ function Script() {
|
|||||||
this.code = "";
|
this.code = "";
|
||||||
this.ramUsage = 0;
|
this.ramUsage = 0;
|
||||||
this.server = ""; //IP of server this script is on
|
this.server = ""; //IP of server this script is on
|
||||||
|
this.module = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
//Get the script data from the Script Editor and save it to the object
|
//Get the script data from the Script Editor and save it to the object
|
||||||
@ -344,6 +345,9 @@ Script.prototype.saveScript = function() {
|
|||||||
|
|
||||||
//Calculate/update ram usage, execution time, etc.
|
//Calculate/update ram usage, execution time, etc.
|
||||||
this.updateRamUsage();
|
this.updateRamUsage();
|
||||||
|
console.log(this.module);
|
||||||
|
|
||||||
|
this.module = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,6 +709,8 @@ Reviver.constructors.Script = Script;
|
|||||||
function loadAllRunningScripts() {
|
function loadAllRunningScripts() {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var total = 0;
|
var total = 0;
|
||||||
|
let skipScriptLoad = (window.location.href.toLowerCase().indexOf("?noscripts") !== -1);
|
||||||
|
if (skipScriptLoad) {console.log("Skipping the load of any scripts during startup");}
|
||||||
for (var property in AllServers) {
|
for (var property in AllServers) {
|
||||||
if (AllServers.hasOwnProperty(property)) {
|
if (AllServers.hasOwnProperty(property)) {
|
||||||
var server = AllServers[property];
|
var server = AllServers[property];
|
||||||
@ -712,13 +718,24 @@ function loadAllRunningScripts() {
|
|||||||
//Reset each server's RAM usage to 0
|
//Reset each server's RAM usage to 0
|
||||||
server.ramUsed = 0;
|
server.ramUsed = 0;
|
||||||
|
|
||||||
for (var j = 0; j < server.runningScripts.length; ++j) {
|
//Reset modules on all scripts
|
||||||
count++;
|
for (var i = 0; i < server.scripts.length; ++i) {
|
||||||
addWorkerScript(server.runningScripts[j], server);
|
server.scripts[i].module = "";
|
||||||
|
}
|
||||||
|
|
||||||
//Offline production
|
if (skipScriptLoad) {
|
||||||
total += scriptCalculateOfflineProduction(server.runningScripts[j]);
|
//Start game with no scripts
|
||||||
}
|
server.runningScripts.length = 0;
|
||||||
|
} else {
|
||||||
|
for (var j = 0; j < server.runningScripts.length; ++j) {
|
||||||
|
count++;
|
||||||
|
server.runningScripts[j].scriptRef.module = "";
|
||||||
|
addWorkerScript(server.runningScripts[j], server);
|
||||||
|
|
||||||
|
//Offline production
|
||||||
|
total += scriptCalculateOfflineProduction(server.runningScripts[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
|
Loading…
Reference in New Issue
Block a user