mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-25 18:50:56 +02:00
more work
This commit is contained in:
@@ -8,10 +8,10 @@ import { ScriptProduction } from "./ScriptProduction";
|
||||
import { ServerAccordions } from "./ServerAccordions";
|
||||
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
workerScripts: Map<number, WorkerScript>;
|
||||
};
|
||||
|
||||
@@ -27,15 +27,15 @@ export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="active-scripts-container">
|
||||
<p>
|
||||
<>
|
||||
<Typography>
|
||||
This page displays a list of all of your scripts that are currently running across every machine. It also
|
||||
provides information about each script's production. The scripts are categorized by the hostname of the servers
|
||||
on which they are running.
|
||||
</p>
|
||||
</Typography>
|
||||
|
||||
<ScriptProduction {...props} />
|
||||
<ServerAccordions {...props} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,16 +5,44 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Money } from "../React/Money";
|
||||
import { MoneyRate } from "../React/MoneyRate";
|
||||
import { use } from "../Context";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
workerScripts: Map<number, WorkerScript>;
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
cell: {
|
||||
borderBottom: "none",
|
||||
padding: theme.spacing(1),
|
||||
margin: theme.spacing(1),
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
size: {
|
||||
width: "1px",
|
||||
},
|
||||
}),
|
||||
);
|
||||
export function ScriptProduction(props: IProps): React.ReactElement {
|
||||
const prodRateSinceLastAug = props.p.scriptProdSinceLastAug / (props.p.playtimeSinceLastAug / 1000);
|
||||
const player = use.Player();
|
||||
const classes = useStyles();
|
||||
const prodRateSinceLastAug = player.scriptProdSinceLastAug / (player.playtimeSinceLastAug / 1000);
|
||||
|
||||
let onlineProduction = 0;
|
||||
for (const ws of props.workerScripts.values()) {
|
||||
@@ -22,27 +50,29 @@ export function ScriptProduction(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<p id="active-scripts-total-prod">
|
||||
Total online production of Active scripts:
|
||||
<span className="money-gold">
|
||||
<span id="active-scripts-total-production-active">
|
||||
<Money money={onlineProduction} />
|
||||
</span>{" "}
|
||||
/ sec
|
||||
</span>
|
||||
<br />
|
||||
Total online production since last Aug installation:
|
||||
<span id="active-scripts-total-prod-aug-total" className="money-gold">
|
||||
<Money money={props.p.scriptProdSinceLastAug} />
|
||||
</span>
|
||||
(
|
||||
<span className="money-gold">
|
||||
<span id="active-scripts-total-prod-aug-avg" className="money-gold">
|
||||
<Money money={prodRateSinceLastAug} />
|
||||
</span>{" "}
|
||||
/ sec
|
||||
</span>
|
||||
)
|
||||
</p>
|
||||
<Table size="small" classes={{ root: classes.size }}>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
|
||||
<Typography variant="body2">Total online production of Active scripts:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left" classes={{ root: classes.cell }}>
|
||||
<Typography variant="body2">
|
||||
<Money money={player.scriptProdSinceLastAug} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow style={{ width: "1px" }}>
|
||||
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
|
||||
<Typography variant="body2">Total online production since last Aug installation:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left" classes={{ root: classes.cell }}>
|
||||
<Typography variant="body2">
|
||||
(<MoneyRate money={prodRateSinceLastAug} />)
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { BBAccordion } from "../React/BBAccordion";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Accordion from "@mui/material/Accordion";
|
||||
import AccordionSummary from "@mui/material/AccordionSummary";
|
||||
import AccordionDetails from "@mui/material/AccordionDetails";
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import { ServerAccordionContent } from "./ServerAccordionContent";
|
||||
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
@@ -34,9 +38,15 @@ export function ServerAccordion(props: IProps): React.ReactElement {
|
||||
const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`;
|
||||
|
||||
return (
|
||||
<BBAccordion
|
||||
headerContent={<pre>{headerTxt}</pre>}
|
||||
panelContent={<ServerAccordionContent workerScripts={props.workerScripts} />}
|
||||
/>
|
||||
<Accordion TransitionProps={{ unmountOnExit: true }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography style={{ whiteSpace: "pre-wrap" }} color="primary">
|
||||
{headerTxt}
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<ServerAccordionContent workerScripts={props.workerScripts} />
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ export function ServerAccordionContent(props: IProps): React.ReactElement {
|
||||
return <ServerAccordionContentPaginated workerScripts={props.workerScripts} />;
|
||||
}
|
||||
|
||||
const scripts = props.workerScripts.map((ws) => {
|
||||
return <WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />;
|
||||
});
|
||||
|
||||
return <ul>{scripts}</ul>;
|
||||
return (
|
||||
<ul>
|
||||
{props.workerScripts.map((ws) => {
|
||||
return <WorkerScriptAccordion key={`${ws.name}_${ws.args}`} workerScript={ws} />;
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
export function ServerAccordionContentPaginated(props: IProps): React.ReactElement {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* React Component for rendering the Accordion elements for all servers
|
||||
* on which scripts are running
|
||||
*/
|
||||
import * as React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import { ServerAccordion } from "./ServerAccordion";
|
||||
|
||||
@@ -18,7 +18,7 @@ interface IServerData {
|
||||
}
|
||||
|
||||
interface IServerToScriptsMap {
|
||||
[key: string]: IServerData;
|
||||
[key: string]: IServerData | undefined;
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
@@ -31,72 +31,47 @@ type IState = {
|
||||
|
||||
const subscriberId = "ActiveScriptsUI";
|
||||
|
||||
export class ServerAccordions extends React.Component<IProps, IState> {
|
||||
serverToScriptMap: IServerToScriptsMap = {};
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
rerenderFlag: false,
|
||||
};
|
||||
|
||||
this.updateServerToScriptsMap();
|
||||
|
||||
this.rerender = this.rerender.bind(this);
|
||||
export function ServerAccordions(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
useEffect(() => {
|
||||
WorkerScriptStartStopEventEmitter.addSubscriber({
|
||||
cb: this.rerender,
|
||||
cb: rerender,
|
||||
id: subscriberId,
|
||||
});
|
||||
}
|
||||
return () => WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId);
|
||||
}, []);
|
||||
|
||||
componentWillUnmount(): void {
|
||||
WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId);
|
||||
}
|
||||
|
||||
updateServerToScriptsMap(): void {
|
||||
const map: IServerToScriptsMap = {};
|
||||
|
||||
for (const ws of this.props.workerScripts.values()) {
|
||||
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);
|
||||
const serverToScriptMap: IServerToScriptsMap = {};
|
||||
for (const ws of props.workerScripts.values()) {
|
||||
const server = getServer(ws.serverIp);
|
||||
if (server == null) {
|
||||
console.warn(`WorkerScript has invalid IP address: ${ws.serverIp}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.serverToScriptMap = map;
|
||||
let data = serverToScriptMap[server.hostname];
|
||||
|
||||
if (data === undefined) {
|
||||
serverToScriptMap[server.hostname] = {
|
||||
server: server,
|
||||
workerScripts: [],
|
||||
};
|
||||
data = serverToScriptMap[server.hostname];
|
||||
}
|
||||
if (data !== undefined) data.workerScripts.push(ws);
|
||||
}
|
||||
|
||||
rerender(): void {
|
||||
this.updateServerToScriptsMap();
|
||||
this.setState((prevState) => {
|
||||
return { rerenderFlag: !prevState.rerenderFlag };
|
||||
});
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
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>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ul className="active-scripts-list" id="active-scripts-list">
|
||||
{Object.values(serverToScriptMap).map((data) => {
|
||||
return (
|
||||
data && <ServerAccordion key={data.server.hostname} server={data.server} workerScripts={data.workerScripts} />
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,15 @@ import * as React from "react";
|
||||
|
||||
import { numeralWrapper } from "../numeralFormat";
|
||||
|
||||
import { BBAccordion } from "../React/BBAccordion";
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Accordion from "@mui/material/Accordion";
|
||||
import AccordionSummary from "@mui/material/AccordionSummary";
|
||||
import AccordionDetails from "@mui/material/AccordionDetails";
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import { AccordionButton } from "../React/AccordionButton";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
|
||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
@@ -41,37 +48,39 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement {
|
||||
const offlineEps = scriptRef.offlineExpGained / scriptRef.offlineRunningTime;
|
||||
|
||||
return (
|
||||
<BBAccordion
|
||||
headerClass="active-scripts-script-header"
|
||||
headerContent={<>{props.workerScript.name}</>}
|
||||
panelClass="active-scripts-script-panel"
|
||||
panelContent={
|
||||
<>
|
||||
<pre>Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}</pre>
|
||||
<pre>Args: {arrayToString(props.workerScript.args)}</pre>
|
||||
<pre>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</pre>
|
||||
<pre>Offline Time: {convertTimeMsToTimeElapsedString(scriptRef.offlineRunningTime * 1e3)}</pre>
|
||||
<pre>
|
||||
Total online production: <Money money={scriptRef.onlineMoneyMade} />
|
||||
</pre>
|
||||
<pre>{Array(26).join(" ") + numeralWrapper.formatExp(scriptRef.onlineExpGained) + " hacking exp"}</pre>
|
||||
<pre>
|
||||
Online production rate: <Money money={onlineMps} /> / second
|
||||
</pre>
|
||||
<pre>{Array(25).join(" ") + numeralWrapper.formatExp(onlineEps) + " hacking exp / second"}</pre>
|
||||
<pre>
|
||||
Total offline production: <Money money={scriptRef.offlineMoneyMade} />
|
||||
</pre>
|
||||
<pre>{Array(27).join(" ") + numeralWrapper.formatExp(scriptRef.offlineExpGained) + " hacking exp"}</pre>
|
||||
<pre>
|
||||
Offline production rate: <Money money={offlineMps} /> / second
|
||||
</pre>
|
||||
<pre>{Array(26).join(" ") + numeralWrapper.formatExp(offlineEps) + " hacking exp / second"}</pre>
|
||||
<Accordion TransitionProps={{ unmountOnExit: true }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography color="primary">{props.workerScript.name}</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<pre>Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}</pre>
|
||||
<pre>Args: {arrayToString(props.workerScript.args)}</pre>
|
||||
<pre>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</pre>
|
||||
<pre>Offline Time: {convertTimeMsToTimeElapsedString(scriptRef.offlineRunningTime * 1e3)}</pre>
|
||||
<pre>
|
||||
Total online production: <Money money={scriptRef.onlineMoneyMade} />
|
||||
</pre>
|
||||
<pre>{Array(26).join(" ") + numeralWrapper.formatExp(scriptRef.onlineExpGained) + " hacking exp"}</pre>
|
||||
<pre>
|
||||
Online production rate: <Money money={onlineMps} /> / second
|
||||
</pre>
|
||||
<pre>{Array(25).join(" ") + numeralWrapper.formatExp(onlineEps) + " hacking exp / second"}</pre>
|
||||
<pre>
|
||||
Total offline production: <Money money={scriptRef.offlineMoneyMade} />
|
||||
</pre>
|
||||
<pre>{Array(27).join(" ") + numeralWrapper.formatExp(scriptRef.offlineExpGained) + " hacking exp"}</pre>
|
||||
<pre>
|
||||
Offline production rate: <Money money={offlineMps} /> / second
|
||||
</pre>
|
||||
<pre>{Array(26).join(" ") + numeralWrapper.formatExp(offlineEps) + " hacking exp / second"}</pre>
|
||||
|
||||
<AccordionButton onClick={logClickHandler} text="Log" />
|
||||
<AccordionButton onClick={killScriptClickHandler} text="Kill Script" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Button onClick={logClickHandler}>
|
||||
<Typography>Log</Typography>
|
||||
</Button>
|
||||
<IconButton onClick={killScriptClickHandler}>
|
||||
<DeleteIcon color="error" />
|
||||
</IconButton>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user