This commit is contained in:
Olivier Gagnon 2021-08-19 16:37:59 -04:00
parent ee3530d9b9
commit df457a0c6e
18 changed files with 194 additions and 105 deletions

File diff suppressed because one or more lines are too long

26
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -3,6 +3,32 @@
Changelog Changelog
========= =========
v0.52.5 - 2021-07-19 CPU cores are useful!? (hydroflame)
-------------------------------------------
** Terminal **
* When executing 'run SCRIPT' any script can now add '--tail' to
automatically bring up the logs.
** Netscript **
* The 'flags' function now works with single letter flags but they only take
one dash.
* Fix several broken bladeburner netscript functions.
* Fix gang.getMemberInformation returning inconsistent data after the gang
rework.
** CPU Cores **
* CPU Cores on the home computer now provide a bonus to grow() money gain
and makes weaken lower more security. Only for scripts running on 'home'
** Misc. **
* Fix weird scrolling in the new Bladeburner React console.
* nerf noodle bar
v0.52.4 - 2021-07-19 Bladeburner in React (hydroflame) v0.52.4 - 2021-07-19 Bladeburner in React (hydroflame)
------------------------------------------- -------------------------------------------

@ -66,7 +66,7 @@ documentation_title = '{0} Documentation'.format(project)
# The short X.Y version. # The short X.Y version.
version = '0.52' version = '0.52'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.52.4' release = '0.52.5'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

@ -1,12 +1,13 @@
growPercent() Netscript Function growPercent() Netscript Function
================================= =================================
.. js:function:: growPercent(server, threads, player) .. js:function:: growPercent(server, threads, player, cores)
:RAM cost: 0 GB :RAM cost: 0 GB
:param server server: The server that receives the growth. :param server server: The server that receives the growth.
:param number threads: The number of thread that would be used. :param number threads: The number of thread that would be used.
:param player player: The player. :param player player: The player.
:param number cores: The amount of cores on the host computer.
:returns: The amount the server's money would be multiplied by with these :returns: The amount the server's money would be multiplied by with these
parameters. parameters.

@ -13,30 +13,42 @@ getMemberInformation() Netscript Function
name: Name of this member. name: Name of this member.
task: Name of currently assigned task. task: Name of currently assigned task.
earnedRespect: Total amount of respect earned by this member. earnedRespect: Total amount of respect earned by this member.
hack: Hacking stat hack: Hacking stat
str: Strength stat str: Strength stat
def: Defense stat def: Defense stat
dex: Dexterity stat dex: Dexterity stat
agi: Agility stat agi: Agility stat
cha: Charisma stat cha: Charisma stat
hack_exp: Hacking experience hack_exp: Hacking experience
str_exp: Strength experience str_exp: Strength experience
def_exp: Defense experience def_exp: Defense experience
dex_exp: Dexterity experience dex_exp: Dexterity experience
agi_exp: Agility experience agi_exp: Agility experience
cha_exp: Charisma experience cha_exp: Charisma experience
hack_mult: Hacking multiplier from equipment. Decimal form hack_mult: Hacking multiplier from equipment. Decimal form
str_mult: Strength multiplier from equipment. Decimal form str_mult: Strength multiplier from equipment. Decimal form
def_mult: Defense multiplier from equipment. Decimal form def_mult: Defense multiplier from equipment. Decimal form
dex_mult: Dexterity multiplier from equipment. Decimal form dex_mult: Dexterity multiplier from equipment. Decimal form
agi_mult: Agility multiplier from equipment. Decimal form agi_mult: Agility multiplier from equipment. Decimal form
cha_mult: Charisma multiplier from equipment. Decimal form cha_mult: Charisma multiplier from equipment. Decimal form
hack_asc_mult: Hacking multiplier from ascension. Decimal form hack_asc_mult: Hacking multiplier from ascension. Decimal form
str_asc_mult: Strength multiplier from ascension. Decimal form str_asc_mult: Strength multiplier from ascension. Decimal form
def_asc_mult: Defense multiplier from ascension. Decimal form def_asc_mult: Defense multiplier from ascension. Decimal form
dex_asc_mult: Dexterity multiplier from ascension. Decimal form dex_asc_mult: Dexterity multiplier from ascension. Decimal form
agi_asc_mult: Agility multiplier from ascension. Decimal form agi_asc_mult: Agility multiplier from ascension. Decimal form
cha_asc_mult: Charisma multiplier from ascension. Decimal form cha_asc_mult: Charisma multiplier from ascension. Decimal form
hack_asc_points: Hacking ascension points.
str_asc_points: Strength ascension points.
def_asc_points: Defense ascension points.
dex_asc_points: Dexterity ascension points.
agi_asc_points: Agility ascension points.
cha_asc_points: Charisma ascension points.
upgrades: Array of names of all owned Non-Augmentation Equipment upgrades: Array of names of all owned Non-Augmentation Equipment
augmentations: Array of names of all owned Augmentations augmentations: Array of names of all owned Augmentations
} }

