few more bugfixes

This commit is contained in:
Olivier Gagnon 2021-11-11 23:28:08 -05:00
parent a54e613e42
commit 3112dc60c0
24 changed files with 72 additions and 86 deletions

@ -16,7 +16,7 @@
* @type {Cypress.PluginConfig} * @type {Cypress.PluginConfig}
*/ */
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
module.exports = (on, config) => { module.exports = (/*on, config*/) => {
// `on` is used to hook into various events Cypress emits // `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config // `config` is the resolved Cypress config
}; };

34
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -102,8 +102,7 @@
"start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer", "start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer",
"build": "webpack --mode production", "build": "webpack --mode production",
"build:dev": "webpack --mode development", "build:dev": "webpack --mode development",
"lint": "npm run lint:jsts & npm run lint:style", "lint": "eslint --fix . --ext js,jsx,ts,tsx",
"lint:jsts": "eslint --fix . --ext js,jsx,ts,tsx",
"preinstall": "node ./scripts/engines-check.js", "preinstall": "node ./scripts/engines-check.js",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",

@ -132,7 +132,6 @@ module.exports = {
], ],
"new-cap": ["error"], "new-cap": ["error"],
"new-parens": ["error"], "new-parens": ["error"],
// TODO: configure this...
"newline-before-return": ["error"], "newline-before-return": ["error"],
"newline-per-chained-call": ["error"], "newline-per-chained-call": ["error"],
"no-alert": ["error"], "no-alert": ["error"],

@ -3,7 +3,7 @@ import { IMap } from "../types";
export const GeneralActions: IMap<Action> = {}; export const GeneralActions: IMap<Action> = {};
let actionNames : Array<string> = [ const actionNames : Array<string> = [
"Training", "Training",
"Field Analysis", "Field Analysis",
"Recruitment", "Recruitment",
@ -12,7 +12,7 @@ let actionNames : Array<string> = [
"Incite Violence" "Incite Violence"
]; ];
for (let actionName of actionNames){ for (const actionName of actionNames){
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
}); });

