more work

This commit is contained in:
Olivier Gagnon
2021-09-17 21:30:02 -04:00
parent 45f2f85a30
commit 907314e76b
33 changed files with 234 additions and 325 deletions
+6 -6
View File
@@ -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>
</>
);
}
+55 -25
View File
@@ -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:&nbsp;
<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:&nbsp;
<span id="active-scripts-total-prod-aug-total" className="money-gold">
<Money money={props.p.scriptProdSinceLastAug} />
</span>
&nbsp;(
<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>
);
}
+15 -5
View File
@@ -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 {
+35 -60
View File
@@ -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>
);
}
+41 -32
View File
@@ -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>
);
}