@ -126,5 +126,5 @@
"watch": "webpack --watch --mode production", "watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development" "watch:dev": "webpack --watch --mode development"
}, },
"version": "0.52.4" "version": "0.52.5"
} }

@ -26,8 +26,18 @@ export function Console(props: IProps): React.ReactElement {
// TODO: Figure out how to actually make the scrolling work correctly. // TODO: Figure out how to actually make the scrolling work correctly.
function scrollToBottom(): void { function scrollToBottom(): void {
if(lastRef.current) function isMaxed(): boolean {
if(!lastRef.current) return false;
const oldTop = lastRef.current.scrollTop;
lastRef.current.scrollTop = lastRef.current.scrollHeight; lastRef.current.scrollTop = lastRef.current.scrollHeight;
const maxed = oldTop === lastRef.current.scrollTop;
lastRef.current.scrollTop = oldTop;
return maxed;
}
if(lastRef.current) {
if(isMaxed())
lastRef.current.scrollTop = lastRef.current.scrollHeight;
}
} }
function rerender(): void { function rerender(): void {

@ -6,7 +6,7 @@
import { IMap } from "./types"; import { IMap } from "./types";
export const CONSTANTS: IMap<any> = { export const CONSTANTS: IMap<any> = {
Version: "0.52.4", Version: "0.52.5",
// Speed (in ms) at which the main loop is updated // Speed (in ms) at which the main loop is updated
_idleSpeed: 200, _idleSpeed: 200,
@ -228,26 +228,30 @@ export const CONSTANTS: IMap<any> = {
TotalNumBitNodes: 24, TotalNumBitNodes: 24,
LatestUpdate: ` LatestUpdate: `
v0.52.4 - 2021-07-19 Bladeburner in React (hydroflame) v0.52.5 - 2021-07-19 CPU cores are useful!? (hydroflame)
------------------------------------------- -------------------------------------------
** Bladeburner ** ** Terminal **
* The entire UI was rebuild in React. It should be more responsive * When executing 'run SCRIPT' any script can now add '--tail' to
automatically bring up the logs.
** Hacknet ** ** Netscript **
* Displays how many time each hash upgrade was bought. * The 'flags' function now works with single letter flags but they only take
* Displays cummulative effect of the upgrade. one dash.
* Removed "Close" button from hash upgrade menu. * Fix several broken bladeburner netscript functions.
* Fix gang.getMemberInformation returning inconsistent data after the gang
rework.
** CPU Cores **
* CPU Cores on the home computer now provide a bonus to grow() money gain
and makes weaken lower more security. Only for scripts running on 'home'
** Misc. ** ** Misc. **
* More popup/modals have dark background, can be dismissed by clicking * Fix weird scrolling in the new Bladeburner React console.
outside, or by pressing escape.
* Small reword in the guide.
* Fix several typos in the bladeburner documentation.
* Linting (no one cares except the dev)
* nerf noodle bar * nerf noodle bar
`, `,
} }

@ -44,8 +44,6 @@ export class HashUpgrade {
// The meaning varies between different upgrades // The meaning varies between different upgrades
value = 0; value = 0;
effectText: (level: number) => JSX.Element | null = () => null;
constructor(p: IConstructorParams) { constructor(p: IConstructorParams) {
if (p.cost != null) { this.cost = p.cost; } if (p.cost != null) { this.cost = p.cost; }
if (p.effectText != null) { this.effectText = p.effectText; } if (p.effectText != null) { this.effectText = p.effectText; }
@ -57,6 +55,9 @@ export class HashUpgrade {
this.value = p.value; this.value = p.value;
} }
// Functions that returns the UI element to display the effect of this upgrade.
effectText: (level: number) => JSX.Element | null = () => null;
getCost(levels: number): number { getCost(levels: number): number {
if (typeof this.cost === "number") { return this.cost; } if (typeof this.cost === "number") { return this.cost; }

@ -11,7 +11,6 @@ import { Player } from "../../Player";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { PopupCloseButton } from "../../ui/React/PopupCloseButton";
import { ServerDropdown, import { ServerDropdown,
ServerType } from "../../ui/React/ServerDropdown" ServerType } from "../../ui/React/ServerDropdown"

@ -204,7 +204,7 @@ export const LocationsMetadata: IConstructorParams[] = [
startingSecurityLevel: 2.5, startingSecurityLevel: 2.5,
}, },
name: LocationName.NewTokyoNoodleBar, name: LocationName.NewTokyoNoodleBar,
types: [LocationType.Company], types: [LocationType.Company, LocationType.Special],
}, },
{ {
city: CityName.NewTokyo, city: CityName.NewTokyo,

@ -45,6 +45,7 @@ export class SpecialLocation extends React.Component<IProps, IState> {
this.btnStyle = { display: "block" }; this.btnStyle = { display: "block" };
this.renderNoodleBar = this.renderNoodleBar.bind(this);
this.createCorporationPopup = this.createCorporationPopup.bind(this); this.createCorporationPopup = this.createCorporationPopup.bind(this);
this.handleBladeburner = this.handleBladeburner.bind(this); this.handleBladeburner = this.handleBladeburner.bind(this);
this.handleResleeving = this.handleResleeving.bind(this); this.handleResleeving = this.handleResleeving.bind(this);
@ -107,6 +108,18 @@ export class SpecialLocation extends React.Component<IProps, IState> {
) )
} }
renderNoodleBar(): React.ReactNode {
function EatNoodles(): void {
dialogBoxCreate(<>You ate some delicious noodles and feel refreshed.</>)
}
return (<StdButton
onClick={EatNoodles}
style={this.btnStyle}
text={'Eat noodles'}
/>)
}
renderCreateCorporation(): React.ReactNode { renderCreateCorporation(): React.ReactNode {
if (!this.props.p.canAccessCorporation()) { if (!this.props.p.canAccessCorporation()) {
return <> return <>
@ -145,6 +158,9 @@ export class SpecialLocation extends React.Component<IProps, IState> {
case LocationName.Sector12NSA: { case LocationName.Sector12NSA: {
return this.renderBladeburner(); return this.renderBladeburner();
} }
case LocationName.NewTokyoNoodleBar: {
return this.renderNoodleBar();
}
default: default:
console.error(`Location ${this.props.loc.name} doesn't have any special properties`); console.error(`Location ${this.props.loc.name} doesn't have any special properties`);
break; break;

@ -853,6 +853,8 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeErrorMsg("grow", `Invalid IP/hostname: ${ip}.`); throw makeRuntimeErrorMsg("grow", `Invalid IP/hostname: ${ip}.`);
} }
const host = getServer(workerScript.serverIp);
// No root access or skill level too low // No root access or skill level too low
const canHack = netscriptCanGrow(server); const canHack = netscriptCanGrow(server);
if (!canHack.res) { if (!canHack.res) {
@ -865,7 +867,7 @@ function NetscriptFunctions(workerScript) {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);} if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable; const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable;
server.moneyAvailable += (1 * threads); // It can be grown even if it has no money server.moneyAvailable += (1 * threads); // It can be grown even if it has no money
processSingleServerGrowth(server, threads, Player); processSingleServerGrowth(server, threads, Player, host.cpuCores);
const moneyAfter = server.moneyAvailable; const moneyAfter = server.moneyAvailable;
workerScript.scriptRef.recordGrow(server.ip, threads); workerScript.scriptRef.recordGrow(server.ip, threads);
var expGain = calculateHackingExpGain(server, Player) * threads; var expGain = calculateHackingExpGain(server, Player) * threads;
@ -896,7 +898,7 @@ function NetscriptFunctions(workerScript) {
if (ip === undefined) { if (ip === undefined) {
throw makeRuntimeErrorMsg("weaken", "Takes 1 argument."); throw makeRuntimeErrorMsg("weaken", "Takes 1 argument.");
} }
var server = getServer(ip); const server = getServer(ip);
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg("weaken", `Invalid IP/hostname: ${ip}`); throw makeRuntimeErrorMsg("weaken", `Invalid IP/hostname: ${ip}`);
} }
@ -907,13 +909,15 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeErrorMsg("weaken", canHack.msg); throw makeRuntimeErrorMsg("weaken", canHack.msg);
} }
var weakenTime = calculateWeakenTime(server, Player); const weakenTime = calculateWeakenTime(server, Player);
workerScript.log("weaken", `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(weakenTime*1000, true)} (t=${numeralWrapper.formatThreads(threads)})`); workerScript.log("weaken", `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(weakenTime*1000, true)} (t=${numeralWrapper.formatThreads(threads)})`);
return netscriptDelay(weakenTime * 1000, workerScript).then(function() { return netscriptDelay(weakenTime * 1000, workerScript).then(function() {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);} if (workerScript.env.stopFlag) return Promise.reject(workerScript);
server.weaken(CONSTANTS.ServerWeakenAmount * threads); const host = getServer(workerScript.serverIp);
const coreBonus = 1+(host.cpuCores-1)/16;
server.weaken(CONSTANTS.ServerWeakenAmount * threads * coreBonus);
workerScript.scriptRef.recordWeaken(server.ip, threads); workerScript.scriptRef.recordWeaken(server.ip, threads);
var expGain = calculateHackingExpGain(server, Player) * threads; const expGain = calculateHackingExpGain(server, Player) * threads;
workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`); workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`);
workerScript.scriptRef.onlineExpGained += expGain; workerScript.scriptRef.onlineExpGained += expGain;
Player.gainHackingExp(expGain); Player.gainHackingExp(expGain);
@ -3671,24 +3675,35 @@ function NetscriptFunctions(workerScript) {
dex: member.dex, dex: member.dex,
agi: member.agi, agi: member.agi,
cha: member.cha, cha: member.cha,
hack_exp: member.hack_exp, hack_exp: member.hack_exp,
str_exp: member.str_exp, str_exp: member.str_exp,
def_exp: member.def_exp, def_exp: member.def_exp,
dex_exp: member.dex_exp, dex_exp: member.dex_exp,
agi_exp: member.agi_exp, agi_exp: member.agi_exp,
cha_exp: member.cha_exp, cha_exp: member.cha_exp,
hack_mult: member.hack_mult, hack_mult: member.hack_mult,
str_mult: member.str_mult, str_mult: member.str_mult,
def_mult: member.def_mult, def_mult: member.def_mult,
dex_mult: member.dex_mult, dex_mult: member.dex_mult,
agi_mult: member.agi_mult, agi_mult: member.agi_mult,
cha_mult: member.cha_mult, cha_mult: member.cha_mult,
hack_asc_mult: member.hack_asc_mult,
str_asc_mult: member.str_asc_mult, hack_asc_mult: member.calculateAscensionMult(member.hack_asc_points),
def_asc_mult: member.def_asc_mult, str_asc_mult: member.calculateAscensionMult(member.str_asc_points),
dex_asc_mult: member.dex_asc_mult, def_asc_mult: member.calculateAscensionMult(member.def_asc_points),
agi_asc_mult: member.agi_asc_mult, dex_asc_mult: member.calculateAscensionMult(member.dex_asc_points),
cha_asc_mult: member.cha_asc_mult, agi_asc_mult: member.calculateAscensionMult(member.agi_asc_points),
cha_asc_mult: member.calculateAscensionMult(member.cha_asc_points),
hack_asc_points: member.hack_asc_points,
str_asc_points: member.str_asc_points,
def_asc_points: member.def_asc_points,
dex_asc_points: member.dex_asc_points,
agi_asc_points: member.agi_asc_points,
cha_asc_points: member.cha_asc_points,
upgrades: member.upgrades.slice(), upgrades: member.upgrades.slice(),
augmentations: member.augmentations.slice(), augmentations: member.augmentations.slice(),
} }
@ -4375,9 +4390,9 @@ function NetscriptFunctions(workerScript) {
checkFormulasAccess("basic.hackPercent", 5); checkFormulasAccess("basic.hackPercent", 5);
return calculatePercentMoneyHacked(server, player); return calculatePercentMoneyHacked(server, player);
}, },
growPercent: function(server, threads, player) { growPercent: function(server, threads, player, cores = 1) {
checkFormulasAccess("basic.growPercent", 5); checkFormulasAccess("basic.growPercent", 5);
return calculateServerGrowth(server, threads, player); return calculateServerGrowth(server, threads, player, cores);
}, },
hackTime: function(server, player) { hackTime: function(server, player) {
checkFormulasAccess("basic.hackTime", 5); checkFormulasAccess("basic.hackTime", 5);
@ -4492,17 +4507,19 @@ function NetscriptFunctions(workerScript) {
} else if(Array.isArray(d[1])) { } else if(Array.isArray(d[1])) {
t = [String]; t = [String];
} }
args['--'+d[0]] = t const numDashes = d[0].length > 1 ? 2 : 1;
args['-'.repeat(numDashes)+d[0]] = t
} }
const ret = libarg(args, {argv: workerScript.args}); const ret = libarg(args, {argv: workerScript.args});
for(const d of data) { for(const d of data) {
if(!ret.hasOwnProperty('--'+d[0])) ret[d[0]] = d[1]; if(!ret.hasOwnProperty('--'+d[0]) || !ret.hasOwnProperty('-'+d[0])) ret[d[0]] = d[1];
} }
for(const key of Object.keys(ret)) { for(const key of Object.keys(ret)) {
if(!key.startsWith('--')) continue; if(!key.startsWith('-')) continue;
const value = ret[key]; const value = ret[key];
delete ret[key]; delete ret[key];
ret[key.slice(2)] = value; const numDashes = key.length === 2 ? 1 : 2;
ret[key.slice(numDashes)] = value;
} }
return ret; return ret;
}, },

@ -313,7 +313,8 @@ export function scriptCalculateOfflineProduction(runningScriptObj) {
if (serv == null) {continue;} if (serv == null) {continue;}
const timesGrown = Math.round(0.5 * runningScriptObj.dataMap[ip][2] / runningScriptObj.onlineRunningTime * timePassed); const timesGrown = Math.round(0.5 * runningScriptObj.dataMap[ip][2] / runningScriptObj.onlineRunningTime * timePassed);
runningScriptObj.log(`Called on ${serv.hostname} ${timesGrown} times while offline`); runningScriptObj.log(`Called on ${serv.hostname} ${timesGrown} times while offline`);
const growth = processSingleServerGrowth(serv, timesGrown, Player); const host = AllServers[runningScriptObj.server];
const growth = processSingleServerGrowth(serv, timesGrown, Player, host.cpuCores);
runningScriptObj.log(`'${serv.hostname}' grown by ${numeralWrapper.format(growth * 100 - 100, '0.000000%')} while offline`); runningScriptObj.log(`'${serv.hostname}' grown by ${numeralWrapper.format(growth * 100 - 100, '0.000000%')} while offline`);
} }
} }
@ -333,9 +334,11 @@ export function scriptCalculateOfflineProduction(runningScriptObj) {
if (runningScriptObj.dataMap[ip][3] == 0 || runningScriptObj.dataMap[ip][3] == null) {continue;} if (runningScriptObj.dataMap[ip][3] == 0 || runningScriptObj.dataMap[ip][3] == null) {continue;}
const serv = AllServers[ip]; const serv = AllServers[ip];
if (serv == null) {continue;} if (serv == null) {continue;}
const host = AllServers[runningScriptObj.server];
const timesWeakened = Math.round(0.5 * runningScriptObj.dataMap[ip][3] / runningScriptObj.onlineRunningTime * timePassed); const timesWeakened = Math.round(0.5 * runningScriptObj.dataMap[ip][3] / runningScriptObj.onlineRunningTime * timePassed);
runningScriptObj.log(`Called weaken() on ${serv.hostname} ${timesWeakened} times while offline`); runningScriptObj.log(`Called weaken() on ${serv.hostname} ${timesWeakened} times while offline`);
serv.weaken(CONSTANTS.ServerWeakenAmount * timesWeakened); const coreBonus = 1+(host.cpuCores-1)/16;
serv.weaken(CONSTANTS.ServerWeakenAmount * timesWeakened * coreBonus);
} }
} }
} }