@ -147,7 +147,7 @@ export class Corporation {
const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle; const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle;
const totalDividends = (this.dividendPercentage / 100) * cycleProfit; const totalDividends = (this.dividendPercentage / 100) * cycleProfit;
const dividendsPerShare = totalDividends / this.totalShares; const dividendsPerShare = totalDividends / this.totalShares;
const dividends = this.numShares * dividendsPerShare * (1 - this.dividendTaxPercentage / 100); const dividends = this.numShares * dividendsPerShare;
let upgrades = -0.15; let upgrades = -0.15;
if (this.unlockUpgrades[5] === 1) { if (this.unlockUpgrades[5] === 1) {
upgrades += 0.05; upgrades += 0.05;

@ -78,7 +78,6 @@ interface IProps {
// Create a popup that lets the player use the Market TA research for Products // Create a popup that lets the player use the Market TA research for Products
export function ProductMarketTaModal(props: IProps): React.ReactElement { export function ProductMarketTaModal(props: IProps): React.ReactElement {
const division = useDivision();
const markupLimit = props.product.rat / props.product.mku; const markupLimit = props.product.rat / props.product.mku;
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {

@ -14,7 +14,6 @@ import { CONSTANTS } from "../../Constants";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { Faction } from "../../Faction/Faction"; import { Faction } from "../../Faction/Faction";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { CreateGangModal } from "./CreateGangModal"; import { CreateGangModal } from "./CreateGangModal";

@ -508,7 +508,6 @@ export function purchaseHashUpgrade(player: IPlayer, upgName: string, upgTarget:
} }
if (!(target instanceof Server)) throw new Error(`'${upgTarget}' is not a normal server.`); if (!(target instanceof Server)) throw new Error(`'${upgTarget}' is not a normal server.`);
const old = target.moneyMax;
target.changeMaximumMoney(upg.value); target.changeMaximumMoney(upg.value);
} catch (e) { } catch (e) {
player.hashManager.refundUpgrade(upgName); player.hashManager.refundUpgrade(upgName);

@ -136,7 +136,7 @@ function iTutorialPrevStep(): void {
function iTutorialEnd(): void { function iTutorialEnd(): void {
ITutorial.isRunning = false; ITutorial.isRunning = false;
ITutorial.currStep = iTutorialSteps.Start;
Player.getHomeComputer().messages.push(LiteratureNames.HackersStartingHandbook); Player.getHomeComputer().messages.push(LiteratureNames.HackersStartingHandbook);
ITutorialEvents.emit(); ITutorialEvents.emit();
} }

@ -430,7 +430,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const hacknet = NetscriptHacknet(Player, workerScript, helper); const hacknet = NetscriptHacknet(Player, workerScript, helper);
const bladeburner = NetscriptBladeburner(Player, workerScript, helper); const bladeburner = NetscriptBladeburner(Player, workerScript, helper);
const codingcontract = NetscriptCodingContract(Player, workerScript, helper); const codingcontract = NetscriptCodingContract(Player, workerScript, helper);
const corporation = NetscriptCorporation(Player, workerScript, helper); const corporation = NetscriptCorporation(Player);
const formulas = NetscriptFormulas(Player, workerScript, helper); const formulas = NetscriptFormulas(Player, workerScript, helper);
const singularity = NetscriptSingularity(Player, workerScript, helper); const singularity = NetscriptSingularity(Player, workerScript, helper);
const stockmarket = NetscriptStockMarket(Player, workerScript, helper); const stockmarket = NetscriptStockMarket(Player, workerScript, helper);

@ -1,5 +1,3 @@
import { INetscriptHelper } from "./INetscriptHelper";
import { WorkerScript } from "../Netscript/WorkerScript";
import { IPlayer } from "../PersonObjects/IPlayer"; import { IPlayer } from "../PersonObjects/IPlayer";
import { OfficeSpace } from "../Corporation/OfficeSpace"; import { OfficeSpace } from "../Corporation/OfficeSpace";
@ -88,11 +86,7 @@ export interface INetscriptCorporation {
getEmployee(divisionName: any, cityName: any, employeeName: any): any; getEmployee(divisionName: any, cityName: any, employeeName: any): any;
} }
export function NetscriptCorporation( export function NetscriptCorporation(player: IPlayer): INetscriptCorporation {
player: IPlayer,
workerScript: WorkerScript,
helper: INetscriptHelper,
): INetscriptCorporation {
function getDivision(divisionName: any): IIndustry { function getDivision(divisionName: any): IIndustry {
const corporation = player.corporation; const corporation = player.corporation;
if (corporation === null) throw new Error("cannot be called without a corporation"); if (corporation === null) throw new Error("cannot be called without a corporation");

@ -1,4 +1,3 @@
import { Corporation } from "./Corporation/Corporation";
import { PlayerObject } from "./PersonObjects/Player/PlayerObject"; import { PlayerObject } from "./PersonObjects/Player/PlayerObject";
import { sanitizeExploits } from "./Exploits/Exploit"; import { sanitizeExploits } from "./Exploits/Exploit";

@ -75,24 +75,7 @@ class BitburnerSaveObject {
const epochTime = Math.round(Date.now() / 1000); const epochTime = Math.round(Date.now() / 1000);
const bn = Player.bitNodeN; const bn = Player.bitNodeN;
const filename = `bitburnerSave_BN${bn}x${SourceFileFlags[bn]}_${epochTime}.json`; const filename = `bitburnerSave_BN${bn}x${SourceFileFlags[bn]}_${epochTime}.json`;
const file = new Blob([saveString], { type: "text/plain" }); download(filename, saveString);
const navigator = window.navigator as any;
if (navigator.msSaveOrOpenBlob) {
// IE10+
navigator.msSaveOrOpenBlob(file, filename);
} else {
// Others
const a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
} }
toJSON(): any { toJSON(): any {
@ -372,8 +355,29 @@ function createBetaUpdateText(): void {
); );
} }
function download(filename: string, content: string): void {
const file = new Blob([content], { type: "text/plain" });
const navigator = window.navigator as any;
if (navigator.msSaveOrOpenBlob) {
// IE10+
navigator.msSaveOrOpenBlob(file, filename);
} else {
// Others
const a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
Reviver.constructors.BitburnerSaveObject = BitburnerSaveObject; Reviver.constructors.BitburnerSaveObject = BitburnerSaveObject;
export { saveObject, loadGame }; export { saveObject, loadGame, download };
const saveObject = new BitburnerSaveObject(); const saveObject = new BitburnerSaveObject();

@ -4,7 +4,6 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers"; import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers";
import Typography from "@mui/material/Typography";
export function ls( export function ls(
terminal: ITerminal, terminal: ITerminal,

@ -3,6 +3,7 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { isScriptFilename } from "../../Script/isScriptFilename"; import { isScriptFilename } from "../../Script/isScriptFilename";
import { CursorPositions } from "../../ScriptEditor/CursorPositions";
export function nano( export function nano(
terminal: ITerminal, terminal: ITerminal,
@ -24,13 +25,15 @@ export function nano(
if (script == null) { if (script == null) {
let code = ""; let code = "";
if (filename.endsWith(".ns") || filename.endsWith(".js")) { if (filename.endsWith(".ns") || filename.endsWith(".js")) {
code = `/** code = `/** @param {NS} ns **/
* @param {NS} ns
**/
export async function main(ns) { export async function main(ns) {
}`; }`;
} }
CursorPositions.saveCursor(filename, {
row: 3,
column: 5,
});
router.toScriptEditor(filepath, code); router.toScriptEditor(filepath, code);
} else { } else {
router.toScriptEditor(filepath, script.code); router.toScriptEditor(filepath, script.code);

@ -2,7 +2,6 @@ import { ITerminal } from "../ITerminal";
import { IRouter } from "../../ui/Router"; import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { Message } from "../../Message/Message";
import { GetServer } from "../../Server/AllServers"; import { GetServer } from "../../Server/AllServers";
import { isScriptFilename } from "../../Script/isScriptFilename"; import { isScriptFilename } from "../../Script/isScriptFilename";

@ -33,8 +33,8 @@ function getDB(): Promise<IDBObjectStore> {
} }
export function load(): Promise<string> { export function load(): Promise<string> {
return new Promise(async (resolve, reject) => { return new Promise((resolve, reject) => {
await getDB() getDB()
.then((db) => { .then((db) => {
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
const request: IDBRequest<string> = db.get("save"); const request: IDBRequest<string> = db.get("save");

@ -480,7 +480,13 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<TextField <TextField
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<Typography color={formatTime(timestampFormat) === "format error" ? "error" : "success"}> <Typography
color={
formatTime(timestampFormat) === "format error" && timestampFormat !== ""
? "error"
: "success"
}
>
Timestamp&nbsp;format:&nbsp; Timestamp&nbsp;format:&nbsp;
</Typography> </Typography>
), ),

@ -3,8 +3,9 @@ import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { saveObject } from "../../SaveObject"; import { load } from "../../db";
import { IRouter } from "../Router"; import { IRouter } from "../Router";
import { download } from "../../SaveObject";
export let RecoveryMode = false; export let RecoveryMode = false;
@ -22,7 +23,9 @@ export function RecoveryRoot({ router }: IProps): React.ReactElement {
router.toTerminal(); router.toTerminal();
} }
Settings.AutosaveInterval = 0; Settings.AutosaveInterval = 0;
saveObject.exportGame(); load().then((content) => {
download("RECOVERY.json", content);
});
return ( return (
<> <>
<Typography variant="h3">RECOVERY MODE ACTIVATED</Typography> <Typography variant="h3">RECOVERY MODE ACTIVATED</Typography>

@ -1,21 +1,6 @@
/** /**
* Generic Event Emitter class following a subscribe/publish paradigm. * Generic Event Emitter class following a subscribe/publish paradigm.
*/ */
type cbFn = (...args: any[]) => any;
interface ISubscriber {
/**
* Callback function that will be run when an event is emitted
*/
cb: cbFn;
/**
* Name/identifier for this subscriber
*/
id: string;
}
function uuidv4(): string { function uuidv4(): string {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0, const r = (Math.random() * 16) | 0,

@ -3,7 +3,6 @@ import { determineAllPossibilitiesForTabCompletion } from "../../src/Terminal/de
import { Server } from "../../src/Server/Server"; import { Server } from "../../src/Server/Server";
import { AddToAllServers, prestigeAllServers } from "../../src/Server/AllServers"; import { AddToAllServers, prestigeAllServers } from "../../src/Server/AllServers";
import { LocationName } from "../../src/Locations/data/LocationNames"; import { LocationName } from "../../src/Locations/data/LocationNames";
import { Message } from "../../src/Message/Message";
import { CodingContract } from "../../src/CodingContracts"; import { CodingContract } from "../../src/CodingContracts";
describe("determineAllPossibilitiesForTabCompletion", function () { describe("determineAllPossibilitiesForTabCompletion", function () {