mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-30 03:23:48 +01:00
Implemented 'kill by PID' functionality
This commit is contained in:
parent
d94516f39b
commit
4f2f75762c
@ -204,8 +204,8 @@ The list contains the name of (i.e. the value returned by
|
|||||||
| | | the string, the result should be an array with only an empty string. |
|
| | | the string, the result should be an array with only an empty string. |
|
||||||
| | | |
|
| | | |
|
||||||
| | | Examples: |
|
| | | Examples: |
|
||||||
| | | ()())() -> [()()(), (())()] |
|
| | | ()())() -> [()()(), (())()] |
|
||||||
| | | (a)())() -> [(a)()(), (a())()] |
|
| | | (a)())() -> [(a)()(), (a())()] |
|
||||||
| | | )( -> [""] |
|
| | | )( -> [""] |
|
||||||
+------------------------------------+------------------------------------------------------------------------------------------+
|
+------------------------------------+------------------------------------------------------------------------------------------+
|
||||||
| Find All Valid Math Expressions | | You are given a string which contains only digits between 0 and 9 as well as a target |
|
| Find All Valid Math Expressions | | You are given a string which contains only digits between 0 and 9 as well as a target |
|
||||||
@ -218,8 +218,8 @@ The list contains the name of (i.e. the value returned by
|
|||||||
| | | |
|
| | | |
|
||||||
| | | Examples: |
|
| | | Examples: |
|
||||||
| | | Input: digits = "123", target = 6 |
|
| | | Input: digits = "123", target = 6 |
|
||||||
| | | Output: [1+2+3, 1*2*3] |
|
| | | Output: [1+2+3, 1*2*3] |
|
||||||
| | | |
|
| | | |
|
||||||
| | | Input: digits = "105", target = 5 |
|
| | | Input: digits = "105", target = 5 |
|
||||||
| | | Output: [1*0+5, 10-5] |
|
| | | Output: [1*0+5, 10-5] |
|
||||||
+------------------------------------+------------------------------------------------------------------------------------------+
|
+------------------------------------+------------------------------------------------------------------------------------------+
|
||||||
|
@ -312,9 +312,12 @@ kill
|
|||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
$ kill [script name] [args...]
|
$ kill [script name] [args...]
|
||||||
|
$ kill [pid]
|
||||||
|
|
||||||
Kill the script specified by the script name and arguments. Each argument must
|
Kill the script specified by the script filename and arguments OR by its PID.
|
||||||
be separated by a space. Remember that a running script is uniquely identified
|
|
||||||
|
If you are killing the script using its filename and arguments, then each argument
|
||||||
|
must be separated by a space. Remember that a running script is uniquely identified
|
||||||
by both its name and the arguments that are used to start it. So, if a script
|
by both its name and the arguments that are used to start it. So, if a script
|
||||||
was ran with the following arguments::
|
was ran with the following arguments::
|
||||||
|
|
||||||
@ -324,8 +327,7 @@ Then to kill this script the same arguments would have to be used::
|
|||||||
|
|
||||||
$ kill foo.script 50e3 sigma-cosmetics
|
$ kill foo.script 50e3 sigma-cosmetics
|
||||||
|
|
||||||
Note that after issuing the 'kill' command for a script, it may take a few seconds for
|
If you are killing the script using its PID, then the PID argument must be numeric.
|
||||||
the script to actually stop running.
|
|
||||||
|
|
||||||
killall
|
killall
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
@ -14,10 +14,15 @@ exec() Netscript Function
|
|||||||
Run a script as a separate process on a specified server. This is similar to the *run* function except
|
Run a script as a separate process on a specified server. This is similar to the *run* function except
|
||||||
that it can be used to run a script on any server, instead of just the current server.
|
that it can be used to run a script on any server, instead of just the current server.
|
||||||
|
|
||||||
Returns true if the script is successfully started, and false otherwise.
|
If the script was successfully started, then this functions returns the PID
|
||||||
|
of that script. Otherwise, it returns 0.
|
||||||
|
|
||||||
Running this function with a *numThreads* argument of 0 will return false without running the script.
|
.. note:: PID stands for Process ID. The PID is a unique identifier for each script.
|
||||||
However, running this function with a negative *numThreads* argument will cause a runtime error.
|
The PID will always be a positive integer.
|
||||||
|
|
||||||
|
.. warning:: Running this function with a *numThreads* argument of 0 will return 0 without
|
||||||
|
running the script. However, running this function with a negative *numThreads*
|
||||||
|
argument will cause a runtime error.
|
||||||
|
|
||||||
The simplest way to use the *exec* command is to call it with just the script name and the target server.
|
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::
|
The following example will try to run *generic-hack.script* on the *foodnstuff* server::
|
||||||
|
@ -27,3 +27,22 @@ kill() Netscript Function
|
|||||||
The following will try to kill a script named *foo.script* on the current server that was ran with the arguments 1 and "foodnstuff"::
|
The following will try to kill a script named *foo.script* on the current server that was ran with the arguments 1 and "foodnstuff"::
|
||||||
|
|
||||||
kill("foo.script", getHostname(), 1, "foodnstuff");
|
kill("foo.script", getHostname(), 1, "foodnstuff");
|
||||||
|
|
||||||
|
.. js:function:: kill(scriptPid)
|
||||||
|
|
||||||
|
:param number scriptPid: PID of the script to kill
|
||||||
|
:RAM cost: 0.5 GB
|
||||||
|
|
||||||
|
Kills the script with the specified PID. Killing a script by its PID will typically
|
||||||
|
have better performance, especially if you have many scripts running.
|
||||||
|
|
||||||
|
If this function successfully kills the specified script, then it will return true.
|
||||||
|
Otherwise, it will return false.
|
||||||
|
|
||||||
|
*Examples:*
|
||||||
|
|
||||||
|
The following example will try to kill the script with the PID 10::
|
||||||
|
|
||||||
|
if (kill(10)) {
|
||||||
|
print("Killed script with PID 10!");
|
||||||
|
}
|
||||||
|
@ -13,10 +13,15 @@ run() Netscript Function
|
|||||||
Run a script as a separate process. This function can only be used to run scripts located on the current server (the server
|
Run a script as a separate process. This function can only be used to run scripts located on the current server (the server
|
||||||
running the script that calls this function).
|
running the script that calls this function).
|
||||||
|
|
||||||
Returns true if the script is successfully started, and false otherwise.
|
If the script was successfully started, then this functions returns the PID
|
||||||
|
of that script. Otherwise, it returns 0.
|
||||||
|
|
||||||
Running this function with a *numThreads* argument of 0 will return false without running the script.
|
.. note:: PID stands for Process ID. The PID is a unique identifier for each script.
|
||||||
However, running this function with a negative *numThreads* argument will cause a runtime error.
|
The PID will always be a positive integer.
|
||||||
|
|
||||||
|
.. warning:: Running this function with a *numThreads* argument of 0 will return 0 without
|
||||||
|
running the script. However, running this function with a negative *numThreads*
|
||||||
|
argument will cause a runtime error.
|
||||||
|
|
||||||
The simplest way to use the *run* command is to call it with just the script name. The following example will run
|
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::
|
'foo.script' single-threaded with no arguments::
|
||||||
|
@ -51,8 +51,6 @@ Here is a summary of all rules you need to follow when writing Netscript JS code
|
|||||||
* grow
|
* grow
|
||||||
* weaken
|
* weaken
|
||||||
* sleep
|
* sleep
|
||||||
* run
|
|
||||||
* exec
|
|
||||||
* prompt
|
* prompt
|
||||||
* wget
|
* wget
|
||||||
|
|
||||||
|
@ -230,10 +230,17 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
* Bug fix: workForFaction() function now properly accounts for disabled logs
|
* Bug fix: workForFaction() function now properly accounts for disabled logs
|
||||||
* When writing to a file, the write() function now casts the data being written to a string (using String())
|
* When writing to a file, the write() function now casts the data being written to a string (using String())
|
||||||
* BitNode-selection page now shows what Source-File level you have for each BitNode
|
* BitNode-selection page now shows what Source-File level you have for each BitNode
|
||||||
|
* Overloaded kill() function so that you can kill a script by its PID
|
||||||
|
* spawn() now only takes 10 seconds to run (decreased from 20 seconds)
|
||||||
|
* run() and exec() now return the PID of the newly-executed scripts, rather than a boolean
|
||||||
|
** (A PID is just a positive integer)
|
||||||
|
* run(), exec(), and spawn() no longer need to be await-ed in NetscriptJS
|
||||||
|
|
||||||
Misc Changes
|
Misc Changes
|
||||||
|
* The 'kill' Terminal command can now kill a script by its PID
|
||||||
* Added 'Solarized Dark' theme to CodeMirror editor
|
* Added 'Solarized Dark' theme to CodeMirror editor
|
||||||
* After Infiltration, you will now return to the company page rather than the city page
|
* After Infiltration, you will now return to the company page rather than the city page
|
||||||
* Bug fix: Stock Market UI should no longer crash for certain locale settings
|
* Bug fix: Stock Market UI should no longer crash for certain locale settings
|
||||||
|
* Bug fix: You can now properly remove unfinished programs (the *.exe-N%-INC files)
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (fn != null && typeof fn === "string") {
|
if (fn != null && typeof fn === "string") {
|
||||||
// Get Logs of another script
|
// Get Logs of another script
|
||||||
if (ip == null) { ip = workerScript.serverIp; }
|
if (ip == null) { ip = workerScript.serverIp; }
|
||||||
const server = getServer(ip, callingFnName);
|
const server = safeGetServer(ip, callingFnName);
|
||||||
|
|
||||||
return findRunningScript(fn, scriptArgs, server);
|
return findRunningScript(fn, scriptArgs, server);
|
||||||
}
|
}
|
||||||
@ -973,6 +973,8 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (scriptname == null || threads == null) {
|
if (scriptname == null || threads == null) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid scriptname or numThreads argument passed to spawn()");
|
throw makeRuntimeRejectMsg(workerScript, "Invalid scriptname or numThreads argument passed to spawn()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const spawnDelay = 10;
|
||||||
setTimeoutRef(() => {
|
setTimeoutRef(() => {
|
||||||
if (scriptname === undefined) {
|
if (scriptname === undefined) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");
|
throw makeRuntimeRejectMsg(workerScript, "spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");
|
||||||
@ -990,40 +992,52 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
||||||
}, 20e3);
|
}, spawnDelay * 1e3);
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.spawn == null) {
|
if (workerScript.shouldLog("spawn")) {
|
||||||
workerScript.scriptRef.log("spawn() will execute " + scriptname + " in 20 seconds");
|
workerScript.scriptRef.log(`spawn() will execute ${scriptname} in ${spawnDelay} seconds`);
|
||||||
}
|
}
|
||||||
NetscriptFunctions(workerScript).exit();
|
NetscriptFunctions(workerScript).exit();
|
||||||
},
|
},
|
||||||
kill: function(filename, ip) {
|
kill: function(filename, ip, ...scriptArgs) {
|
||||||
updateDynamicRam("kill", getRamCost("kill"));
|
updateDynamicRam("kill", getRamCost("kill"));
|
||||||
if (filename === undefined || ip === undefined) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Usage: kill(scriptname, server, [arg1], [arg2]...)");
|
let res;
|
||||||
|
const killByPid = (typeof filename === "number");
|
||||||
|
if (killByPid) {
|
||||||
|
// Kill by pid
|
||||||
|
res = killWorkerScript(filename);
|
||||||
|
} else {
|
||||||
|
// Kill by filename/ip
|
||||||
|
if (filename === undefined || ip === undefined) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Usage: kill(scriptname, server, [arg1], [arg2]...)");
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = safeGetServer(ip);
|
||||||
|
const runningScriptObj = getRunningScript(filename, ip, "kill", scriptArgs);
|
||||||
|
if (runningScriptObj == null) {
|
||||||
|
workerScript.log(`tail() failed. ${getCannotFindRunningScriptErrorMessage(filename, ip, scriptArgs)}`)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = killWorkerScript(runningScriptObj, server.ip);
|
||||||
}
|
}
|
||||||
var server = getServer(ip);
|
|
||||||
if (server == null) {
|
|
||||||
workerScript.scriptRef.log("kill() failed. Invalid IP or hostname passed in: " + ip);
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "kill() failed. Invalid IP or hostname passed in: " + ip);
|
|
||||||
}
|
|
||||||
var argsForKillTarget = [];
|
|
||||||
for (var i = 2; i < arguments.length; ++i) {
|
|
||||||
argsForKillTarget.push(arguments[i]);
|
|
||||||
}
|
|
||||||
var runningScriptObj = findRunningScript(filename, argsForKillTarget, server);
|
|
||||||
if (runningScriptObj == null) {
|
|
||||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + arrayToString(argsForKillTarget));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var res = killWorkerScript(runningScriptObj, server.ip);
|
|
||||||
if (res) {
|
if (res) {
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.kill == null) {
|
if (workerScript.shouldLog("kill")) {
|
||||||
workerScript.scriptRef.log("Killing " + filename + " on " + server.hostname + " with args: " + arrayToString(argsForKillTarget) + ". May take up to a few minutes for the scripts to die...");
|
if (killByPid) {
|
||||||
|
workerScript.log(`Killing script with PID ${filename}`);
|
||||||
|
} else {
|
||||||
|
workerScript.log(`Killing ${filename} on ${ip} with args: ${arrayToString(scriptArgs)}.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.kill == null) {
|
if (workerScript.shouldLog("kill")) {
|
||||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + arrayToString(argsForKillTarget));
|
if (killByPid) {
|
||||||
|
workerScript.log(`kill() failed. No such script with PID ${filename}`);
|
||||||
|
} else {
|
||||||
|
workerScript.log(`kill() failed. No such script ${filename} on ${ip} with args: ${arrayToString(scriptArgs)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -605,42 +605,53 @@ export function loadAllRunningScripts() {
|
|||||||
* Run a script from inside another script (run(), exec(), spawn(), etc.)
|
* Run a script from inside another script (run(), exec(), spawn(), etc.)
|
||||||
*/
|
*/
|
||||||
export function runScriptFromScript(server, scriptname, args, workerScript, threads=1) {
|
export function runScriptFromScript(server, scriptname, args, workerScript, threads=1) {
|
||||||
//Check if the script is already running
|
// Sanitize arguments
|
||||||
let runningScriptObj = findRunningScript(scriptname, args, server);
|
if (!(workerScript instanceof WorkerScript)) {
|
||||||
if (runningScriptObj != null) {
|
return 0;
|
||||||
workerScript.scriptRef.log(scriptname + " is already running on " + server.hostname);
|
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//'null/undefined' arguments are not allowed
|
if (typeof scriptname !== "string" || !Array.isArray(args)) {
|
||||||
|
workerScript.log(`ERROR: runScriptFromScript() failed due to invalid arguments`);
|
||||||
|
console.error(`runScriptFromScript() failed due to invalid arguments`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the script is already running
|
||||||
|
let runningScriptObj = server.getRunningScript(scriptname, args);
|
||||||
|
if (runningScriptObj != null) {
|
||||||
|
workerScript.log(`${scriptname} is already running on ${server.hostname}`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'null/undefined' arguments are not allowed
|
||||||
for (let i = 0; i < args.length; ++i) {
|
for (let i = 0; i < args.length; ++i) {
|
||||||
if (args[i] == null) {
|
if (args[i] == null) {
|
||||||
workerScript.scriptRef.log("ERROR: Cannot execute a script with null/undefined as an argument");
|
workerScript.log("ERROR: Cannot execute a script with null/undefined as an argument");
|
||||||
return Promise.resolve(false);
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the script exists and if it does run it
|
// Check if the script exists and if it does run it
|
||||||
for (let i = 0; i < server.scripts.length; ++i) {
|
for (let i = 0; i < server.scripts.length; ++i) {
|
||||||
if (server.scripts[i].filename == scriptname) {
|
if (server.scripts[i].filename === scriptname) {
|
||||||
//Check for admin rights and that there is enough RAM availble to run
|
// Check for admin rights and that there is enough RAM availble to run
|
||||||
var script = server.scripts[i];
|
const script = server.scripts[i];
|
||||||
var ramUsage = script.ramUsage;
|
let ramUsage = script.ramUsage;
|
||||||
threads = Math.round(Number(threads)); //Convert to number and round
|
threads = Math.round(Number(threads));
|
||||||
if (threads === 0) { return Promise.resolve(false); }
|
if (threads === 0) { return 0; }
|
||||||
ramUsage = ramUsage * threads;
|
ramUsage = ramUsage * threads;
|
||||||
var ramAvailable = server.maxRam - server.ramUsed;
|
const ramAvailable = server.maxRam - server.ramUsed;
|
||||||
|
|
||||||
if (server.hasAdminRights == false) {
|
if (server.hasAdminRights == false) {
|
||||||
workerScript.scriptRef.log("Cannot run script " + scriptname + " on " + server.hostname + " because you do not have root access!");
|
workerScript.log(`Cannot run script ${scriptname} on ${server.hostname} because you do not have root access!`);
|
||||||
return Promise.resolve(false);
|
return 0;
|
||||||
} else if (ramUsage > ramAvailable){
|
} else if (ramUsage > ramAvailable){
|
||||||
workerScript.scriptRef.log("Cannot run script " + scriptname + "(t=" + threads + ") on " + server.hostname + " because there is not enough available RAM!");
|
workerScript.log(`Cannot run script ${scriptname} (t=${threads}) on ${server.hostname} because there is not enough available RAM!`);
|
||||||
return Promise.resolve(false);
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
//Able to run script
|
// Able to run script
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.exec == null && workerScript.disableLogs.run == null && workerScript.disableLogs.spawn == null) {
|
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.exec == null && workerScript.disableLogs.run == null && workerScript.disableLogs.spawn == null) {
|
||||||
workerScript.scriptRef.log(`Running script: ${scriptname} on ${server.hostname} with ${threads} threads and args: ${arrayToString(args)}. May take a few seconds to start up...`);
|
workerScript.log(`Running script: ${scriptname} on ${server.hostname} with ${threads} threads and args: ${arrayToString(args)}.`);
|
||||||
}
|
}
|
||||||
let runningScriptObj = new RunningScript(script, args);
|
let runningScriptObj = new RunningScript(script, args);
|
||||||
runningScriptObj.threads = threads;
|
runningScriptObj.threads = threads;
|
||||||
@ -649,10 +660,14 @@ export function runScriptFromScript(server, scriptname, args, workerScript, thre
|
|||||||
// Push onto runningScripts.
|
// Push onto runningScripts.
|
||||||
// This has to come after addWorkerScript() because that fn updates RAM usage
|
// This has to come after addWorkerScript() because that fn updates RAM usage
|
||||||
server.runScript(runningScriptObj, Player.hacknet_node_money_mult);
|
server.runScript(runningScriptObj, Player.hacknet_node_money_mult);
|
||||||
return Promise.resolve(true);
|
|
||||||
|
// Once the WorkerScript is constructed in addWorkerScript(), the RunningScript
|
||||||
|
// object should have a PID assigned to it, so we return that
|
||||||
|
return runningScriptObj.pid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workerScript.scriptRef.log("Could not find script " + scriptname + " on " + server.hostname);
|
|
||||||
return Promise.resolve(false);
|
workerScript.log(`Could not find script ${scriptname} on ${server.hostname}`);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import { IReturnStatus } from "../types";
|
|||||||
import { isScriptFilename } from "../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../Script/ScriptHelpersTS";
|
||||||
|
|
||||||
import { createRandomIp } from "../../utils/IPAddress";
|
import { createRandomIp } from "../../utils/IPAddress";
|
||||||
|
import { compareArrays } from "../../utils/helpers/compareArrays";
|
||||||
|
|
||||||
interface IConstructorParams {
|
interface IConstructorParams {
|
||||||
adminRights?: boolean;
|
adminRights?: boolean;
|
||||||
@ -113,8 +114,27 @@ export class BaseServer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given the name of the script, returns the corresponding
|
/**
|
||||||
// script object on the server (if it exists)
|
* Find an actively running script on this server
|
||||||
|
* @param scriptName - Filename of script to search for
|
||||||
|
* @param scriptArgs - Arguments that script is being run with
|
||||||
|
* @returns RunningScript for the specified active script
|
||||||
|
* Returns null if no such script can be found
|
||||||
|
*/
|
||||||
|
getRunningScript(scriptName: string, scriptArgs: any[]): RunningScript | null {
|
||||||
|
for (let rs of this.runningScripts) {
|
||||||
|
if (rs.filename === scriptName && compareArrays(rs.args, scriptArgs)) {
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the name of the script, returns the corresponding
|
||||||
|
* Script object on the server (if it exists)
|
||||||
|
*/
|
||||||
getScript(scriptName: string): Script | null {
|
getScript(scriptName: string): Script | null {
|
||||||
for (let i = 0; i < this.scripts.length; i++) {
|
for (let i = 0; i < this.scripts.length; i++) {
|
||||||
if (this.scripts[i].filename === scriptName) {
|
if (this.scripts[i].filename === scriptName) {
|
||||||
@ -129,7 +149,6 @@ export class BaseServer {
|
|||||||
* Returns boolean indicating whether the given script is running on this server
|
* Returns boolean indicating whether the given script is running on this server
|
||||||
*/
|
*/
|
||||||
isRunning(fn: string): boolean {
|
isRunning(fn: string): boolean {
|
||||||
// Check that the script isnt currently running
|
|
||||||
for (const runningScriptObj of this.runningScripts) {
|
for (const runningScriptObj of this.runningScripts) {
|
||||||
if (runningScriptObj.filename === fn) {
|
if (runningScriptObj.filename === fn) {
|
||||||
return true;
|
return true;
|
||||||
@ -157,7 +176,7 @@ export class BaseServer {
|
|||||||
* @returns {IReturnStatus} Return status object indicating whether or not file was deleted
|
* @returns {IReturnStatus} Return status object indicating whether or not file was deleted
|
||||||
*/
|
*/
|
||||||
removeFile(fn: string): IReturnStatus {
|
removeFile(fn: string): IReturnStatus {
|
||||||
if (fn.endsWith(".exe")) {
|
if (fn.endsWith(".exe") || fn.match(/^.+\.exe-\d+(?:\.\d*)?%-INC$/) != null) {
|
||||||
for (let i = 0; i < this.programs.length; ++i) {
|
for (let i = 0; i < this.programs.length; ++i) {
|
||||||
if (this.programs[i] === fn) {
|
if (this.programs[i] === fn) {
|
||||||
this.programs.splice(i, 1);
|
this.programs.splice(i, 1);
|
||||||
|
@ -1150,7 +1150,7 @@ let Terminal = {
|
|||||||
killWorkerScript(s.runningScripts[i], s.ip, false);
|
killWorkerScript(s.runningScripts[i], s.ip, false);
|
||||||
}
|
}
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emitEvent();
|
||||||
post("Killing all running scripts. May take up to a few minutes for the scripts to die...");
|
post("Killing all running scripts");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "ls": {
|
case "ls": {
|
||||||
@ -1573,19 +1573,32 @@ let Terminal = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill by PID
|
||||||
|
if (typeof commandArray[1] === "number") {
|
||||||
|
const pid = commandArray[1];
|
||||||
|
const res = killWorkerScript(pid);
|
||||||
|
if (res) {
|
||||||
|
post(`Killing script with PID ${pid}`);
|
||||||
|
} else {
|
||||||
|
post(`Failed to kill script with PID ${pid}. No such script exists`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const s = Player.getCurrentServer();
|
const s = Player.getCurrentServer();
|
||||||
const scriptName = Terminal.getFilepath(commandArray[1]);
|
const scriptName = Terminal.getFilepath(commandArray[1]);
|
||||||
const args = [];
|
const args = [];
|
||||||
for (let i = 2; i < commandArray.length; ++i) {
|
for (let i = 2; i < commandArray.length; ++i) {
|
||||||
args.push(commandArray[i]);
|
args.push(commandArray[i]);
|
||||||
}
|
}
|
||||||
const runningScript = findRunningScript(scriptName, args, s);
|
const runningScript = s.getRunningScript(scriptName, args);
|
||||||
if (runningScript == null) {
|
if (runningScript == null) {
|
||||||
postError("No such script is running. Nothing to kill");
|
postError("No such script is running. Nothing to kill");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
killWorkerScript(runningScript, s.ip);
|
killWorkerScript(runningScript, s.ip);
|
||||||
post(`Killing ${scriptName}. May take up to a few seconds for the scripts to die...`);
|
post(`Killing ${scriptName}`);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Terminal.postThrownError(e);
|
Terminal.postThrownError(e);
|
||||||
}
|
}
|
||||||
@ -2291,7 +2304,6 @@ let Terminal = {
|
|||||||
} else {
|
} else {
|
||||||
// Able to run script
|
// Able to run script
|
||||||
post("Running script with " + numThreads + " thread(s) and args: " + arrayToString(args) + ".");
|
post("Running script with " + numThreads + " thread(s) and args: " + arrayToString(args) + ".");
|
||||||
post("May take a few seconds to start up the process...");
|
|
||||||
var runningScriptObj = new RunningScript(script, args);
|
var runningScriptObj = new RunningScript(script, args);
|
||||||
runningScriptObj.threads = numThreads;
|
runningScriptObj.threads = numThreads;
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ export function removeTrailingSlash(s: string): string {
|
|||||||
* not the entire filepath
|
* not the entire filepath
|
||||||
*/
|
*/
|
||||||
export function isValidFilename(filename: string): boolean {
|
export function isValidFilename(filename: string): boolean {
|
||||||
// Allows alphanumerics, hyphens, underscores.
|
// Allows alphanumerics, hyphens, underscores, and percentage signs
|
||||||
// Must have a file extension
|
// Must have a file extension
|
||||||
const regex = /^[.a-zA-Z0-9_-]+[.][.a-zA-Z0-9]+$/;
|
const regex = /^[.a-zA-Z0-9_-]+[.][a-zA-Z0-9]+(?:-\d+(?:\.\d*)?%-INC)?$/;
|
||||||
|
|
||||||
// match() returns null if no match is found
|
// match() returns null if no match is found
|
||||||
return filename.match(regex) != null;
|
return filename.match(regex) != null;
|
||||||
@ -49,7 +49,7 @@ export function isValidFilename(filename: string): boolean {
|
|||||||
* not an entire path
|
* not an entire path
|
||||||
*/
|
*/
|
||||||
export function isValidDirectoryName(name: string): boolean {
|
export function isValidDirectoryName(name: string): boolean {
|
||||||
// Allows alphanumerics, hyphens and underscores.
|
// Allows alphanumerics, hyphens, underscores, and percentage signs.
|
||||||
// Name can begin with a single period, but otherwise cannot have any
|
// Name can begin with a single period, but otherwise cannot have any
|
||||||
const regex = /^.?[a-zA-Z0-9_-]+$/;
|
const regex = /^.?[a-zA-Z0-9_-]+$/;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ export const TerminalHelpText: string =
|
|||||||
"home Connect to home computer<br>" +
|
"home Connect to home computer<br>" +
|
||||||
"hostname Displays the hostname of the machine<br>" +
|
"hostname Displays the hostname of the machine<br>" +
|
||||||
"ifconfig Displays the IP address of the machine<br>" +
|
"ifconfig Displays the IP address of the machine<br>" +
|
||||||
"kill [script] [args...] Stops the specified script on the current server <br>" +
|
"kill [script/pid] [args...] Stops the specified script on the current server <br>" +
|
||||||
"killall Stops all running scripts on the current machine<br>" +
|
"killall Stops all running scripts on the current machine<br>" +
|
||||||
"ls [dir] [| grep pattern] Displays all files on the machine<br>" +
|
"ls [dir] [| grep pattern] Displays all files on the machine<br>" +
|
||||||
"lscpu Displays the number of CPU cores on the machine<br>" +
|
"lscpu Displays the number of CPU cores on the machine<br>" +
|
||||||
@ -128,15 +128,16 @@ export const HelpTexts: IMap<string> = {
|
|||||||
ifconfig: "ipconfig<br>" +
|
ifconfig: "ipconfig<br>" +
|
||||||
"Prints the IP address of the current server",
|
"Prints the IP address of the current server",
|
||||||
kill: "kill [script name] [args...]<br>" +
|
kill: "kill [script name] [args...]<br>" +
|
||||||
"Kill the script specified by the script name and arguments. Each argument must be separated by " +
|
"kill [pid]<br>" +
|
||||||
"a space. Remember that a running script is uniquely identified by " +
|
"Kill the script specified by the script name and arguments OR by its PID.<br><br>" +
|
||||||
"both its name and the arguments that are used to start it. So, if a script was ran with the following arguments:<br><br>" +
|
"If you are killing the script using its filename and arguments, then each " +
|
||||||
|
"argument must be separated by a space. Remember that a running script is " +
|
||||||
|
"uniquely identified by both its name and the arguments that are used to start " +
|
||||||
|
"it. So, if a script was ran with the following arguments:<br><br>" +
|
||||||
"run foo.script 1 sigma-cosmetics<br><br>" +
|
"run foo.script 1 sigma-cosmetics<br><br>" +
|
||||||
"Then to kill this script the same arguments would have to be used:<br><br>" +
|
"Then to kill this script the same arguments would have to be used:<br><br>" +
|
||||||
"kill foo.script 1 sigma-cosmetics<br><br>" +
|
"kill foo.script 1 sigma-cosmetics<br><br>" +
|
||||||
"Note that after issuing the 'kill' command for a script, it may take a while for the script to actually stop running. " +
|
"If you are killing the script using its PID, then the PID argument must be numeric",
|
||||||
"This will happen if the script is in the middle of a command such as grow() or weaken() that takes time to execute. " +
|
|
||||||
"The script will not be stopped/killed until after that time has elapsed.",
|
|
||||||
killall: "killall<br>" +
|
killall: "killall<br>" +
|
||||||
"Kills all scripts on the current server. " +
|
"Kills all scripts on the current server. " +
|
||||||
"Note that after the 'kill' command is issued for a script, it may take a while for the script to actually stop running. " +
|
"Note that after the 'kill' command is issued for a script, it may take a while for the script to actually stop running. " +
|
||||||
|
@ -67,6 +67,10 @@ describe("Terminal Directory Tests", function() {
|
|||||||
expect(isValidFilename("_foo.lit")).to.equal(true);
|
expect(isValidFilename("_foo.lit")).to.equal(true);
|
||||||
expect(isValidFilename("mult.periods.script")).to.equal(true);
|
expect(isValidFilename("mult.periods.script")).to.equal(true);
|
||||||
expect(isValidFilename("mult.per-iods.again.script")).to.equal(true);
|
expect(isValidFilename("mult.per-iods.again.script")).to.equal(true);
|
||||||
|
expect(isValidFilename("BruteSSH.exe-50%-INC")).to.equal(true);
|
||||||
|
expect(isValidFilename("DeepscanV1.exe-1.01%-INC")).to.equal(true);
|
||||||
|
expect(isValidFilename("DeepscanV2.exe-1.00%-INC")).to.equal(true);
|
||||||
|
expect(isValidFilename("AutoLink.exe-1.%-INC")).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false for invalid filenames", function() {
|
it("should return false for invalid filenames", function() {
|
||||||
@ -79,6 +83,10 @@ describe("Terminal Directory Tests", function() {
|
|||||||
expect(isValidFilename("foo._script")).to.equal(false);
|
expect(isValidFilename("foo._script")).to.equal(false);
|
||||||
expect(isValidFilename("foo.hyphened-ext")).to.equal(false);
|
expect(isValidFilename("foo.hyphened-ext")).to.equal(false);
|
||||||
expect(isValidFilename("")).to.equal(false);
|
expect(isValidFilename("")).to.equal(false);
|
||||||
|
expect(isValidFilename("AutoLink-1.%-INC.exe")).to.equal(false);
|
||||||
|
expect(isValidFilename("AutoLink.exe-1.%-INC.exe")).to.equal(false);
|
||||||
|
expect(isValidFilename("foo%.exe")).to.equal(false);
|
||||||
|
expect(isValidFilename("-1.00%-INC")).to.equal(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user