Threads are a positive integer (#366)

* Added new positive integer ns validation helper
* `run`, `exec`, and `spawn` verify threads as a positive integer.
* `run` terminal command also fails if the provided threadcount is not a positive integer.
* Removed some references to .script files in various documentation, and removed some of the NS1 example blocks
This commit is contained in:
Snarling 2023-02-14 01:32:01 -05:00 committed by GitHub
parent b0bdf0c7ad
commit 08e71c732b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 165 additions and 474 deletions

@ -454,7 +454,7 @@ Execute a program, script, or :ref:`codingcontracts`.
The '[-t]', '[num threads]', and '[args...]' arguments are only valid when
running a script. The '-t' flag is used to indicate that the script should
be run with the specified number of threads. If the flag is omitted, then
be run with the specified integer number of threads. If the flag is omitted,
the script will be run with a single thread by default. If the '-t' flag is
used, then it MUST come immediately after the script name, and the
[num threads] argument MUST come immediately afterwards.

@ -18,25 +18,12 @@ RAM cost: 0 GB
Arguments passed into a script can be accessed as a normal array by using the `[]` operator (`args[0]`<!-- -->, `args[1]`<!-- -->, etc...). Arguments can be string, number, or boolean. Use `args.length` to get the number of arguments that were passed into a script.
## Example 1
`run example.script 7 text true`
```js
// NS1 - example.script
tprint(args.length) // 3
tprint(args[0]); // 7 (number)
tprint(args[1]); // "text" (string)
tprint(args[2]); // true (boolean)
tprint(args[3]); // undefined, because only 3 arguments were provided
```
## Example 2
## Example
`run example.js 7 text true`
```js
// NS2 - example.js
// example.js
export async function main(ns) {
ns.tprint(ns.args.length) // 3
ns.tprint(ns.args[0]); // 7 (number)

@ -9,7 +9,7 @@ Start another script on any server.
**Signature:**
```typescript
exec(script: string, host: string, numThreads?: number, ...args: (string | number | boolean)[]): number;
exec(script: string, hostname: string, numThreads?: number, ...args: (string | number | boolean)[]): number;
```
## Parameters
@ -17,8 +17,8 @@ exec(script: string, host: string, numThreads?: number, ...args: (string | numbe
| Parameter | Type | Description |
| --- | --- | --- |
| script | string | Filename of script to execute. |
| host | string | Hostname of the <code>target server</code> on which to execute the script. |
| numThreads | number | _(Optional)_ Optional thread count for new script. Set to 1 by default. Will be rounded down to the nearest integer. |
| hostname | string | Hostname of the <code>target server</code> on which to execute the script. |
| numThreads | number | _(Optional)_ Integer number of threads for new script. Defaults to 1. |
| args | (string \| number \| boolean)\[\] | Additional arguments to pass into the new script that is being run. Note that if any arguments are being passed into the new script, then the third argument numThreads must be filled in with a value. |
**Returns:**
@ -39,43 +39,22 @@ PID stands for Process ID. The PID is a unique identifier for each script. The P
Running this function with a numThreads argument of 0 or less will cause a runtime error.
## Example 1
## Example
```ts
// NS1:
```js
// The simplest way to use the exec command is to call it with just the script name
// and the target server. The following example will try to run generic-hack.script
// and the target server. The following example will try to run generic-hack.js
// on the foodnstuff server.
exec("generic-hack.script", "foodnstuff");
ns.exec("generic-hack.js", "foodnstuff");
// The following example will try to run the script generic-hack.script on the
// The following example will try to run the script generic-hack.js on the
// joesguns server with 10 threads.
exec("generic-hack.script", "joesguns", 10);
ns.exec("generic-hack.js", "joesguns", 10);
// This last example will try to run the script foo.script on the foodnstuff server
// This last example will try to run the script foo.js on the foodnstuff server
// with 5 threads. It will also pass the number 1 and the string “test” in as
// arguments to the script.
exec("foo.script", "foodnstuff", 5, 1, "test");
```
## Example 2
```ts
// NS2:
// The simplest way to use the exec command is to call it with just the script name
// and the target server. The following example will try to run generic-hack.script
// on the foodnstuff server.
ns.exec("generic-hack.script", "foodnstuff");
// The following example will try to run the script generic-hack.script on the
// joesguns server with 10 threads.
ns.exec("generic-hack.script", "joesguns", 10);
// This last example will try to run the script foo.script on the foodnstuff server
// with 5 threads. It will also pass the number 1 and the string “test” in as
// arguments to the script.
ns.exec("foo.script", "foodnstuff", 5, 1, "test");
ns.exec("foo.js", "foodnstuff", 5, 1, "test");
```

@ -33,26 +33,14 @@ Returns a boolean indicating whether the specified file exists on the target ser
If the hostname/ip argument is omitted, then the function will search through the current server (the server running the script that calls this function) for the file.
## Example 1
```ts
// NS1:
//The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
fileExists("foo.script", "foodnstuff");
//The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
fileExists("ftpcrack.exe");
```
\*
## Example 2
## Example
```ts
// NS2:
// The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
ns.fileExists("foo.script", "foodnstuff");
```js
// The function call will return true if the script named foo.js exists on the foodnstuff server, and false otherwise.
ns.fileExists("foo.js", "foodnstuff");
// The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
ns.fileExists("ftpcrack.exe");

@ -31,17 +31,7 @@ Allows Unix-like flag parsing.
## Example
```ts
// example.script
var data = flags([
['delay', 0], // a default number means this flag is a number
['server', 'foodnstuff'], // a default string means this flag is a string
['exclude', []], // a default array means this flag is a default array of string
['help', false], // a default boolean means this flag is a boolean
]);
tprint(data);
// example.js
```js
export async function main(ns) {
const data = ns.flags([
['delay', 0], // a default number means this flag is a number
@ -52,15 +42,15 @@ export async function main(ns) {
ns.tprint(data);
}
// [home ~/]> run example.script
// [home ~/]> run example.js
// {"_":[],"delay":0,"server":"foodnstuff","exclude":[],"help":false}
// [home ~/]> run example.script --delay 3000
// [home ~/]> run example.js --delay 3000
// {"_":[],"server":"foodnstuff","exclude":[],"help":false,"delay":3000}
// [home ~/]> run example.script --delay 3000 --server harakiri-sushi
// [home ~/]> run example.js --delay 3000 --server harakiri-sushi
// {"_":[],"exclude":[],"help":false,"delay":3000,"server":"harakiri-sushi"}
// [home ~/]> run example.script --delay 3000 --server harakiri-sushi hello world
// [home ~/]> run example.js --delay 3000 --server harakiri-sushi hello world
// {"_":["hello","world"],"exclude":[],"help":false,"delay":3000,"server":"harakiri-sushi"}
// [home ~/]> run example.script --delay 3000 --server harakiri-sushi hello world --exclude a --exclude b
// [home ~/]> run example.js --delay 3000 --server harakiri-sushi hello world --exclude a --exclude b
// {"_":["hello","world"],"help":false,"delay":3000,"server":"harakiri-sushi","exclude":["a","b"]}
// [home ~/]> run example.script --help
// {"_":[],"delay":0,"server":"foodnstuff","exclude":[],"help":true}

@ -34,33 +34,17 @@ Returns a scripts logs. The logs are returned as an array, where each line is
Otherwise, the fn, hostname/ip, and args… arguments can be used to get the logs from another script. Remember that scripts are uniquely identified by both their names and arguments.
## Example 1
## Example
```ts
// NS1:
//Get logs from foo.script on the current server that was run with no args
getScriptLogs("foo.script");
```js
//Get logs from foo.js on the current server that was run with no args
ns.getScriptLogs("foo.js");
//Open logs from foo.script on the foodnstuff server that was run with no args
getScriptLogs("foo.script", "foodnstuff");
//Open logs from foo.js on the foodnstuff server that was run with no args
ns.getScriptLogs("foo.js", "foodnstuff");
//Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
getScriptLogs("foo.script", "foodnstuff", 1, "test");
```
## Example 2
```ts
// NS2:
//Get logs from foo.script on the current server that was run with no args
ns.getScriptLogs("foo.script");
//Open logs from foo.script on the foodnstuff server that was run with no args
ns.getScriptLogs("foo.script", "foodnstuff");
//Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
ns.getScriptLogs("foo.script", "foodnstuff", 1, "test");
//Open logs from foo.js on the foodnstuff server that was run with the arguments [1, "test"]
ns.getScriptLogs("foo.js", "foodnstuff", 1, "test");
```

@ -32,33 +32,17 @@ RAM cost: 0.1 GB
Returns a boolean indicating whether the specified script is running on the target server. If you use a PID instead of a filename, the hostname and args parameters are unnecessary. Remember that a script is uniquely identified by both its name and its arguments.
## Example 1
## Example
```ts
// NS1:
//The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
isRunning("foo.script", "foodnstuff");
```js
//The function call will return true if there is a script named foo.js with no arguments running on the foodnstuff server, and false otherwise:
ns.isRunning("foo.js", "foodnstuff");
//The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
isRunning("foo.script", getHostname());
//The function call will return true if there is a script named foo.js with no arguments running on the current server, and false otherwise:
ns.isRunning("foo.js", ns.getHostname());
//The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
isRunning("foo.script", "joesguns", 1, 5, "test");
```
## Example 2
```ts
// NS2:
//The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
ns.isRunning("foo.script", "foodnstuff");
//The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
ns.isRunning("foo.script", ns.getHostname());
//The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
ns.isRunning("foo.script", "joesguns", 1, 5, "test");
//The function call will return true if there is a script named foo.js running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
ns.isRunning("foo.js", "joesguns", 1, 5, "test");
```

@ -37,10 +37,10 @@ Kills the script with the provided filename, running on the specified host with
```js
// kill the script "foo.js" on the same server the current script is running from, with no arguments
ns.kill("foo.script");
ns.kill("foo.js");
// kill the script "foo.js" on the "n00dles" server with no arguments.
ns.kill("foo.script", "n00dles");
ns.kill("foo.js", "n00dles");
// kill the script foo.js on the current server that was ran with the arguments [1, “foodnstuff”, false]:
ns.kill("foo.js", ns.getHostname(), 1, "foodnstuff", false);

@ -72,7 +72,7 @@ export async function main(ns) {
| [deleteServer(host)](./bitburner.ns.deleteserver.md) | Delete a purchased server. |
| [disableLog(fn)](./bitburner.ns.disablelog.md) | Disables logging for the given function. |
| [enableLog(fn)](./bitburner.ns.enablelog.md) | Enable logging for a certain function. |
| [exec(script, host, numThreads, args)](./bitburner.ns.exec.md) | Start another script on any server. |
| [exec(script, hostname, numThreads, args)](./bitburner.ns.exec.md) | Start another script on any server. |
| [exit()](./bitburner.ns.exit.md) | Terminates the current script immediately. |
| [fileExists(filename, host)](./bitburner.ns.fileexists.md) | Check if a file exists. |
| [flags(schema)](./bitburner.ns.flags.md) | Parse command line flags. |

@ -28,7 +28,7 @@ Data in the specified text file.
RAM cost: 0 GB
This function is used to read data from a text file (.txt) or script (.script, .js).
This function is used to read data from a text file (.txt) or script (.js or .script).
This function will return the data in the specified file. If the file does not exist, an empty string will be returned.

@ -17,7 +17,7 @@ run(script: string, numThreads?: number, ...args: (string | number | boolean)[])
| Parameter | Type | Description |
| --- | --- | --- |
| script | string | Filename of script to run. |
| numThreads | number | _(Optional)_ Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer. |
| numThreads | number | _(Optional)_ Integer number of threads for new script. Defaults to 1. |
| args | (string \| number \| boolean)\[\] | Additional arguments to pass into the new script that is being run. Note that if any arguments are being passed into the new script, then the second argument numThreads must be filled in with a value. |
**Returns:**
@ -38,33 +38,17 @@ PID stands for Process ID. The PID is a unique identifier for each script. The P
Running this function with a numThreads argument of 0 or less will cause a runtime error.
## Example 1
## Example
```ts
// NS1:
//The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
run("foo.script");
```js
//The simplest way to use the run command is to call it with just the script name. The following example will run foo.js single-threaded with no arguments:
ns.run("foo.js");
//The following example will run foo.script but with 5 threads instead of single-threaded:
run("foo.script", 5);
//The following example will run foo.js but with 5 threads instead of single-threaded:
ns.run("foo.js", 5);
//This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
run("foo.script", 1, 'foodnstuff');
```
## Example 2
```ts
// NS2:
//The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
ns.run("foo.script");
//The following example will run foo.script but with 5 threads instead of single-threaded:
ns.run("foo.script", 5);
//This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
ns.run("foo.script", 1, 'foodnstuff');
//This next example will run foo.js single-threaded, and will pass the string foodnstuff into the script as an argument:
ns.run("foo.js", 1, 'foodnstuff');
```

@ -35,36 +35,21 @@ Copies a script or literature (.lit) file(s) to another server. The files argume
## Example 1
```ts
// NS1:
```js
//Copies foo.lit from the helios server to the home computer:
scp("foo.lit", "home", "helios");
ns.scp("foo.lit", "home", "helios" );
//Tries to copy three files from rothman-uni to home computer:
files = ["foo1.lit", "foo2.script", "foo3.script"];
scp(files, "home", "rothman-uni");
files = ["foo1.lit", "foo2.txt", "foo3.js"];
ns.scp(files, "home", "rothman-uni");
```
## Example 2
```ts
// NS2:
//Copies foo.lit from the helios server to the home computer:
ns.scp("foo.lit", "home", "helios" );
//Tries to copy three files from rothman-uni to home computer:
files = ["foo1.lit", "foo2.script", "foo3.script"];
ns.scp(files, "home", "rothman-uni");
```
## Example 3
```ts
//ns2, copies files from home to a target server
```js
const server = ns.args[0];
const files = ["hack.js","weaken.js","grow.js"];
const files = ["hack.js", "weaken.js", "grow.js"];
ns.scp(files, server, "home");
```

@ -33,28 +33,14 @@ Returns a boolean indicating whether any instance of the specified script is run
This is different than the [isRunning](./bitburner.ns.isrunning.md) function because it does not try to identify a specific instance of a running script by its arguments.
## Example 1
## Example
```ts
// NS1:
//The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
scriptRunning("foo.script", "foodnstuff");
```js
//The function call will return true if there is any script named foo.js running on the foodnstuff server, and false otherwise:
ns.scriptRunning("foo.js", "foodnstuff");
//The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
scriptRunning("foo.script", getHostname());
```
\*
## Example 2
```ts
// NS2:
//The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
ns.scriptRunning("foo.script", "foodnstuff");
//The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
ns.scriptRunning("foo.script", ns.getHostname());
//The function call will return true if there is any script named “foo.js” running on the current server, and false otherwise:
ns.scriptRunning("foo.js", ns.getHostname());
```

@ -17,7 +17,7 @@ spawn(script: string, numThreads?: number, ...args: (string | number | boolean)[
| Parameter | Type | Description |
| --- | --- | --- |
| script | string | Filename of script to execute. |
| numThreads | number | _(Optional)_ Number of threads to spawn new script with. Will be rounded to nearest integer. |
| numThreads | number | _(Optional)_ Integer number of threads for new script. Defaults to 1. |
| args | (string \| number \| boolean)\[\] | Additional arguments to pass into the new script that is being run. |
**Returns:**
@ -34,21 +34,11 @@ Because this function immediately terminates the script, it does not have a retu
Running this function with a numThreads argument of 0 or less will cause a runtime error.
## Example 1
## Example
```ts
// NS1:
//The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
spawn('foo.script', 10, 'foodnstuff', 90);
```
## Example 2
```ts
// NS2:
//The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
ns.spawn('foo.script', 10, 'foodnstuff', 90);
```js
//The following example will execute the script foo.js with 10 threads and the arguments foodnstuff and 90:
ns.spawn('foo.js', 10, 'foodnstuff', 90);
```

@ -34,33 +34,17 @@ If the function is called with no arguments, it will open the current scripts
Otherwise, the fn, hostname/ip, and args… arguments can be used to get the logs from another script. Remember that scripts are uniquely identified by both their names and arguments.
## Example 1
## Example
```ts
// NS1:
//Open logs from foo.script on the current server that was run with no args
tail("foo.script");
```js
//Open logs from foo.js on the current server that was run with no args
ns.tail("foo.js");
//Get logs from foo.script on the foodnstuff server that was run with no args
tail("foo.script", "foodnstuff");
//Get logs from foo.js on the foodnstuff server that was run with no args
ns.tail("foo.js", "foodnstuff");
//Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
tail("foo.script", "foodnstuff", 1, "test");
```
## Example 2
```ts
// NS2:
//Open logs from foo.script on the current server that was run with no args
ns.tail("foo.script");
//Get logs from foo.script on the foodnstuff server that was run with no args
ns.tail("foo.script", "foodnstuff");
//Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
ns.tail("foo.script", "foodnstuff", 1, "test");
//Get logs from foo.js on the foodnstuff server that was run with the arguments [1, "test"]
ns.tail("foo.js", "foodnstuff", 1, "test");
```

@ -30,25 +30,16 @@ True if the data was successfully retrieved from the URL, false otherwise.
RAM cost: 0 GB
Retrieves data from a URL and downloads it to a file on the specified server. The data can only be downloaded to a script (.script, .js) or a text file (.txt). If the file already exists, it will be overwritten by this command. Note that it will not be possible to download data from many websites because they do not allow cross-origin resource sharing (CORS).
Retrieves data from a URL and downloads it to a file on the specified server. The data can only be downloaded to a script (.js or .script) or a text file (.txt). If the file already exists, it will be overwritten by this command. Note that it will not be possible to download data from many websites because they do not allow cross-origin resource sharing (CORS).
IMPORTANT: This is an asynchronous function that returns a Promise. The Promises resolved value will be a boolean indicating whether or not the data was successfully retrieved from the URL. Because the function is async and returns a Promise, it is recommended you use wget in NetscriptJS (Netscript 2.0).
In NetscriptJS, you must preface any call to wget with the await keyword (like you would [hack](./bitburner.ns.hack.md) or [sleep](./bitburner.ns.sleep.md)<!-- -->). wget will still work in Netscript 1.0, but the function's execution will not be synchronous (i.e. it may not execute when you expect/want it to). Furthermore, since Promises are not supported in ES5, you will not be able to process the returned value of wget in Netscript 1.0.
## Example 1
## Example
```ts
// NS1:
wget("https://raw.githubusercontent.com/bitburner-official/bitburner-src/master/README.md", "game_readme.txt");
```
## Example 2
```ts
// NS2:
```js
await ns.wget("https://raw.githubusercontent.com/bitburner-official/bitburner-src/master/README.md", "game_readme.txt");
```

@ -38,6 +38,7 @@ import { RamCostConstants } from "./RamCostGenerator";
export const helpers = {
string,
number,
positiveInteger,
scriptArgs,
argsToString,
makeBasicErrorMsg,
@ -157,6 +158,15 @@ function number(ctx: NetscriptContext, argName: string, v: unknown): number {
throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a number. ${debugType(v)}`, "TYPE");
}
/** Convert provided value v for argument argName to a positive integer, throwing if it looks like something else. */
function positiveInteger(ctx: NetscriptContext, argName: string, v: unknown): number {
const n = number(ctx, argName, v);
if (n < 1 || !Number.isInteger(n)) {
throw makeRuntimeErrorMsg(ctx, `${argName} should be a positive integer, was ${n}`, "TYPE");
}
return n;
}
/** Returns args back if it is a ScriptArg[]. Throws an error if it is not. */
function scriptArgs(ctx: NetscriptContext, args: unknown) {
if (!isScriptArgs(args)) throw makeRuntimeErrorMsg(ctx, "'args' is not an array of script args", "TYPE");

@ -684,11 +684,8 @@ export const ns: InternalAPI<NSFull> = {
(ctx) =>
(_scriptname, _threads = 1, ..._args) => {
const scriptname = helpers.string(ctx, "scriptname", _scriptname);
const threads = helpers.number(ctx, "threads", _threads);
const threads = helpers.positiveInteger(ctx, "threads", _threads);
const args = helpers.scriptArgs(ctx, _args);
if (isNaN(threads) || threads <= 0) {
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid thread count. Must be numeric and > 0, is ${threads}`);
}
const scriptServer = GetServer(ctx.workerScript.hostname);
if (scriptServer == null) {
throw helpers.makeRuntimeErrorMsg(ctx, "Could not find server. This is a bug. Report to dev.");
@ -701,11 +698,8 @@ export const ns: InternalAPI<NSFull> = {
(_scriptname, _hostname, _threads = 1, ..._args) => {
const scriptname = helpers.string(ctx, "scriptname", _scriptname);
const hostname = helpers.string(ctx, "hostname", _hostname);
const threads = helpers.number(ctx, "threads", _threads);
const threads = helpers.positiveInteger(ctx, "threads", _threads);
const args = helpers.scriptArgs(ctx, _args);
if (isNaN(threads) || threads <= 0) {
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid thread count. Must be numeric and > 0, is ${threads}`);
}
const server = helpers.getServer(ctx, hostname);
return runScriptFromScript("exec", server, scriptname, args, ctx.workerScript, threads);
},
@ -713,17 +707,10 @@ export const ns: InternalAPI<NSFull> = {
(ctx) =>
(_scriptname, _threads = 1, ..._args) => {
const scriptname = helpers.string(ctx, "scriptname", _scriptname);
const threads = helpers.number(ctx, "threads", _threads);
const threads = helpers.positiveInteger(ctx, "threads", _threads);
const args = helpers.scriptArgs(ctx, _args);
if (!scriptname || !threads) {
throw helpers.makeRuntimeErrorMsg(ctx, "Usage: spawn(scriptname, threads)");
}
const spawnDelay = 10;
setTimeout(() => {
if (isNaN(threads) || threads <= 0) {
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid thread count. Must be numeric and > 0, is ${threads}`);
}
const scriptServer = GetServer(ctx.workerScript.hostname);
if (scriptServer == null) {
throw helpers.makeRuntimeErrorMsg(ctx, "Could not find server. This is a bug. Report to dev");

@ -4561,22 +4561,10 @@ export interface NS {
* Use `args.length` to get the number of arguments that were passed into a script.
*
* @example
* `run example.script 7 text true`
*
* ```js
* // NS1 - example.script
* tprint(args.length) // 3
* tprint(args[0]); // 7 (number)
* tprint(args[1]); // "text" (string)
* tprint(args[2]); // true (boolean)
* tprint(args[3]); // undefined, because only 3 arguments were provided
* ```
*
* @example
* `run example.js 7 text true`
*
* ```js
* // NS2 - example.js
* // example.js
* export async function main(ns) {
* ns.tprint(ns.args.length) // 3
* ns.tprint(ns.args[0]); // 7 (number)
@ -5061,28 +5049,15 @@ export interface NS {
* Remember that scripts are uniquely identified by both their names and arguments.
*
* @example
* ```ts
* // NS1:
* //Get logs from foo.script on the current server that was run with no args
* getScriptLogs("foo.script");
* ```js
* //Get logs from foo.js on the current server that was run with no args
* ns.getScriptLogs("foo.js");
*
* //Open logs from foo.script on the foodnstuff server that was run with no args
* getScriptLogs("foo.script", "foodnstuff");
* //Open logs from foo.js on the foodnstuff server that was run with no args
* ns.getScriptLogs("foo.js", "foodnstuff");
*
* //Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* getScriptLogs("foo.script", "foodnstuff", 1, "test");
* ```
* @example
* ```ts
* // NS2:
* //Get logs from foo.script on the current server that was run with no args
* ns.getScriptLogs("foo.script");
*
* //Open logs from foo.script on the foodnstuff server that was run with no args
* ns.getScriptLogs("foo.script", "foodnstuff");
*
* //Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* ns.getScriptLogs("foo.script", "foodnstuff", 1, "test");
* //Open logs from foo.js on the foodnstuff server that was run with the arguments [1, "test"]
* ns.getScriptLogs("foo.js", "foodnstuff", 1, "test");
* ```
* @param fn - Optional. Filename of script to get logs from.
* @param host - Optional. Hostname of the server that the script is on.
@ -5125,28 +5100,15 @@ export interface NS {
* Remember that scripts are uniquely identified by both their names and arguments.
*
* @example
* ```ts
* // NS1:
* //Open logs from foo.script on the current server that was run with no args
* tail("foo.script");
* ```js
* //Open logs from foo.js on the current server that was run with no args
* ns.tail("foo.js");
*
* //Get logs from foo.script on the foodnstuff server that was run with no args
* tail("foo.script", "foodnstuff");
* //Get logs from foo.js on the foodnstuff server that was run with no args
* ns.tail("foo.js", "foodnstuff");
*
* //Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* tail("foo.script", "foodnstuff", 1, "test");
* ```
* @example
* ```ts
* // NS2:
* //Open logs from foo.script on the current server that was run with no args
* ns.tail("foo.script");
*
* //Get logs from foo.script on the foodnstuff server that was run with no args
* ns.tail("foo.script", "foodnstuff");
*
* //Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* ns.tail("foo.script", "foodnstuff", 1, "test");
* //Get logs from foo.js on the foodnstuff server that was run with the arguments [1, "test"]
* ns.tail("foo.js", "foodnstuff", 1, "test");
* ```
* @param fn - Optional. Filename or PID of the script being tailed. If omitted, the current script is tailed.
* @param host - Optional. Hostname of the script being tailed. Defaults to the server this script is running on. If args are specified, this is not optional.
@ -5408,31 +5370,18 @@ export interface NS {
* Running this function with a numThreads argument of 0 or less will cause a runtime error.
*
* @example
* ```ts
* // NS1:
* //The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
* run("foo.script");
* ```js
* //The simplest way to use the run command is to call it with just the script name. The following example will run foo.js single-threaded with no arguments:
* ns.run("foo.js");
*
* //The following example will run foo.script but with 5 threads instead of single-threaded:
* run("foo.script", 5);
* //The following example will run foo.js but with 5 threads instead of single-threaded:
* ns.run("foo.js", 5);
*
* //This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
* run("foo.script", 1, 'foodnstuff');
* ```
* @example
* ```ts
* // NS2:
* //The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
* ns.run("foo.script");
*
* //The following example will run foo.script but with 5 threads instead of single-threaded:
* ns.run("foo.script", 5);
*
* //This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
* ns.run("foo.script", 1, 'foodnstuff');
* //This next example will run foo.js single-threaded, and will pass the string foodnstuff into the script as an argument:
* ns.run("foo.js", 1, 'foodnstuff');
* ```
* @param script - Filename of script to run.
* @param numThreads - Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer.
* @param numThreads - Integer number of threads for new script. Defaults to 1.
* @param args - Additional arguments to pass into the new script that is being run. Note that if any arguments are being passed into the new script, then the second argument numThreads must be filled in with a value.
* @returns Returns the PID of a successfully started script, and 0 otherwise.
*/
@ -5455,46 +5404,28 @@ export interface NS {
* Running this function with a numThreads argument of 0 or less will cause a runtime error.
*
* @example
* ```ts
* // NS1:
* ```js
* // The simplest way to use the exec command is to call it with just the script name
* // and the target server. The following example will try to run generic-hack.script
* // and the target server. The following example will try to run generic-hack.js
* // on the foodnstuff server.
* exec("generic-hack.script", "foodnstuff");
* ns.exec("generic-hack.js", "foodnstuff");
*
* // The following example will try to run the script generic-hack.script on the
* // The following example will try to run the script generic-hack.js on the
* // joesguns server with 10 threads.
* exec("generic-hack.script", "joesguns", 10);
* ns.exec("generic-hack.js", "joesguns", 10);
*
* // This last example will try to run the script foo.script on the foodnstuff server
* // This last example will try to run the script foo.js on the foodnstuff server
* // with 5 threads. It will also pass the number 1 and the string “test” in as
* // arguments to the script.
* exec("foo.script", "foodnstuff", 5, 1, "test");
* ```
* @example
* ```ts
* // NS2:
* // The simplest way to use the exec command is to call it with just the script name
* // and the target server. The following example will try to run generic-hack.script
* // on the foodnstuff server.
* ns.exec("generic-hack.script", "foodnstuff");
*
* // The following example will try to run the script generic-hack.script on the
* // joesguns server with 10 threads.
* ns.exec("generic-hack.script", "joesguns", 10);
*
* // This last example will try to run the script foo.script on the foodnstuff server
* // with 5 threads. It will also pass the number 1 and the string “test” in as
* // arguments to the script.
* ns.exec("foo.script", "foodnstuff", 5, 1, "test");
* ns.exec("foo.js", "foodnstuff", 5, 1, "test");
* ```
* @param script - Filename of script to execute.
* @param host - Hostname of the `target server` on which to execute the script.
* @param numThreads - Optional thread count for new script. Set to 1 by default. Will be rounded down to the nearest integer.
* @param hostname - Hostname of the `target server` on which to execute the script.
* @param numThreads - Integer number of threads for new script. Defaults to 1.
* @param args - Additional arguments to pass into the new script that is being run. Note that if any arguments are being passed into the new script, then the third argument numThreads must be filled in with a value.
* @returns Returns the PID of a successfully started script, and 0 otherwise.
*/
exec(script: string, host: string, numThreads?: number, ...args: (string | number | boolean)[]): number;
exec(script: string, hostname: string, numThreads?: number, ...args: (string | number | boolean)[]): number;
/**
* Terminate current script and start another in 10 seconds.
@ -5511,19 +5442,12 @@ export interface NS {
* Running this function with a numThreads argument of 0 or less will cause a runtime error.
*
* @example
* ```ts
* // NS1:
* //The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
* spawn('foo.script', 10, 'foodnstuff', 90);
* ```
* @example
* ```ts
* // NS2:
* //The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
* ns.spawn('foo.script', 10, 'foodnstuff', 90);
* ```js
* //The following example will execute the script foo.js with 10 threads and the arguments foodnstuff and 90:
* ns.spawn('foo.js', 10, 'foodnstuff', 90);
* ```
* @param script - Filename of script to execute.
* @param numThreads - Number of threads to spawn new script with. Will be rounded to nearest integer.
* @param numThreads - Integer number of threads for new script. Defaults to 1.
* @param args - Additional arguments to pass into the new script that is being run.
*/
spawn(script: string, numThreads?: number, ...args: (string | number | boolean)[]): void;
@ -5558,10 +5482,10 @@ export interface NS {
* @example
* ```js
* // kill the script "foo.js" on the same server the current script is running from, with no arguments
* ns.kill("foo.script");
* ns.kill("foo.js");
*
* // kill the script "foo.js" on the "n00dles" server with no arguments.
* ns.kill("foo.script", "n00dles");
* ns.kill("foo.js", "n00dles");
*
* // kill the script foo.js on the current server that was ran with the arguments [1, “foodnstuff”, false]:
* ns.kill("foo.js", ns.getHostname(), 1, "foodnstuff", false);
@ -5605,30 +5529,18 @@ export interface NS {
* specifying a single file to copy, or an array of strings specifying multiple files to copy.
*
* @example
* ```ts
* // NS1:
* //Copies foo.lit from the helios server to the home computer:
* scp("foo.lit", "home", "helios");
*
* //Tries to copy three files from rothman-uni to home computer:
* files = ["foo1.lit", "foo2.script", "foo3.script"];
* scp(files, "home", "rothman-uni");
* ```
* @example
* ```ts
* // NS2:
* ```js
* //Copies foo.lit from the helios server to the home computer:
* ns.scp("foo.lit", "home", "helios" );
*
* //Tries to copy three files from rothman-uni to home computer:
* files = ["foo1.lit", "foo2.script", "foo3.script"];
* ns.scp(files, "home", "rothman-uni");
* files = ["foo1.lit", "foo2.txt", "foo3.js"];
* ns.scp(files, "home", "rothman-uni");
* ```
* @example
* ```ts
* //ns2, copies files from home to a target server
* ```js
* const server = ns.args[0];
* const files = ["hack.js","weaken.js","grow.js"];
* const files = ["hack.js", "weaken.js", "grow.js"];
* ns.scp(files, server, "home");
* ```
* @param files - Filename or an array of filenames of script/literature files to copy. Note that if a file is located in a subdirectory, the filename must include the leading `/`.
@ -5947,20 +5859,10 @@ export interface NS {
* If the hostname/ip argument is omitted, then the function will search through the current
* server (the server running the script that calls this function) for the file.
*
* @example
* ```ts
* // NS1:
* //The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
* fileExists("foo.script", "foodnstuff");
*
* //The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
* fileExists("ftpcrack.exe");
* ```
* * @example
* ```ts
* // NS2:
* // The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
* ns.fileExists("foo.script", "foodnstuff");
* ```js
* // The function call will return true if the script named foo.js exists on the foodnstuff server, and false otherwise.
* ns.fileExists("foo.js", "foodnstuff");
*
* // The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
* ns.fileExists("ftpcrack.exe");
@ -5981,28 +5883,15 @@ export interface NS {
* Remember that a script is uniquely identified by both its name and its arguments.
*
* @example
* ```ts
* // NS1:
* //The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
* isRunning("foo.script", "foodnstuff");
* ```js
* //The function call will return true if there is a script named foo.js with no arguments running on the foodnstuff server, and false otherwise:
* ns.isRunning("foo.js", "foodnstuff");
*
* //The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
* isRunning("foo.script", getHostname());
* //The function call will return true if there is a script named foo.js with no arguments running on the current server, and false otherwise:
* ns.isRunning("foo.js", ns.getHostname());
*
* //The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
* isRunning("foo.script", "joesguns", 1, 5, "test");
* ```
* @example
* ```ts
* // NS2:
* //The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
* ns.isRunning("foo.script", "foodnstuff");
*
* //The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
* ns.isRunning("foo.script", ns.getHostname());
*
* //The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
* ns.isRunning("foo.script", "joesguns", 1, 5, "test");
* //The function call will return true if there is a script named foo.js running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
* ns.isRunning("foo.js", "joesguns", 1, 5, "test");
* ```
* @param script - Filename or PID of script to check. This is case-sensitive.
* @param host - Hostname of target server.
@ -6217,7 +6106,7 @@ export interface NS {
* @remarks
* RAM cost: 0 GB
*
* This function is used to read data from a text file (.txt) or script (.script, .js).
* This function is used to read data from a text file (.txt) or script (.js or .script).
*
* This function will return the data in the specified file.
* If the file does not exist, an empty string will be returned.
@ -6324,22 +6213,12 @@ export interface NS {
* identify a specific instance of a running script by its arguments.
*
* @example
* ```ts
* // NS1:
* //The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
* scriptRunning("foo.script", "foodnstuff");
* ```js
* //The function call will return true if there is any script named foo.js running on the foodnstuff server, and false otherwise:
* ns.scriptRunning("foo.js", "foodnstuff");
*
* //The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
* scriptRunning("foo.script", getHostname());
* ```
* * @example
* ```ts
* // NS2:
* //The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
* ns.scriptRunning("foo.script", "foodnstuff");
*
* //The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
* ns.scriptRunning("foo.script", ns.getHostname());
* //The function call will return true if there is any script named “foo.js” running on the current server, and false otherwise:
* ns.scriptRunning("foo.js", ns.getHostname());
* ```
* @param script - Filename of script to check. This is case-sensitive.
* @param host - Hostname of target server.
@ -6702,7 +6581,7 @@ export interface NS {
* RAM cost: 0 GB
*
* Retrieves data from a URL and downloads it to a file on the specified server.
* The data can only be downloaded to a script (.script, .js) or a text file (.txt).
* The data can only be downloaded to a script (.js or .script) or a text file (.txt).
* If the file already exists, it will be overwritten by this command.
* Note that it will not be possible to download data from many websites because they
* do not allow cross-origin resource sharing (CORS).
@ -6719,13 +6598,7 @@ export interface NS {
* you will not be able to process the returned value of wget in Netscript 1.0.
*
* @example
* ```ts
* // NS1:
* wget("https://raw.githubusercontent.com/bitburner-official/bitburner-src/master/README.md", "game_readme.txt");
* ```
* @example
* ```ts
* // NS2:
* ```js
* await ns.wget("https://raw.githubusercontent.com/bitburner-official/bitburner-src/master/README.md", "game_readme.txt");
* ```
* @param url - URL to pull data from.
@ -6836,17 +6709,7 @@ export interface NS {
*
* Allows Unix-like flag parsing.
* @example
* ```ts
* // example.script
* var data = flags([
* ['delay', 0], // a default number means this flag is a number
* ['server', 'foodnstuff'], // a default string means this flag is a string
* ['exclude', []], // a default array means this flag is a default array of string
* ['help', false], // a default boolean means this flag is a boolean
* ]);
* tprint(data);
*
* // example.js
* ```js
* export async function main(ns) {
* const data = ns.flags([
* ['delay', 0], // a default number means this flag is a number
@ -6857,15 +6720,15 @@ export interface NS {
* ns.tprint(data);
* }
*
* // [home ~/]> run example.script
* // [home ~/]> run example.js
* // {"_":[],"delay":0,"server":"foodnstuff","exclude":[],"help":false}
* // [home ~/]> run example.script --delay 3000
* // [home ~/]> run example.js --delay 3000
* // {"_":[],"server":"foodnstuff","exclude":[],"help":false,"delay":3000}
* // [home ~/]> run example.script --delay 3000 --server harakiri-sushi
* // [home ~/]> run example.js --delay 3000 --server harakiri-sushi
* // {"_":[],"exclude":[],"help":false,"delay":3000,"server":"harakiri-sushi"}
* // [home ~/]> run example.script --delay 3000 --server harakiri-sushi hello world
* // [home ~/]> run example.js --delay 3000 --server harakiri-sushi hello world
* // {"_":["hello","world"],"exclude":[],"help":false,"delay":3000,"server":"harakiri-sushi"}
* // [home ~/]> run example.script --delay 3000 --server harakiri-sushi hello world --exclude a --exclude b
* // [home ~/]> run example.js --delay 3000 --server harakiri-sushi hello world --exclude a --exclude b
* // {"_":["hello","world"],"help":false,"delay":3000,"server":"harakiri-sushi","exclude":["a","b"]}
* // [home ~/]> run example.script --help
* // {"_":[],"delay":0,"server":"foodnstuff","exclude":[],"help":true}

@ -22,13 +22,12 @@ export function runScript(commandArgs: (string | number | boolean)[], server: Ba
permissive: true,
argv: commandArgs.slice(1),
});
const threadFlag = Math.round(parseFloat(flags["-t"]));
const tailFlag = flags["--tail"] === true;
if (flags["-t"] !== undefined && (threadFlag < 0 || isNaN(threadFlag))) {
Terminal.error("Invalid number of threads specified. Number of threads must be greater than 0");
const numThreads = parseFloat(flags["-t"] ?? 1);
if (numThreads < 1 || !Number.isInteger(numThreads)) {
Terminal.error("Invalid number of threads specified. Number of threads must be an integer greater than 0");
return;
}
const numThreads = !isNaN(threadFlag) && threadFlag > 0 ? threadFlag : 1;
const args = flags["_"];
// Check if this script is already running