mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-17 13:13:49 +01:00
CODEBASE: Fix lint errors 1 (#1732)
This commit is contained in:
parent
f7ee3a340f
commit
f6502dd490
@ -34,6 +34,7 @@ module.exports = {
|
|||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"react/no-unescaped-entities": "off",
|
"react/no-unescaped-entities": "off",
|
||||||
|
"@typescript-eslint/restrict-template-expressions": "off",
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
react: {
|
react: {
|
||||||
|
17
src/@types/global.d.ts
vendored
17
src/@types/global.d.ts
vendored
@ -31,4 +31,21 @@ declare global {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "loader" is not exposed in the public API.
|
||||||
|
*/
|
||||||
|
module "monaco-editor" {
|
||||||
|
namespace languages {
|
||||||
|
interface ILanguageExtensionPoint {
|
||||||
|
loader: () => Promise<{
|
||||||
|
language: {
|
||||||
|
tokenizer: {
|
||||||
|
root: any[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContrac
|
|||||||
try {
|
try {
|
||||||
return Factions[fac].getInfo().offerHackingWork;
|
return Factions[fac].getInfo().offerHackingWork;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
console.error("Error when trying to filter Hacking Factions for Coding Contract Generation", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -207,8 +207,8 @@ export function sellMaterial(material: Material, amount: string, price: string):
|
|||||||
try {
|
try {
|
||||||
if (temp.includes("MP")) throw "Only one reference to MP is allowed in sell price.";
|
if (temp.includes("MP")) throw "Only one reference to MP is allowed in sell price.";
|
||||||
temp = eval?.(temp);
|
temp = eval?.(temp);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
throw new Error("Invalid value or expression for sell price field: " + e);
|
throw new Error("Invalid value or expression for sell price field", { cause: error });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp == null || isNaN(parseFloat(temp))) {
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
@ -231,8 +231,8 @@ export function sellMaterial(material: Material, amount: string, price: string):
|
|||||||
tempQty = tempQty.replace(/INV/g, material.productionAmount.toString());
|
tempQty = tempQty.replace(/INV/g, material.productionAmount.toString());
|
||||||
try {
|
try {
|
||||||
tempQty = eval?.(tempQty);
|
tempQty = eval?.(tempQty);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
throw new Error("Invalid value or expression for sell quantity field", { cause: error });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempQty == null || isNaN(parseFloat(tempQty))) {
|
if (tempQty == null || isNaN(parseFloat(tempQty))) {
|
||||||
@ -263,8 +263,8 @@ export function sellProduct(product: Product, city: CityName, amt: string, price
|
|||||||
try {
|
try {
|
||||||
if (temp.includes("MP")) throw "Only one reference to MP is allowed in sell price.";
|
if (temp.includes("MP")) throw "Only one reference to MP is allowed in sell price.";
|
||||||
temp = eval?.(temp);
|
temp = eval?.(temp);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
throw new Error("Invalid value or expression for sell price field: " + e);
|
throw new Error("Invalid value or expression for sell price field.", { cause: error });
|
||||||
}
|
}
|
||||||
if (temp == null || isNaN(parseFloat(temp))) {
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
throw new Error("Invalid value or expression for sell price field.");
|
throw new Error("Invalid value or expression for sell price field.");
|
||||||
@ -291,8 +291,8 @@ export function sellProduct(product: Product, city: CityName, amt: string, price
|
|||||||
temp = temp.replace(/INV/g, product.cityData[city].stored.toString());
|
temp = temp.replace(/INV/g, product.cityData[city].stored.toString());
|
||||||
try {
|
try {
|
||||||
temp = eval?.(temp);
|
temp = eval?.(temp);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
throw new Error("Invalid value or expression for sell quantity field", { cause: error });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp == null || isNaN(parseFloat(temp))) {
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
@ -585,13 +585,16 @@ Attempted export amount: ${amount}`);
|
|||||||
}
|
}
|
||||||
if (!error && isNaN(evaluated)) error = "evaluated value is NaN";
|
if (!error && isNaN(evaluated)) error = "evaluated value is NaN";
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new Error(`Error while trying to set the exported amount of ${material.name}.
|
throw new Error(
|
||||||
|
`Error while trying to set the exported amount of ${material.name}.
|
||||||
Error occurred while testing keyword replacement with ${testReplacement}.
|
Error occurred while testing keyword replacement with ${testReplacement}.
|
||||||
Your input: ${amount}
|
Your input: ${amount}
|
||||||
Sanitized input: ${sanitizedAmt}
|
Sanitized input: ${sanitizedAmt}
|
||||||
Input after replacement: ${replaced}
|
Input after replacement: ${replaced}
|
||||||
Evaluated value: ${evaluated}
|
Evaluated value: ${evaluated}` +
|
||||||
Error encountered: ${error}`);
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||||
|
`Error encountered: ${error}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ export function ExpandNewCity(props: IProps): React.ReactElement {
|
|||||||
function expand(): void {
|
function expand(): void {
|
||||||
try {
|
try {
|
||||||
purchaseOffice(corp, division, city);
|
purchaseOffice(corp, division, city);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ export function NewDivisionTab(props: IProps): React.ReactElement {
|
|||||||
if (disabledText) return;
|
if (disabledText) return;
|
||||||
try {
|
try {
|
||||||
createDivision(corp, industry, name);
|
createDivision(corp, industry, name);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ export function BuybackSharesModal(props: IProps): React.ReactElement {
|
|||||||
props.onClose();
|
props.onClose();
|
||||||
props.rerender();
|
props.rerender();
|
||||||
setShares(NaN);
|
setShares(NaN);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(`${err}`);
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ export function ExportModal(props: ExportModalProps): React.ReactElement {
|
|||||||
try {
|
try {
|
||||||
if (!targetDivision || !targetCity) return;
|
if (!targetDivision || !targetCity) return;
|
||||||
actions.exportMaterial(targetDivision, targetCity, props.mat, exportAmount);
|
actions.exportMaterial(targetDivision, targetCity, props.mat, exportAmount);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ export function FindInvestorsModal(props: IProps): React.ReactElement {
|
|||||||
);
|
);
|
||||||
props.onClose();
|
props.onClose();
|
||||||
props.rerender();
|
props.rerender();
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(`${err}`);
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +45,8 @@ export function GoPublicModal(props: IProps): React.ReactElement {
|
|||||||
props.onClose();
|
props.onClose();
|
||||||
props.rerender();
|
props.rerender();
|
||||||
setShares(NaN);
|
setShares(NaN);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(`${err}`);
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ export function IssueDividendsModal(props: IProps): React.ReactElement {
|
|||||||
if (percent === null) return;
|
if (percent === null) return;
|
||||||
try {
|
try {
|
||||||
actions.issueDividends(corp, percent / 100);
|
actions.issueDividends(corp, percent / 100);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
|
@ -55,8 +55,8 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
|
|||||||
);
|
);
|
||||||
props.onClose();
|
props.onClose();
|
||||||
props.rerender();
|
props.rerender();
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(`${err}`);
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ export function MakeProductModal(props: IProps): React.ReactElement {
|
|||||||
if (isNaN(design) || isNaN(marketing)) return;
|
if (isNaN(design) || isNaN(marketing)) return;
|
||||||
try {
|
try {
|
||||||
actions.makeProduct(corp, division, city, name, design, marketing);
|
actions.makeProduct(corp, division, city, name, design, marketing);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ function BulkPurchaseSection(props: IBPProps): React.ReactElement {
|
|||||||
function bulkPurchase(): void {
|
function bulkPurchase(): void {
|
||||||
try {
|
try {
|
||||||
actions.bulkPurchase(corp, division, props.warehouse, props.mat, parseFloat(buyAmt));
|
actions.bulkPurchase(corp, division, props.warehouse, props.mat, parseFloat(buyAmt));
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
@ -119,8 +119,8 @@ export function PurchaseMaterialModal(props: IProps): React.ReactElement {
|
|||||||
if (buyAmt === null) return;
|
if (buyAmt === null) return;
|
||||||
try {
|
try {
|
||||||
actions.buyMaterial(division, props.mat, buyAmt);
|
actions.buyMaterial(division, props.mat, buyAmt);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
|
@ -39,8 +39,8 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement {
|
|||||||
if (n === null || disabled) return;
|
if (n === null || disabled) return;
|
||||||
try {
|
try {
|
||||||
actions.research(division, n.researchName);
|
actions.research(division, n.researchName);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ export function SellMaterialModal(props: IProps): React.ReactElement {
|
|||||||
function sellMaterial(): void {
|
function sellMaterial(): void {
|
||||||
try {
|
try {
|
||||||
actions.sellMaterial(props.mat, amt, price);
|
actions.sellMaterial(props.mat, amt, price);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ export function SellProductModal(props: IProps): React.ReactElement {
|
|||||||
function sellProduct(): void {
|
function sellProduct(): void {
|
||||||
try {
|
try {
|
||||||
actions.sellProduct(props.product, props.city, iQty, px, checked);
|
actions.sellProduct(props.product, props.city, iQty, px, checked);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
|
@ -27,8 +27,9 @@ function SSoption(props: ISSoptionProps): React.ReactElement {
|
|||||||
const matName = props.matName;
|
const matName = props.matName;
|
||||||
const material = props.warehouse.materials[matName];
|
const material = props.warehouse.materials[matName];
|
||||||
setSmartSupplyOption(props.warehouse, material, newValue);
|
setSmartSupplyOption(props.warehouse, material, newValue);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
setChecked(newValue);
|
setChecked(newValue);
|
||||||
}
|
}
|
||||||
@ -40,8 +41,9 @@ function SSoption(props: ISSoptionProps): React.ReactElement {
|
|||||||
const matName = props.matName;
|
const matName = props.matName;
|
||||||
const material = props.warehouse.materials[matName];
|
const material = props.warehouse.materials[matName];
|
||||||
setSmartSupplyOption(props.warehouse, material, newValue);
|
setSmartSupplyOption(props.warehouse, material, newValue);
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(String(error));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
setChecked(newValue);
|
setChecked(newValue);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import { CONSTANTS } from "./Constants";
|
|||||||
import { commitHash } from "./utils/helpers/commitHash";
|
import { commitHash } from "./utils/helpers/commitHash";
|
||||||
import { resolveFilePath } from "./Paths/FilePath";
|
import { resolveFilePath } from "./Paths/FilePath";
|
||||||
import { hasScriptExtension } from "./Paths/ScriptFilePath";
|
import { hasScriptExtension } from "./Paths/ScriptFilePath";
|
||||||
import { handleGetSaveDataError } from "./Netscript/ErrorMessages";
|
import { handleGetSaveDataInfoError } from "./Netscript/ErrorMessages";
|
||||||
|
|
||||||
interface IReturnWebStatus extends IReturnStatus {
|
interface IReturnWebStatus extends IReturnStatus {
|
||||||
data?: Record<string, unknown>;
|
data?: Record<string, unknown>;
|
||||||
@ -103,14 +103,14 @@ function initAppNotifier(): void {
|
|||||||
const funcs = {
|
const funcs = {
|
||||||
terminal: (message: string, type?: string) => {
|
terminal: (message: string, type?: string) => {
|
||||||
const typesFn: Record<string, (s: string) => void> = {
|
const typesFn: Record<string, (s: string) => void> = {
|
||||||
info: Terminal.info,
|
info: (s) => Terminal.info(s),
|
||||||
warn: Terminal.warn,
|
warn: (s) => Terminal.warn(s),
|
||||||
error: Terminal.error,
|
error: (s) => Terminal.error(s),
|
||||||
success: Terminal.success,
|
success: (s) => Terminal.success(s),
|
||||||
};
|
};
|
||||||
let fn;
|
let fn;
|
||||||
if (type) fn = typesFn[type];
|
if (type) fn = typesFn[type];
|
||||||
if (!fn) fn = Terminal.print;
|
if (!fn) fn = (s: string) => Terminal.print(s);
|
||||||
fn.bind(Terminal)(message);
|
fn.bind(Terminal)(message);
|
||||||
},
|
},
|
||||||
toast: (message: string, type: ToastVariant, duration = 2000) => SnackbarEvents.emit(message, type, duration),
|
toast: (message: string, type: ToastVariant, duration = 2000) => SnackbarEvents.emit(message, type, duration),
|
||||||
@ -124,12 +124,10 @@ function initSaveFunctions(): void {
|
|||||||
const funcs = {
|
const funcs = {
|
||||||
triggerSave: (): Promise<void> => saveObject.saveGame(true),
|
triggerSave: (): Promise<void> => saveObject.saveGame(true),
|
||||||
triggerGameExport: (): void => {
|
triggerGameExport: (): void => {
|
||||||
try {
|
saveObject.exportGame().catch((error) => {
|
||||||
saveObject.exportGame();
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000);
|
SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000);
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
triggerScriptsExport: (): void => exportScripts("*", Player.getHomeComputer()),
|
triggerScriptsExport: (): void => exportScripts("*", Player.getHomeComputer()),
|
||||||
getSaveData: async (): Promise<{ save: SaveData; fileName: string }> => {
|
getSaveData: async (): Promise<{ save: SaveData; fileName: string }> => {
|
||||||
@ -159,22 +157,28 @@ function initElectronBridge(): void {
|
|||||||
const bridge = window.electronBridge;
|
const bridge = window.electronBridge;
|
||||||
if (!bridge) return;
|
if (!bridge) return;
|
||||||
|
|
||||||
bridge.receive("get-save-data-request", async () => {
|
bridge.receive("get-save-data-request", () => {
|
||||||
let saveData;
|
window.appSaveFns
|
||||||
try {
|
.getSaveData()
|
||||||
saveData = await window.appSaveFns.getSaveData();
|
.then((saveData) => {
|
||||||
} catch (error) {
|
bridge.send("get-save-data-response", saveData);
|
||||||
handleGetSaveDataError(error);
|
})
|
||||||
return;
|
.catch((error) => {
|
||||||
}
|
handleGetSaveDataInfoError(error);
|
||||||
bridge.send("get-save-data-response", saveData);
|
});
|
||||||
});
|
});
|
||||||
bridge.receive("get-save-info-request", async (saveData: unknown) => {
|
bridge.receive("get-save-info-request", (saveData: unknown) => {
|
||||||
if (typeof saveData !== "string" && !(saveData instanceof Uint8Array)) {
|
if (typeof saveData !== "string" && !(saveData instanceof Uint8Array)) {
|
||||||
throw new Error("Error while trying to get save info");
|
throw new Error("Error while trying to get save info");
|
||||||
}
|
}
|
||||||
const saveInfo = await window.appSaveFns.getSaveInfo(saveData);
|
window.appSaveFns
|
||||||
bridge.send("get-save-info-response", saveInfo);
|
.getSaveInfo(saveData)
|
||||||
|
.then((saveInfo) => {
|
||||||
|
bridge.send("get-save-info-response", saveInfo);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
handleGetSaveDataInfoError(error, true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
bridge.receive("push-save-request", (params: unknown) => {
|
bridge.receive("push-save-request", (params: unknown) => {
|
||||||
if (typeof params !== "object") throw new Error("Error trying to push save request");
|
if (typeof params !== "object") throw new Error("Error trying to push save request");
|
||||||
@ -182,7 +186,7 @@ function initElectronBridge(): void {
|
|||||||
window.appSaveFns.pushSaveData(save, automatic);
|
window.appSaveFns.pushSaveData(save, automatic);
|
||||||
});
|
});
|
||||||
bridge.receive("trigger-save", () => {
|
bridge.receive("trigger-save", () => {
|
||||||
return window.appSaveFns
|
window.appSaveFns
|
||||||
.triggerSave()
|
.triggerSave()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
bridge.send("save-completed");
|
bridge.send("save-completed");
|
||||||
|
@ -97,7 +97,7 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
|
|||||||
startWork();
|
startWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a special flag for whether the player this faction is the player's
|
// We have a special flag for whether this faction is the player's
|
||||||
// gang faction because if the player has a gang, they cannot do any other action
|
// gang faction because if the player has a gang, they cannot do any other action
|
||||||
const isPlayersGang = Player.gang && Player.getGangName() === faction.name;
|
const isPlayersGang = Player.gang && Player.getGangName() === faction.name;
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => {
|
|||||||
try {
|
try {
|
||||||
await saveObject.importGame(importData.saveData);
|
await saveObject.importGame(importData.saveData);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
|
console.error(e);
|
||||||
SnackbarEvents.emit(String(e), ToastVariant.ERROR, 5000);
|
SnackbarEvents.emit(String(e), ToastVariant.ERROR, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ export class Gang {
|
|||||||
this.processTerritoryAndPowerGains(cycles);
|
this.processTerritoryAndPowerGains(cycles);
|
||||||
this.storedCycles -= cycles;
|
this.storedCycles -= cycles;
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
console.error(`Exception caught when processing Gang: ${e}`);
|
console.error("Exception caught when processing Gang", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle "nextUpdate" resolver after this update
|
// Handle "nextUpdate" resolver after this update
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let result;
|
|
||||||
|
|
||||||
do {
|
|
||||||
const board = ns.go.getBoardState();
|
|
||||||
const validMoves = ns.go.analysis.getValidMoves();
|
|
||||||
|
|
||||||
const [growX, growY] = getGrowMove(board, validMoves);
|
|
||||||
const [randX, randY] = getRandomMove(board, validMoves);
|
|
||||||
// Try to pick a grow move, otherwise choose a random move
|
|
||||||
const x = growX ?? randX;
|
|
||||||
const y = growY ?? randY;
|
|
||||||
|
|
||||||
if (x === undefined) {
|
|
||||||
// Pass turn if no moves are found
|
|
||||||
result = await ns.go.passTurn();
|
|
||||||
} else {
|
|
||||||
// Play the selected move
|
|
||||||
result = await ns.go.makeMove(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ns.sleep(100);
|
|
||||||
} while (result?.type !== "gameOver" && result?.type !== "pass");
|
|
||||||
|
|
||||||
// After the opponent passes, end the game by passing as well
|
|
||||||
await ns.go.passTurn();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Choose one of the empty points on the board at random to play
|
|
||||||
*/
|
|
||||||
const getRandomMove = (board, validMoves) => {
|
|
||||||
const moveOptions = [];
|
|
||||||
const size = board[0].length;
|
|
||||||
|
|
||||||
// Look through all the points on the board
|
|
||||||
for (let x = 0; x < size; x++) {
|
|
||||||
for (let y = 0; y < size; y++) {
|
|
||||||
// Make sure the point is a valid move
|
|
||||||
const isValidMove = validMoves[x][y];
|
|
||||||
// Leave some spaces to make it harder to capture our pieces
|
|
||||||
const isNotReservedSpace = x % 2 || y % 2;
|
|
||||||
|
|
||||||
if (isValidMove && isNotReservedSpace) {
|
|
||||||
moveOptions.push([x, y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose one of the found moves at random
|
|
||||||
const randomIndex = Math.floor(Math.random() * moveOptions.length);
|
|
||||||
return moveOptions[randomIndex] ?? [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Choose a point connected to a friendly stone to play
|
|
||||||
*/
|
|
||||||
const getGrowMove = (board, validMoves) => {
|
|
||||||
const moveOptions = [];
|
|
||||||
const size = board[0].length;
|
|
||||||
|
|
||||||
// Look through all the points on the board
|
|
||||||
for (let x = 0; x < size; x++) {
|
|
||||||
for (let y = 0; y < size; y++) {
|
|
||||||
// make sure the move is valid
|
|
||||||
const isValidMove = validMoves[x][y];
|
|
||||||
// Leave some open spaces to make it harder to capture our pieces
|
|
||||||
const isNotReservedSpace = x % 2 || y % 2;
|
|
||||||
|
|
||||||
// Make sure we are connected to a friendly piece
|
|
||||||
const neighbors = getNeighbors(board, x, y);
|
|
||||||
const hasFriendlyNeighbor = neighbors.includes("X");
|
|
||||||
|
|
||||||
if (isValidMove && isNotReservedSpace && hasFriendlyNeighbor) {
|
|
||||||
moveOptions.push([x, y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose one of the found moves at random
|
|
||||||
const randomIndex = Math.floor(Math.random() * moveOptions.length);
|
|
||||||
return moveOptions[randomIndex] ?? [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find all adjacent points in the four connected directions
|
|
||||||
*/
|
|
||||||
const getNeighbors = (board, x, y) => {
|
|
||||||
const north = board[x + 1]?.[y];
|
|
||||||
const east = board[x][y + 1];
|
|
||||||
const south = board[x - 1]?.[y];
|
|
||||||
const west = board[x]?.[y - 1];
|
|
||||||
|
|
||||||
return [north, east, south, west];
|
|
||||||
};
|
|
@ -20,6 +20,7 @@ import { GoSubnetSearch } from "./GoSubnetSearch";
|
|||||||
import { CorruptableText } from "../../ui/React/CorruptableText";
|
import { CorruptableText } from "../../ui/React/CorruptableText";
|
||||||
import { makeAIMove, resetAI, resolveCurrentTurn } from "../boardAnalysis/goAI";
|
import { makeAIMove, resetAI, resolveCurrentTurn } from "../boardAnalysis/goAI";
|
||||||
import { GoScoreExplanation } from "./GoScoreExplanation";
|
import { GoScoreExplanation } from "./GoScoreExplanation";
|
||||||
|
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
interface GoGameboardWrapperProps {
|
interface GoGameboardWrapperProps {
|
||||||
showInstructions: () => void;
|
showInstructions: () => void;
|
||||||
@ -63,7 +64,7 @@ export function GoGameboardWrapper({ showInstructions }: GoGameboardWrapperProps
|
|||||||
|
|
||||||
// Do not implement useCallback for this function without ensuring GoGameboard still rerenders for every move
|
// Do not implement useCallback for this function without ensuring GoGameboard still rerenders for every move
|
||||||
// Currently this function changing is what triggers a GoGameboard rerender, which is needed
|
// Currently this function changing is what triggers a GoGameboard rerender, which is needed
|
||||||
async function clickHandler(x: number, y: number) {
|
function clickHandler(x: number, y: number) {
|
||||||
if (showPriorMove) {
|
if (showPriorMove) {
|
||||||
SnackbarEvents.emit(
|
SnackbarEvents.emit(
|
||||||
`Currently showing a past board state. Please disable "Show previous move" to continue.`,
|
`Currently showing a past board state. Please disable "Show previous move" to continue.`,
|
||||||
@ -94,7 +95,7 @@ export function GoGameboardWrapper({ showInstructions }: GoGameboardWrapperProps
|
|||||||
const didUpdateBoard = makeMove(boardState, x, y, currentPlayer);
|
const didUpdateBoard = makeMove(boardState, x, y, currentPlayer);
|
||||||
if (didUpdateBoard) {
|
if (didUpdateBoard) {
|
||||||
rerender();
|
rerender();
|
||||||
takeAiTurn(boardState);
|
takeAiTurn(boardState).catch((error) => exceptionAlert(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ export function GoGameboardWrapper({ showInstructions }: GoGameboardWrapperProps
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
takeAiTurn(boardState);
|
takeAiTurn(boardState).catch((error) => exceptionAlert(error));
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +99,13 @@ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, i
|
|||||||
Error has been logged to the console.\n\nType of error: ${typeof e}\nValue of error: ${e}`;
|
Error has been logged to the console.\n\nType of error: ${typeof e}\nValue of error: ${e}`;
|
||||||
e = ws ? basicErrorMessage(ws, msg, "UNKNOWN") : msg;
|
e = ws ? basicErrorMessage(ws, msg, "UNKNOWN") : msg;
|
||||||
}
|
}
|
||||||
dialogBoxCreate(initialText + e);
|
dialogBoxCreate(initialText + String(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Use this handler to handle the error when we call getSaveData function */
|
/** Use this handler to handle the error when we call getSaveData function or getSaveInfo function */
|
||||||
export function handleGetSaveDataError(error: unknown) {
|
export function handleGetSaveDataInfoError(error: unknown, fromGetSaveInfo = false) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
let errorMessage = `Cannot get save data. Error: ${error}.`;
|
let errorMessage = `Cannot get save ${fromGetSaveInfo ? "info" : "data"}. Error: ${error}.`;
|
||||||
if (error instanceof RangeError) {
|
if (error instanceof RangeError) {
|
||||||
errorMessage += " This may be because the save data is too large.";
|
errorMessage += " This may be because the save data is too large.";
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ function spawnOptions(ctx: NetscriptContext, threadOrOption: unknown): CompleteS
|
|||||||
function mapToString(map: Map<unknown, unknown>): string {
|
function mapToString(map: Map<unknown, unknown>): string {
|
||||||
const formattedMap = [...map]
|
const formattedMap = [...map]
|
||||||
.map((m) => {
|
.map((m) => {
|
||||||
return `${m[0]} => ${m[1]}`;
|
return `${String(m[0])} => ${String(m[1])}`;
|
||||||
})
|
})
|
||||||
.join("; ");
|
.join("; ");
|
||||||
return `< Map: ${formattedMap} >`;
|
return `< Map: ${formattedMap} >`;
|
||||||
@ -245,7 +245,7 @@ function setToString(set: Set<unknown>): string {
|
|||||||
/** Convert multiple arguments for tprint or print into a single string. */
|
/** Convert multiple arguments for tprint or print into a single string. */
|
||||||
function argsToString(args: unknown[]): string {
|
function argsToString(args: unknown[]): string {
|
||||||
// Reduce array of args into a single output string
|
// Reduce array of args into a single output string
|
||||||
return args.reduce((out, arg) => {
|
return args.reduce((out: string, arg) => {
|
||||||
if (arg === null) {
|
if (arg === null) {
|
||||||
return (out += "null");
|
return (out += "null");
|
||||||
}
|
}
|
||||||
@ -264,12 +264,13 @@ function argsToString(args: unknown[]): string {
|
|||||||
return (out += setToString(nativeArg));
|
return (out += setToString(nativeArg));
|
||||||
}
|
}
|
||||||
if (typeof nativeArg === "object") {
|
if (typeof nativeArg === "object") {
|
||||||
return (out += JSON.stringify(nativeArg, (_, value) => {
|
return (out += JSON.stringify(nativeArg, (_, value: unknown) => {
|
||||||
/**
|
/**
|
||||||
* If the property is a promise, we will return a string that clearly states that it's a promise object, not a
|
* If the property is a promise, we will return a string that clearly states that it's a promise object, not a
|
||||||
* normal object. If we don't do that, all promises will be serialized into "{}".
|
* normal object. If we don't do that, all promises will be serialized into "{}".
|
||||||
*/
|
*/
|
||||||
if (value instanceof Promise) {
|
if (value instanceof Promise) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string -- "[object Promise]" is exactly the string that we want.
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
if (value instanceof Map) {
|
if (value instanceof Map) {
|
||||||
@ -282,8 +283,8 @@ function argsToString(args: unknown[]): string {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (out += `${nativeArg}`);
|
return (out += String(nativeArg));
|
||||||
}, "") as string;
|
}, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateHGWOptions(ctx: NetscriptContext, opts: unknown): CompleteHGWOptions {
|
function validateHGWOptions(ctx: NetscriptContext, opts: unknown): CompleteHGWOptions {
|
||||||
@ -296,6 +297,7 @@ function validateHGWOptions(ctx: NetscriptContext, opts: unknown): CompleteHGWOp
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (typeof opts !== "object") {
|
if (typeof opts !== "object") {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||||
throw errorMessage(ctx, `BasicHGWOptions must be an object if specified, was ${opts}`);
|
throw errorMessage(ctx, `BasicHGWOptions must be an object if specified, was ${opts}`);
|
||||||
}
|
}
|
||||||
// Safe assertion since threadOrOption type has been narrowed to a non-null object
|
// Safe assertion since threadOrOption type has been narrowed to a non-null object
|
||||||
@ -723,7 +725,7 @@ function createPublicRunningScript(runningScript: RunningScript, workerScript?:
|
|||||||
args: runningScript.args.slice(),
|
args: runningScript.args.slice(),
|
||||||
dynamicRamUsage: workerScript && roundToTwo(workerScript.dynamicRamUsage),
|
dynamicRamUsage: workerScript && roundToTwo(workerScript.dynamicRamUsage),
|
||||||
filename: runningScript.filename,
|
filename: runningScript.filename,
|
||||||
logs: runningScript.logs.map((x) => "" + x),
|
logs: runningScript.logs.map((x) => String(x)),
|
||||||
offlineExpGained: runningScript.offlineExpGained,
|
offlineExpGained: runningScript.offlineExpGained,
|
||||||
offlineMoneyMade: runningScript.offlineMoneyMade,
|
offlineMoneyMade: runningScript.offlineMoneyMade,
|
||||||
offlineRunningTime: runningScript.offlineRunningTime,
|
offlineRunningTime: runningScript.offlineRunningTime,
|
||||||
@ -782,13 +784,21 @@ function validateBitNodeOptions(ctx: NetscriptContext, bitNodeOptions: unknown):
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (typeof bitNodeOptions !== "object") {
|
if (typeof bitNodeOptions !== "object") {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||||
throw errorMessage(ctx, `bitNodeOptions must be an object if it's specified. It was ${bitNodeOptions}.`);
|
throw errorMessage(ctx, `bitNodeOptions must be an object if it's specified. It was ${bitNodeOptions}.`);
|
||||||
}
|
}
|
||||||
const options = bitNodeOptions as Unknownify<BitNodeOptions>;
|
const options = bitNodeOptions as Unknownify<BitNodeOptions>;
|
||||||
if (!(options.sourceFileOverrides instanceof Map)) {
|
if (!(options.sourceFileOverrides instanceof Map)) {
|
||||||
throw errorMessage(ctx, `sourceFileOverrides must be a Map.`);
|
throw errorMessage(ctx, `sourceFileOverrides must be a Map.`);
|
||||||
}
|
}
|
||||||
const validationResultForSourceFileOverrides = validateSourceFileOverrides(options.sourceFileOverrides, true);
|
const validationResultForSourceFileOverrides = validateSourceFileOverrides(
|
||||||
|
/**
|
||||||
|
* Cast the type from Map<any, any> to Map<number, number> to satisfy the lint rule. The validation logic in
|
||||||
|
* validateSourceFileOverrides will check the data.
|
||||||
|
*/
|
||||||
|
options.sourceFileOverrides as Map<number, number>,
|
||||||
|
true,
|
||||||
|
);
|
||||||
if (!validationResultForSourceFileOverrides.valid) {
|
if (!validationResultForSourceFileOverrides.valid) {
|
||||||
throw errorMessage(
|
throw errorMessage(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -542,7 +542,7 @@ export const ns: InternalAPI<NSFull> = {
|
|||||||
return [] as string[];
|
return [] as string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
return runningScriptObj.logs.map((x) => "" + x);
|
return runningScriptObj.logs.map((x) => String(x));
|
||||||
},
|
},
|
||||||
tail:
|
tail:
|
||||||
(ctx) =>
|
(ctx) =>
|
||||||
@ -1870,7 +1870,7 @@ function getFunctionNames(obj: object, prefix: string): string[] {
|
|||||||
} else if (typeof value === "function") {
|
} else if (typeof value === "function") {
|
||||||
functionNames.push(prefix + key);
|
functionNames.push(prefix + key);
|
||||||
} else if (typeof value === "object") {
|
} else if (typeof value === "object") {
|
||||||
functionNames.push(...getFunctionNames(value, `${prefix}${key}.`));
|
functionNames.push(...getFunctionNames(value as object, `${prefix}${key}.`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return functionNames;
|
return functionNames;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { Singularity as ISingularity, Task as ITask } from "@nsdefs";
|
import type { Singularity as ISingularity } from "@nsdefs";
|
||||||
|
|
||||||
import { Player } from "@player";
|
import { Player } from "@player";
|
||||||
import { AugmentationName, CityName, FactionWorkType, GymType, LocationName, UniversityClassType } from "@enums";
|
import { AugmentationName, CityName, FactionWorkType, GymType, LocationName, UniversityClassType } from "@enums";
|
||||||
@ -1142,7 +1142,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
|||||||
? resolveScriptFilePath(helpers.string(ctx, "cbScript", _cbScript), ctx.workerScript.name)
|
? resolveScriptFilePath(helpers.string(ctx, "cbScript", _cbScript), ctx.workerScript.name)
|
||||||
: false;
|
: false;
|
||||||
if (cbScript === null) {
|
if (cbScript === null) {
|
||||||
throw helpers.errorMessage(ctx, `Could not resolve file path: ${_cbScript}`);
|
throw helpers.errorMessage(ctx, `Could not resolve file path. callbackScript is null.`);
|
||||||
}
|
}
|
||||||
enterBitNode(true, Player.bitNodeN, nextBN, helpers.validateBitNodeOptions(ctx, _bitNodeOptions));
|
enterBitNode(true, Player.bitNodeN, nextBN, helpers.validateBitNodeOptions(ctx, _bitNodeOptions));
|
||||||
if (cbScript) {
|
if (cbScript) {
|
||||||
@ -1159,7 +1159,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
|||||||
? resolveScriptFilePath(helpers.string(ctx, "cbScript", _cbScript), ctx.workerScript.name)
|
? resolveScriptFilePath(helpers.string(ctx, "cbScript", _cbScript), ctx.workerScript.name)
|
||||||
: false;
|
: false;
|
||||||
if (cbScript === null) {
|
if (cbScript === null) {
|
||||||
throw helpers.errorMessage(ctx, `Could not resolve file path: ${_cbScript}`);
|
throw helpers.errorMessage(ctx, `Could not resolve file path. callbackScript is null.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wd = GetServer(SpecialServers.WorldDaemon);
|
const wd = GetServer(SpecialServers.WorldDaemon);
|
||||||
@ -1194,7 +1194,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
|||||||
getCurrentWork: (ctx) => () => {
|
getCurrentWork: (ctx) => () => {
|
||||||
helpers.checkSingularityAccess(ctx);
|
helpers.checkSingularityAccess(ctx);
|
||||||
if (!Player.currentWork) return null;
|
if (!Player.currentWork) return null;
|
||||||
return Player.currentWork.APICopy() as ITask;
|
return Player.currentWork.APICopy();
|
||||||
},
|
},
|
||||||
exportGame: (ctx) => () => {
|
exportGame: (ctx) => () => {
|
||||||
helpers.checkSingularityAccess(ctx);
|
helpers.checkSingularityAccess(ctx);
|
||||||
|
@ -30,7 +30,7 @@ function makeScriptBlob(code: string): Blob {
|
|||||||
// config object to provide a hook point.
|
// config object to provide a hook point.
|
||||||
export const config = {
|
export const config = {
|
||||||
doImport(url: ScriptURL): Promise<ScriptModule> {
|
doImport(url: ScriptURL): Promise<ScriptModule> {
|
||||||
return import(/*webpackIgnore:true*/ url);
|
return import(/*webpackIgnore:true*/ url) as Promise<ScriptModule>;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ export function getGangFaction(this: PlayerObject): Faction {
|
|||||||
return fac;
|
return fac;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGangName(this: PlayerObject): string {
|
export function getGangName(this: PlayerObject): FactionName | null {
|
||||||
const gang = this.gang;
|
const gang = this.gang;
|
||||||
return gang ? gang.facName : "";
|
return gang ? gang.facName : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasGangWith(this: PlayerObject, facName: FactionName): boolean {
|
export function hasGangWith(this: PlayerObject, facName: FactionName): boolean {
|
||||||
|
@ -302,7 +302,7 @@ export function applyForJob(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!company.hasPosition(pos)) {
|
if (!company.hasPosition(pos)) {
|
||||||
console.error(`Company ${company.name} does not have position ${pos}. Player.applyToCompany() failed.`);
|
console.error(`Company ${company.name} does not have position ${pos.name}. Player.applyToCompany() failed.`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ export function setPlayer(playerObj: PlayerObject): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function loadPlayer(saveString: string): PlayerObject {
|
export function loadPlayer(saveString: string): PlayerObject {
|
||||||
const player = JSON.parse(saveString, Reviver);
|
const player = JSON.parse(saveString, Reviver) as PlayerObject;
|
||||||
player.money = parseFloat(player.money + "");
|
player.money = parseFloat(player.money + "");
|
||||||
player.exploits = sanitizeExploits(player.exploits);
|
player.exploits = sanitizeExploits(player.exploits);
|
||||||
return player;
|
return player;
|
||||||
|
@ -18,7 +18,7 @@ function error(errorMsg: string, { id }: RFAMessage): RFAMessage {
|
|||||||
return new RFAMessage({ error: errorMsg, id: id });
|
return new RFAMessage({ error: errorMsg, id: id });
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RFARequestHandler: Record<string, (message: RFAMessage) => void | RFAMessage> = {
|
export const RFARequestHandler: Record<string, (message: RFAMessage) => RFAMessage> = {
|
||||||
pushFile: function (msg: RFAMessage): RFAMessage {
|
pushFile: function (msg: RFAMessage): RFAMessage {
|
||||||
if (!isFileData(msg.params)) return error("Misses parameters", msg);
|
if (!isFileData(msg.params)) return error("Misses parameters", msg);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export class Remote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageEvent(this: WebSocket, e: MessageEvent): void {
|
function handleMessageEvent(this: WebSocket, e: MessageEvent): void {
|
||||||
const msg: RFAMessage = JSON.parse(e.data);
|
const msg = JSON.parse(e.data as string) as RFAMessage;
|
||||||
|
|
||||||
if (!msg.method || !RFARequestHandler[msg.method]) {
|
if (!msg.method || !RFARequestHandler[msg.method]) {
|
||||||
const response = new RFAMessage({ error: "Unknown message received", id: msg.id });
|
const response = new RFAMessage({ error: "Unknown message received", id: msg.id });
|
||||||
|
@ -44,7 +44,7 @@ import { isBinaryFormat } from "../electron/saveDataBinaryFormat";
|
|||||||
import { downloadContentAsFile } from "./utils/FileUtils";
|
import { downloadContentAsFile } from "./utils/FileUtils";
|
||||||
import { showAPIBreaks } from "./utils/APIBreaks/APIBreak";
|
import { showAPIBreaks } from "./utils/APIBreaks/APIBreak";
|
||||||
import { breakInfos261 } from "./utils/APIBreaks/2.6.1";
|
import { breakInfos261 } from "./utils/APIBreaks/2.6.1";
|
||||||
import { handleGetSaveDataError } from "./Netscript/ErrorMessages";
|
import { handleGetSaveDataInfoError } from "./Netscript/ErrorMessages";
|
||||||
|
|
||||||
/* SaveObject.js
|
/* SaveObject.js
|
||||||
* Defines the object used to save/load games
|
* Defines the object used to save/load games
|
||||||
@ -130,7 +130,7 @@ class BitburnerSaveObject {
|
|||||||
try {
|
try {
|
||||||
saveData = await this.getSaveData();
|
saveData = await this.getSaveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleGetSaveDataError(error);
|
handleGetSaveDataInfoError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -170,7 +170,7 @@ class BitburnerSaveObject {
|
|||||||
try {
|
try {
|
||||||
saveData = await this.getSaveData();
|
saveData = await this.getSaveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleGetSaveDataError(error);
|
handleGetSaveDataInfoError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const filename = this.getSaveFileName();
|
const filename = this.getSaveFileName();
|
||||||
@ -698,9 +698,12 @@ function evaluateVersionCompatibility(ver: string | number): void {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
anyExportsFailed = true;
|
anyExportsFailed = true;
|
||||||
// We just need the text error, not a full stack trace
|
// We just need the text error, not a full stack trace
|
||||||
console.error(`Failed to load export of material ${material.name} (${division.name} ${warehouse.city})
|
console.error(
|
||||||
|
`Failed to load export of material ${material.name} (${division.name} ${warehouse.city})
|
||||||
Original export details: ${JSON.stringify(originalExport)}
|
Original export details: ${JSON.stringify(originalExport)}
|
||||||
Error: ${e}`);
|
Error: ${e}`,
|
||||||
|
e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,16 +808,16 @@ async function loadGame(saveData: SaveData): Promise<boolean> {
|
|||||||
if (Object.hasOwn(saveObj, "LastExportBonus")) {
|
if (Object.hasOwn(saveObj, "LastExportBonus")) {
|
||||||
try {
|
try {
|
||||||
ExportBonus.setLastExportBonus(JSON.parse(saveObj.LastExportBonus));
|
ExportBonus.setLastExportBonus(JSON.parse(saveObj.LastExportBonus));
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
ExportBonus.setLastExportBonus(new Date().getTime());
|
ExportBonus.setLastExportBonus(new Date().getTime());
|
||||||
console.error("ERROR: Failed to parse last export bonus Settings " + err);
|
console.error(`ERROR: Failed to parse last export bonus setting. Error: ${error}.`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Player.gang && Object.hasOwn(saveObj, "AllGangsSave")) {
|
if (Player.gang && Object.hasOwn(saveObj, "AllGangsSave")) {
|
||||||
try {
|
try {
|
||||||
loadAllGangs(saveObj.AllGangsSave);
|
loadAllGangs(saveObj.AllGangsSave);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
console.error("ERROR: Failed to parse AllGangsSave: " + e);
|
console.error(`ERROR: Failed to parse AllGangsSave. Error: ${error}.`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Object.hasOwn(saveObj, "VersionSave")) {
|
if (Object.hasOwn(saveObj, "VersionSave")) {
|
||||||
|
@ -106,7 +106,7 @@ export class RunningScript {
|
|||||||
|
|
||||||
let logEntry = txt;
|
let logEntry = txt;
|
||||||
if (Settings.TimestampsFormat && typeof txt === "string") {
|
if (Settings.TimestampsFormat && typeof txt === "string") {
|
||||||
logEntry = "[" + formatTime(Settings.TimestampsFormat) + "] " + logEntry;
|
logEntry = `[${formatTime(Settings.TimestampsFormat)}] ${txt}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logs.push(logEntry);
|
this.logs.push(logEntry);
|
||||||
|
@ -14,6 +14,7 @@ import { NetscriptExtra } from "../NetscriptFunctions/Extra";
|
|||||||
import * as enums from "../Enums";
|
import * as enums from "../Enums";
|
||||||
import { ns } from "../NetscriptFunctions";
|
import { ns } from "../NetscriptFunctions";
|
||||||
import { isLegacyScript } from "../Paths/ScriptFilePath";
|
import { isLegacyScript } from "../Paths/ScriptFilePath";
|
||||||
|
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
/** Event emitter used for tracking when changes have been made to a content file. */
|
/** Event emitter used for tracking when changes have been made to a content file. */
|
||||||
export const fileEditEvents = new EventEmitter<[hostname: string, filename: ContentFilePath]>();
|
export const fileEditEvents = new EventEmitter<[hostname: string, filename: ContentFilePath]>();
|
||||||
@ -36,7 +37,9 @@ export class ScriptEditor {
|
|||||||
for (const [apiKey, apiValue] of Object.entries(apiLayer)) {
|
for (const [apiKey, apiValue] of Object.entries(apiLayer)) {
|
||||||
if (apiLayer === api && apiKey in hiddenAPI) continue;
|
if (apiLayer === api && apiKey in hiddenAPI) continue;
|
||||||
apiKeys.push(apiKey);
|
apiKeys.push(apiKey);
|
||||||
if (typeof apiValue === "object") populate(apiValue);
|
if (typeof apiValue === "object") {
|
||||||
|
populate(apiValue as object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
populate();
|
populate();
|
||||||
@ -44,23 +47,25 @@ export class ScriptEditor {
|
|||||||
(async function () {
|
(async function () {
|
||||||
// We have to improve the default js language otherwise theme sucks
|
// We have to improve the default js language otherwise theme sucks
|
||||||
const jsLanguage = monaco.languages.getLanguages().find((l) => l.id === "javascript");
|
const jsLanguage = monaco.languages.getLanguages().find((l) => l.id === "javascript");
|
||||||
// Unsupported function is not exposed in monaco public API.
|
if (!jsLanguage) {
|
||||||
const l = await (jsLanguage as any).loader();
|
return;
|
||||||
|
}
|
||||||
|
const loader = await jsLanguage.loader();
|
||||||
// replaced the bare tokens with regexes surrounded by \b, e.g. \b{token}\b which matches a word-break on either side
|
// replaced the bare tokens with regexes surrounded by \b, e.g. \b{token}\b which matches a word-break on either side
|
||||||
// this prevents the highlighter from highlighting pieces of variables that start with a reserved token name
|
// this prevents the highlighter from highlighting pieces of variables that start with a reserved token name
|
||||||
l.language.tokenizer.root.unshift([new RegExp("\\bns\\b"), { token: "ns" }]);
|
loader.language.tokenizer.root.unshift([new RegExp("\\bns\\b"), { token: "ns" }]);
|
||||||
for (const symbol of apiKeys)
|
for (const symbol of apiKeys)
|
||||||
l.language.tokenizer.root.unshift([new RegExp(`\\b${symbol}\\b`), { token: "netscriptfunction" }]);
|
loader.language.tokenizer.root.unshift([new RegExp(`\\b${symbol}\\b`), { token: "netscriptfunction" }]);
|
||||||
const otherKeywords = ["let", "const", "var", "function", "arguments"];
|
const otherKeywords = ["let", "const", "var", "function", "arguments"];
|
||||||
const otherKeyvars = ["true", "false", "null", "undefined"];
|
const otherKeyvars = ["true", "false", "null", "undefined"];
|
||||||
otherKeywords.forEach((k) =>
|
otherKeywords.forEach((k) =>
|
||||||
l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeywords" }]),
|
loader.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeywords" }]),
|
||||||
);
|
);
|
||||||
otherKeyvars.forEach((k) =>
|
otherKeyvars.forEach((k) =>
|
||||||
l.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeyvars" }]),
|
loader.language.tokenizer.root.unshift([new RegExp(`\\b${k}\\b`), { token: "otherkeyvars" }]),
|
||||||
);
|
);
|
||||||
l.language.tokenizer.root.unshift([new RegExp("\\bthis\\b"), { token: "this" }]);
|
loader.language.tokenizer.root.unshift([new RegExp("\\bthis\\b"), { token: "this" }]);
|
||||||
})();
|
})().catch((e) => exceptionAlert(e));
|
||||||
|
|
||||||
// Add ts definitions for API
|
// Add ts definitions for API
|
||||||
const source = netscriptDefinitions.replace(/export /g, "");
|
const source = netscriptDefinitions.replace(/export /g, "");
|
||||||
@ -112,16 +117,20 @@ export class ScriptEditor {
|
|||||||
// returns a reject promise if the language worker is not loaded yet, so we wait to
|
// returns a reject promise if the language worker is not loaded yet, so we wait to
|
||||||
// call it until the language gets loaded.
|
// call it until the language gets loaded.
|
||||||
const languageWorker = new Promise<(...uris: monaco.Uri[]) => unknown>((resolve) =>
|
const languageWorker = new Promise<(...uris: monaco.Uri[]) => unknown>((resolve) =>
|
||||||
monaco.languages.onLanguage(language, () => getLanguageWorker().then(resolve)),
|
monaco.languages.onLanguage(language, () => {
|
||||||
|
getLanguageWorker()
|
||||||
|
.then(resolve)
|
||||||
|
.catch((error) => exceptionAlert(error));
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
// Whenever a model is created, arange for it synced to the language server.
|
// Whenever a model is created, arrange for it to be synced to the language server.
|
||||||
monaco.editor.onDidCreateModel((model) => {
|
monaco.editor.onDidCreateModel((model) => {
|
||||||
if (language === "typescript" && isLegacyScript(model.uri.path)) {
|
if (language === "typescript" && isLegacyScript(model.uri.path)) {
|
||||||
// Don't sync legacy scripts to typescript worker.
|
// Don't sync legacy scripts to typescript worker.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (["javascript", "typescript"].includes(model.getLanguageId())) {
|
if (["javascript", "typescript"].includes(model.getLanguageId())) {
|
||||||
languageWorker.then((cb) => cb(model.uri));
|
languageWorker.then((resolve) => resolve(model.uri)).catch((error) => exceptionAlert(error));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import { useCallback } from "react";
|
|||||||
import { type AST, getFileType, parseAST } from "../../utils/ScriptTransformer";
|
import { type AST, getFileType, parseAST } from "../../utils/ScriptTransformer";
|
||||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||||
import { hasScriptExtension, isLegacyScript } from "../../Paths/ScriptFilePath";
|
import { hasScriptExtension, isLegacyScript } from "../../Paths/ScriptFilePath";
|
||||||
|
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// Map of filename -> code
|
// Map of filename -> code
|
||||||
@ -105,7 +106,9 @@ function Root(props: IProps): React.ReactElement {
|
|||||||
const server = GetServer(currentScript.hostname);
|
const server = GetServer(currentScript.hostname);
|
||||||
if (server === null) throw new Error("Server should not be null but it is.");
|
if (server === null) throw new Error("Server should not be null but it is.");
|
||||||
server.writeToContentFile(currentScript.path, currentScript.code);
|
server.writeToContentFile(currentScript.path, currentScript.code);
|
||||||
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
|
if (Settings.SaveGameOnFileSave) {
|
||||||
|
saveObject.saveGame().catch((error) => exceptionAlert(error));
|
||||||
|
}
|
||||||
rerender();
|
rerender();
|
||||||
}, [rerender]);
|
}, [rerender]);
|
||||||
|
|
||||||
@ -285,7 +288,9 @@ function Root(props: IProps): React.ReactElement {
|
|||||||
if (!server) throw new Error("Server should not be null but it is.");
|
if (!server) throw new Error("Server should not be null but it is.");
|
||||||
// This server helper already handles overwriting, etc.
|
// This server helper already handles overwriting, etc.
|
||||||
server.writeToContentFile(scriptToSave.path, scriptToSave.code);
|
server.writeToContentFile(scriptToSave.path, scriptToSave.code);
|
||||||
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
|
if (Settings.SaveGameOnFileSave) {
|
||||||
|
saveObject.saveGame().catch((error) => exceptionAlert(error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentTabIndex(): number | undefined {
|
function currentTabIndex(): number | undefined {
|
||||||
|
@ -35,7 +35,10 @@ export function Toolbar({ editor, onSave }: IProps) {
|
|||||||
const [optionsOpen, { on: openOptions, off: closeOptions }] = useBoolean(false);
|
const [optionsOpen, { on: openOptions, off: closeOptions }] = useBoolean(false);
|
||||||
|
|
||||||
function beautify(): void {
|
function beautify(): void {
|
||||||
editor?.getAction("editor.action.formatDocument")?.run();
|
editor
|
||||||
|
?.getAction("editor.action.formatDocument")
|
||||||
|
?.run()
|
||||||
|
.catch((error) => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { ram, ramEntries, isUpdatingRAM, options, saveOptions } = useScriptEditorContext();
|
const { ram, ramEntries, isUpdatingRAM, options, saveOptions } = useScriptEditorContext();
|
||||||
|
@ -218,7 +218,7 @@ export function makeTheme(theme: IScriptEditorTheme): editor.IStandaloneThemeDat
|
|||||||
return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors };
|
return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadThemes(defineTheme: DefineThemeFn): Promise<void> {
|
export function loadThemes(defineTheme: DefineThemeFn): void {
|
||||||
defineTheme("monokai", {
|
defineTheme("monokai", {
|
||||||
base: "vs-dark",
|
base: "vs-dark",
|
||||||
inherit: true,
|
inherit: true,
|
||||||
|
@ -157,7 +157,12 @@ export const Settings = {
|
|||||||
disableSuffixes: false,
|
disableSuffixes: false,
|
||||||
|
|
||||||
load(saveString: string) {
|
load(saveString: string) {
|
||||||
const save = JSON.parse(saveString);
|
const save = JSON.parse(saveString) as {
|
||||||
|
theme?: typeof Settings.theme;
|
||||||
|
styles?: typeof Settings.styles;
|
||||||
|
overview?: typeof Settings.overview;
|
||||||
|
EditorTheme?: typeof Settings.EditorTheme;
|
||||||
|
};
|
||||||
save.theme && Object.assign(Settings.theme, save.theme);
|
save.theme && Object.assign(Settings.theme, save.theme);
|
||||||
save.styles && Object.assign(Settings.styles, save.styles);
|
save.styles && Object.assign(Settings.styles, save.styles);
|
||||||
save.overview && Object.assign(Settings.overview, save.overview);
|
save.overview && Object.assign(Settings.overview, save.overview);
|
||||||
|
@ -50,7 +50,7 @@ export function buyStock(
|
|||||||
}
|
}
|
||||||
if (stock == null || isNaN(shares)) {
|
if (stock == null || isNaN(shares)) {
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
helpers.log(ctx, () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
|
helpers.log(ctx, () => `Invalid arguments: stock='${stock?.name}' shares='${shares}'`);
|
||||||
} else if (opts.suppressDialog !== true) {
|
} else if (opts.suppressDialog !== true) {
|
||||||
dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
|
dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ export function sellStock(
|
|||||||
// Sanitize/Validate arguments
|
// Sanitize/Validate arguments
|
||||||
if (stock == null || shares < 0 || isNaN(shares)) {
|
if (stock == null || shares < 0 || isNaN(shares)) {
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
helpers.log(ctx, () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
|
helpers.log(ctx, () => `Invalid arguments: stock='${stock?.name}' shares='${shares}'`);
|
||||||
} else if (opts.suppressDialog !== true) {
|
} else if (opts.suppressDialog !== true) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer",
|
"Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer",
|
||||||
@ -225,7 +225,7 @@ export function shortStock(
|
|||||||
}
|
}
|
||||||
if (stock == null || isNaN(shares)) {
|
if (stock == null || isNaN(shares)) {
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
helpers.log(ctx, () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
|
helpers.log(ctx, () => `Invalid arguments: stock='${stock?.name}' shares='${shares}'`);
|
||||||
} else if (opts.suppressDialog !== true) {
|
} else if (opts.suppressDialog !== true) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Failed to initiate a short position in a stock. This is probably " +
|
"Failed to initiate a short position in a stock. This is probably " +
|
||||||
@ -321,7 +321,7 @@ export function sellShort(
|
|||||||
): boolean {
|
): boolean {
|
||||||
if (stock == null || isNaN(shares) || shares < 0) {
|
if (stock == null || isNaN(shares) || shares < 0) {
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
helpers.log(ctx, () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
|
helpers.log(ctx, () => `Invalid arguments: stock='${stock?.name}' shares='${shares}'`);
|
||||||
} else if (!opts.suppressDialog) {
|
} else if (!opts.suppressDialog) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Failed to sell a short position in a stock. This is probably " +
|
"Failed to sell a short position in a stock. This is probably " +
|
||||||
|
@ -20,7 +20,13 @@ export function exportScripts(pattern: string, server: BaseServer, currDir = roo
|
|||||||
const filename = `bitburner${
|
const filename = `bitburner${
|
||||||
hasScriptExtension(pattern) ? "Scripts" : pattern.endsWith(".txt") ? "Texts" : "Files"
|
hasScriptExtension(pattern) ? "Scripts" : pattern.endsWith(".txt") ? "Texts" : "Files"
|
||||||
}.zip`;
|
}.zip`;
|
||||||
zip.generateAsync({ type: "blob" }).then((content: Blob) => downloadContentAsFile(content, filename));
|
zip
|
||||||
|
.generateAsync({ type: "blob" })
|
||||||
|
.then((content: Blob) => downloadContentAsFile(content, filename))
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
Terminal.error(`Cannot compress scripts with pattern ${pattern} on ${server.hostname}. Error: ${error}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function download(args: (string | number | boolean)[], server: BaseServer): void {
|
export function download(args: (string | number | boolean)[], server: BaseServer): void {
|
||||||
@ -33,9 +39,10 @@ export function download(args: (string | number | boolean)[], server: BaseServer
|
|||||||
try {
|
try {
|
||||||
exportScripts(pattern, server, Terminal.currDir);
|
exportScripts(pattern, server, Terminal.currDir);
|
||||||
return;
|
return;
|
||||||
} catch (e: any) {
|
} catch (error) {
|
||||||
const msg = String(e?.message ?? e);
|
console.error(error);
|
||||||
return Terminal.error(msg);
|
Terminal.error(`Cannot export scripts with pattern ${pattern} on ${server.hostname}. Error: ${error}`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const path = Terminal.getFilepath(pattern);
|
const path = Terminal.getFilepath(pattern);
|
||||||
|
@ -383,13 +383,19 @@ function writeToTerminal(
|
|||||||
if (options.isVerbose) Terminal.print(verboseInfo);
|
if (options.isVerbose) Terminal.print(verboseInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOutFile(outFileStr: string, options: Options, server: BaseServer): ContentFilePath | void {
|
function checkOutFile(outFileStr: string, options: Options, server: BaseServer): ContentFilePath | null {
|
||||||
if (!outFileStr) return;
|
if (!outFileStr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const outFilePath = Terminal.getFilepath(outFileStr);
|
const outFilePath = Terminal.getFilepath(outFileStr);
|
||||||
if (!outFilePath || !hasTextExtension(outFilePath)) {
|
if (!outFilePath || !hasTextExtension(outFilePath)) {
|
||||||
return Terminal.error(ERR.badOutFile(outFileStr));
|
Terminal.error(ERR.badOutFile(outFileStr));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!options.isOverWrite && server.textFiles.has(outFilePath)) {
|
||||||
|
Terminal.error(ERR.outFileExists(outFileStr));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (!options.isOverWrite && server.textFiles.has(outFilePath)) return Terminal.error(ERR.outFileExists(outFileStr));
|
|
||||||
return outFilePath;
|
return outFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +439,8 @@ export function grep(args: (string | number | boolean)[], server: BaseServer): v
|
|||||||
if (options.isPipeIn) files.length = 0;
|
if (options.isPipeIn) files.length = 0;
|
||||||
if (!options.isQuiet) writeToTerminal(prettyResult, options, results, files, pattern);
|
if (!options.isQuiet) writeToTerminal(prettyResult, options, results, files, pattern);
|
||||||
if (params.outfile && outFilePath) server.writeToContentFile(outFilePath, rawResult.join("\n"));
|
if (params.outfile && outFilePath) server.writeToContentFile(outFilePath, rawResult.join("\n"));
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
Terminal.error("grep processing error: " + e);
|
console.error(error);
|
||||||
|
Terminal.error(`grep processing error: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,8 @@ export function kill(args: (string | number | boolean)[], server: BaseServer): v
|
|||||||
if (killed >= 5) {
|
if (killed >= 5) {
|
||||||
Terminal.print(`... killed ${killed} instances total`);
|
Terminal.print(`... killed ${killed} instances total`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
Terminal.error(e + "");
|
console.error(error);
|
||||||
|
Terminal.error(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ export function mem(args: (string | number | boolean)[], server: BaseServer): vo
|
|||||||
// Let's warn the user that he might need to save his script again to generate the detailed entries
|
// Let's warn the user that he might need to save his script again to generate the detailed entries
|
||||||
Terminal.warn("You might have to open & save this script to see the detailed RAM usage information.");
|
Terminal.warn("You might have to open & save this script to see the detailed RAM usage information.");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
Terminal.error(e + "");
|
console.error(error);
|
||||||
|
Terminal.error(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,10 @@ export function run(args: (string | number | boolean)[], server: BaseServer): vo
|
|||||||
if (hasScriptExtension(path)) {
|
if (hasScriptExtension(path)) {
|
||||||
return runScript(path, args, server);
|
return runScript(path, args, server);
|
||||||
} else if (hasContractExtension(path)) {
|
} else if (hasContractExtension(path)) {
|
||||||
Terminal.runContract(path);
|
Terminal.runContract(path).catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
Terminal.error(`Cannot run contract ${path} on ${server.hostname}. Error: ${error}.`);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
} else if (hasProgramExtension(path)) {
|
} else if (hasProgramExtension(path)) {
|
||||||
return runProgram(path, args, server);
|
return runProgram(path, args, server);
|
||||||
|
@ -25,7 +25,7 @@ export function runScript(path: ScriptFilePath, commandArgs: (string | number |
|
|||||||
argv: commandArgs,
|
argv: commandArgs,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Terminal.error(`Invalid arguments. ${String(error)}.`);
|
Terminal.error(`Invalid arguments. ${error}.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const tailFlag = flags["--tail"] === true;
|
const tailFlag = flags["--tail"] === true;
|
||||||
|
@ -32,7 +32,8 @@ export function tail(commandArray: (string | number | boolean)[], server: BaseSe
|
|||||||
}
|
}
|
||||||
LogBoxEvents.emit(runningScript);
|
LogBoxEvents.emit(runningScript);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
Terminal.error(e + "");
|
console.error(error);
|
||||||
|
Terminal.error(String(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ function getDB(): Promise<IDBObjectStore> {
|
|||||||
export function load(): Promise<SaveData> {
|
export function load(): Promise<SaveData> {
|
||||||
return getDB().then((db) => {
|
return getDB().then((db) => {
|
||||||
return new Promise<SaveData>((resolve, reject) => {
|
return new Promise<SaveData>((resolve, reject) => {
|
||||||
const request: IDBRequest<SaveData> = db.get("save");
|
const request = db.get("save") as IDBRequest<SaveData>;
|
||||||
request.onerror = function (this: IDBRequest<SaveData>) {
|
request.onerror = function (this: IDBRequest<SaveData>) {
|
||||||
reject(new Error("Error in Database request to get save data", { cause: this.error }));
|
reject(new Error("Error in Database request to get save data", { cause: this.error }));
|
||||||
};
|
};
|
||||||
|
@ -237,7 +237,7 @@ const Engine: {
|
|||||||
Engine.Counters.autoSaveCounter = 60 * 5; // Let's check back in a bit
|
Engine.Counters.autoSaveCounter = 60 * 5; // Let's check back in a bit
|
||||||
} else {
|
} else {
|
||||||
Engine.Counters.autoSaveCounter = Settings.AutosaveInterval * 5;
|
Engine.Counters.autoSaveCounter = Settings.AutosaveInterval * 5;
|
||||||
saveObject.saveGame(!Settings.SuppressSavedGameToast);
|
saveObject.saveGame(!Settings.SuppressSavedGameToast).catch((error) => console.error(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -75,6 +75,7 @@ import { HistoryProvider } from "./React/Documentation";
|
|||||||
import { GoRoot } from "../Go/ui/GoRoot";
|
import { GoRoot } from "../Go/ui/GoRoot";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
import { isBitNodeFinished } from "../BitNode/BitNodeUtils";
|
import { isBitNodeFinished } from "../BitNode/BitNodeUtils";
|
||||||
|
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
const htmlLocation = location;
|
const htmlLocation = location;
|
||||||
|
|
||||||
@ -154,8 +155,14 @@ export function GameRoot(): React.ReactElement {
|
|||||||
for (const server of GetAllServers()) {
|
for (const server of GetAllServers()) {
|
||||||
server.runningScriptMap.clear();
|
server.runningScriptMap.clear();
|
||||||
}
|
}
|
||||||
saveObject.saveGame();
|
saveObject
|
||||||
setTimeout(() => htmlLocation.reload(), 2000);
|
.saveGame()
|
||||||
|
.then(() => {
|
||||||
|
setTimeout(() => htmlLocation.reload(), 2000);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
exceptionAlert(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function attemptedForbiddenRouting(name: string) {
|
function attemptedForbiddenRouting(name: string) {
|
||||||
@ -333,11 +340,13 @@ export function GameRoot(): React.ReactElement {
|
|||||||
case Page.Options: {
|
case Page.Options: {
|
||||||
mainPage = (
|
mainPage = (
|
||||||
<GameOptionsRoot
|
<GameOptionsRoot
|
||||||
save={() => saveObject.saveGame()}
|
save={() => {
|
||||||
|
saveObject.saveGame().catch((error) => exceptionAlert(error));
|
||||||
|
}}
|
||||||
export={() => {
|
export={() => {
|
||||||
// Apply the export bonus before saving the game
|
// Apply the export bonus before saving the game
|
||||||
onExport();
|
onExport();
|
||||||
saveObject.exportGame();
|
saveObject.exportGame().catch((error) => exceptionAlert(error));
|
||||||
}}
|
}}
|
||||||
forceKill={killAllScripts}
|
forceKill={killAllScripts}
|
||||||
softReset={softReset}
|
softReset={softReset}
|
||||||
@ -356,7 +365,7 @@ export function GameRoot(): React.ReactElement {
|
|||||||
exportGameFn={() => {
|
exportGameFn={() => {
|
||||||
// Apply the export bonus before saving the game
|
// Apply the export bonus before saving the game
|
||||||
onExport();
|
onExport();
|
||||||
saveObject.exportGame();
|
saveObject.exportGame().catch((error) => exceptionAlert(error));
|
||||||
}}
|
}}
|
||||||
installAugmentationsFn={() => {
|
installAugmentationsFn={() => {
|
||||||
installAugmentations();
|
installAugmentations();
|
||||||
@ -395,7 +404,9 @@ export function GameRoot(): React.ReactElement {
|
|||||||
!ITutorial.isRunning ? (
|
!ITutorial.isRunning ? (
|
||||||
<CharacterOverview
|
<CharacterOverview
|
||||||
parentOpen={parentOpen}
|
parentOpen={parentOpen}
|
||||||
save={() => saveObject.saveGame()}
|
save={() => {
|
||||||
|
saveObject.saveGame().catch((error) => exceptionAlert(error));
|
||||||
|
}}
|
||||||
killScripts={killAllScripts}
|
killScripts={killAllScripts}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -38,7 +38,7 @@ import { useBoolean } from "../hooks";
|
|||||||
|
|
||||||
import { ComparisonIcon } from "./ComparisonIcon";
|
import { ComparisonIcon } from "./ComparisonIcon";
|
||||||
import { SaveData } from "../../../types";
|
import { SaveData } from "../../../types";
|
||||||
import { handleGetSaveDataError } from "../../../Netscript/ErrorMessages";
|
import { handleGetSaveDataInfoError } from "../../../Netscript/ErrorMessages";
|
||||||
|
|
||||||
const useStyles = makeStyles()((theme: Theme) => ({
|
const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
root: {
|
root: {
|
||||||
@ -140,7 +140,7 @@ export const ImportSave = (props: { saveData: SaveData; automatic: boolean }): J
|
|||||||
// We cannot show dialog box in this screen (due to "withPopups = false"), so we will try showing it with a
|
// We cannot show dialog box in this screen (due to "withPopups = false"), so we will try showing it with a
|
||||||
// delay. 1 second is usually enough to go back to other normal screens that allow showing popups.
|
// delay. 1 second is usually enough to go back to other normal screens that allow showing popups.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleGetSaveDataError(error);
|
handleGetSaveDataInfoError(error);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
/** Generic Event Emitter class following a subscribe/publish paradigm. */
|
/** Generic Event Emitter class following a subscribe/publish paradigm. */
|
||||||
export class EventEmitter<T extends any[]> {
|
export class EventEmitter<T extends any[]> {
|
||||||
private subscribers: Set<(...args: [...T]) => void | undefined> = new Set();
|
private subscribers: Set<(...args: [...T]) => void> = new Set();
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
subscribe(s: (...args: [...T]) => void): () => void {
|
subscribe(s: (...args: [...T]) => void): () => void {
|
||||||
this.subscribers.add(s);
|
this.subscribers.add(s);
|
||||||
|
@ -239,7 +239,7 @@ export const v2APIBreak = () => {
|
|||||||
for (const server of GetAllServers()) {
|
for (const server of GetAllServers()) {
|
||||||
server.runningScriptMap = new Map();
|
server.runningScriptMap = new Map();
|
||||||
}
|
}
|
||||||
saveObject.exportGame();
|
saveObject.exportGame().catch((e) => console.error(e));
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatOffenders = (offenders: IFileLine[]): string => {
|
const formatOffenders = (offenders: IFileLine[]): string => {
|
||||||
|
Loading…
Reference in New Issue
Block a user