mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 01:23: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.
|
||||
|
||||
.. note:: Limit and Stop orders do **not** take into account the fact that
|
||||
transactions can influence a stock's price. If a stock's price
|
||||
changes mid-transaction, a limit/stop order will continue to execute
|
||||
even if its conditions are no longer met.
|
||||
.. note:: Stop Orders do **not** take into account the fact that transactions can
|
||||
influence a stock's price. Limit Orders, however, do take this into account.
|
||||
|
||||
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
|
||||
---------------------------
|
||||
|
@ -4,6 +4,11 @@ grow() Netscript Function
|
||||
.. js:function:: grow(hostname/ip)
|
||||
|
||||
: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
|
||||
:RAM cost: 0.15 GB
|
||||
|
||||
@ -19,3 +24,4 @@ grow() Netscript Function
|
||||
Example::
|
||||
|
||||
grow("foodnstuff");
|
||||
grow("foodnstuff", { threads: 5 }); // Only use 5 threads to grow
|
||||
|
@ -4,6 +4,11 @@ hack() Netscript Function
|
||||
.. js:function:: hack(hostname/ip)
|
||||
|
||||
: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
|
||||
:RAM cost: 0.1 GB
|
||||
|
||||
@ -20,3 +25,4 @@ hack() Netscript Function
|
||||
|
||||
hack("foodnstuff");
|
||||
hack("10.1.2.3");
|
||||
hack("foodnstuff", { threads: 5 }); // Only use 5 threads to hack
|
||||
|
@ -1,9 +1,14 @@
|
||||
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 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
|
||||
by the number of script threads
|
||||
:RAM cost: 0.15 GB
|
||||
@ -18,3 +23,4 @@ weaken() Netscript Function
|
||||
Example::
|
||||
|
||||
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 workType:
|
||||
Type of work to perform for the faction
|
||||
Type of work to perform for the faction:
|
||||
|
||||
* hacking/hacking contracts/hackingcontracts
|
||||
* field/fieldwork/field work
|
||||
|
@ -233,9 +233,12 @@ export let CONSTANTS: IMap<any> = {
|
||||
* Re-sleeves can no longer have the NeuroFlux Governor augmentation
|
||||
** 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)
|
||||
* Netscript Singularity functions no longer cost extra RAM outside of BitNode-4
|
||||
* 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: Fixed sleeve.getInformation() throwing error in certain scenarios
|
||||
* 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: run(), exec(), and spawn() Netscript functions now throw if called with 0 threads
|
||||
* 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) {
|
||||
const task = this.getTask();
|
||||
if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) {return 0;}
|
||||
var statWeight = (task.hackWeight/100) * this.hack +
|
||||
(task.strWeight/100) * this.str +
|
||||
(task.defWeight/100) * this.def +
|
||||
(task.dexWeight/100) * this.dex +
|
||||
(task.agiWeight/100) * this.agi +
|
||||
(task.chaWeight/100) * this.cha;
|
||||
if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) { return 0; }
|
||||
let statWeight = (task.hackWeight / 100) * this.hack +
|
||||
(task.strWeight / 100) * this.str +
|
||||
(task.defWeight / 100) * this.def +
|
||||
(task.dexWeight / 100) * this.dex +
|
||||
(task.agiWeight / 100) * this.agi +
|
||||
(task.chaWeight / 100) * this.cha;
|
||||
statWeight -= (3.5 * task.difficulty);
|
||||
if (statWeight <= 0) { return 0; }
|
||||
const territoryMult = Math.pow(AllGangs[gang.facName].territory * 100, task.territory.wanted) / 100;
|
||||
if (isNaN(territoryMult) || territoryMult <= 0) { return 0; }
|
||||
if (task.baseWanted < 0) {
|
||||
return 0.5 * task.baseWanted * statWeight * territoryMult;
|
||||
return 0.4 * task.baseWanted * statWeight * territoryMult;
|
||||
} 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 { HacknetServer } from "../Hacknet/HacknetServer";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Server } from "../Server/Server";
|
||||
|
||||
|
@ -110,6 +110,7 @@ import {
|
||||
getStockMarket4SDataCost,
|
||||
getStockMarket4STixApiCost
|
||||
} from "./StockMarket/StockMarketCosts";
|
||||
import { isValidFilePath } from "./Terminal/DirectoryHelpers";
|
||||
import { TextFile, getTextFile, createTextFile } from "./TextFile";
|
||||
|
||||
import {
|
||||
@ -1013,8 +1014,14 @@ function NetscriptFunctions(workerScript) {
|
||||
});
|
||||
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");
|
||||
}
|
||||
|
||||
@ -1724,6 +1731,7 @@ function NetscriptFunctions(workerScript) {
|
||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||
workerScript.log("Purchased 4S Market Data");
|
||||
}
|
||||
displayStockMarketContent();
|
||||
return true;
|
||||
},
|
||||
purchase4SMarketDataTixApi : function() {
|
||||
@ -1749,6 +1757,7 @@ function NetscriptFunctions(workerScript) {
|
||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||
workerScript.log("Purchased 4S Market Data TIX API");
|
||||
}
|
||||
displayStockMarketContent();
|
||||
return true;
|
||||
},
|
||||
getPurchasedServerLimit : function() {
|
||||
@ -1919,8 +1928,12 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return port.write(data);
|
||||
} else if (isString(port)) { // Write to script or text file
|
||||
var fn = port;
|
||||
var server = workerScript.getServer();
|
||||
const fn = port;
|
||||
if (!isValidFilePath(fn)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, `write() failed due to invalid filepath: ${fn}`);
|
||||
}
|
||||
|
||||
const server = workerScript.getServer();
|
||||
if (server == null) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
var s = safeGetServer(ip, "wget");
|
||||
|
@ -178,7 +178,6 @@ function startNetscript1Script(workerScript) {
|
||||
fnArgs.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
console.log(fnArgs);
|
||||
let cb = arguments[arguments.length-1];
|
||||
let fnPromise = entry.apply(null, fnArgs);
|
||||
fnPromise.then(function(res) {
|
||||
@ -289,7 +288,7 @@ function startNetscript1Script(workerScript) {
|
||||
*/
|
||||
function processNetscript1Imports(code, workerScript) {
|
||||
//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();
|
||||
if (server == null) {
|
||||
@ -305,10 +304,10 @@ function processNetscript1Imports(code, workerScript) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var generatedCode = ""; //Generated Javascript Code
|
||||
var hasImports = false;
|
||||
let generatedCode = ""; // Generated Javascript Code
|
||||
let hasImports = false;
|
||||
|
||||
//Walk over the tree and process ImportDeclaration nodes
|
||||
// Walk over the tree and process ImportDeclaration nodes
|
||||
walk.simple(ast, {
|
||||
ImportDeclaration: (node) => {
|
||||
hasImports = true;
|
||||
@ -323,7 +322,7 @@ function processNetscript1Imports(code, workerScript) {
|
||||
let scriptAst = parse(script.code, {ecmaVersion:5, allowReserved:true, sourceType:"module"});
|
||||
|
||||
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 fnNames = []; //Names only
|
||||
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
|
||||
generatedCode =
|
||||
generatedCode +=
|
||||
"var " + 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);
|
||||
code = generatedCode + code;
|
||||
|
||||
var res = {
|
||||
code: code,
|
||||
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
|
||||
import * as walk from "acorn-walk";
|
||||
|
||||
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||
|
||||
import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
||||
import { parse, Node } from "../../utils/acorn";
|
||||
|
||||
@ -71,12 +73,12 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(`Error dynamically importing module from ${nextModule} for RAM calculations: ${e}`);
|
||||
return -1;
|
||||
return RamCalculationErrorCode.URLImportError;
|
||||
}
|
||||
} else {
|
||||
if (!Array.isArray(otherScripts)) {
|
||||
console.warn(`parseOnlyRamCalculate() not called with array of scripts`);
|
||||
return -1;
|
||||
return RamCalculationErrorCode.ImportError;
|
||||
}
|
||||
|
||||
let script = null;
|
||||
@ -89,8 +91,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
|
||||
if (script == null) {
|
||||
console.warn("Invalid script");
|
||||
return -1; // No such script on the server.
|
||||
return RamCalculationErrorCode.ImportError; // No such script on the server
|
||||
}
|
||||
|
||||
code = script.code;
|
||||
@ -191,7 +192,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
// console.info("parse or eval error: ", error);
|
||||
// This is not unexpected. The user may be editing a script, and it may be in
|
||||
// a transitory invalid state.
|
||||
return -1;
|
||||
return RamCalculationErrorCode.SyntaxError;
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,8 +311,8 @@ export async function calculateRamUsage(codeCopy, otherScripts) {
|
||||
} catch (e) {
|
||||
console.error(`Failed to parse script for RAM calculations:`);
|
||||
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
|
||||
async updateRamUsage(otherScripts: Script[]) {
|
||||
var res = await calculateRamUsage(this.code, otherScripts);
|
||||
if (res !== -1) {
|
||||
if (res > 0) {
|
||||
this.ramUsage = roundToTwo(res);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Script } from "./Script";
|
||||
|
||||
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||
import { calculateRamUsage } from "./RamCalculations";
|
||||
import { isScriptFilename } from "./ScriptHelpersTS";
|
||||
|
||||
@ -190,10 +191,22 @@ export async function updateScriptEditorContent() {
|
||||
|
||||
var codeCopy = code.repeat(1);
|
||||
var ramUsage = await calculateRamUsage(codeCopy, Player.getCurrentServer().scripts);
|
||||
if (ramUsage !== -1) {
|
||||
if (ramUsage > 0) {
|
||||
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.format(ramUsage, '0.00') + " GB";
|
||||
} else {
|
||||
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 { RunningScript } from "../Script/RunningScript";
|
||||
import { Script } from "../Script/Script";
|
||||
import { isValidFilePath } from "../Terminal/DirectoryHelpers";
|
||||
import { TextFile } from "../TextFile";
|
||||
import { IReturnStatus } from "../types";
|
||||
|
||||
@ -223,10 +224,10 @@ export class BaseServer {
|
||||
* Overwrites existing files. Creates new files if the script does not eixst
|
||||
*/
|
||||
writeToScriptFile(fn: string, code: string) {
|
||||
var ret = {success: false, overwritten: false};
|
||||
if (!isScriptFilename(fn)) { return ret; }
|
||||
var ret = { success: false, overwritten: false };
|
||||
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) {
|
||||
if (fn === this.scripts[i].filename) {
|
||||
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);
|
||||
this.scripts.push(newScript);
|
||||
ret.success = true;
|
||||
@ -250,9 +251,9 @@ export class BaseServer {
|
||||
// Overwrites existing files. Creates new files if the text file does not exist
|
||||
writeToTextFile(fn: string, txt: string) {
|
||||
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) {
|
||||
if (this.textFiles[i].fn === fn) {
|
||||
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);
|
||||
this.textFiles.push(newFile);
|
||||
ret.success = true;
|
||||
|
@ -1475,7 +1475,7 @@ let Terminal = {
|
||||
}
|
||||
|
||||
let url = commandArray[1];
|
||||
let target = commandArray[2];
|
||||
let target = Terminal.getFilepath(commandArray[2]);
|
||||
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
||||
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.
|
||||
* 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.
|
||||
@ -149,44 +152,6 @@ export function getAllParentDirectories(path: string): string {
|
||||
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.
|
||||
*/
|
||||
|
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 {
|
||||
evaluateDirectoryPath,
|
||||
getAllParentDirectories,
|
||||
getSubdirectories,
|
||||
} from "./DirectoryHelpers";
|
||||
import { getSubdirectories } from "./DirectoryServerHelpers";
|
||||
|
||||
import {
|
||||
Aliases,
|
||||
|
Loading…
Reference in New Issue
Block a user