diff --git a/src/DarkWeb/DarkWeb.tsx b/src/DarkWeb/DarkWeb.tsx
index ad3ccac47..8b4c5b79a 100644
--- a/src/DarkWeb/DarkWeb.tsx
+++ b/src/DarkWeb/DarkWeb.tsx
@@ -1,9 +1,10 @@
+import React from "react";
import { DarkWebItems } from "./DarkWebItems";
import { Player } from "../Player";
import { Terminal } from "../Terminal";
import { SpecialServers } from "../Server/data/SpecialServers";
-import { numeralWrapper } from "../ui/numeralFormat";
+import { Money } from "../ui/React/Money";
//Posts a "help" message if connected to DarkWeb
export function checkIfConnectedToDarkweb(): void {
@@ -20,7 +21,11 @@ export function checkIfConnectedToDarkweb(): void {
export function listAllDarkwebItems(): void {
for (const key in DarkWebItems) {
const item = DarkWebItems[key];
- Terminal.print(`${item.program} - ${numeralWrapper.formatMoney(item.price)} - ${item.description}`);
+ Terminal.printRaw(
+ <>
+ {item.program} - - {item.description}`
+ >,
+ );
}
}
@@ -38,7 +43,7 @@ export function buyDarkwebItem(itemName: string): void {
// return if invalid
if (item === null) {
- Terminal.print("Unrecognized item: " + itemName);
+ Terminal.error("Unrecognized item: " + itemName);
return;
}
@@ -50,7 +55,7 @@ export function buyDarkwebItem(itemName: string): void {
// return if the player doesn't have enough money
if (Player.money.lt(item.price)) {
- Terminal.print("Not enough money to purchase " + item.program);
+ Terminal.error("Not enough money to purchase " + item.program);
return;
}
diff --git a/src/Programs/data/ProgramsMetadata.ts b/src/Programs/data/ProgramsMetadata.ts
index 436038710..e0e9c34f1 100644
--- a/src/Programs/data/ProgramsMetadata.ts
+++ b/src/Programs/data/ProgramsMetadata.ts
@@ -190,7 +190,7 @@ export const programsMetadata: IProgramCreationParams[] = [
time: CONSTANTS.MillisecondsPerQuarterHour,
},
run: (router: IRouter, terminal: ITerminal): void => {
- terminal.print("This executable cannot be run.");
+ terminal.error("This executable cannot be run.");
terminal.print("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5.");
},
},
@@ -204,7 +204,7 @@ export const programsMetadata: IProgramCreationParams[] = [
time: CONSTANTS.MillisecondsPer2Hours,
},
run: (router: IRouter, terminal: ITerminal): void => {
- terminal.print("This executable cannot be run.");
+ terminal.error("This executable cannot be run.");
terminal.print("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
},
},
@@ -219,18 +219,18 @@ export const programsMetadata: IProgramCreationParams[] = [
},
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]): void => {
if (args.length !== 1) {
- terminal.print("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
+ terminal.error("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
return;
}
const targetServer = GetServer(args[0]);
if (targetServer == null) {
- terminal.print("Invalid server IP/hostname");
+ terminal.error("Invalid server IP/hostname");
return;
}
if (!(targetServer instanceof Server)) {
- terminal.print(`ServerProfiler.exe can only be run on normal servers.`);
+ terminal.error(`ServerProfiler.exe can only be run on normal servers.`);
return;
}
@@ -268,7 +268,7 @@ export const programsMetadata: IProgramCreationParams[] = [
time: CONSTANTS.MillisecondsPerQuarterHour,
},
run: (router: IRouter, terminal: ITerminal): void => {
- terminal.print("This executable cannot be run.");
+ terminal.error("This executable cannot be run.");
terminal.print("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'.");
terminal.print("When using scan-analyze, click on a server's hostname to connect to it.");
},
diff --git a/src/Terminal/ITerminal.ts b/src/Terminal/ITerminal.ts
index 0971d6d22..f482af52c 100644
--- a/src/Terminal/ITerminal.ts
+++ b/src/Terminal/ITerminal.ts
@@ -1,3 +1,4 @@
+import React from "react";
import { TextFile } from "../TextFile";
import { Script } from "../Script/Script";
import { IPlayer } from "../PersonObjects/IPlayer";
@@ -18,6 +19,13 @@ export class Output {
}
}
+export class RawOutput {
+ raw: React.ReactNode;
+ constructor(node: React.ReactNode) {
+ this.raw = node;
+ }
+}
+
export class Link {
hostname: string;
dashes: string;
@@ -46,7 +54,7 @@ export interface ITerminal {
commandHistory: string[];
commandHistoryIndex: number;
- outputHistory: (Output | Link)[];
+ outputHistory: (Output | Link | RawOutput)[];
// True if a Coding Contract prompt is opened
contractOpen: boolean;
@@ -56,6 +64,7 @@ export interface ITerminal {
currDir: string;
print(s: string): void;
+ printRaw(node: React.ReactNode): void;
error(s: string): void;
clear(): void;
diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts
index 35b0f3363..2c657bd07 100644
--- a/src/Terminal/Terminal.ts
+++ b/src/Terminal/Terminal.ts
@@ -1,4 +1,4 @@
-import { ITerminal, Output, Link, TTimer } from "./ITerminal";
+import { ITerminal, Output, Link, RawOutput, TTimer } from "./ITerminal";
import { IRouter } from "../ui/Router";
import { IPlayer } from "../PersonObjects/IPlayer";
import { HacknetServer } from "../Hacknet/HacknetServer";
@@ -77,7 +77,7 @@ export class Terminal implements ITerminal {
commandHistory: string[] = [];
commandHistoryIndex = 0;
- outputHistory: (Output | Link)[] = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
+ outputHistory: (Output | Link | RawOutput)[] = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
// True if a Coding Contract prompt is opened
contractOpen = false;
@@ -93,7 +93,7 @@ export class Terminal implements ITerminal {
TerminalEvents.emit();
}
- append(item: Output | Link): void {
+ append(item: Output | Link | RawOutput): void {
this.outputHistory.push(item);
if (this.outputHistory.length > Settings.MaxTerminalCapacity) {
this.outputHistory.splice(0, this.outputHistory.length - Settings.MaxTerminalCapacity);
@@ -105,6 +105,10 @@ export class Terminal implements ITerminal {
this.append(new Output(s, "primary"));
}
+ printRaw(node: React.ReactNode): void {
+ this.append(new RawOutput(node));
+ }
+
error(s: string): void {
this.append(new Output(s, "error"));
}
@@ -428,10 +432,10 @@ export class Terminal implements ITerminal {
case CodingContractResult.Failure:
++contract.tries;
if (contract.tries >= contract.getMaxNumTries()) {
- this.print("Contract FAILED - Contract is now self-destructing");
+ this.error("Contract FAILED - Contract is now self-destructing");
serv.removeContract(contract);
} else {
- this.print(`Contract FAILED - ${contract.getMaxNumTries() - contract.tries} tries remaining`);
+ this.error(`Contract FAILED - ${contract.getMaxNumTries() - contract.tries} tries remaining`);
}
break;
case CodingContractResult.Cancelled:
@@ -580,7 +584,7 @@ export class Terminal implements ITerminal {
if (commandArray.length === 1 && commandArray[0] == "help") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -588,7 +592,7 @@ export class Terminal implements ITerminal {
if (commandArray.length === 1 && commandArray[0] == "ls") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -596,7 +600,7 @@ export class Terminal implements ITerminal {
if (commandArray.length === 1 && commandArray[0] == "scan") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -604,7 +608,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 1 && commandArray[0] == "scan-analyze") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -612,7 +616,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 2 && commandArray[0] == "scan-analyze" && commandArray[1] === 2) {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -624,11 +628,11 @@ export class Terminal implements ITerminal {
) {
iTutorialNextStep();
} else {
- this.print("Wrong command! Try again!");
+ this.error("Wrong command! Try again!");
return;
}
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -636,7 +640,7 @@ export class Terminal implements ITerminal {
if (commandArray.length === 1 && commandArray[0] === "analyze") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -644,7 +648,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 2 && commandArray[0] == "run" && commandArray[1] == "NUKE.exe") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -652,7 +656,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 1 && commandArray[0] == "hack") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -660,7 +664,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 1 && commandArray[0] == "home") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -668,7 +672,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 2 && commandArray[0] == "nano" && commandArray[1] == "n00dles.script") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -676,7 +680,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 1 && commandArray[0] == "free") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -684,7 +688,7 @@ export class Terminal implements ITerminal {
if (commandArray.length == 2 && commandArray[0] == "run" && commandArray[1] == "n00dles.script") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
@@ -692,12 +696,12 @@ export class Terminal implements ITerminal {
if (commandArray.length == 2 && commandArray[0] == "tail" && commandArray[1] == "n00dles.script") {
iTutorialNextStep();
} else {
- this.print("Bad command. Please follow the tutorial");
+ this.error("Bad command. Please follow the tutorial");
return;
}
break;
default:
- this.print("Please follow the tutorial, or click 'EXIT' if you'd like to skip it");
+ this.error("Please follow the tutorial, or click 'EXIT' if you'd like to skip it");
return;
}
}
diff --git a/src/Terminal/commands/analyze.ts b/src/Terminal/commands/analyze.ts
index bd1004a40..c45fdf866 100644
--- a/src/Terminal/commands/analyze.ts
+++ b/src/Terminal/commands/analyze.ts
@@ -11,7 +11,7 @@ export function analyze(
args: (string | number)[],
): void {
if (args.length !== 0) {
- terminal.print("Incorrect usage of analyze command. Usage: analyze");
+ terminal.error("Incorrect usage of analyze command. Usage: analyze");
return;
}
terminal.startAnalyze();
diff --git a/src/Terminal/commands/backdoor.ts b/src/Terminal/commands/backdoor.ts
index 72247327f..7c0736fdd 100644
--- a/src/Terminal/commands/backdoor.ts
+++ b/src/Terminal/commands/backdoor.ts
@@ -13,7 +13,7 @@ export function backdoor(
args: (string | number)[],
): void {
if (args.length !== 0) {
- terminal.print("Incorrect usage of backdoor command. Usage: backdoor");
+ terminal.error("Incorrect usage of backdoor command. Usage: backdoor");
return;
}
diff --git a/src/Terminal/commands/kill.ts b/src/Terminal/commands/kill.ts
index b826c454b..9c8a70f90 100644
--- a/src/Terminal/commands/kill.ts
+++ b/src/Terminal/commands/kill.ts
@@ -24,7 +24,7 @@ export function kill(
if (res) {
terminal.print(`Killing script with PID ${pid}`);
} else {
- terminal.print(`Failed to kill script with PID ${pid}. No such script exists`);
+ terminal.error(`Failed to kill script with PID ${pid}. No such script exists`);
}
return;
diff --git a/src/Terminal/commands/ls.tsx b/src/Terminal/commands/ls.tsx
index 51956e8d8..b324e37e9 100644
--- a/src/Terminal/commands/ls.tsx
+++ b/src/Terminal/commands/ls.tsx
@@ -1,8 +1,10 @@
+import React from "react";
import { ITerminal } from "../ITerminal";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers";
+import Typography from "@mui/material/Typography";
export function ls(
terminal: ITerminal,
@@ -112,7 +114,7 @@ export function ls(
allMessages.sort();
folders.sort();
- function postSegments(segments: string[]): void {
+ function postSegments(segments: string[], style?: any): void {
const maxLength = Math.max(...segments.map((s) => s.length)) + 1;
const filesPerRow = Math.floor(80 / maxLength);
for (let i = 0; i < segments.length; i++) {
@@ -124,23 +126,27 @@ export function ls(
i++;
}
i--;
- terminal.print(row);
+ if (!style) {
+ terminal.print(row);
+ } else {
+ terminal.printRaw({row});
+ }
}
}
const groups = [
- { segments: folders },
+ { segments: folders, style: { color: "cyan" } },
{ segments: allMessages },
{ segments: allTextFiles },
{ segments: allPrograms },
{ segments: allContracts },
- { segments: allScripts },
+ { segments: allScripts, style: { color: "yellow", fontStyle: "bold" } },
].filter((g) => g.segments.length > 0);
for (let i = 0; i < groups.length; i++) {
if (i !== 0) {
terminal.print("");
terminal.print("");
}
- postSegments(groups[i].segments);
+ postSegments(groups[i].segments, groups[i].style);
}
}
diff --git a/src/Terminal/commands/runProgram.ts b/src/Terminal/commands/runProgram.ts
index f4c8d83dc..3c95f5d90 100644
--- a/src/Terminal/commands/runProgram.ts
+++ b/src/Terminal/commands/runProgram.ts
@@ -41,5 +41,5 @@ export function runProgram(
}
}
- terminal.print("Invalid executable. Cannot be run");
+ terminal.error("Invalid executable. Cannot be run");
}
diff --git a/src/Terminal/commands/runScript.ts b/src/Terminal/commands/runScript.ts
index 029dc7e68..95056c82a 100644
--- a/src/Terminal/commands/runScript.ts
+++ b/src/Terminal/commands/runScript.ts
@@ -41,7 +41,7 @@ export function runScript(
// Check if this script is already running
if (findRunningScript(scriptName, args, server) != null) {
- terminal.print("ERROR: This script is already running. Cannot run multiple instances");
+ terminal.error("This script is already running. Cannot run multiple instances");
return;
}
@@ -56,12 +56,12 @@ export function runScript(
const ramAvailable = server.maxRam - server.ramUsed;
if (!server.hasAdminRights) {
- terminal.print("Need root access to run script");
+ terminal.error("Need root access to run script");
return;
}
if (ramUsage > ramAvailable) {
- terminal.print(
+ terminal.error(
"This machine does not have enough RAM to run this script with " +
numThreads +
" threads. Script requires " +
@@ -90,5 +90,5 @@ export function runScript(
return;
}
- terminal.print("ERROR: No such script");
+ terminal.error("No such script");
}
diff --git a/src/Terminal/commands/wget.ts b/src/Terminal/commands/wget.ts
index 9d951770a..9119d01a7 100644
--- a/src/Terminal/commands/wget.ts
+++ b/src/Terminal/commands/wget.ts
@@ -19,7 +19,7 @@ export function wget(
const url = args[0] + "";
const target = terminal.getFilepath(args[1] + "");
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
- return terminal.print(`wget failed: Invalid target file. Target file must be script or text file`);
+ return terminal.error(`wget failed: Invalid target file. Target file must be script or text file`);
}
$.get(
url,
@@ -31,7 +31,7 @@ export function wget(
res = server.writeToTextFile(target, data);
}
if (!res.success) {
- return terminal.print("wget failed");
+ return terminal.error("wget failed");
}
if (res.overwritten) {
return terminal.print(`wget successfully retrieved content and overwrote ${target}`);
diff --git a/src/Terminal/ui/TerminalRoot.tsx b/src/Terminal/ui/TerminalRoot.tsx
index 151df43ba..47ded43a7 100644
--- a/src/Terminal/ui/TerminalRoot.tsx
+++ b/src/Terminal/ui/TerminalRoot.tsx
@@ -7,7 +7,7 @@ import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import Box from "@mui/material/Box";
-import { ITerminal, Output, Link } from "../ITerminal";
+import { ITerminal, Output, Link, RawOutput } from "../ITerminal";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { TerminalInput } from "./TerminalInput";
@@ -94,6 +94,14 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE
);
+ if (item instanceof RawOutput)
+ return (
+
+
+ {item.raw}
+
+
+ );
if (item instanceof Link)
return (