mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 15:43:49 +01:00
Fixed numerous reported bugs. Refactored some of the directory-related code. Added documentation for MasonDs changes to hack/grow/weaken
This commit is contained in:
parent
29e0ce5f96
commit
b0918d7bd3
@ -134,10 +134,15 @@ A Stop Order to buy will execute if the stock's price <= order's price
|
|||||||
|
|
||||||
A Stop Order to sell will execute if the stock's price >= order's price.
|
A Stop Order to sell will execute if the stock's price >= order's price.
|
||||||
|
|
||||||
.. note:: Limit and Stop orders do **not** take into account the fact that
|
.. note:: Stop Orders do **not** take into account the fact that transactions can
|
||||||
transactions can influence a stock's price. If a stock's price
|
influence a stock's price. Limit Orders, however, do take this into account.
|
||||||
changes mid-transaction, a limit/stop order will continue to execute
|
|
||||||
even if its conditions are no longer met.
|
For example, assume you have a Limit Order set to purchase a stock at
|
||||||
|
$5. Then, the stock's price drops to $5 and your Limit Order executes.
|
||||||
|
However, the transaction causes the stock's price to increase before
|
||||||
|
the order finishes executing all of the shares. Your Limit Order will
|
||||||
|
stop executing, and will continue only when the stock's price drops back to
|
||||||
|
$5 or below.
|
||||||
|
|
||||||
Automating the Stock Market
|
Automating the Stock Market
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -4,6 +4,11 @@ grow() Netscript Function
|
|||||||
.. js:function:: grow(hostname/ip)
|
.. js:function:: grow(hostname/ip)
|
||||||
|
|
||||||
:param string hostname/ip: IP or hostname of the target server to grow
|
:param string hostname/ip: IP or hostname of the target server to grow
|
||||||
|
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||||
|
|
||||||
|
* threads (*number*) - Number of threads to use for this function.
|
||||||
|
Must be less than or equal to the number of threads the script is running with.
|
||||||
|
|
||||||
:returns: The number by which the money on the server was multiplied for the growth
|
:returns: The number by which the money on the server was multiplied for the growth
|
||||||
:RAM cost: 0.15 GB
|
:RAM cost: 0.15 GB
|
||||||
|
|
||||||
@ -19,3 +24,4 @@ grow() Netscript Function
|
|||||||
Example::
|
Example::
|
||||||
|
|
||||||
grow("foodnstuff");
|
grow("foodnstuff");
|
||||||
|
grow("foodnstuff", { threads: 5 }); // Only use 5 threads to grow
|
||||||
|
@ -4,6 +4,11 @@ hack() Netscript Function
|
|||||||
.. js:function:: hack(hostname/ip)
|
.. js:function:: hack(hostname/ip)
|
||||||
|
|
||||||
:param string hostname/ip: IP or hostname of the target server to hack
|
:param string hostname/ip: IP or hostname of the target server to hack
|
||||||
|
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||||
|
|
||||||
|
* threads (*number*) - Number of threads to use for this function.
|
||||||
|
Must be less than or equal to the number of threads the script is running with.
|
||||||
|
|
||||||
:returns: The amount of money stolen if the hack is successful, and zero otherwise
|
:returns: The amount of money stolen if the hack is successful, and zero otherwise
|
||||||
:RAM cost: 0.1 GB
|
:RAM cost: 0.1 GB
|
||||||
|
|
||||||
@ -20,3 +25,4 @@ hack() Netscript Function
|
|||||||
|
|
||||||
hack("foodnstuff");
|
hack("foodnstuff");
|
||||||
hack("10.1.2.3");
|
hack("10.1.2.3");
|
||||||
|
hack("foodnstuff", { threads: 5 }); // Only use 5 threads to hack
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
weaken() Netscript Function
|
weaken() Netscript Function
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
.. js:function:: weaken(hostname/ip)
|
.. js:function:: weaken(hostname/ip, options={})
|
||||||
|
|
||||||
:param string hostname/ip: IP or hostname of the target server to weaken
|
:param string hostname/ip: IP or hostname of the target server to weaken
|
||||||
|
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||||
|
|
||||||
|
* threads (*number*) - Number of threads to use for this function.
|
||||||
|
Must be less than or equal to the number of threads the script is running with.
|
||||||
|
|
||||||
:returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied
|
:returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied
|
||||||
by the number of script threads
|
by the number of script threads
|
||||||
:RAM cost: 0.15 GB
|
:RAM cost: 0.15 GB
|
||||||
@ -18,3 +23,4 @@ weaken() Netscript Function
|
|||||||
Example::
|
Example::
|
||||||
|
|
||||||
weaken("foodnstuff");
|
weaken("foodnstuff");
|
||||||
|
weaken("foodnstuff", { threads: 5 }); // Only use 5 threads to weaken
|
||||||
|
@ -5,7 +5,7 @@ workForFaction() Netscript Function
|
|||||||
|
|
||||||
:param string factionName: Name of faction to work for. CASE-SENSITIVE
|
:param string factionName: Name of faction to work for. CASE-SENSITIVE
|
||||||
:param string workType:
|
:param string workType:
|
||||||
Type of work to perform for the faction
|
Type of work to perform for the faction:
|
||||||
|
|
||||||
* hacking/hacking contracts/hackingcontracts
|
* hacking/hacking contracts/hackingcontracts
|
||||||
* field/fieldwork/field work
|
* field/fieldwork/field work
|
||||||
|
@ -233,9 +233,12 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
* Re-sleeves can no longer have the NeuroFlux Governor augmentation
|
* Re-sleeves can no longer have the NeuroFlux Governor augmentation
|
||||||
** This is just a temporary patch until the mechanic gets re-worked
|
** This is just a temporary patch until the mechanic gets re-worked
|
||||||
|
|
||||||
|
* hack(), grow(), and weaken() functions now take optional arguments for number of threads to use (by MasonD)
|
||||||
|
|
||||||
* Adjusted RAM costs of Netscript Singularity functions (mostly increased)
|
* Adjusted RAM costs of Netscript Singularity functions (mostly increased)
|
||||||
* Netscript Singularity functions no longer cost extra RAM outside of BitNode-4
|
* Netscript Singularity functions no longer cost extra RAM outside of BitNode-4
|
||||||
* Corporation employees no longer have an "age" stat
|
* Corporation employees no longer have an "age" stat
|
||||||
|
* Gang Wanted level gain rate capped at 100 (per employee)
|
||||||
* Bug Fix: Corporation employees stats should no longer become negative
|
* Bug Fix: Corporation employees stats should no longer become negative
|
||||||
* Bug Fix: Fixed sleeve.getInformation() throwing error in certain scenarios
|
* Bug Fix: Fixed sleeve.getInformation() throwing error in certain scenarios
|
||||||
* Bug Fix: Coding contracts should no longer generate on the w0r1d_d43m0n server
|
* Bug Fix: Coding contracts should no longer generate on the w0r1d_d43m0n server
|
||||||
@ -245,5 +248,9 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
* Bug Fix: Purchasing hash upgrades for Bladeburner/Corporation when you don't actually have access to those mechanics no longer gives hashes
|
* Bug Fix: Purchasing hash upgrades for Bladeburner/Corporation when you don't actually have access to those mechanics no longer gives hashes
|
||||||
* Bug Fix: run(), exec(), and spawn() Netscript functions now throw if called with 0 threads
|
* Bug Fix: run(), exec(), and spawn() Netscript functions now throw if called with 0 threads
|
||||||
* Bug Fix: Faction UI should now automatically update reputation
|
* Bug Fix: Faction UI should now automatically update reputation
|
||||||
|
* Bug Fix: Fixed purchase4SMarketData()
|
||||||
|
* Bug Fix: Netscript1.0 now works properly for multiple 'namespace' imports (import * as namespace from "script")
|
||||||
|
* Bug Fix: Terminal 'wget' command now correctly evaluates directory paths
|
||||||
|
* Bug Fix: wget(), write(), and scp() Netscript functions now fail if an invalid filepath is passed in
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
22
src/Gang.js
22
src/Gang.js
@ -682,21 +682,25 @@ GangMember.prototype.calculateRespectGain = function(gang) {
|
|||||||
|
|
||||||
GangMember.prototype.calculateWantedLevelGain = function(gang) {
|
GangMember.prototype.calculateWantedLevelGain = function(gang) {
|
||||||
const task = this.getTask();
|
const task = this.getTask();
|
||||||
if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) {return 0;}
|
if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) { return 0; }
|
||||||
var statWeight = (task.hackWeight/100) * this.hack +
|
let statWeight = (task.hackWeight / 100) * this.hack +
|
||||||
(task.strWeight/100) * this.str +
|
(task.strWeight / 100) * this.str +
|
||||||
(task.defWeight/100) * this.def +
|
(task.defWeight / 100) * this.def +
|
||||||
(task.dexWeight/100) * this.dex +
|
(task.dexWeight / 100) * this.dex +
|
||||||
(task.agiWeight/100) * this.agi +
|
(task.agiWeight / 100) * this.agi +
|
||||||
(task.chaWeight/100) * this.cha;
|
(task.chaWeight / 100) * this.cha;
|
||||||
statWeight -= (3.5 * task.difficulty);
|
statWeight -= (3.5 * task.difficulty);
|
||||||
if (statWeight <= 0) { return 0; }
|
if (statWeight <= 0) { return 0; }
|
||||||
const territoryMult = Math.pow(AllGangs[gang.facName].territory * 100, task.territory.wanted) / 100;
|
const territoryMult = Math.pow(AllGangs[gang.facName].territory * 100, task.territory.wanted) / 100;
|
||||||
if (isNaN(territoryMult) || territoryMult <= 0) { return 0; }
|
if (isNaN(territoryMult) || territoryMult <= 0) { return 0; }
|
||||||
if (task.baseWanted < 0) {
|
if (task.baseWanted < 0) {
|
||||||
return 0.5 * task.baseWanted * statWeight * territoryMult;
|
return 0.4 * task.baseWanted * statWeight * territoryMult;
|
||||||
} else {
|
} else {
|
||||||
return 7 * task.baseWanted / (Math.pow(3 * statWeight * territoryMult, 0.8));
|
const calc = 7 * task.baseWanted / (Math.pow(3 * statWeight * territoryMult, 0.8));
|
||||||
|
|
||||||
|
// Put an arbitrary cap on this to prevent wanted level from rising too fast if the
|
||||||
|
// denominator is very small. Might want to rethink formula later
|
||||||
|
return Math.max(100, calc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
import { IReturnStatus } from "../types";
|
import { IReturnStatus } from "../types";
|
||||||
|
|
||||||
//import { HacknetServer } from "../Hacknet/HacknetServer";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { Server } from "../Server/Server";
|
import { Server } from "../Server/Server";
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ import {
|
|||||||
getStockMarket4SDataCost,
|
getStockMarket4SDataCost,
|
||||||
getStockMarket4STixApiCost
|
getStockMarket4STixApiCost
|
||||||
} from "./StockMarket/StockMarketCosts";
|
} from "./StockMarket/StockMarketCosts";
|
||||||
|
import { isValidFilePath } from "./Terminal/DirectoryHelpers";
|
||||||
import { TextFile, getTextFile, createTextFile } from "./TextFile";
|
import { TextFile, getTextFile, createTextFile } from "./TextFile";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -1013,8 +1014,14 @@ function NetscriptFunctions(workerScript) {
|
|||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (!scriptname.endsWith(".lit") && !isScriptFilename(scriptname) &&
|
|
||||||
!scriptname.endsWith("txt")) {
|
// Invalid file type
|
||||||
|
if (!isValidFilePath(scriptname)) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, `Error: scp() failed due to invalid filename: ${scriptname}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid file name
|
||||||
|
if (!scriptname.endsWith(".lit") && !isScriptFilename(scriptname) && !scriptname.endsWith("txt")) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: scp() does not work with this file type. It only works for .script, .lit, and .txt files");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: scp() does not work with this file type. It only works for .script, .lit, and .txt files");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1724,6 +1731,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||||
workerScript.log("Purchased 4S Market Data");
|
workerScript.log("Purchased 4S Market Data");
|
||||||
}
|
}
|
||||||
|
displayStockMarketContent();
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchase4SMarketDataTixApi : function() {
|
purchase4SMarketDataTixApi : function() {
|
||||||
@ -1749,6 +1757,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||||
workerScript.log("Purchased 4S Market Data TIX API");
|
workerScript.log("Purchased 4S Market Data TIX API");
|
||||||
}
|
}
|
||||||
|
displayStockMarketContent();
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
getPurchasedServerLimit : function() {
|
getPurchasedServerLimit : function() {
|
||||||
@ -1919,8 +1928,12 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
return port.write(data);
|
return port.write(data);
|
||||||
} else if (isString(port)) { // Write to script or text file
|
} else if (isString(port)) { // Write to script or text file
|
||||||
var fn = port;
|
const fn = port;
|
||||||
var server = workerScript.getServer();
|
if (!isValidFilePath(fn)) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, `write() failed due to invalid filepath: ${fn}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = workerScript.getServer();
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Error getting Server for this script in write(). This is a bug please contact game dev");
|
throw makeRuntimeRejectMsg(workerScript, "Error getting Server for this script in write(). This is a bug please contact game dev");
|
||||||
}
|
}
|
||||||
@ -2251,7 +2264,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
},
|
},
|
||||||
wget: async function(url, target, ip=workerScript.serverIp) {
|
wget: async function(url, target, ip=workerScript.serverIp) {
|
||||||
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
||||||
workerSript.log(`ERROR: wget() failed because of an invalid target file: ${target}. Target file must be a script or text file`);
|
workerScript.log(`ERROR: wget() failed because of an invalid target file: ${target}. Target file must be a script or text file`);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
var s = safeGetServer(ip, "wget");
|
var s = safeGetServer(ip, "wget");
|
||||||
|
@ -178,7 +178,6 @@ function startNetscript1Script(workerScript) {
|
|||||||
fnArgs.push(arguments[i]);
|
fnArgs.push(arguments[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(fnArgs);
|
|
||||||
let cb = arguments[arguments.length-1];
|
let cb = arguments[arguments.length-1];
|
||||||
let fnPromise = entry.apply(null, fnArgs);
|
let fnPromise = entry.apply(null, fnArgs);
|
||||||
fnPromise.then(function(res) {
|
fnPromise.then(function(res) {
|
||||||
@ -289,7 +288,7 @@ function startNetscript1Script(workerScript) {
|
|||||||
*/
|
*/
|
||||||
function processNetscript1Imports(code, workerScript) {
|
function processNetscript1Imports(code, workerScript) {
|
||||||
//allowReserved prevents 'import' from throwing error in ES5
|
//allowReserved prevents 'import' from throwing error in ES5
|
||||||
var ast = parse(code, {ecmaVersion:6, allowReserved:true, sourceType:"module"});
|
const ast = parse(code, { ecmaVersion: 6, allowReserved: true, sourceType: "module" });
|
||||||
|
|
||||||
var server = workerScript.getServer();
|
var server = workerScript.getServer();
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
@ -305,10 +304,10 @@ function processNetscript1Imports(code, workerScript) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var generatedCode = ""; //Generated Javascript Code
|
let generatedCode = ""; // Generated Javascript Code
|
||||||
var hasImports = false;
|
let hasImports = false;
|
||||||
|
|
||||||
//Walk over the tree and process ImportDeclaration nodes
|
// Walk over the tree and process ImportDeclaration nodes
|
||||||
walk.simple(ast, {
|
walk.simple(ast, {
|
||||||
ImportDeclaration: (node) => {
|
ImportDeclaration: (node) => {
|
||||||
hasImports = true;
|
hasImports = true;
|
||||||
@ -323,7 +322,7 @@ function processNetscript1Imports(code, workerScript) {
|
|||||||
let scriptAst = parse(script.code, {ecmaVersion:5, allowReserved:true, sourceType:"module"});
|
let scriptAst = parse(script.code, {ecmaVersion:5, allowReserved:true, sourceType:"module"});
|
||||||
|
|
||||||
if (node.specifiers.length === 1 && node.specifiers[0].type === "ImportNamespaceSpecifier") {
|
if (node.specifiers.length === 1 && node.specifiers[0].type === "ImportNamespaceSpecifier") {
|
||||||
//import * as namespace from script
|
// import * as namespace from script
|
||||||
let namespace = node.specifiers[0].local.name;
|
let namespace = node.specifiers[0].local.name;
|
||||||
let fnNames = []; //Names only
|
let fnNames = []; //Names only
|
||||||
let fnDeclarations = []; //FunctionDeclaration Node objects
|
let fnDeclarations = []; //FunctionDeclaration Node objects
|
||||||
@ -335,7 +334,7 @@ function processNetscript1Imports(code, workerScript) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Now we have to generate the code that would create the namespace
|
//Now we have to generate the code that would create the namespace
|
||||||
generatedCode =
|
generatedCode +=
|
||||||
"var " + namespace + ";\n" +
|
"var " + namespace + ";\n" +
|
||||||
"(function (namespace) {\n";
|
"(function (namespace) {\n";
|
||||||
|
|
||||||
@ -406,6 +405,7 @@ function processNetscript1Imports(code, workerScript) {
|
|||||||
|
|
||||||
//Add the imported code and re-generate in ES5 (JS Interpreter for NS1 only supports ES5);
|
//Add the imported code and re-generate in ES5 (JS Interpreter for NS1 only supports ES5);
|
||||||
code = generatedCode + code;
|
code = generatedCode + code;
|
||||||
|
|
||||||
var res = {
|
var res = {
|
||||||
code: code,
|
code: code,
|
||||||
lineOffset: lineOffset
|
lineOffset: lineOffset
|
||||||
|
5
src/Script/RamCalculationErrorCodes.ts
Normal file
5
src/Script/RamCalculationErrorCodes.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export enum RamCalculationErrorCode {
|
||||||
|
SyntaxError = -1,
|
||||||
|
ImportError = -2,
|
||||||
|
URLImportError = -3,
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
// Calculate a script's RAM usage
|
// Calculate a script's RAM usage
|
||||||
import * as walk from "acorn-walk";
|
import * as walk from "acorn-walk";
|
||||||
|
|
||||||
|
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||||
|
|
||||||
import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
||||||
import { parse, Node } from "../../utils/acorn";
|
import { parse, Node } from "../../utils/acorn";
|
||||||
|
|
||||||
@ -71,12 +73,12 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(`Error dynamically importing module from ${nextModule} for RAM calculations: ${e}`);
|
console.error(`Error dynamically importing module from ${nextModule} for RAM calculations: ${e}`);
|
||||||
return -1;
|
return RamCalculationErrorCode.URLImportError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Array.isArray(otherScripts)) {
|
if (!Array.isArray(otherScripts)) {
|
||||||
console.warn(`parseOnlyRamCalculate() not called with array of scripts`);
|
console.warn(`parseOnlyRamCalculate() not called with array of scripts`);
|
||||||
return -1;
|
return RamCalculationErrorCode.ImportError;
|
||||||
}
|
}
|
||||||
|
|
||||||
let script = null;
|
let script = null;
|
||||||
@ -89,8 +91,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
console.warn("Invalid script");
|
return RamCalculationErrorCode.ImportError; // No such script on the server
|
||||||
return -1; // No such script on the server.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
code = script.code;
|
code = script.code;
|
||||||
@ -191,7 +192,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
|||||||
// console.info("parse or eval error: ", error);
|
// console.info("parse or eval error: ", error);
|
||||||
// This is not unexpected. The user may be editing a script, and it may be in
|
// This is not unexpected. The user may be editing a script, and it may be in
|
||||||
// a transitory invalid state.
|
// a transitory invalid state.
|
||||||
return -1;
|
return RamCalculationErrorCode.SyntaxError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,8 +311,8 @@ export async function calculateRamUsage(codeCopy, otherScripts) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Failed to parse script for RAM calculations:`);
|
console.error(`Failed to parse script for RAM calculations:`);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
return -1;
|
return RamCalculationErrorCode.SyntaxError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return RamCalculationErrorCode.SyntaxError;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ export class Script {
|
|||||||
// Updates the script's RAM usage based on its code
|
// Updates the script's RAM usage based on its code
|
||||||
async updateRamUsage(otherScripts: Script[]) {
|
async updateRamUsage(otherScripts: Script[]) {
|
||||||
var res = await calculateRamUsage(this.code, otherScripts);
|
var res = await calculateRamUsage(this.code, otherScripts);
|
||||||
if (res !== -1) {
|
if (res > 0) {
|
||||||
this.ramUsage = roundToTwo(res);
|
this.ramUsage = roundToTwo(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Script } from "./Script";
|
import { Script } from "./Script";
|
||||||
|
|
||||||
|
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||||
import { calculateRamUsage } from "./RamCalculations";
|
import { calculateRamUsage } from "./RamCalculations";
|
||||||
import { isScriptFilename } from "./ScriptHelpersTS";
|
import { isScriptFilename } from "./ScriptHelpersTS";
|
||||||
|
|
||||||
@ -190,10 +191,22 @@ export async function updateScriptEditorContent() {
|
|||||||
|
|
||||||
var codeCopy = code.repeat(1);
|
var codeCopy = code.repeat(1);
|
||||||
var ramUsage = await calculateRamUsage(codeCopy, Player.getCurrentServer().scripts);
|
var ramUsage = await calculateRamUsage(codeCopy, Player.getCurrentServer().scripts);
|
||||||
if (ramUsage !== -1) {
|
if (ramUsage > 0) {
|
||||||
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.format(ramUsage, '0.00') + " GB";
|
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.format(ramUsage, '0.00') + " GB";
|
||||||
} else {
|
} else {
|
||||||
scriptEditorRamText.innerText = "RAM: Syntax Error";
|
switch (ramUsage) {
|
||||||
|
case RamCalculationErrorCode.ImportError:
|
||||||
|
scriptEditorRamText.innerText = "RAM: Import Error";
|
||||||
|
break;
|
||||||
|
case RamCalculationErrorCode.URLImportError:
|
||||||
|
scriptEditorRamText.innerText = "RAM: HTTP Import Error";
|
||||||
|
break;
|
||||||
|
case RamCalculationErrorCode.SyntaxError:
|
||||||
|
default:
|
||||||
|
scriptEditorRamText.innerText = "RAM: Syntax Error";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { CodingContract } from "../CodingContracts";
|
|||||||
import { Message } from "../Message/Message";
|
import { Message } from "../Message/Message";
|
||||||
import { RunningScript } from "../Script/RunningScript";
|
import { RunningScript } from "../Script/RunningScript";
|
||||||
import { Script } from "../Script/Script";
|
import { Script } from "../Script/Script";
|
||||||
|
import { isValidFilePath } from "../Terminal/DirectoryHelpers";
|
||||||
import { TextFile } from "../TextFile";
|
import { TextFile } from "../TextFile";
|
||||||
import { IReturnStatus } from "../types";
|
import { IReturnStatus } from "../types";
|
||||||
|
|
||||||
@ -223,10 +224,10 @@ export class BaseServer {
|
|||||||
* Overwrites existing files. Creates new files if the script does not eixst
|
* Overwrites existing files. Creates new files if the script does not eixst
|
||||||
*/
|
*/
|
||||||
writeToScriptFile(fn: string, code: string) {
|
writeToScriptFile(fn: string, code: string) {
|
||||||
var ret = {success: false, overwritten: false};
|
var ret = { success: false, overwritten: false };
|
||||||
if (!isScriptFilename(fn)) { return ret; }
|
if (!isValidFilePath(fn) || !isScriptFilename(fn)) { return ret; }
|
||||||
|
|
||||||
//Check if the script already exists, and overwrite it if it does
|
// Check if the script already exists, and overwrite it if it does
|
||||||
for (let i = 0; i < this.scripts.length; ++i) {
|
for (let i = 0; i < this.scripts.length; ++i) {
|
||||||
if (fn === this.scripts[i].filename) {
|
if (fn === this.scripts[i].filename) {
|
||||||
let script = this.scripts[i];
|
let script = this.scripts[i];
|
||||||
@ -239,7 +240,7 @@ export class BaseServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise, create a new script
|
// Otherwise, create a new script
|
||||||
const newScript = new Script(fn, code, this.ip, this.scripts);
|
const newScript = new Script(fn, code, this.ip, this.scripts);
|
||||||
this.scripts.push(newScript);
|
this.scripts.push(newScript);
|
||||||
ret.success = true;
|
ret.success = true;
|
||||||
@ -250,9 +251,9 @@ export class BaseServer {
|
|||||||
// Overwrites existing files. Creates new files if the text file does not exist
|
// Overwrites existing files. Creates new files if the text file does not exist
|
||||||
writeToTextFile(fn: string, txt: string) {
|
writeToTextFile(fn: string, txt: string) {
|
||||||
var ret = { success: false, overwritten: false };
|
var ret = { success: false, overwritten: false };
|
||||||
if (!fn.endsWith("txt")) { return ret; }
|
if (!isValidFilePath(fn) || !fn.endsWith("txt")) { return ret; }
|
||||||
|
|
||||||
//Check if the text file already exists, and overwrite if it does
|
// Check if the text file already exists, and overwrite if it does
|
||||||
for (let i = 0; i < this.textFiles.length; ++i) {
|
for (let i = 0; i < this.textFiles.length; ++i) {
|
||||||
if (this.textFiles[i].fn === fn) {
|
if (this.textFiles[i].fn === fn) {
|
||||||
ret.overwritten = true;
|
ret.overwritten = true;
|
||||||
@ -262,7 +263,7 @@ export class BaseServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise create a new text file
|
// Otherwise create a new text file
|
||||||
var newFile = new TextFile(fn, txt);
|
var newFile = new TextFile(fn, txt);
|
||||||
this.textFiles.push(newFile);
|
this.textFiles.push(newFile);
|
||||||
ret.success = true;
|
ret.success = true;
|
||||||
|
@ -1475,7 +1475,7 @@ let Terminal = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let url = commandArray[1];
|
let url = commandArray[1];
|
||||||
let target = commandArray[2];
|
let target = Terminal.getFilepath(commandArray[2]);
|
||||||
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
||||||
return post(`wget failed: Invalid target file. Target file must be script or text file`);
|
return post(`wget failed: Invalid target file. Target file must be script or text file`);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Helper functions that implement "directory" functionality in the Terminal.
|
* Helper functions that implement "directory" functionality in the Terminal.
|
||||||
* These aren't real directories, they're more of a pseudo-directory implementation
|
* These aren't "real" directories, it's more of a pseudo-directory implementation
|
||||||
|
* that uses mainly string manipulation.
|
||||||
|
*
|
||||||
|
* This file contains functions that deal only with that string manipulation.
|
||||||
|
* Functions that need to access/process Server-related things can be
|
||||||
|
* found in ./DirectoryServerHelpers.ts
|
||||||
*/
|
*/
|
||||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
|
||||||
import { Server } from "../Server/Server";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes leading forward slash ("/") from a string.
|
* Removes leading forward slash ("/") from a string.
|
||||||
@ -149,44 +152,6 @@ export function getAllParentDirectories(path: string): string {
|
|||||||
return t_path.slice(0, lastSlash + 1);
|
return t_path.slice(0, lastSlash + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a directory (by the full directory path) and a server, returns all
|
|
||||||
* subdirectories of that directory. This is only for FIRST-LEVEl/immediate subdirectories
|
|
||||||
*/
|
|
||||||
export function getSubdirectories(serv: Server | HacknetServer, dir: string): string[] {
|
|
||||||
const res: string[] = [];
|
|
||||||
|
|
||||||
if (!isValidDirectoryPath(dir)) { return res; }
|
|
||||||
|
|
||||||
let t_dir = dir;
|
|
||||||
if (!t_dir.endsWith("/")) { t_dir += "/"; }
|
|
||||||
|
|
||||||
function processFile(fn: string) {
|
|
||||||
if (t_dir === "/" && isInRootDirectory(fn)) {
|
|
||||||
const subdir = getFirstParentDirectory(fn);
|
|
||||||
if (subdir !== "/" && !res.includes(subdir)) {
|
|
||||||
res.push(subdir);
|
|
||||||
}
|
|
||||||
} else if (fn.startsWith(t_dir)) {
|
|
||||||
const remaining = fn.slice(t_dir.length);
|
|
||||||
const subdir = getFirstParentDirectory(remaining);
|
|
||||||
if (subdir !== "/" && !res.includes(subdir)) {
|
|
||||||
res.push(subdir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const script of serv.scripts) {
|
|
||||||
processFile(script.filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const txt of serv.textFiles) {
|
|
||||||
processFile(txt.fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a file path refers to a file in the root directory.
|
* Checks if a file path refers to a file in the root directory.
|
||||||
*/
|
*/
|
||||||
|
53
src/Terminal/DirectoryServerHelpers.ts
Normal file
53
src/Terminal/DirectoryServerHelpers.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Helper functions that implement "directory" functionality in the Terminal.
|
||||||
|
* These aren't "real" directories, it's more of a pseudo-directory implementation
|
||||||
|
* that uses mainly string manipulation.
|
||||||
|
*
|
||||||
|
* This file contains function that deal with Server-related directory things.
|
||||||
|
* Functions that deal with the string manipulation can be found in
|
||||||
|
* ./DirectoryHelpers.ts
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
isValidDirectoryPath,
|
||||||
|
isInRootDirectory,
|
||||||
|
getFirstParentDirectory,
|
||||||
|
} from "./DirectoryHelpers";
|
||||||
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a directory (by the full directory path) and a server, returns all
|
||||||
|
* subdirectories of that directory. This is only for FIRST-LEVEl/immediate subdirectories
|
||||||
|
*/
|
||||||
|
export function getSubdirectories(serv: BaseServer, dir: string): string[] {
|
||||||
|
const res: string[] = [];
|
||||||
|
|
||||||
|
if (!isValidDirectoryPath(dir)) { return res; }
|
||||||
|
|
||||||
|
let t_dir = dir;
|
||||||
|
if (!t_dir.endsWith("/")) { t_dir += "/"; }
|
||||||
|
|
||||||
|
function processFile(fn: string) {
|
||||||
|
if (t_dir === "/" && isInRootDirectory(fn)) {
|
||||||
|
const subdir = getFirstParentDirectory(fn);
|
||||||
|
if (subdir !== "/" && !res.includes(subdir)) {
|
||||||
|
res.push(subdir);
|
||||||
|
}
|
||||||
|
} else if (fn.startsWith(t_dir)) {
|
||||||
|
const remaining = fn.slice(t_dir.length);
|
||||||
|
const subdir = getFirstParentDirectory(remaining);
|
||||||
|
if (subdir !== "/" && !res.includes(subdir)) {
|
||||||
|
res.push(subdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const script of serv.scripts) {
|
||||||
|
processFile(script.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const txt of serv.textFiles) {
|
||||||
|
processFile(txt.fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
evaluateDirectoryPath,
|
evaluateDirectoryPath,
|
||||||
getAllParentDirectories,
|
getAllParentDirectories,
|
||||||
getSubdirectories,
|
|
||||||
} from "./DirectoryHelpers";
|
} from "./DirectoryHelpers";
|
||||||
|
import { getSubdirectories } from "./DirectoryServerHelpers";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Aliases,
|
Aliases,
|
||||||
|
Loading…
Reference in New Issue
Block a user