mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-22 06:02:26 +01:00
Added recent scripts subpage of active scripts
This commit is contained in:
parent
6d39fda3fa
commit
c34d53bc14
36
dist/vendor.bundle.js
vendored
36
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
27
src/Netscript/RecentScripts.ts
Normal file
27
src/Netscript/RecentScripts.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { RunningScript } from "src/Script/RunningScript";
|
||||
import { WorkerScript } from "./WorkerScript";
|
||||
|
||||
export const recentScripts: RecentScript[] = [];
|
||||
|
||||
export function AddRecentScript(workerScript: WorkerScript): void {
|
||||
if (recentScripts.find((r) => r.pid === workerScript.pid)) return;
|
||||
recentScripts.push({
|
||||
filename: workerScript.name,
|
||||
args: workerScript.args,
|
||||
pid: workerScript.pid,
|
||||
timestamp: new Date(),
|
||||
|
||||
runningScript: workerScript.scriptRef,
|
||||
});
|
||||
while (recentScripts.length > 50) {
|
||||
recentScripts.pop();
|
||||
}
|
||||
}
|
||||
|
||||
export interface RecentScript {
|
||||
filename: string;
|
||||
args: string[];
|
||||
pid: number;
|
||||
timestamp: Date;
|
||||
runningScript: RunningScript;
|
||||
}
|
@ -11,6 +11,7 @@ import { GetServer } from "../Server/AllServers";
|
||||
|
||||
import { compareArrays } from "../utils/helpers/compareArrays";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { AddRecentScript } from "./RecentScripts";
|
||||
|
||||
export function killWorkerScript(runningScriptObj: RunningScript, hostname: string, rerenderUi?: boolean): boolean;
|
||||
export function killWorkerScript(workerScript: WorkerScript): boolean;
|
||||
@ -85,49 +86,44 @@ function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi = tru
|
||||
* Helper function that removes the script being killed from the global pool.
|
||||
* Also handles other cleanup-time operations
|
||||
*
|
||||
* @param {WorkerScript | number} - Identifier for WorkerScript. Either the object itself, or
|
||||
* @param {WorkerScript} - Identifier for WorkerScript. Either the object itself, or
|
||||
* its index in the global workerScripts array
|
||||
*/
|
||||
function removeWorkerScript(workerScript: WorkerScript, rerenderUi = true): void {
|
||||
if (workerScript instanceof WorkerScript) {
|
||||
const ip = workerScript.hostname;
|
||||
const name = workerScript.name;
|
||||
const ip = workerScript.hostname;
|
||||
const name = workerScript.name;
|
||||
|
||||
// Get the server on which the script runs
|
||||
const server = GetServer(ip);
|
||||
if (server == null) {
|
||||
console.error(`Could not find server on which this script is running: ${ip}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the RunningScript object from that server
|
||||
for (let i = 0; i < server.runningScripts.length; ++i) {
|
||||
const runningScript = server.runningScripts[i];
|
||||
if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) {
|
||||
server.runningScripts.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate ram used on that server
|
||||
server.ramUsed = 0;
|
||||
for (const rs of server.runningScripts) server.ramUsed += rs.ramUsage * rs.threads;
|
||||
|
||||
// Delete script from global pool (workerScripts)
|
||||
const res = workerScripts.delete(workerScript.pid);
|
||||
if (!res) {
|
||||
console.warn(`removeWorkerScript() called with WorkerScript that wasn't in the global map:`);
|
||||
console.warn(workerScript);
|
||||
}
|
||||
|
||||
if (rerenderUi) {
|
||||
WorkerScriptStartStopEventEmitter.emit();
|
||||
}
|
||||
} else {
|
||||
console.error(`Invalid argument passed into removeWorkerScript():`);
|
||||
console.error(workerScript);
|
||||
// Get the server on which the script runs
|
||||
const server = GetServer(ip);
|
||||
if (server == null) {
|
||||
console.error(`Could not find server on which this script is running: ${ip}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the RunningScript object from that server
|
||||
for (let i = 0; i < server.runningScripts.length; ++i) {
|
||||
const runningScript = server.runningScripts[i];
|
||||
if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) {
|
||||
server.runningScripts.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate ram used on that server
|
||||
server.ramUsed = 0;
|
||||
for (const rs of server.runningScripts) server.ramUsed += rs.ramUsage * rs.threads;
|
||||
|
||||
// Delete script from global pool (workerScripts)
|
||||
const res = workerScripts.delete(workerScript.pid);
|
||||
if (!res) {
|
||||
console.warn(`removeWorkerScript() called with WorkerScript that wasn't in the global map:`);
|
||||
console.warn(workerScript);
|
||||
}
|
||||
AddRecentScript(workerScript);
|
||||
|
||||
if (rerenderUi) {
|
||||
WorkerScriptStartStopEventEmitter.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
31
src/ui/ActiveScripts/ActiveScriptsPage.tsx
Normal file
31
src/ui/ActiveScripts/ActiveScriptsPage.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Root React Component for the "Active Scripts" UI page. This page displays
|
||||
* and provides information about all of the player's scripts that are currently running
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import { ScriptProduction } from "./ScriptProduction";
|
||||
import { ServerAccordions } from "./ServerAccordions";
|
||||
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
interface IProps {
|
||||
workerScripts: Map<number, WorkerScript>;
|
||||
}
|
||||
|
||||
export function ActiveScriptsPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<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.
|
||||
</Typography>
|
||||
|
||||
<ScriptProduction />
|
||||
<ServerAccordions {...props} />
|
||||
</>
|
||||
);
|
||||
}
|
@ -3,17 +3,16 @@
|
||||
* and provides information about all of the player's scripts that are currently running
|
||||
*/
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Tabs from "@mui/material/Tabs";
|
||||
import Tab from "@mui/material/Tab";
|
||||
|
||||
import { ScriptProduction } from "./ScriptProduction";
|
||||
import { ServerAccordions } from "./ServerAccordions";
|
||||
|
||||
import { ActiveScriptsPage } from "./ActiveScriptsPage";
|
||||
import { RecentScriptsPage } from "./RecentScriptsPage";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
type IProps = {
|
||||
interface IProps {
|
||||
workerScripts: Map<number, WorkerScript>;
|
||||
};
|
||||
}
|
||||
|
||||
export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
@ -26,17 +25,19 @@ export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const [tab, setTab] = useState<"active" | "recent">("active");
|
||||
function handleChange(event: React.SyntheticEvent, tab: "active" | "recent"): void {
|
||||
setTab(tab);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">Active Scripts</Typography>
|
||||
<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.
|
||||
</Typography>
|
||||
<Tabs variant="fullWidth" value={tab} onChange={handleChange}>
|
||||
<Tab label={"Active"} value={"active"} />
|
||||
<Tab label={"Recent"} value={"recent"} />
|
||||
</Tabs>
|
||||
|
||||
<ScriptProduction />
|
||||
<ServerAccordions {...props} />
|
||||
{tab === "active" && <ActiveScriptsPage workerScripts={props.workerScripts} />}
|
||||
{tab === "recent" && <RecentScriptsPage />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
165
src/ui/ActiveScripts/RecentScriptAccordion.tsx
Normal file
165
src/ui/ActiveScripts/RecentScriptAccordion.tsx
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* React Component for displaying a single WorkerScript's info as an
|
||||
* Accordion element
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { numeralWrapper } from "../numeralFormat";
|
||||
|
||||
import Table from "@mui/material/Table";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import Box from "@mui/material/Box";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
|
||||
import Collapse from "@mui/material/Collapse";
|
||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||
|
||||
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
|
||||
import { arrayToString } from "../../utils/helpers/arrayToString";
|
||||
import { Money } from "../React/Money";
|
||||
import { MoneyRate } from "../React/MoneyRate";
|
||||
import { RecentScript } from "../..//Netscript/RecentScripts";
|
||||
import { LogBoxEvents } from "../React/LogBoxManager";
|
||||
|
||||
const useStyles = makeStyles({
|
||||
noborder: {
|
||||
borderBottom: "none",
|
||||
},
|
||||
});
|
||||
|
||||
interface IProps {
|
||||
recentScript: RecentScript;
|
||||
}
|
||||
|
||||
export function RecentScriptAccordion(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const recentScript = props.recentScript;
|
||||
|
||||
// Calculations for script stats
|
||||
const onlineMps = recentScript.runningScript.onlineMoneyMade / recentScript.runningScript.onlineRunningTime;
|
||||
const onlineEps = recentScript.runningScript.onlineExpGained / recentScript.runningScript.onlineRunningTime;
|
||||
|
||||
function logClickHandler(): void {
|
||||
LogBoxEvents.emit(recentScript.runningScript);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)} component={Paper}>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography>
|
||||
└ {recentScript.filename} (died{" "}
|
||||
{convertTimeMsToTimeElapsedString(new Date().getTime() - recentScript.timestamp.getTime())} ago)
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} timeout={0} unmountOnExit>
|
||||
<Box mx={6}>
|
||||
<Table padding="none" size="small">
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Threads:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>{numeralWrapper.formatThreads(recentScript.runningScript.threads)}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder} colSpan={2}>
|
||||
<Typography>└ Args: {arrayToString(recentScript.args)}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Online Time:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>
|
||||
{convertTimeMsToTimeElapsedString(recentScript.runningScript.onlineRunningTime * 1e3)}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Offline Time:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>
|
||||
{convertTimeMsToTimeElapsedString(recentScript.runningScript.offlineRunningTime * 1e3)}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Total online production:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography>
|
||||
<Money money={recentScript.runningScript.onlineMoneyMade} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder} colSpan={1} />
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography>
|
||||
{numeralWrapper.formatExp(recentScript.runningScript.onlineExpGained) + " hacking exp"}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Online production rate:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography>
|
||||
<MoneyRate money={onlineMps} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder} colSpan={1} />
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography> {numeralWrapper.formatExp(onlineEps) + " hacking exp / sec"}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder}>
|
||||
<Typography>└ Total offline production:</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography>
|
||||
<Money money={recentScript.runningScript.offlineMoneyMade} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className={classes.noborder} colSpan={1} />
|
||||
<TableCell className={classes.noborder} align="left">
|
||||
<Typography>
|
||||
{numeralWrapper.formatExp(recentScript.runningScript.offlineExpGained) + " hacking exp"}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Button onClick={logClickHandler}>LOG</Button>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</>
|
||||
);
|
||||
}
|
20
src/ui/ActiveScripts/RecentScriptsPage.tsx
Normal file
20
src/ui/ActiveScripts/RecentScriptsPage.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Root React Component for the "Active Scripts" UI page. This page displays
|
||||
* and provides information about all of the player's scripts that are currently running
|
||||
*/
|
||||
import React from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
import { recentScripts } from "../../Netscript/RecentScripts";
|
||||
import { RecentScriptAccordion } from "./RecentScriptAccordion";
|
||||
|
||||
export function RecentScriptsPage(): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Typography>List of all recently killed scripts.</Typography>
|
||||
{recentScripts.map((r) => (
|
||||
<RecentScriptAccordion key={r.pid} recentScript={r} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user