diff --git a/src/BitNode/ui/BitverseRoot.tsx b/src/BitNode/ui/BitverseRoot.tsx
index b9ca56661..c9152ae33 100644
--- a/src/BitNode/ui/BitverseRoot.tsx
+++ b/src/BitNode/ui/BitverseRoot.tsx
@@ -2,7 +2,7 @@ import React, { useState } from "react";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { IRouter } from "../../ui/Router";
import { BitNodes } from "../BitNode";
-import { enterBitNode } from "../../RedPill";
+import { enterBitNode, setRedPillFlag } from "../../RedPill";
import { PortalPopup } from "./PortalPopup";
import { createPopup } from "../../ui/React/createPopup";
import { CinematicText } from "../../ui/React/CinematicText";
@@ -71,6 +71,7 @@ interface IProps {
}
export function BitverseRoot(props: IProps): React.ReactElement {
+ setRedPillFlag(true);
const player = use.Player();
const enter = enterBitNode;
const destroyed = player.bitNodeN;
diff --git a/src/Message/MessageHelpers.js b/src/Message/MessageHelpers.js
index 1b9a9be53..1dd9879bd 100644
--- a/src/Message/MessageHelpers.js
+++ b/src/Message/MessageHelpers.js
@@ -48,17 +48,18 @@ function addMessageToServer(msg, serverHostname) {
//Checks if any of the 'timed' messages should be sent
function checkForMessagesToSend() {
- var jumper0 = Messages[MessageFilenames.Jumper0];
- var jumper1 = Messages[MessageFilenames.Jumper1];
- var jumper2 = Messages[MessageFilenames.Jumper2];
- var jumper3 = Messages[MessageFilenames.Jumper3];
- var jumper4 = Messages[MessageFilenames.Jumper4];
- var cybersecTest = Messages[MessageFilenames.CyberSecTest];
- var nitesecTest = Messages[MessageFilenames.NiteSecTest];
- var bitrunnersTest = Messages[MessageFilenames.BitRunnersTest];
- var redpill = Messages[MessageFilenames.RedPill];
+ if (redPillFlag) return;
+ const jumper0 = Messages[MessageFilenames.Jumper0];
+ const jumper1 = Messages[MessageFilenames.Jumper1];
+ const jumper2 = Messages[MessageFilenames.Jumper2];
+ const jumper3 = Messages[MessageFilenames.Jumper3];
+ const jumper4 = Messages[MessageFilenames.Jumper4];
+ const cybersecTest = Messages[MessageFilenames.CyberSecTest];
+ const nitesecTest = Messages[MessageFilenames.NiteSecTest];
+ const bitrunnersTest = Messages[MessageFilenames.BitRunnersTest];
+ const redpill = Messages[MessageFilenames.RedPill];
- var redpillOwned = false;
+ const redpillOwned = false;
if (Augmentations[AugmentationNames.TheRedPill].owned) {
redpillOwned = true;
}
diff --git a/src/RedPill.d.ts b/src/RedPill.d.ts
index d60d01977..b9909c1d1 100644
--- a/src/RedPill.d.ts
+++ b/src/RedPill.d.ts
@@ -1,2 +1,3 @@
export declare let redPillFlag: boolean;
export declare function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number);
+export declare function setRedPillFlag(b: boolean): void;
diff --git a/src/RedPill.jsx b/src/RedPill.jsx
index ef4f685a1..768175910 100644
--- a/src/RedPill.jsx
+++ b/src/RedPill.jsx
@@ -9,7 +9,11 @@ import { SourceFiles } from "./SourceFile/SourceFiles";
import { dialogBoxCreate } from "../utils/DialogBox";
-let redPillFlag = false;
+export let redPillFlag = false;
+
+export function setRedPillFlag(b) {
+ redPillFlag = b;
+}
function giveSourceFile(bitNodeNumber) {
var sourceFileKey = "SourceFile" + bitNodeNumber.toString();
@@ -81,5 +85,3 @@ export function enterBitNode(router, flume, destroyedBitNode, newBitNode) {
}
prestigeSourceFile(flume);
}
-
-export { redPillFlag };
diff --git a/src/SaveObject.jsx b/src/SaveObject.jsx
index d8c06168b..fdc7c5893 100755
--- a/src/SaveObject.jsx
+++ b/src/SaveObject.jsx
@@ -3,8 +3,6 @@ import { Companies, loadCompanies } from "./Company/Companies";
import { CONSTANTS } from "./Constants";
import { Engine } from "./engine";
import { Factions, loadFactions } from "./Faction/Factions";
-import { loadFconf } from "./Fconf/Fconf";
-import { FconfSettings } from "./Fconf/FconfSettings";
import { loadAllGangs, AllGangs } from "./Gang/AllGangs";
import { loadMessages, initMessages, Messages } from "./Message/MessageHelpers";
import { Player, loadPlayer } from "./Player";
@@ -42,7 +40,6 @@ function BitburnerSaveObject() {
this.MessagesSave = "";
this.StockMarketSave = "";
this.SettingsSave = "";
- this.FconfSettingsSave = "";
this.VersionSave = "";
this.AllGangsSave = "";
this.LastExportBonus = "";
@@ -74,7 +71,6 @@ BitburnerSaveObject.prototype.getSaveString = function () {
this.MessagesSave = JSON.stringify(Messages);
this.StockMarketSave = JSON.stringify(StockMarket);
this.SettingsSave = JSON.stringify(Settings);
- this.FconfSettingsSave = JSON.stringify(FconfSettings);
this.VersionSave = JSON.stringify(CONSTANTS.Version);
this.LastExportBonus = JSON.stringify(ExportBonus.LastExportBonus);
if (Player.inGang()) {
diff --git a/src/Script/RunningScript.ts b/src/Script/RunningScript.ts
index cf5f9fac9..683b095be 100644
--- a/src/Script/RunningScript.ts
+++ b/src/Script/RunningScript.ts
@@ -75,7 +75,7 @@ export class RunningScript {
}
let logEntry = txt;
- if (FconfSettings.ENABLE_TIMESTAMPS) {
+ if (Settings.EnableTimestamps) {
logEntry = "[" + getTimestamp() + "] " + logEntry;
}
diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts
index 596bfaf89..99a168e6e 100644
--- a/src/Settings/Settings.ts
+++ b/src/Settings/Settings.ts
@@ -38,6 +38,16 @@ interface IDefaultSettings {
*/
DisableTextEffects: boolean;
+ /**
+ * Enable bash hotkeys
+ */
+ EnableBashHotkeys: boolean;
+
+ /**
+ * Enable timestamps
+ */
+ EnableTimestamps: boolean;
+
/**
* Locale used for display numbers
*/
@@ -116,6 +126,8 @@ const defaultSettings: IDefaultSettings = {
DisableASCIIArt: false,
DisableHotkeys: false,
DisableTextEffects: false,
+ EnableBashHotkeys: false,
+ EnableTimestamps: false,
Locale: "en",
MaxLogCapacity: 50,
MaxPortCapacity: 50,
@@ -140,6 +152,8 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
DisableASCIIArt: defaultSettings.DisableASCIIArt,
DisableHotkeys: defaultSettings.DisableHotkeys,
DisableTextEffects: defaultSettings.DisableTextEffects,
+ EnableBashHotkeys: defaultSettings.EnableBashHotkeys,
+ EnableTimestamps: defaultSettings.EnableTimestamps,
Locale: "en",
MaxLogCapacity: defaultSettings.MaxLogCapacity,
MaxPortCapacity: defaultSettings.MaxPortCapacity,
diff --git a/src/Sidebar/ui/SidebarRoot.tsx b/src/Sidebar/ui/SidebarRoot.tsx
index 8d648c6e6..4138a8522 100644
--- a/src/Sidebar/ui/SidebarRoot.tsx
+++ b/src/Sidebar/ui/SidebarRoot.tsx
@@ -52,7 +52,6 @@ import { redPillFlag } from "../../RedPill";
import { inMission } from "../../Missions";
import { KEY } from "../../../utils/helpers/keyCodes";
-import { FconfSettings } from "../../Fconf/FconfSettings";
const openedMixin = (theme: Theme): CSSObject => ({
width: theme.spacing(31),
@@ -297,7 +296,7 @@ export function SidebarRoot(props: IProps): React.ReactElement {
clickCreateProgram();
} else if (event.keyCode === KEY.F && event.altKey) {
// Overriden by Fconf
- if (props.page == Page.Terminal && FconfSettings.ENABLE_BASH_HOTKEYS) {
+ if (props.page == Page.Terminal && Settings.EnableBashHotkeys) {
return;
}
event.preventDefault();
diff --git a/src/Terminal/ITerminal.ts b/src/Terminal/ITerminal.ts
index c7c842605..7c8922706 100644
--- a/src/Terminal/ITerminal.ts
+++ b/src/Terminal/ITerminal.ts
@@ -2,6 +2,8 @@ import { TextFile } from "../TextFile";
import { Script } from "../Script/Script";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IRouter } from "../ui/Router";
+import { Settings } from "../Settings/Settings";
+import { getTimestamp } from "../../utils/helpers/getTimestamp";
export class Output {
text: string;
@@ -10,6 +12,7 @@ export class Output {
text: string,
color: "inherit" | "initial" | "primary" | "secondary" | "error" | "textPrimary" | "textSecondary" | undefined,
) {
+ if (Settings.EnableTimestamps) text = "[" + getTimestamp() + "] " + text;
this.text = text;
this.color = color;
}
@@ -18,6 +21,7 @@ export class Output {
export class Link {
hostname: string;
constructor(hostname: string) {
+ if (Settings.EnableTimestamps) hostname = "[" + getTimestamp() + "] " + hostname;
this.hostname = hostname;
}
}
diff --git a/src/Terminal/ui/TerminalInput.tsx b/src/Terminal/ui/TerminalInput.tsx
index 9dfc5b900..4c360a0b6 100644
--- a/src/Terminal/ui/TerminalInput.tsx
+++ b/src/Terminal/ui/TerminalInput.tsx
@@ -12,7 +12,7 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { determineAllPossibilitiesForTabCompletion } from "../determineAllPossibilitiesForTabCompletion";
import { tabCompletion } from "../tabCompletion";
-import { FconfSettings } from "../../Fconf/FconfSettings";
+import { Settings } from "../../Settings/Settings";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
@@ -230,11 +230,8 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
}
// Select previous command.
- if (
- event.keyCode === KEY.UPARROW ||
- (FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.P && event.ctrlKey)
- ) {
- if (FconfSettings.ENABLE_BASH_HOTKEYS) {
+ if (event.keyCode === KEY.UPARROW || (Settings.EnableBashHotkeys && event.keyCode === KEY.P && event.ctrlKey)) {
+ if (Settings.EnableBashHotkeys) {
event.preventDefault();
}
const i = terminal.commandHistoryIndex;
@@ -261,11 +258,8 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
}
// Select next command
- if (
- event.keyCode === KEY.DOWNARROW ||
- (FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.M && event.ctrlKey)
- ) {
- if (FconfSettings.ENABLE_BASH_HOTKEYS) {
+ if (event.keyCode === KEY.DOWNARROW || (Settings.EnableBashHotkeys && event.keyCode === KEY.M && event.ctrlKey)) {
+ if (Settings.EnableBashHotkeys) {
event.preventDefault();
}
const i = terminal.commandHistoryIndex;
@@ -290,7 +284,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
}
// Extra Bash Emulation Hotkeys, must be enabled through .fconf
- if (FconfSettings.ENABLE_BASH_HOTKEYS) {
+ if (Settings.EnableBashHotkeys) {
if (event.keyCode === KEY.A && event.ctrlKey) {
event.preventDefault();
moveTextCursor("home");
diff --git a/src/index.tsx b/src/index.tsx
index e0be26a7b..2cbaceb5c 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,7 +1,7 @@
import React from "react";
import ReactDOM from "react-dom";
-import { TTheme as Theme, colors } from "./ui/React/Theme";
+import { TTheme as Theme, ThemeEvents } from "./ui/React/Theme";
import { LoadingScreen } from "./ui/LoadingScreen";
import "./engineStyle";
@@ -12,13 +12,15 @@ ReactDOM.render(
document.getElementById("mainmenu-container"),
);
-// setTimeout(() => {
-// colors.primary = "#fff";
-// refreshTheme();
-// ReactDOM.render(
-//
-//
-// ,
-// document.getElementById("mainmenu-container"),
-// );
-// }, 5000);
+function rerender() {
+ ReactDOM.render(
+
+
+ ,
+ document.getElementById("mainmenu-container"),
+ );
+}
+
+(function () {
+ ThemeEvents.subscribe(rerender);
+})();
diff --git a/src/ui/React/GameOptionsRoot.tsx b/src/ui/React/GameOptionsRoot.tsx
index 6d4fbd911..1fe4fcc55 100644
--- a/src/ui/React/GameOptionsRoot.tsx
+++ b/src/ui/React/GameOptionsRoot.tsx
@@ -74,6 +74,9 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
const [disableHotkeys, setDisableHotkeys] = useState(Settings.DisableHotkeys);
const [disableASCIIArt, setDisableASCIIArt] = useState(Settings.DisableASCIIArt);
const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects);
+ const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys);
+ const [enableTimestamps, setEnableTimestamps] = useState(Settings.EnableTimestamps);
+
const [locale, setLocale] = useState(Settings.Locale);
const [diagnosticOpen, setDiagnosticOpen] = useState(false);
const [deleteGameOpen, setDeleteOpen] = useState(false);
@@ -152,6 +155,15 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
Settings.Locale = event.target.value as string;
}
+ function handleEnableBashHotkeysChange(event: React.ChangeEvent): void {
+ setEnableBashHotkeys(event.target.checked);
+ Settings.EnableBashHotkeys = event.target.checked;
+ }
+ function handleEnableTimestampsChange(event: React.ChangeEvent): void {
+ setEnableTimestamps(event.target.checked);
+ Settings.EnableTimestamps = event.target.checked;
+ }
+
function startImport(): void {
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) return;
const ii = importInput.current;
@@ -454,6 +466,43 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
}
/>
+
+
+ }
+ label={
+
+ Improved Bash emulation mode. Setting this to 1 enables several new Terminal shortcuts and
+ features that more closely resemble a real Bash-style shell. Note that when this mode is
+ enabled, the default browser shortcuts are overriden by the new Bash shortcuts.
+
+ }
+ >
+ Enable bash hotkeys
+
+ }
+ />
+
+
+ }
+ label={
+
+ Terminal commands and log entries will be timestamped. The timestamp will have the format: M/D
+ h:m
+
+ }
+ >
+ Enable timestamps
+
+ }
+ />
+
+
Sets the locale for displaying numbers.}>
Locale
diff --git a/src/ui/React/Theme.tsx b/src/ui/React/Theme.tsx
index da4c3ed4c..bcfdda8da 100644
--- a/src/ui/React/Theme.tsx
+++ b/src/ui/React/Theme.tsx
@@ -1,5 +1,8 @@
import React from "react";
import { createTheme, ThemeProvider, Theme, StyledEngineProvider } from "@mui/material/styles";
+import { EventEmitter } from "../../utils/EventEmitter";
+
+export const ThemeEvents = new EventEmitter<[]>();
declare module "@mui/material/styles" {
interface Theme {