Merge pull request #1690 from danielyxie/dev

Few bugfix
This commit is contained in:
hydroflame 2021-11-11 17:00:57 -05:00 committed by GitHub
commit f635f233cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 141 additions and 136 deletions

42
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -82,7 +82,7 @@ List of Factions and their Requirements
| | | server | | | | | server | |
| | | | | | | | | |
+ +----------------+-----------------------------------------+-------------------------------+ + +----------------+-----------------------------------------+-------------------------------+
| | Bitrunners | * Install a backdoor on the run4theh111z| | | | BitRunners | * Install a backdoor on the run4theh111z| |
| | | server | | | | | server | |
| | | | | | | | | |
+---------------------+----------------+-----------------------------------------+-------------------------------+ +---------------------+----------------+-----------------------------------------+-------------------------------+

@ -61,7 +61,7 @@ v1.0.0 - 2021-11-10 Breaking the API :( (blame hydroflame)
* Button colors can be edited. * Button colors can be edited.
* Added 2 new colors in the theme editor: background primary and background secondary. * Added 2 new colors in the theme editor: background primary and background secondary.
* infiltration uses key instead of keycode so it should work better on non-american keyboards. * infiltration uses key instead of keycode so it should work better on non-american keyboards.
* nerf noodle bar. * buff noodle bar.
v0.58.0 - 2021-10-27 Road to Steam (hydroflame & community) v0.58.0 - 2021-10-27 Road to Steam (hydroflame & community)
----------------------------------------------------------- -----------------------------------------------------------

@ -10,7 +10,7 @@ getPlayer() Netscript Function
Returns an object with the Player's stats. The object has the following properties:: Returns an object with the Player's stats. The object has the following properties::
{ {
hacking_skill: Current Hacking skill level hacking: Current Hacking skill level
hp: Current health points hp: Current health points
max_hp: Maximum health points max_hp: Maximum health points
strength: Current Strength skill level strength: Current Strength skill level

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

22
package-lock.json generated

@ -1,11 +1,11 @@
{ {
"name": "bitburner", "name": "bitburner",
"version": "0.58.0", "version": "1.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "0.58.0", "version": "1.0.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "SEE LICENSE IN license.txt", "license": "SEE LICENSE IN license.txt",
"dependencies": { "dependencies": {
@ -28,6 +28,7 @@
"arg": "^5.0.0", "arg": "^5.0.0",
"better-react-mathjax": "^1.0.3", "better-react-mathjax": "^1.0.3",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"date-fns": "^2.25.0",
"decimal.js": "7.2.3", "decimal.js": "7.2.3",
"escodegen": "^1.11.0", "escodegen": "^1.11.0",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",
@ -6963,6 +6964,18 @@
"whatwg-url": "^7.0.0" "whatwg-url": "^7.0.0"
} }
}, },
"node_modules/date-fns": {
"version": "2.25.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-now": { "node_modules/date-now": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@ -26992,6 +27005,11 @@
"whatwg-url": "^7.0.0" "whatwg-url": "^7.0.0"
} }
}, },
"date-fns": {
"version": "2.25.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w=="
},
"date-now": { "date-now": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",

@ -29,6 +29,7 @@
"arg": "^5.0.0", "arg": "^5.0.0",
"better-react-mathjax": "^1.0.3", "better-react-mathjax": "^1.0.3",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"date-fns": "^2.25.0",
"decimal.js": "7.2.3", "decimal.js": "7.2.3",
"escodegen": "^1.11.0", "escodegen": "^1.11.0",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",

@ -67,7 +67,7 @@ BitNodes["BitNode2"] = new BitNode(
<br /> <br />
<br /> <br />
Organized crime groups quickly filled the void of power left behind from the collapse of Western government in the Organized crime groups quickly filled the void of power left behind from the collapse of Western government in the
2050s. As society and civlization broke down, people quickly succumbed to the innate human impulse of evil and 2050s. As society and civilization broke down, people quickly succumbed to the innate human impulse of evil and
savagery. The organized crime factions quickly rose to the top of the modern world. savagery. The organized crime factions quickly rose to the top of the modern world.
<br /> <br />
<br /> <br />

@ -224,7 +224,6 @@ export class Action implements IAction {
let high = real + diff; let high = real + diff;
const city = inst.getCurrentCity(); const city = inst.getCurrentCity();
const r = city.pop / city.popEst; const r = city.pop / city.popEst;
console.log(`${est} ${real}`);
if (r < 1) low *= r; if (r < 1) low *= r;
else high *= r; else high *= r;
return [clamp(low), clamp(high)]; return [clamp(low), clamp(high)];

@ -38,7 +38,7 @@ function EffectText(props: IEffectTextProps): React.ReactElement {
return ( return (
<Typography> <Typography>
Issue ${numeralWrapper.format(newShares, "0.000a")} new shares for{" "} Issue {numeralWrapper.format(newShares, "0.000a")} new shares for{" "}
{numeralWrapper.formatMoney(newShares * newSharePrice)}? {numeralWrapper.formatMoney(newShares * newSharePrice)}?
</Typography> </Typography>
); );

@ -42,5 +42,6 @@ export function ExploitName(exploit: string): string {
} }
export function sanitizeExploits(exploits: Exploit[]): Exploit[] { export function sanitizeExploits(exploits: Exploit[]): Exploit[] {
return exploits.filter((e: Exploit) => Object.keys(Exploit).includes(e)); exploits = exploits.filter((e: Exploit) => Object.keys(Exploit).includes(e));
return [...new Set(exploits)];
} }

@ -1,9 +1,11 @@
import { Player } from "../Player"; import { Player } from "../Player";
import { sanitizeExploits } from "./Exploit";
export function applyExploit(): void { export function applyExploit(): void {
if (Player.exploits && Player.exploits.length === 0) { if (Player.exploits && Player.exploits.length === 0) {
return; return;
} }
Player.exploits = sanitizeExploits(Player.exploits);
const inc = Math.pow(1.001, Player.exploits.length); const inc = Math.pow(1.001, Player.exploits.length);
const dec = Math.pow(0.999, Player.exploits.length); const dec = Math.pow(0.999, Player.exploits.length);

@ -20,8 +20,6 @@ import { createRandomIp } from "../utils/IPAddress";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
interface IConstructorParams { interface IConstructorParams {
adminRights?: boolean; adminRights?: boolean;
hostname: string; hostname: string;
@ -53,6 +51,9 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
// Total number of hashes earned by this server // Total number of hashes earned by this server
totalHashesGenerated = 0; totalHashesGenerated = 0;
// Flag indicating wehther this is a purchased server
purchasedByPlayer = true;
constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) { constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) {
super(params); super(params);
@ -95,7 +96,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
upgradeCore(levels: number, prodMult: number): void { upgradeCore(levels: number, prodMult: number): void {
this.cores = Math.min(HacknetServerConstants.MaxCores, Math.round(this.cores + levels)); this.cores = Math.min(HacknetServerConstants.MaxCores, Math.round(this.cores + levels));
this.updateHashRate(prodMult); this.updateHashRate(prodMult);
this.cpuCores=this.cores; this.cpuCores = this.cores;
} }
upgradeLevel(levels: number, prodMult: number): void { upgradeLevel(levels: number, prodMult: number): void {

@ -119,7 +119,6 @@ export function Game(props: IProps): React.ReactElement {
} }
function Progress(): React.ReactElement { function Progress(): React.ReactElement {
console.log(results);
return ( return (
<Typography variant="h4"> <Typography variant="h4">
<span style={{ color: "gray" }}>{results.slice(0, results.length - 1)}</span> <span style={{ color: "gray" }}>{results.slice(0, results.length - 1)}</span>

@ -35,8 +35,6 @@ export const Literatures: IMap<Literature> = {};
"<u>Getting Started with Corporations</u><br>" + "<u>Getting Started with Corporations</u><br>" +
"To get started, visit the City Hall in Sector-12 in order to create a Corporation. This requires " + "To get started, visit the City Hall in Sector-12 in order to create a Corporation. This requires " +
"$150b of your own money, but this $150b will get put into your Corporation's funds. " + "$150b of your own money, but this $150b will get put into your Corporation's funds. " +
"After creating your Corporation, you will see it listed as one of the locations in the city. Click on " +
"your Corporation in order to manage it.<br><br>" +
"Your Corporation can have many different divisions, each in a different Industry. There are many different " + "Your Corporation can have many different divisions, each in a different Industry. There are many different " +
"types of Industries, each with different properties. To create your first division, click the " + "types of Industries, each with different properties. To create your first division, click the " +
"'Expand into new Industry' button at the top of the management UI. The Agriculture " + "'Expand into new Industry' button at the top of the management UI. The Agriculture " +

@ -855,10 +855,7 @@ export function startFactionHackWork(this: IPlayer, router: IRouter, faction: Fa
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkHacking); this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkHacking);
this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workRepGainRate = this.workRepGainRate = getFactionFieldWorkRepGain(this, faction);
((this.hacking + this.intelligence) / CONSTANTS.MaxSkillLevel) *
this.faction_rep_mult *
this.getIntelligenceBonus(0.5);
this.factionWorkType = CONSTANTS.FactionWorkHacking; this.factionWorkType = CONSTANTS.FactionWorkHacking;
this.currentWorkFactionDescription = "carrying out hacking contracts"; this.currentWorkFactionDescription = "carrying out hacking contracts";
@ -1695,9 +1692,7 @@ export function regenerateHp(this: IPlayer, amt: number): void {
export function hospitalize(this: IPlayer): number { export function hospitalize(this: IPlayer): number {
const cost = getHospitalizationCost(this); const cost = getHospitalizationCost(this);
if (Settings.SuppressHospitalizationPopup === false) { SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, "warning");
SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, "warning");
}
this.loseMoney(cost, "hospitalization"); this.loseMoney(cost, "hospitalization");
this.hp = this.max_hp; this.hp = this.max_hp;
@ -2631,6 +2626,7 @@ export function canAccessResleeving(this: IPlayer): boolean {
export function giveExploit(this: IPlayer, exploit: Exploit): void { export function giveExploit(this: IPlayer, exploit: Exploit): void {
if (!this.exploits.includes(exploit)) { if (!this.exploits.includes(exploit)) {
this.exploits.push(exploit); this.exploits.push(exploit);
SnackbarEvents.emit("SF -1 acquired!", "success");
} }
} }

@ -8,7 +8,7 @@ import { IMap } from "../types";
import { Terminal } from "../Terminal"; import { Terminal } from "../Terminal";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
import { getTimestamp } from "../utils/helpers/getTimestamp"; import { formatTime } from "../utils/helpers/formatTime";
export class RunningScript { export class RunningScript {
// Script arguments // Script arguments
@ -74,8 +74,8 @@ export class RunningScript {
} }
let logEntry = txt; let logEntry = txt;
if (Settings.EnableTimestamps) { if (Settings.TimestampsFormat) {
logEntry = "[" + getTimestamp() + "] " + logEntry; logEntry = "[" + formatTime(Settings.TimestampsFormat) + "] " + logEntry;
} }
this.logs.push(logEntry); this.logs.push(logEntry);

@ -42,11 +42,11 @@ export function OptionsModal(props: IProps): React.ReactElement {
<Box display="flex" flexDirection="row" alignItems="center"> <Box display="flex" flexDirection="row" alignItems="center">
<Typography>Theme: </Typography> <Typography>Theme: </Typography>
<Select onChange={(event) => setTheme(event.target.value)} value={theme}> <Select onChange={(event) => setTheme(event.target.value)} value={theme}>
<MenuItem value="vs-dark">dark</MenuItem>
<MenuItem value="light">light</MenuItem>
<MenuItem value="monokai">monokai</MenuItem> <MenuItem value="monokai">monokai</MenuItem>
<MenuItem value="solarized-dark">solarized-dark</MenuItem> <MenuItem value="solarized-dark">solarized-dark</MenuItem>
<MenuItem value="solarized-light">solarized-light</MenuItem> <MenuItem value="solarized-light">solarized-light</MenuItem>
<MenuItem value="vs-dark">dark</MenuItem>
<MenuItem value="light">light</MenuItem>
</Select> </Select>
</Box> </Box>

@ -64,7 +64,7 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
}, },
}); });
monaco.editor.defineTheme("solarish-dark", { monaco.editor.defineTheme("solarized-dark", {
base: "vs-dark", base: "vs-dark",
inherit: true, inherit: true,
rules: [ rules: [
@ -113,16 +113,16 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
foreground: "268bd2", foreground: "268bd2",
}, },
{ {
token: "type.identifier.js", token: "type.identifier.js",
foreground: "b58900", foreground: "b58900",
}, },
{ {
token: "delimiter.square.js", token: "delimiter.square.js",
foreground: "0087ff", foreground: "0087ff",
}, },
{ {
token: "delimiter.bracket.js", token: "delimiter.bracket.js",
foreground: "0087ff", foreground: "0087ff",
}, },
{ {
token: "this", token: "this",
@ -141,13 +141,13 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
}, },
}); });
monaco.editor.defineTheme("solarish-light", { monaco.editor.defineTheme("solarized-light", {
base: "vs", base: "vs",
inherit: true, inherit: true,
rules: [ rules: [
{ {
foreground: "657b83", foreground: "657b83",
background: "fdf6e3", background: "fdf6e3",
token: "", token: "",
}, },
{ {
@ -191,16 +191,16 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
foreground: "268bd2", foreground: "268bd2",
}, },
{ {
token: "type.identifier.js", token: "type.identifier.js",
foreground: "b58900", foreground: "b58900",
}, },
{ {
token: "delimiter.square.js", token: "delimiter.square.js",
foreground: "0087ff", foreground: "0087ff",
}, },
{ {
token: "delimiter.bracket.js", token: "delimiter.bracket.js",
foreground: "0087ff", foreground: "0087ff",
}, },
{ {
token: "this", token: "this",

@ -94,6 +94,9 @@ export class BaseServer {
// Text files on this server // Text files on this server
textFiles: TextFile[] = []; textFiles: TextFile[] = [];
// Flag indicating wehther this is a purchased server
purchasedByPlayer = false;
constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) { constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) {
this.ip = params.ip ? params.ip : createRandomIp(); this.ip = params.ip ? params.ip : createRandomIp();

@ -48,9 +48,6 @@ export class Server extends BaseServer {
// How many ports are currently opened on the server // How many ports are currently opened on the server
openPortCount = 0; openPortCount = 0;
// Flag indicating wehther this is a purchased server
purchasedByPlayer = false;
// Hacking level required to hack this server // Hacking level required to hack this server
requiredHackingSkill = 1; requiredHackingSkill = 1;

@ -44,9 +44,9 @@ interface IDefaultSettings {
EnableBashHotkeys: boolean; EnableBashHotkeys: boolean;
/** /**
* Enable timestamps * Timestamps format
*/ */
EnableTimestamps: boolean; TimestampsFormat: string;
/** /**
* Locale used for display numbers * Locale used for display numbers
@ -83,11 +83,6 @@ interface IDefaultSettings {
*/ */
SuppressFactionInvites: boolean; SuppressFactionInvites: boolean;
/**
* Whether to show a popup message when player is hospitalized from taking too much damage
*/
SuppressHospitalizationPopup: boolean;
/** /**
* Whether the user should be shown a dialog box whenever they receive a new message file. * Whether the user should be shown a dialog box whenever they receive a new message file.
*/ */
@ -171,7 +166,7 @@ export const defaultSettings: IDefaultSettings = {
DisableHotkeys: false, DisableHotkeys: false,
DisableTextEffects: false, DisableTextEffects: false,
EnableBashHotkeys: false, EnableBashHotkeys: false,
EnableTimestamps: false, TimestampsFormat: "",
Locale: "en", Locale: "en",
MaxLogCapacity: 50, MaxLogCapacity: 50,
MaxPortCapacity: 50, MaxPortCapacity: 50,
@ -179,7 +174,6 @@ export const defaultSettings: IDefaultSettings = {
SaveGameOnFileSave: true, SaveGameOnFileSave: true,
SuppressBuyAugmentationConfirmation: false, SuppressBuyAugmentationConfirmation: false,
SuppressFactionInvites: false, SuppressFactionInvites: false,
SuppressHospitalizationPopup: false,
SuppressMessages: false, SuppressMessages: false,
SuppressTravelConfirmation: false, SuppressTravelConfirmation: false,
SuppressBladeburnerPopup: false, SuppressBladeburnerPopup: false,
@ -231,7 +225,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
DisableHotkeys: defaultSettings.DisableHotkeys, DisableHotkeys: defaultSettings.DisableHotkeys,
DisableTextEffects: defaultSettings.DisableTextEffects, DisableTextEffects: defaultSettings.DisableTextEffects,
EnableBashHotkeys: defaultSettings.EnableBashHotkeys, EnableBashHotkeys: defaultSettings.EnableBashHotkeys,
EnableTimestamps: defaultSettings.EnableTimestamps, TimestampsFormat: defaultSettings.TimestampsFormat,
Locale: "en", Locale: "en",
MaxLogCapacity: defaultSettings.MaxLogCapacity, MaxLogCapacity: defaultSettings.MaxLogCapacity,
MaxPortCapacity: defaultSettings.MaxPortCapacity, MaxPortCapacity: defaultSettings.MaxPortCapacity,
@ -241,7 +235,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
SaveGameOnFileSave: defaultSettings.SaveGameOnFileSave, SaveGameOnFileSave: defaultSettings.SaveGameOnFileSave,
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation, SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
SuppressFactionInvites: defaultSettings.SuppressFactionInvites, SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
SuppressHospitalizationPopup: defaultSettings.SuppressHospitalizationPopup,
SuppressMessages: defaultSettings.SuppressMessages, SuppressMessages: defaultSettings.SuppressMessages,
SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation, SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation,
SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup, SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup,
@ -289,5 +282,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
Object.assign(Settings.theme, save.theme); Object.assign(Settings.theme, save.theme);
delete save.theme; delete save.theme;
Object.assign(Settings, save); Object.assign(Settings, save);
console.log(Settings.TimestampsFormat);
}, },
}; };

@ -4,7 +4,7 @@ import { Script } from "../Script/Script";
import { IPlayer } from "../PersonObjects/IPlayer"; import { IPlayer } from "../PersonObjects/IPlayer";
import { IRouter } from "../ui/Router"; import { IRouter } from "../ui/Router";
import { Settings } from "../Settings/Settings"; import { Settings } from "../Settings/Settings";
import { getTimestamp } from "../utils/helpers/getTimestamp"; import { formatTime } from "../utils/helpers/formatTime";
export class Output { export class Output {
text: string; text: string;
@ -13,7 +13,7 @@ export class Output {
text: string, text: string,
color: "inherit" | "initial" | "primary" | "secondary" | "error" | "textPrimary" | "textSecondary" | undefined, color: "inherit" | "initial" | "primary" | "secondary" | "error" | "textPrimary" | "textSecondary" | undefined,
) { ) {
if (Settings.EnableTimestamps) text = "[" + getTimestamp() + "] " + text; if (Settings.TimestampsFormat) text = "[" + formatTime(Settings.TimestampsFormat) + "] " + text;
this.text = text; this.text = text;
this.color = color; this.color = color;
} }
@ -22,10 +22,10 @@ export class Output {
export class RawOutput { export class RawOutput {
raw: React.ReactNode; raw: React.ReactNode;
constructor(node: React.ReactNode) { constructor(node: React.ReactNode) {
if (Settings.EnableTimestamps) if (Settings.TimestampsFormat)
node = ( node = (
<> <>
[{getTimestamp()}] {node} [{formatTime(Settings.TimestampsFormat)}] {node}
</> </>
); );
this.raw = node; this.raw = node;
@ -36,7 +36,7 @@ export class Link {
hostname: string; hostname: string;
dashes: string; dashes: string;
constructor(dashes: string, hostname: string) { constructor(dashes: string, hostname: string) {
if (Settings.EnableTimestamps) dashes = "[" + getTimestamp() + "] " + dashes; if (Settings.TimestampsFormat) dashes = "[" + formatTime(Settings.TimestampsFormat) + "] " + dashes;
this.hostname = hostname; this.hostname = hostname;
this.dashes = dashes; this.dashes = dashes;
} }

@ -27,7 +27,11 @@ export function download(
const file = new Blob([server.scripts[i].code], { const file = new Blob([server.scripts[i].code], {
type: "text/plain", type: "text/plain",
}); });
zip.file(server.scripts[i].filename + ".js", file); let name = server.scripts[i].filename;
if (name.startsWith("/")) {
name = name.slice(1);
}
zip.file(name + ".js", file);
} }
} }
if (fn === "*" || fn === "*.txt") { if (fn === "*" || fn === "*.txt") {

@ -253,7 +253,7 @@ const Engine: {
let offlineReputation = 0; let offlineReputation = 0;
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75; const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
Player.gainMoney(offlineHackingIncome, "hacknet"); Player.gainMoney(offlineHackingIncome, "hacking");
// Process offline progress // Process offline progress
loadAllRunningScripts(); // This also takes care of offline production for those scripts loadAllRunningScripts(); // This also takes care of offline production for those scripts
if (Player.isWorking) { if (Player.isWorking) {

@ -7,6 +7,5 @@ export function dialogBoxCreate(txt: string | JSX.Element): void {
AlertEvents.emit(txt); AlertEvents.emit(txt);
} else { } else {
AlertEvents.emit(<span dangerouslySetInnerHTML={{ __html: txt }} />); AlertEvents.emit(<span dangerouslySetInnerHTML={{ __html: txt }} />);
console.log('emit"');
} }
} }

@ -19,6 +19,7 @@ import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem"; import ListItem from "@mui/material/ListItem";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";
import DownloadIcon from "@mui/icons-material/Download"; import DownloadIcon from "@mui/icons-material/Download";
import UploadIcon from "@mui/icons-material/Upload"; import UploadIcon from "@mui/icons-material/Upload";
@ -30,6 +31,7 @@ import { ThemeEditorModal } from "./ThemeEditorModal";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { save, deleteGame } from "../../db"; import { save, deleteGame } from "../../db";
import { formatTime } from "../../utils/helpers/formatTime";
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
@ -66,9 +68,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
const [suppressBuyAugmentationConfirmation, setSuppressBuyAugmentationConfirmation] = useState( const [suppressBuyAugmentationConfirmation, setSuppressBuyAugmentationConfirmation] = useState(
Settings.SuppressBuyAugmentationConfirmation, Settings.SuppressBuyAugmentationConfirmation,
); );
const [suppressHospitalizationPopup, setSuppressHospitalizationPopup] = useState(
Settings.SuppressHospitalizationPopup,
);
const [suppressBladeburnerPopup, setSuppressBladeburnerPopup] = useState(Settings.SuppressBladeburnerPopup); const [suppressBladeburnerPopup, setSuppressBladeburnerPopup] = useState(Settings.SuppressBladeburnerPopup);
@ -76,7 +75,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
const [disableASCIIArt, setDisableASCIIArt] = useState(Settings.DisableASCIIArt); const [disableASCIIArt, setDisableASCIIArt] = useState(Settings.DisableASCIIArt);
const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects); const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects);
const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys); const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys);
const [enableTimestamps, setEnableTimestamps] = useState(Settings.EnableTimestamps); const [timestampFormat, setTimestampFormat] = useState(Settings.TimestampsFormat);
const [saveGameOnFileSave, setSaveGameOnFileSave] = useState(Settings.SaveGameOnFileSave); const [saveGameOnFileSave, setSaveGameOnFileSave] = useState(Settings.SaveGameOnFileSave);
const [locale, setLocale] = useState(Settings.Locale); const [locale, setLocale] = useState(Settings.Locale);
@ -129,11 +128,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
Settings.SuppressBuyAugmentationConfirmation = event.target.checked; Settings.SuppressBuyAugmentationConfirmation = event.target.checked;
} }
function handleSuppressHospitalizationPopupChange(event: React.ChangeEvent<HTMLInputElement>): void {
setSuppressHospitalizationPopup(event.target.checked);
Settings.SuppressHospitalizationPopup = event.target.checked;
}
function handleSuppressBladeburnerPopupChange(event: React.ChangeEvent<HTMLInputElement>): void { function handleSuppressBladeburnerPopupChange(event: React.ChangeEvent<HTMLInputElement>): void {
setSuppressBladeburnerPopup(event.target.checked); setSuppressBladeburnerPopup(event.target.checked);
Settings.SuppressBladeburnerPopup = event.target.checked; Settings.SuppressBladeburnerPopup = event.target.checked;
@ -162,9 +156,9 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
setEnableBashHotkeys(event.target.checked); setEnableBashHotkeys(event.target.checked);
Settings.EnableBashHotkeys = event.target.checked; Settings.EnableBashHotkeys = event.target.checked;
} }
function handleEnableTimestampsChange(event: React.ChangeEvent<HTMLInputElement>): void { function handleTimestampFormatChange(event: React.ChangeEvent<HTMLInputElement>): void {
setEnableTimestamps(event.target.checked); setTimestampFormat(event.target.value);
Settings.EnableTimestamps = event.target.checked; Settings.TimestampsFormat = event.target.value;
} }
function handleSaveGameOnFile(event: React.ChangeEvent<HTMLInputElement>): void { function handleSaveGameOnFile(event: React.ChangeEvent<HTMLInputElement>): void {
setSaveGameOnFileSave(event.target.checked); setSaveGameOnFileSave(event.target.checked);
@ -326,7 +320,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</Typography> </Typography>
} }
> >
<Typography>Suppress messages</Typography> <Typography>Suppress story messages</Typography>
</Tooltip> </Tooltip>
} }
/> />
@ -388,25 +382,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
} }
/> />
</ListItem> </ListItem>
<ListItem>
<FormControlLabel
control={
<Switch checked={suppressHospitalizationPopup} onChange={handleSuppressHospitalizationPopupChange} />
}
label={
<Tooltip
title={
<Typography>
If this is set, a popup message will no longer be shown when you are hospitalized after taking
too much damage.
</Typography>
}
>
<Typography>Suppress hospitalization popup</Typography>
</Tooltip>
}
/>
</ListItem>
{!!props.player.bladeburner && ( {!!props.player.bladeburner && (
<ListItem> <ListItem>
<FormControlLabel <FormControlLabel
@ -493,21 +468,28 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
/> />
</ListItem> </ListItem>
<ListItem> <ListItem>
<FormControlLabel <Tooltip
control={<Switch checked={enableTimestamps} onChange={handleEnableTimestampsChange} />} title={
label={ <Typography>
<Tooltip Terminal commands and log entries will be timestamped. See
title={ https://date-fns.org/docs/Getting-Started/
<Typography> </Typography>
Terminal commands and log entries will be timestamped. The timestamp will have the format: M/D
h:m
</Typography>
}
>
<Typography>Enable timestamps</Typography>
</Tooltip>
} }
/> >
<span>
<TextField
InputProps={{
startAdornment: (
<Typography color={formatTime(timestampFormat) === "format error" ? "error" : "success"}>
Timestamp&nbsp;format:&nbsp;
</Typography>
),
}}
value={timestampFormat}
onChange={handleTimestampFormatChange}
/>
</span>
</Tooltip>
</ListItem> </ListItem>
<ListItem> <ListItem>

@ -0,0 +1,10 @@
import { format } from "date-fns";
export function formatTime(fmt: string): string {
try {
return format(new Date(), fmt);
} catch (err: any) {
console.error(err);
return "format error";
}
}

@ -7,6 +7,7 @@ export function getTimestamp(): string {
const stringWidth = -2; const stringWidth = -2;
const formattedHours: string = `0${d.getHours()}`.slice(stringWidth); const formattedHours: string = `0${d.getHours()}`.slice(stringWidth);
const formattedMinutes: string = `0${d.getMinutes()}`.slice(stringWidth); const formattedMinutes: string = `0${d.getMinutes()}`.slice(stringWidth);
const formattedSeconds: string = `0${d.getSeconds()}`.slice(stringWidth);
return `${d.getMonth() + 1}/${d.getDate()} ${formattedHours}:${formattedMinutes}`; return `${d.getMonth() + 1}/${d.getDate()} ${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
} }