mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-23 08:03:48 +01:00
Minor bugfixes with killing Netscript scripts, and cleaned up text
This commit is contained in:
parent
4f2f75762c
commit
06cd584f10
@ -6,7 +6,7 @@ clear() Netscript Function
|
|||||||
:param string/number port/fn: Port or text file to clear
|
:param string/number port/fn: Port or text file to clear
|
||||||
:RAM cost: 1 GB
|
:RAM cost: 1 GB
|
||||||
|
|
||||||
This function is used to clear data in a `Netscript Ports <http://bitburner.wikia.com/wiki/Netscript_Ports>`_ or a text file.
|
This function is used to clear data in a :ref:`Netscript Port <netscript_ports>` or a text file.
|
||||||
|
|
||||||
If the *port/fn* argument is a number between 1 and 20, then it specifies a port and will clear it (deleting all data from the underlying queue).
|
If the *port/fn* argument is a number between 1 and 20, then it specifies a port and will clear it (deleting all data from the underlying queue).
|
||||||
|
|
||||||
|
@ -11,3 +11,6 @@ getGrowTime() Netscript Function
|
|||||||
|
|
||||||
The function takes in an optional *hackLvl* parameter that can be specified
|
The function takes in an optional *hackLvl* parameter that can be specified
|
||||||
to see what the grow time would be at different hacking levels.
|
to see what the grow time would be at different hacking levels.
|
||||||
|
|
||||||
|
.. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will
|
||||||
|
return :code:`Infinity`.
|
||||||
|
@ -11,3 +11,6 @@ getHackTime() Netscript Function
|
|||||||
|
|
||||||
The function takes in an optional *hackLvl* parameter that can be specified
|
The function takes in an optional *hackLvl* parameter that can be specified
|
||||||
to see what the hack time would be at different hacking levels.
|
to see what the hack time would be at different hacking levels.
|
||||||
|
|
||||||
|
.. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will
|
||||||
|
return :code:`Infinity`.
|
||||||
|
@ -11,3 +11,6 @@ getWeakenTime() Netscript Function
|
|||||||
|
|
||||||
The function takes in an optional *hackLvl* parameter that can be specified
|
The function takes in an optional *hackLvl* parameter that can be specified
|
||||||
to see what the weaken time would be at different hacking levels.
|
to see what the weaken time would be at different hacking levels.
|
||||||
|
|
||||||
|
.. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will
|
||||||
|
return :code:`Infinity`.
|
||||||
|
@ -4,7 +4,7 @@ growthAnalyze() Netscript Function
|
|||||||
.. js:function:: growthAnalyze(hostname/ip, growthAmount)
|
.. js:function:: growthAnalyze(hostname/ip, growthAmount)
|
||||||
|
|
||||||
:param string hostname/ip: IP or hostname of server to analyze
|
:param string hostname/ip: IP or hostname of server to analyze
|
||||||
:param number growthAmount: Multiplicative factor by which the server is grown. Decimal form.
|
:param number growthAmount: Multiplicative factor by which the server is grown. Decimal form. Must be >= 1.
|
||||||
:returns: The amount of grow() calls needed to grow the specified server by the specified amount
|
:returns: The amount of grow() calls needed to grow the specified server by the specified amount
|
||||||
:RAM cost: 1 GB
|
:RAM cost: 1 GB
|
||||||
|
|
||||||
|
@ -57,6 +57,10 @@ And the data in port 1 will look like::
|
|||||||
|
|
||||||
[3, 4, 5, 6, 7, 8, 9]
|
[3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
.. warning:: In :ref:`netscriptjs`, do not trying writing base
|
||||||
|
`Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_
|
||||||
|
to a port.
|
||||||
|
|
||||||
**Port Handles**
|
**Port Handles**
|
||||||
|
|
||||||
WARNING: Port Handles only work in :ref:`netscriptjs`. They do not work in :ref:`netscript1`
|
WARNING: Port Handles only work in :ref:`netscriptjs`. They do not work in :ref:`netscript1`
|
||||||
@ -213,16 +217,6 @@ to specify a namespace for the import::
|
|||||||
keyword should **NOT** be used in :ref:`netscript1`, as this will break the script.
|
keyword should **NOT** be used in :ref:`netscript1`, as this will break the script.
|
||||||
It can, however, be used in :ref:`netscriptjs` (but it's not required).
|
It can, however, be used in :ref:`netscriptjs` (but it's not required).
|
||||||
|
|
||||||
Importing in NetscriptJS
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
There is a minor annoyance when using the `import` feature in :ref:`netscriptjs`.
|
|
||||||
If you make a change in a NetscriptJS script, then you have to manually "refresh" all other
|
|
||||||
scripts that import from that script.
|
|
||||||
|
|
||||||
The easiest way to do this is to simply save and then refresh the game. Alternatively,
|
|
||||||
you can open up all the scripts that need to be "refreshed" in the script editor
|
|
||||||
and then simply re-save them.
|
|
||||||
|
|
||||||
Standard, Built-In JavaScript Objects
|
Standard, Built-In JavaScript Objects
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
Standard built-in JavaScript objects such as
|
Standard built-in JavaScript objects such as
|
||||||
|
@ -63,17 +63,17 @@ Examples
|
|||||||
**Basic example usage**::
|
**Basic example usage**::
|
||||||
|
|
||||||
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
||||||
sleeve.shockRecovery(i);
|
sleeve.setToShockRecovery(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(10 * 60 * 60); // wait 10h
|
||||||
|
|
||||||
|
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
||||||
|
sleeve.setToSynchronize(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(10*60*60); // wait 10h
|
sleep(10*60*60); // wait 10h
|
||||||
|
|
||||||
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
||||||
sleeve.synchronize(i);
|
sleeve.setToCommitCrime(i, 'shoplift');
|
||||||
}
|
|
||||||
|
|
||||||
sleep(10*60*60); // wait 10h
|
|
||||||
|
|
||||||
for (var i = 0; i < sleeve.getNumSleeves(); i++) {
|
|
||||||
sleeve.commitCrime(i, 'shoplift');
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import { AugmentationsRoot } from "./ui/Root";
|
|||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
import { Factions, factionExists } from "../Faction/Factions";
|
import { Factions, factionExists } from "../Faction/Factions";
|
||||||
import { addWorkerScript } from "../NetscriptWorker";
|
import { startWorkerScript } from "../NetscriptWorker";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { prestigeAugmentation } from "../Prestige";
|
import { prestigeAugmentation } from "../Prestige";
|
||||||
import { saveObject } from "../SaveObject";
|
import { saveObject } from "../SaveObject";
|
||||||
@ -2078,18 +2078,17 @@ function installAugmentations(cbScript=null) {
|
|||||||
//Run a script after prestiging
|
//Run a script after prestiging
|
||||||
if (cbScript && isString(cbScript)) {
|
if (cbScript && isString(cbScript)) {
|
||||||
var home = Player.getHomeComputer();
|
var home = Player.getHomeComputer();
|
||||||
for (var i = 0; i < home.scripts.length; ++i) {
|
for (const script of home.scripts) {
|
||||||
if (home.scripts[i].filename === cbScript) {
|
if (script.filename === cbScript) {
|
||||||
var script = home.scripts[i];
|
const ramUsage = script.ramUsage;
|
||||||
var ramUsage = script.ramUsage;
|
const ramAvailable = home.maxRam - home.ramUsed;
|
||||||
var ramAvailable = home.maxRam - home.ramUsed;
|
|
||||||
if (ramUsage > ramAvailable) {
|
if (ramUsage > ramAvailable) {
|
||||||
return; //Not enough RAM
|
return; // Not enough RAM
|
||||||
}
|
}
|
||||||
var runningScriptObj = new RunningScript(script, []); //No args
|
const runningScriptObj = new RunningScript(script, []); // No args
|
||||||
runningScriptObj.threads = 1; //Only 1 thread
|
runningScriptObj.threads = 1; // Only 1 thread
|
||||||
home.runScript(runningScriptObj, Player.hacknet_node_money_mult);
|
|
||||||
addWorkerScript(runningScriptObj, home);
|
startWorkerScript(runningScriptObj, home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,6 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
Netscript Changes
|
Netscript Changes
|
||||||
* Added tail() Netscript function
|
* Added tail() Netscript function
|
||||||
* hacknet.getNodeStats() function now returns an additional property for Hacknet Servers: hashCapacity
|
* hacknet.getNodeStats() function now returns an additional property for Hacknet Servers: hashCapacity
|
||||||
* 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
|
* Overloaded kill() function so that you can kill a script by its PID
|
||||||
@ -235,6 +234,9 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
* run() and exec() now return the PID of the newly-executed scripts, rather than a boolean
|
* run() and exec() now return the PID of the newly-executed scripts, rather than a boolean
|
||||||
** (A PID is just a positive integer)
|
** (A PID is just a positive integer)
|
||||||
* run(), exec(), and spawn() no longer need to be await-ed in NetscriptJS
|
* run(), exec(), and spawn() no longer need to be await-ed in NetscriptJS
|
||||||
|
* Bug fix: workForFaction() function now properly accounts for disabled logs
|
||||||
|
* Bug fix: RAM should now be properly calculated when running a callback script with installAugmentations()
|
||||||
|
* Bug fix: Fixed bug that caused scripts killed by exit()/spawn() to "clean up" twice
|
||||||
|
|
||||||
Misc Changes
|
Misc Changes
|
||||||
* The 'kill' Terminal command can now kill a script by its PID
|
* The 'kill' Terminal command can now kill a script by its PID
|
||||||
@ -242,5 +244,7 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
* 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)
|
* Bug fix: You can now properly remove unfinished programs (the *.exe-N%-INC files)
|
||||||
|
* Bug fix: Fixed an issue that allowed you to increase money on servers with a 'maxMoney' of 0 (like CSEC)
|
||||||
|
* Bug fix: Scripts no longer persist if they were started with syntax/import errors
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,17 @@ export const HashUpgradesMetadata: IConstructorParams[] = [
|
|||||||
{
|
{
|
||||||
costPerLevel: 50,
|
costPerLevel: 50,
|
||||||
desc: "Use hashes to decrease the minimum security of a single server by 2%. " +
|
desc: "Use hashes to decrease the minimum security of a single server by 2%. " +
|
||||||
"Note that a server's minimum security cannot go below 1.",
|
"Note that a server's minimum security cannot go below 1. This effect persists " +
|
||||||
|
"until you install Augmentations (since servers are reset at that time).",
|
||||||
hasTargetServer: true,
|
hasTargetServer: true,
|
||||||
name: "Reduce Minimum Security",
|
name: "Reduce Minimum Security",
|
||||||
value: 0.98,
|
value: 0.98,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
costPerLevel: 50,
|
costPerLevel: 50,
|
||||||
desc: "Use hashes to increase the maximum amount of money on a single server by 2%",
|
desc: "Use hashes to increase the maximum amount of money on a single server by 2%. " +
|
||||||
|
"This effect persists until you install Augmentations (since servers " +
|
||||||
|
"are reset at that time).",
|
||||||
hasTargetServer: true,
|
hasTargetServer: true,
|
||||||
name: "Increase Maximum Money",
|
name: "Increase Maximum Money",
|
||||||
value: 1.02,
|
value: 1.02,
|
||||||
|
@ -89,7 +89,7 @@ function removeWorkerScript(workerScript: WorkerScript, rerenderUi: boolean=true
|
|||||||
// Recalculate ram used on that server
|
// Recalculate ram used on that server
|
||||||
server.ramUsed = roundToTwo(server.ramUsed - workerScript.ramUsage);
|
server.ramUsed = roundToTwo(server.ramUsed - workerScript.ramUsage);
|
||||||
if (server.ramUsed < 0) {
|
if (server.ramUsed < 0) {
|
||||||
console.warn(`Server RAM usage went negative (if it's due to floating pt imprecision, it's okay): ${server.ramUsed}`);
|
console.warn(`Server (${server.hostname}) RAM usage went negative (if it's due to floating pt imprecision, it's okay): ${server.ramUsed}`);
|
||||||
server.ramUsed = 0;
|
server.ramUsed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,8 +611,8 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (time === undefined) {
|
if (time === undefined) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "sleep() call has incorrect number of arguments. Takes 1 argument");
|
throw makeRuntimeRejectMsg(workerScript, "sleep() call has incorrect number of arguments. Takes 1 argument");
|
||||||
}
|
}
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.sleep == null) {
|
if (workerScript.shouldLog("sleep")) {
|
||||||
workerScript.scriptRef.log("Sleeping for " + time + " milliseconds");
|
workerScript.log(`Sleeping for ${time} milliseconds`);
|
||||||
}
|
}
|
||||||
return netscriptDelay(time, workerScript).then(function() {
|
return netscriptDelay(time, workerScript).then(function() {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
@ -652,10 +652,10 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (growthPercentage == 1) {
|
if (growthPercentage == 1) {
|
||||||
expGain = 0;
|
expGain = 0;
|
||||||
}
|
}
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) {
|
if (workerScript.shouldLog("grow")) {
|
||||||
workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " +
|
workerScript.log("Available money on " + server.hostname + " grown by " +
|
||||||
formatNumber((moneyAfter/moneyBefore)*100 - 100, 6) + "%. Gained " +
|
formatNumber((moneyAfter/moneyBefore)*100 - 100, 6) + "%. Gained " +
|
||||||
formatNumber(expGain, 4) + " hacking exp (t=" + threads +")");
|
formatNumber(expGain, 4) + " hacking exp (t=" + threads +")");
|
||||||
}
|
}
|
||||||
workerScript.scriptRef.onlineExpGained += expGain;
|
workerScript.scriptRef.onlineExpGained += expGain;
|
||||||
Player.gainHackingExp(expGain);
|
Player.gainHackingExp(expGain);
|
||||||
@ -670,8 +670,8 @@ function NetscriptFunctions(workerScript) {
|
|||||||
|
|
||||||
// Check argument validity
|
// Check argument validity
|
||||||
const server = safeGetServer(ip, 'growthAnalyze');
|
const server = safeGetServer(ip, 'growthAnalyze');
|
||||||
if (isNaN(growth)) {
|
if (typeof growth !== "number" || isNaN(growth) || growth < 1) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, `Invalid growth argument passed into growthAnalyze: ${growth}. Must be numeric`);
|
throw makeRuntimeRejectMsg(workerScript, `Invalid growth argument passed into growthAnalyze: ${growth}. Must be numeric and >= 1`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return numCycleForGrowth(server, Number(growth), Player);
|
return numCycleForGrowth(server, Number(growth), Player);
|
||||||
@ -993,10 +993,15 @@ function NetscriptFunctions(workerScript) {
|
|||||||
|
|
||||||
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
||||||
}, spawnDelay * 1e3);
|
}, spawnDelay * 1e3);
|
||||||
|
|
||||||
if (workerScript.shouldLog("spawn")) {
|
if (workerScript.shouldLog("spawn")) {
|
||||||
workerScript.scriptRef.log(`spawn() will execute ${scriptname} in ${spawnDelay} seconds`);
|
workerScript.log(`spawn() will execute ${scriptname} in ${spawnDelay} seconds`);
|
||||||
|
}
|
||||||
|
|
||||||
|
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
||||||
|
if (killWorkerScript(workerScript)) {
|
||||||
|
workerScript.log("Exiting...");
|
||||||
}
|
}
|
||||||
NetscriptFunctions(workerScript).exit();
|
|
||||||
},
|
},
|
||||||
kill: function(filename, ip, ...scriptArgs) {
|
kill: function(filename, ip, ...scriptArgs) {
|
||||||
updateDynamicRam("kill", getRamCost("kill"));
|
updateDynamicRam("kill", getRamCost("kill"));
|
||||||
@ -1015,7 +1020,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
const server = safeGetServer(ip);
|
const server = safeGetServer(ip);
|
||||||
const runningScriptObj = getRunningScript(filename, ip, "kill", scriptArgs);
|
const runningScriptObj = getRunningScript(filename, ip, "kill", scriptArgs);
|
||||||
if (runningScriptObj == null) {
|
if (runningScriptObj == null) {
|
||||||
workerScript.log(`tail() failed. ${getCannotFindRunningScriptErrorMessage(filename, ip, scriptArgs)}`)
|
workerScript.log(`kill() failed. ${getCannotFindRunningScriptErrorMessage(filename, ip, scriptArgs)}`)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1064,14 +1069,11 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return scriptsRunning;
|
return scriptsRunning;
|
||||||
},
|
},
|
||||||
exit : function() {
|
exit : function() {
|
||||||
var server = getServer(workerScript.serverIp);
|
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
||||||
if (server == null) {
|
if (killWorkerScript(workerScript)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Error getting Server for this script in exit(). This is a bug please contact game dev");
|
workerScript.log("Exiting...");
|
||||||
}
|
|
||||||
if (killWorkerScript(workerScript.scriptRef, server.ip)) {
|
|
||||||
workerScript.scriptRef.log("Exiting...");
|
|
||||||
} else {
|
} else {
|
||||||
workerScript.scriptRef.log("Exit failed(). This is a bug please contact game developer");
|
workerScript.log("Exit failed(). This is a bug please contact game developer");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scp: function(scriptname, ip1, ip2) {
|
scp: function(scriptname, ip1, ip2) {
|
||||||
@ -3495,9 +3497,13 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||||
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
|
workerScript.log("Installing Augmentations. This will cause this script to be killed");
|
||||||
installAugmentations(cbScript);
|
setTimeoutRef(() => {
|
||||||
return true;
|
installAugmentations(cbScript);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
||||||
|
killWorkerScript(workerScript);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Gang API
|
// Gang API
|
||||||
|
@ -48,6 +48,8 @@ for (var i = 0; i < CONSTANTS.NumNetscriptPorts; ++i) {
|
|||||||
export function prestigeWorkerScripts() {
|
export function prestigeWorkerScripts() {
|
||||||
for (const ws of workerScripts.values()) {
|
for (const ws of workerScripts.values()) {
|
||||||
ws.env.stopFlag = true;
|
ws.env.stopFlag = true;
|
||||||
|
killWorkerScript(ws);
|
||||||
|
console.log(`Killing ${ws.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emitEvent();
|
||||||
@ -149,6 +151,7 @@ function startNetscript1Script(workerScript) {
|
|||||||
dialogBoxCreate("Error processing Imports in " + workerScript.name + ":<br>" + e);
|
dialogBoxCreate("Error processing Imports in " + workerScript.name + ":<br>" + e);
|
||||||
workerScript.env.stopFlag = true;
|
workerScript.env.stopFlag = true;
|
||||||
workerScript.running = false;
|
workerScript.running = false;
|
||||||
|
killWorkerScript(workerScript);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +163,7 @@ function startNetscript1Script(workerScript) {
|
|||||||
if (typeof entry === "function") {
|
if (typeof entry === "function") {
|
||||||
//Async functions need to be wrapped. See JS-Interpreter documentation
|
//Async functions need to be wrapped. See JS-Interpreter documentation
|
||||||
if (name === "hack" || name === "grow" || name === "weaken" || name === "sleep" ||
|
if (name === "hack" || name === "grow" || name === "weaken" || name === "sleep" ||
|
||||||
name === "prompt" || name === "run" || name === "exec") {
|
name === "prompt") {
|
||||||
let tempWrapper = function() {
|
let tempWrapper = function() {
|
||||||
let fnArgs = [];
|
let fnArgs = [];
|
||||||
|
|
||||||
@ -183,7 +186,8 @@ function startNetscript1Script(workerScript) {
|
|||||||
}
|
}
|
||||||
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper));
|
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper));
|
||||||
} else if (name === "sprintf" || name === "vsprintf" || name === "scp" ||
|
} else if (name === "sprintf" || name === "vsprintf" || name === "scp" ||
|
||||||
name == "write" || name === "read" || name === "tryWrite") {
|
name == "write" || name === "read" || name === "tryWrite" ||
|
||||||
|
name === "run" || name === "exec") {
|
||||||
let tempWrapper = function() {
|
let tempWrapper = function() {
|
||||||
let fnArgs = [];
|
let fnArgs = [];
|
||||||
|
|
||||||
@ -232,6 +236,7 @@ function startNetscript1Script(workerScript) {
|
|||||||
dialogBoxCreate("Syntax ERROR in " + workerScript.name + ":<br>" + e);
|
dialogBoxCreate("Syntax ERROR in " + workerScript.name + ":<br>" + e);
|
||||||
workerScript.env.stopFlag = true;
|
workerScript.env.stopFlag = true;
|
||||||
workerScript.running = false;
|
workerScript.running = false;
|
||||||
|
killWorkerScript(workerScript);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,14 +450,35 @@ function generateNextPid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a script
|
* Used to start a RunningScript (by creating and starting its
|
||||||
*
|
* corresponding WorkerScript), and add the RunningScript to the server on which
|
||||||
* Given a RunningScript object, constructs a corresponding WorkerScript,
|
* it is active
|
||||||
|
* @param {RunningScript} runningScriptObj - Script that's being run
|
||||||
|
* @param {Server} server - Server on which the script is to be run
|
||||||
|
* @returns {number} pid of started script
|
||||||
|
*/
|
||||||
|
export function startWorkerScript(runningScript, server) {
|
||||||
|
if (createAndAddWorkerScript(runningScript, server)) {
|
||||||
|
// Push onto runningScripts.
|
||||||
|
// This has to come after createAndAddWorkerScript() because that fn updates RAM usage
|
||||||
|
server.runScript(runningScript, Player.hacknet_node_money_mult);
|
||||||
|
|
||||||
|
// Once the WorkerScript is constructed in createAndAddWorkerScript(), the RunningScript
|
||||||
|
// object should have a PID assigned to it, so we return that
|
||||||
|
return runningScript.pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a RunningScript object, constructs its corresponding WorkerScript,
|
||||||
* adds it to the global 'workerScripts' pool, and begins executing it.
|
* adds it to the global 'workerScripts' pool, and begins executing it.
|
||||||
* @param {RunningScript} runningScriptObj - Script that's being run
|
* @param {RunningScript} runningScriptObj - Script that's being run
|
||||||
* @param {Server} server - Server on which the script is to be run
|
* @param {Server} server - Server on which the script is to be run
|
||||||
|
* returns {boolean} indicating whether or not the workerScript was successfully added
|
||||||
*/
|
*/
|
||||||
export function addWorkerScript(runningScriptObj, server) {
|
export function createAndAddWorkerScript(runningScriptObj, server) {
|
||||||
const filename = runningScriptObj.filename;
|
const filename = runningScriptObj.filename;
|
||||||
|
|
||||||
// Update server's ram usage
|
// Update server's ram usage
|
||||||
@ -471,7 +497,7 @@ export function addWorkerScript(runningScriptObj, server) {
|
|||||||
`the game and the script's RAM usage increased (either because of an update to the game or ` +
|
`the game and the script's RAM usage increased (either because of an update to the game or ` +
|
||||||
`your changes to the script.)`
|
`your changes to the script.)`
|
||||||
);
|
);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
server.ramUsed = roundToTwo(server.ramUsed + ramUsage);
|
server.ramUsed = roundToTwo(server.ramUsed + ramUsage);
|
||||||
|
|
||||||
@ -489,31 +515,35 @@ export function addWorkerScript(runningScriptObj, server) {
|
|||||||
const s = new WorkerScript(runningScriptObj, pid, NetscriptFunctions);
|
const s = new WorkerScript(runningScriptObj, pid, NetscriptFunctions);
|
||||||
s.ramUsage = ramUsage;
|
s.ramUsage = ramUsage;
|
||||||
|
|
||||||
|
// Add the WorkerScript to the global pool
|
||||||
|
workerScripts.set(pid, s);
|
||||||
|
WorkerScriptStartStopEventEmitter.emitEvent();
|
||||||
|
|
||||||
// Start the script's execution
|
// Start the script's execution
|
||||||
let p = null; // Script's resulting promise
|
let p = null; // Script's resulting promise
|
||||||
if (s.name.endsWith(".js") || s.name.endsWith(".ns")) {
|
if (s.name.endsWith(".js") || s.name.endsWith(".ns")) {
|
||||||
p = startNetscript2Script(s);
|
p = startNetscript2Script(s);
|
||||||
} else {
|
} else {
|
||||||
p = startNetscript1Script(s);
|
p = startNetscript1Script(s);
|
||||||
if (!(p instanceof Promise)) { return; }
|
if (!(p instanceof Promise)) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once the code finishes (either resolved or rejected, doesnt matter), set its
|
// Once the code finishes (either resolved or rejected, doesnt matter), set its
|
||||||
// running status to false
|
// running status to false
|
||||||
p.then(function(w) {
|
p.then(function(w) {
|
||||||
|
// If the WorkerScript is no longer "running", then this means its execution was
|
||||||
|
// already stopped somewhere else (maybe by something like exit()). This prevents
|
||||||
|
// the script from being cleaned up twice
|
||||||
|
if (!w.running) { return; }
|
||||||
|
|
||||||
console.log("Stopping script " + w.name + " because it finished running naturally");
|
console.log("Stopping script " + w.name + " because it finished running naturally");
|
||||||
killWorkerScript(s);
|
killWorkerScript(s);
|
||||||
w.scriptRef.log("Script finished running");
|
w.log("Script finished running");
|
||||||
}).catch(function(w) {
|
}).catch(function(w) {
|
||||||
if (w instanceof Error) {
|
if (w instanceof Error) {
|
||||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
||||||
console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
|
console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
|
||||||
return;
|
return;
|
||||||
} else if (w.constructor === Array && w.length === 2 && w[0] === "RETURNSTATEMENT") {
|
|
||||||
// Script ends with a return statement
|
|
||||||
console.log("Script returning with value: " + w[1]);
|
|
||||||
// TODO maybe do something with this in the future
|
|
||||||
return;
|
|
||||||
} else if (w instanceof WorkerScript) {
|
} else if (w instanceof WorkerScript) {
|
||||||
if (isScriptErrorMessage(w.errorMessage)) {
|
if (isScriptErrorMessage(w.errorMessage)) {
|
||||||
var errorTextArray = w.errorMessage.split("|");
|
var errorTextArray = w.errorMessage.split("|");
|
||||||
@ -529,9 +559,9 @@ export function addWorkerScript(runningScriptObj, server) {
|
|||||||
dialogBoxCreate("Script runtime error: <br>Server Ip: " + serverIp +
|
dialogBoxCreate("Script runtime error: <br>Server Ip: " + serverIp +
|
||||||
"<br>Script name: " + scriptName +
|
"<br>Script name: " + scriptName +
|
||||||
"<br>Args:" + arrayToString(w.args) + "<br>" + errorMsg);
|
"<br>Args:" + arrayToString(w.args) + "<br>" + errorMsg);
|
||||||
w.scriptRef.log("Script crashed with runtime error");
|
w.log("Script crashed with runtime error");
|
||||||
} else {
|
} else {
|
||||||
w.scriptRef.log("Script killed");
|
w.log("Script killed");
|
||||||
return; // Already killed, so stop here
|
return; // Already killed, so stop here
|
||||||
}
|
}
|
||||||
w.running = false;
|
w.running = false;
|
||||||
@ -548,10 +578,7 @@ export function addWorkerScript(runningScriptObj, server) {
|
|||||||
killWorkerScript(s);
|
killWorkerScript(s);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add the WorkerScript to the global pool
|
return true;
|
||||||
workerScripts.set(pid, s);
|
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -589,7 +616,7 @@ export function loadAllRunningScripts() {
|
|||||||
server.runningScripts.length = 0;
|
server.runningScripts.length = 0;
|
||||||
} else {
|
} else {
|
||||||
for (let j = 0; j < server.runningScripts.length; ++j) {
|
for (let j = 0; j < server.runningScripts.length; ++j) {
|
||||||
addWorkerScript(server.runningScripts[j], server);
|
createAndAddWorkerScript(server.runningScripts[j], server);
|
||||||
|
|
||||||
// Offline production
|
// Offline production
|
||||||
total += scriptCalculateOfflineProduction(server.runningScripts[j]);
|
total += scriptCalculateOfflineProduction(server.runningScripts[j]);
|
||||||
@ -655,15 +682,8 @@ export function runScriptFromScript(server, scriptname, args, workerScript, thre
|
|||||||
}
|
}
|
||||||
let runningScriptObj = new RunningScript(script, args);
|
let runningScriptObj = new RunningScript(script, args);
|
||||||
runningScriptObj.threads = threads;
|
runningScriptObj.threads = threads;
|
||||||
addWorkerScript(runningScriptObj, server);
|
|
||||||
|
|
||||||
// Push onto runningScripts.
|
return startWorkerScript(runningScriptObj, server);
|
||||||
// This has to come after addWorkerScript() because that fn updates RAM usage
|
|
||||||
server.runScript(runningScriptObj, Player.hacknet_node_money_mult);
|
|
||||||
|
|
||||||
// Once the WorkerScript is constructed in addWorkerScript(), the RunningScript
|
|
||||||
// object should have a PID assigned to it, so we return that
|
|
||||||
return runningScriptObj.pid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { HacknetServer } from "../Hacknet/HacknetServer";
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { Programs } from "../Programs/Programs";
|
import { Programs } from "../Programs/Programs";
|
||||||
|
|
||||||
|
import { isValidNumber } from "../utils/helpers/isValidNumber";
|
||||||
import { isValidIPAddress } from "../../utils/helpers/isValidIPAddress";
|
import { isValidIPAddress } from "../../utils/helpers/isValidIPAddress";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,11 +36,17 @@ export function safetlyCreateUniqueServer(params: IConstructorParams): Server {
|
|||||||
return new Server(params);
|
return new Server(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of cycles needed to grow the specified server by the
|
/**
|
||||||
// specified amount. 'growth' parameter is in decimal form, not percentage
|
* Returns the number of "growth cycles" needed to grow the specified server by the
|
||||||
|
* specified amount.
|
||||||
|
* @param server - Server being grown
|
||||||
|
* @param growth - How much the server is being grown by, in DECIMAL form (e.g. 1.5 rather than 50)
|
||||||
|
* @param p - Reference to Player object
|
||||||
|
* @returns Number of "growth cycles" needed
|
||||||
|
*/
|
||||||
export function numCycleForGrowth(server: Server, growth: number, p: IPlayer) {
|
export function numCycleForGrowth(server: Server, growth: number, p: IPlayer) {
|
||||||
let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty;
|
let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty;
|
||||||
if(ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) {
|
if (ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) {
|
||||||
ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate;
|
ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,12 +82,12 @@ export function processSingleServerGrowth(server: Server, numCycles: number, p:
|
|||||||
server.moneyAvailable *= serverGrowth;
|
server.moneyAvailable *= serverGrowth;
|
||||||
|
|
||||||
// in case of data corruption
|
// in case of data corruption
|
||||||
if (server.moneyMax && isNaN(server.moneyAvailable)) {
|
if (isValidNumber(server.moneyMax) && isNaN(server.moneyAvailable)) {
|
||||||
server.moneyAvailable = server.moneyMax;
|
server.moneyAvailable = server.moneyMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cap at max
|
// cap at max
|
||||||
if (server.moneyMax && server.moneyAvailable > server.moneyMax) {
|
if (isValidNumber(server.moneyMax) && server.moneyAvailable > server.moneyMax) {
|
||||||
server.moneyAvailable = server.moneyMax;
|
server.moneyAvailable = server.moneyMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ import {
|
|||||||
import { showLiterature } from "./Literature";
|
import { showLiterature } from "./Literature";
|
||||||
import { Message } from "./Message/Message";
|
import { Message } from "./Message/Message";
|
||||||
import { showMessage } from "./Message/MessageHelpers";
|
import { showMessage } from "./Message/MessageHelpers";
|
||||||
import { addWorkerScript } from "./NetscriptWorker";
|
import { startWorkerScript } from "./NetscriptWorker";
|
||||||
import { killWorkerScript } from "./Netscript/killWorkerScript";
|
import { killWorkerScript } from "./Netscript/killWorkerScript";
|
||||||
import { WorkerScriptStartStopEventEmitter } from "./Netscript/WorkerScriptStartStopEventEmitter";
|
import { WorkerScriptStartStopEventEmitter } from "./Netscript/WorkerScriptStartStopEventEmitter";
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
@ -2303,21 +2303,19 @@ let Terminal = {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Able to run script
|
// Able to run script
|
||||||
post("Running script with " + numThreads + " thread(s) and args: " + arrayToString(args) + ".");
|
|
||||||
var runningScriptObj = new RunningScript(script, args);
|
var runningScriptObj = new RunningScript(script, args);
|
||||||
runningScriptObj.threads = numThreads;
|
runningScriptObj.threads = numThreads;
|
||||||
|
|
||||||
addWorkerScript(runningScriptObj, server);
|
if (startWorkerScript(runningScriptObj, server)) {
|
||||||
|
post("Running script with " + numThreads + " thread(s) and args: " + arrayToString(args) + ".");
|
||||||
// This has to come after addWorkerScript() because that fn
|
} else {
|
||||||
// updates the RAM usage. This kinda sucks, address if possible
|
postError(`Failed to start script`);
|
||||||
server.runScript(runningScriptObj, Player.hacknet_node_money_mult);
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
post("ERROR: No such script");
|
post("ERROR: No such script");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
7
src/utils/helpers/isValidNumber.ts
Normal file
7
src/utils/helpers/isValidNumber.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Checks that a variable is a valid number. A valid number
|
||||||
|
* must be a "number" type and cannot be NaN
|
||||||
|
*/
|
||||||
|
export function isValidNumber(n: number): boolean {
|
||||||
|
return (typeof n === "number") && !isNaN(n);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user