From 504ee4695009d320ac089f949e0167b6f930bf9c Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Tue, 26 Oct 2021 20:26:05 -0400 Subject: [PATCH] terminal colors --- src/DarkWeb/DarkWeb.tsx | 13 +++++--- src/Programs/data/ProgramsMetadata.ts | 12 +++---- src/Terminal/ITerminal.ts | 11 ++++++- src/Terminal/Terminal.ts | 46 +++++++++++++++------------ src/Terminal/commands/analyze.ts | 2 +- src/Terminal/commands/backdoor.ts | 2 +- src/Terminal/commands/kill.ts | 2 +- src/Terminal/commands/ls.tsx | 16 +++++++--- src/Terminal/commands/runProgram.ts | 2 +- src/Terminal/commands/runScript.ts | 8 ++--- src/Terminal/commands/wget.ts | 4 +-- src/Terminal/ui/TerminalRoot.tsx | 10 +++++- 12 files changed, 80 insertions(+), 48 deletions(-) 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 (