mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-21 08:42:53 +02:00
Finished refactoring Active Scripts UI into React/TypeScript. Currently untested
This commit is contained in:
@@ -4,9 +4,14 @@
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { ScriptProduction } from "./ScriptProduction";
|
||||
import { ServerAccordions } from "./ServerAccordions";
|
||||
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
workerScripts: WorkerScript[];
|
||||
}
|
||||
|
||||
@@ -25,6 +30,8 @@ export class ActiveScriptsRoot extends React.Component<IProps, any> {
|
||||
the servers on which they are running.
|
||||
</p>
|
||||
|
||||
<ScriptProduction {...this.props} />
|
||||
<ServerAccordions {...this.props} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* React Component for displaying the total production and production rate
|
||||
* of scripts on the 'Active Scripts' UI page
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { numeralWrapper } from "../numeralFormat";
|
||||
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
workerScripts: WorkerScript[];
|
||||
}
|
||||
|
||||
export function ScriptProduction(props: IProps): React.ReactElement {
|
||||
const prodRateSinceLastAug = props.p.scriptProdSinceLastAug / (props.p.playtimeSinceLastAug / 1000);
|
||||
|
||||
let onlineProduction = 0;
|
||||
for (const ws of props.workerScripts) {
|
||||
onlineProduction += (ws.scriptRef.onlineMoneyMade / ws.scriptRef.onlineRunningTime);
|
||||
}
|
||||
|
||||
return (
|
||||
<p id="active-scripts-total-prod">
|
||||
Total online production of Active scripts:
|
||||
<span className="money-gold">
|
||||
<span id="active-scripts-total-production-active">
|
||||
{numeralWrapper.formatMoney(onlineProduction)}
|
||||
</span> / sec
|
||||
</span><br />
|
||||
|
||||
Total online production since last Aug installation:
|
||||
<span id="active-scripts-total-prod-aug-total" className="money-gold">
|
||||
{numeralWrapper.formatMoney(props.p.scriptProdSinceLastAug)}
|
||||
</span>
|
||||
(<span className="money-gold">
|
||||
<span id="active-scripts-total-prod-aug-avg" className="money-gold">
|
||||
{numeralWrapper.formatMoney(prodRateSinceLastAug)}
|
||||
</span> / sec
|
||||
</span>)
|
||||
</p>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* React Component for rendering the Accordion element for a single
|
||||
* server in the 'Active Scripts' UI page
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { WorkerScriptAccordion } from "./WorkerScriptAccordion";
|
||||
import { Accordion } from "../React/Accordion";
|
||||
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
|
||||
type IProps = {
|
||||
server: BaseServer;
|
||||
workerScripts: WorkerScript[];
|
||||
}
|
||||
|
||||
export function ServerAccordion(props: IProps): React.ReactElement {
|
||||
const server = props.server;
|
||||
|
||||
// Accordion's header text
|
||||
// TODO: calculate the longest hostname length rather than hard coding it
|
||||
const longestHostnameLength = 18;
|
||||
const paddedName = `${server.hostname}${" ".repeat(longestHostnameLength)}`.slice(0, Math.max(server.hostname.length, longestHostnameLength));
|
||||
const barOptions = {
|
||||
progress: server.ramUsed / server.maxRam,
|
||||
totalTicks: 30
|
||||
};
|
||||
const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`.replace(/\s/g, ' ');
|
||||
|
||||
const scripts = props.workerScripts.map((ws) => {
|
||||
return (
|
||||
<WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />
|
||||
)
|
||||
});
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
headerContent={
|
||||
<p>{headerTxt}</p>
|
||||
}
|
||||
panelContent={
|
||||
<ul>{scripts}</ul>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* React Component for rendering the Accordion elements for all servers
|
||||
* on which scripts are running
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { ServerAccordion } from "./ServerAccordion";
|
||||
|
||||
import { getServer } from "../../Server/ServerHelpers";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
|
||||
// Map of server hostname -> all workerscripts on that server for all active scripts
|
||||
interface IServerData {
|
||||
server: BaseServer;
|
||||
workerScripts: WorkerScript[];
|
||||
}
|
||||
|
||||
interface IServerToScriptsMap {
|
||||
[key: string]: IServerData;
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
workerScripts: WorkerScript[];
|
||||
};
|
||||
|
||||
export class ServerAccordions extends React.Component<IProps> {
|
||||
serverToScriptMap: IServerToScriptsMap = {};
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.updateServerToScriptsMap();
|
||||
|
||||
// TODO
|
||||
// We subscribe to an event emitter that publishes whenever a script is
|
||||
// started/stopped. This allows us to only update the map when necessary
|
||||
}
|
||||
|
||||
updateServerToScriptsMap(): void {
|
||||
const map: IServerToScriptsMap = {};
|
||||
|
||||
for (const ws of this.props.workerScripts) {
|
||||
const server = getServer(ws.serverIp);
|
||||
if (server == null) {
|
||||
console.warn(`WorkerScript has invalid IP address: ${ws.serverIp}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map[server.hostname] == null) {
|
||||
map[server.hostname] = {
|
||||
server: server,
|
||||
workerScripts: [],
|
||||
};
|
||||
}
|
||||
|
||||
map[server.hostname].workerScripts.push(ws);
|
||||
}
|
||||
|
||||
this.serverToScriptMap = map;
|
||||
}
|
||||
|
||||
render() {
|
||||
const elems = Object.keys(this.serverToScriptMap).map((serverName) => {
|
||||
const data = this.serverToScriptMap[serverName];
|
||||
return (
|
||||
<ServerAccordion
|
||||
key={serverName}
|
||||
server={data.server}
|
||||
workerScripts={data.workerScripts}
|
||||
/>
|
||||
)
|
||||
});
|
||||
|
||||
return (
|
||||
<ul className="active-scripts-list" id="active-scripts-list">
|
||||
{elems}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,16 @@
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { Accordion } from "../React/Accordion";
|
||||
import { numeralWrapper } from "../numeralFormat";
|
||||
|
||||
import { Accordion } from "../React/Accordion";
|
||||
import { AccordionButton } from "../React/AccordionButton";
|
||||
|
||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
|
||||
import { logBoxCreate } from "../../../utils/LogBox";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { arrayToString } from "../../../utils/helpers/arrayToString";
|
||||
|
||||
type IProps = {
|
||||
@@ -15,7 +21,17 @@ type IProps = {
|
||||
}
|
||||
|
||||
export function WorkerScriptAccordion(props: IProps): React.ReactElement {
|
||||
const workerScript = props.workerScript;
|
||||
const scriptRef = workerScript.scriptRef;
|
||||
|
||||
const logClickHandler = logBoxCreate.bind(null, scriptRef);
|
||||
const killScriptButton = killWorkerScript.bind(null, scriptRef, scriptRef.server);
|
||||
|
||||
// Calculations for script stats
|
||||
const onlineMps = scriptRef.onlineMoneyMade / scriptRef.onlineRunningTime;
|
||||
const onlineEps = scriptRef.onlineExpGained / scriptRef.onlineRunningTime;
|
||||
const offlineMps = scriptRef.offlineMoneyMade / scriptRef.offlineRunningTime;
|
||||
const offlineEps = scriptRef.offlineExpGained / scriptRef.offlineRunningTime;
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
@@ -27,12 +43,27 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement {
|
||||
panelClass="active-scripts-script-panel"
|
||||
panelContent={
|
||||
<>
|
||||
<p>
|
||||
Threads: {props.workerScript.scriptRef.threads}
|
||||
</p>
|
||||
<p>
|
||||
Args: {arrayToString(props.workerScript.args)}
|
||||
</p>
|
||||
<p>Threads: {props.workerScript.scriptRef.threads}</p>
|
||||
<p>Args: {arrayToString(props.workerScript.args)}</p>
|
||||
<p>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</p>
|
||||
<p>Offline Time: {convertTimeMsToTimeElapsedString(scriptRef.offlineRunningTime * 1e3)}</p>
|
||||
<p>Total online production: {numeralWrapper.formatMoney(scriptRef.onlineMoneyMade)}</p>
|
||||
<p>{(Array(26).join(" ") + numeralWrapper.formatBigNumber(scriptRef.onlineExpGained) + " hacking exp").replace( / /g, " ")}</p>
|
||||
<p>Online production rate: {numeralWrapper.formatMoney(onlineMps)} / second</p>
|
||||
<p>{(Array(25).join(" ") + numeralWrapper.formatBigNumber(onlineEps) + " hacking exp / second").replace( / /g, " ")}</p>
|
||||
<p>Total offline production: {numeralWrapper.formatMoney(scriptRef.offlineMoneyMade)}</p>
|
||||
<p>{(Array(27).join(" ") + numeralWrapper.formatBigNumber(scriptRef.offlineExpGained) + " hacking exp").replace( / /g, " ")}</p>
|
||||
<p>Offline production rate: {numeralWrapper.formatMoney(offlineMps)} / second</p>
|
||||
<p>{(Array(26).join(" ") + numeralWrapper.formatBigNumber(offlineEps) + " hacking exp / second").replace( / /g, " ")}</p>
|
||||
|
||||
<AccordionButton
|
||||
onClick={logClickHandler}
|
||||
text="Log"
|
||||
/>
|
||||
<AccordionButton
|
||||
onClick={killScriptButton}
|
||||
text="Kill Script"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user