terminal colors

This commit is contained in:
Olivier Gagnon 2021-10-26 20:26:05 -04:00
parent 6865fe6463
commit 504ee46950
12 changed files with 80 additions and 48 deletions

@ -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} - <Money money={item.price} /> - {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;
}

@ -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.");
},

@ -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;

@ -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;
}
}

@ -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();

@ -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;
}

@ -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;

@ -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(<span style={style}>{row}</span>);
}
}
}
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);
}
}

@ -41,5 +41,5 @@ export function runProgram(
}
}
terminal.print("Invalid executable. Cannot be run");
terminal.error("Invalid executable. Cannot be run");
}

@ -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");
}

@ -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}`);

@ -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
</Typography>
</ListItem>
);
if (item instanceof RawOutput)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>
<Typography classes={{ root: classes.preformatted }} paragraph={false}>
{item.raw}
</Typography>
</ListItem>
);
if (item instanceof Link)
return (
<ListItem key={i} classes={{ root: classes.nopadding }}>