@ -60,8 +60,8 @@ export function numCycleForGrowth(server: Server, growth: number, p: IPlayer): n
} }
//Applied server growth for a single server. Returns the percentage growth //Applied server growth for a single server. Returns the percentage growth
export function processSingleServerGrowth(server: Server, threads: number, p: IPlayer): number { export function processSingleServerGrowth(server: Server, threads: number, p: IPlayer, cores: number = 1): number {
let serverGrowth = calculateServerGrowth(server, threads, p); let serverGrowth = calculateServerGrowth(server, threads, p, cores);
if (serverGrowth < 1) { if (serverGrowth < 1) {
console.warn("serverGrowth calculated to be less than 1"); console.warn("serverGrowth calculated to be less than 1");
serverGrowth = 1; serverGrowth = 1;

@ -3,7 +3,7 @@ import { Server } from "../Server";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
export function calculateServerGrowth(server: Server, threads: number, p: IPlayer): number { export function calculateServerGrowth(server: Server, threads: number, p: IPlayer, cores: number = 1): number {
const numServerGrowthCycles = Math.max(Math.floor(threads), 0); const numServerGrowthCycles = Math.max(Math.floor(threads), 0);
//Get adjusted growth rate, which accounts for server security //Get adjusted growth rate, which accounts for server security
@ -16,5 +16,6 @@ export function calculateServerGrowth(server: Server, threads: number, p: IPlaye
const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate; const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
//Apply serverGrowth for the calculated number of growth cycles //Apply serverGrowth for the calculated number of growth cycles
return Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.hacking_grow_mult); const coreBonus = 1+(cores-1)/16;
return Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.hacking_grow_mult * coreBonus);
} }

@ -98,6 +98,7 @@ import { Money } from "./ui/React/Money";
import autosize from "autosize"; import autosize from "autosize";
import * as JSZip from "jszip"; import * as JSZip from "jszip";
import * as FileSaver from "file-saver"; import * as FileSaver from "file-saver";
import * as libarg from 'arg';
import React from "react"; import React from "react";
@ -2378,28 +2379,18 @@ let Terminal = {
} }
const server = Player.getCurrentServer(); const server = Player.getCurrentServer();
let numThreads = 1;
const args = [];
const scriptName = Terminal.getFilepath(commandArray[1]); const scriptName = Terminal.getFilepath(commandArray[1]);
if (commandArray.length > 2) { const runArgs = {'--tail': Boolean, '-t': Number};
if (commandArray.length >= 4 && commandArray[2] == "-t") { const flags = libarg(runArgs, {permissive: true, argv: commandArray.slice(2)});
numThreads = Math.round(parseFloat(commandArray[3])); const threadFlag = Math.round(parseFloat(flags['-t']));
if (isNaN(numThreads) || numThreads < 1) { const tailFlag = flags['--tail'] === true;
postError("Invalid number of threads specified. Number of threads must be greater than 0"); if(flags['-t'] !== undefined && (threadFlag < 0 || isNaN(threadFlag))) {
return; postError("Invalid number of threads specified. Number of threads must be greater than 0");
} return;
for (let i = 4; i < commandArray.length; ++i) {
args.push(commandArray[i]);
}
} else {
for (let i = 2; i < commandArray.length; ++i) {
args.push(commandArray[i])
}
}
} }
const numThreads = !isNaN(threadFlag) && threadFlag > 0 ? threadFlag : 1;
const args = flags['_'];
// Check if this script is already running // Check if this script is already running
if (findRunningScript(scriptName, args, server) != null) { if (findRunningScript(scriptName, args, server) != null) {
@ -2408,33 +2399,41 @@ let Terminal = {
} }
// Check if the script exists and if it does run it // Check if the script exists and if it does run it
for (var i = 0; i < server.scripts.length; i++) { for (let i = 0; i < server.scripts.length; i++) {
if (server.scripts[i].filename === scriptName) { if (server.scripts[i].filename !== scriptName) {
// Check for admin rights and that there is enough RAM availble to run continue
var script = server.scripts[i];
var ramUsage = script.ramUsage * numThreads;
var ramAvailable = server.maxRam - server.ramUsed;
if (server.hasAdminRights == false) {
post("Need root access to run script");
return;
} else if (ramUsage > ramAvailable){
post("This machine does not have enough RAM to run this script with " +
numThreads + " threads. Script requires " + ramUsage + "GB of RAM");
return;
} else {
// Able to run script
var runningScriptObj = new RunningScript(script, args);
runningScriptObj.threads = numThreads;
if (startWorkerScript(runningScriptObj, server)) {
post(`Running script with ${numThreads} thread(s), pid ${runningScriptObj.pid} and args: ${arrayToString(args)}.`);
} else {
postError(`Failed to start script`);
}
return;
}
} }
// Check for admin rights and that there is enough RAM availble to run
const script = server.scripts[i];
const ramUsage = script.ramUsage * numThreads;
const ramAvailable = server.maxRam - server.ramUsed;
if (!server.hasAdminRights) {
post("Need root access to run script");
return;
}
if (ramUsage > ramAvailable){
post("This machine does not have enough RAM to run this script with " +
numThreads + " threads. Script requires " + ramUsage + "GB of RAM");
return;
}
// Able to run script
const runningScript = new RunningScript(script, args);
runningScript.threads = numThreads;
const success = startWorkerScript(runningScript, server);
if (!success) {
postError(`Failed to start script`);
return
}
post(`Running script with ${numThreads} thread(s), pid ${runningScript.pid} and args: ${arrayToString(args)}.`);
if(tailFlag) {
logBoxCreate(runningScript)
}
return;
} }
post("ERROR: No such script"); post("ERROR: No such script");