mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-19 06:03:50 +01:00
Unify error handling
This commit is contained in:
parent
8dd507883a
commit
5798c4c7d3
@ -126,15 +126,15 @@ function installAugmentations(force?: boolean): boolean {
|
|||||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
level = ` - ${ownedAug.level}`;
|
level = ` - ${ownedAug.level}`;
|
||||||
}
|
}
|
||||||
augmentationList += aug.name + level + "<br>";
|
augmentationList += aug.name + level + "\n";
|
||||||
}
|
}
|
||||||
Player.queuedAugmentations = [];
|
Player.queuedAugmentations = [];
|
||||||
if (!force) {
|
if (!force) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You slowly drift to sleep as scientists put you under in order " +
|
"You slowly drift to sleep as scientists put you under in order " +
|
||||||
"to install the following Augmentations:<br>" +
|
"to install the following Augmentations:\n" +
|
||||||
augmentationList +
|
augmentationList +
|
||||||
"<br>You wake up in your home...you feel different...",
|
"\nYou wake up in your home...you feel different...",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
prestigeAugmentation();
|
prestigeAugmentation();
|
||||||
|
@ -11,7 +11,7 @@ export function win(p: IPlayer, n: number): void {
|
|||||||
export function reachedLimit(p: IPlayer): boolean {
|
export function reachedLimit(p: IPlayer): boolean {
|
||||||
const reached = p.getCasinoWinnings() > gainLimit;
|
const reached = p.getCasinoWinnings() > gainLimit;
|
||||||
if (reached) {
|
if (reached) {
|
||||||
dialogBoxCreate(<>Alright cheater get out of here. You're not allowed here anymore.</>);
|
dialogBoxCreate("Alright cheater get out of here. You're not allowed here anymore.");
|
||||||
}
|
}
|
||||||
return reached;
|
return reached;
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ export class Game<T, U> extends React.Component<T, U> {
|
|||||||
reachedLimit(p: IPlayer): boolean {
|
reachedLimit(p: IPlayer): boolean {
|
||||||
const reached = p.getCasinoWinnings() > gainLimit;
|
const reached = p.getCasinoWinnings() > gainLimit;
|
||||||
if (reached) {
|
if (reached) {
|
||||||
dialogBoxCreate(<>Alright cheater get out of here. You're not allowed here anymore.</>);
|
dialogBoxCreate("Alright cheater get out of here. You're not allowed here anymore.");
|
||||||
}
|
}
|
||||||
return reached;
|
return reached;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ export class Corporation {
|
|||||||
if (isNaN(this.funds) || this.funds === Infinity || this.funds === -Infinity) {
|
if (isNaN(this.funds) || this.funds === Infinity || this.funds === -Infinity) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"There was an error calculating your Corporations funds and they got reset to 0. " +
|
"There was an error calculating your Corporations funds and they got reset to 0. " +
|
||||||
"This is a bug. Please report to game developer.<br><br>" +
|
"This is a bug. Please report to game developer.\n\n" +
|
||||||
"(Your funds have been set to $150b for the inconvenience)",
|
"(Your funds have been set to $150b for the inconvenience)",
|
||||||
);
|
);
|
||||||
this.funds = 150e9;
|
this.funds = 150e9;
|
||||||
|
@ -825,14 +825,7 @@ export class Industry implements IIndustry {
|
|||||||
sellAmt = eval(tmp);
|
sellAmt = eval(tmp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Error evaluating your sell amount for material " +
|
`Error evaluating your sell amount for material ${mat.name} in ${this.name}'s ${city} office. The sell amount is being set to zero`,
|
||||||
mat.name +
|
|
||||||
" in " +
|
|
||||||
this.name +
|
|
||||||
"'s " +
|
|
||||||
city +
|
|
||||||
" office. The sell amount " +
|
|
||||||
"is being set to zero",
|
|
||||||
);
|
);
|
||||||
sellAmt = 0;
|
sellAmt = 0;
|
||||||
}
|
}
|
||||||
@ -879,27 +872,13 @@ export class Industry implements IIndustry {
|
|||||||
amt = eval(amtStr);
|
amt = eval(amtStr);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Calculating export for " +
|
`Calculating export for ${mat.name} in ${this.name}'s ${city} division failed with error: ${e}`,
|
||||||
mat.name +
|
|
||||||
" in " +
|
|
||||||
this.name +
|
|
||||||
"'s " +
|
|
||||||
city +
|
|
||||||
" division failed with " +
|
|
||||||
"error: " +
|
|
||||||
e,
|
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isNaN(amt)) {
|
if (isNaN(amt)) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Error calculating export amount for " +
|
`Error calculating export amount for ${mat.name} in ${this.name}'s ${city} division.`,
|
||||||
mat.name +
|
|
||||||
" in " +
|
|
||||||
this.name +
|
|
||||||
"'s " +
|
|
||||||
city +
|
|
||||||
" division.",
|
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1172,13 +1151,7 @@ export class Industry implements IIndustry {
|
|||||||
tmp = eval(tmp);
|
tmp = eval(tmp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Error evaluating your sell price expression for " +
|
`Error evaluating your sell price expression for ${product.name} in ${this.name}'s ${city} office. Sell price is being set to MAX`,
|
||||||
product.name +
|
|
||||||
" in " +
|
|
||||||
this.name +
|
|
||||||
"'s " +
|
|
||||||
city +
|
|
||||||
" office. Sell price is being set to MAX",
|
|
||||||
);
|
);
|
||||||
tmp = product.maxsll;
|
tmp = product.maxsll;
|
||||||
}
|
}
|
||||||
|
@ -60,9 +60,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
|
|||||||
const fac = Factions[selectedFaction];
|
const fac = Factions[selectedFaction];
|
||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
const rep = repGain(money);
|
const rep = repGain(money);
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(`You gained ${numeralWrapper.formatReputation(rep)} reputation with ${fac.name} by bribing them.`);
|
||||||
"You gained " + numeralWrapper.formatReputation(rep) + " reputation with " + fac.name + " by bribing them.",
|
|
||||||
);
|
|
||||||
fac.playerReputation += rep;
|
fac.playerReputation += rep;
|
||||||
corp.funds = corp.funds - money;
|
corp.funds = corp.funds - money;
|
||||||
props.onClose();
|
props.onClose();
|
||||||
|
@ -89,14 +89,11 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
let dialogContents =
|
let dialogContents =
|
||||||
`Issued ${numeralWrapper.format(newShares, "0.000a")} new shares` +
|
`Issued ${numeralWrapper.format(newShares, "0.000a")} new shares` +
|
||||||
` and raised ${numeralWrapper.formatMoney(profit)}.`;
|
` and raised ${numeralWrapper.formatMoney(profit)}.` +
|
||||||
if (privateShares > 0) {
|
(privateShares > 0)
|
||||||
dialogContents += `<br>${numeralWrapper.format(
|
? "\n" + numeralWrapper.format(privateShares, "0.000a") + "of these shares were bought by private investors."
|
||||||
privateShares,
|
: "";
|
||||||
"0.000a",
|
dialogContents += `\n\nStock price decreased to ${numeralWrapper.formatMoney(corp.sharePrice)}`;
|
||||||
)} of these shares were bought by private investors.`;
|
|
||||||
}
|
|
||||||
dialogContents += `<br><br>Stock price decreased to ${numeralWrapper.formatMoney(corp.sharePrice)}`;
|
|
||||||
dialogBoxCreate(dialogContents);
|
dialogBoxCreate(dialogContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +42,7 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
`Researched ${n.text}. It may take a market cycle ` +
|
`Researched ${n.text}. It may take a market cycle (~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of the Research apply.`,
|
||||||
`(~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of ` +
|
|
||||||
`the Research apply.`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,7 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
if (mult > 0) {
|
if (mult > 0) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You threw a party for the office! The morale and happiness " +
|
"You threw a party for the office! The morale and happiness of each employee increased by " +
|
||||||
"of each employee increased by " +
|
|
||||||
numeralWrapper.formatPercentage(mult - 1),
|
numeralWrapper.formatPercentage(mult - 1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -94,12 +94,9 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
|||||||
return "You purchased " + aug.name;
|
return "You purchased " + aug.name;
|
||||||
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
|
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You purchased " +
|
`You purchased ${aug.name}. Its enhancements will not take effect until they are installed.` +
|
||||||
aug.name +
|
"To install your augmentations, go to the 'Augmentations' tab on the left-hand navigation menu." +
|
||||||
". Its enhancements will not take " +
|
"Purchasing additional augmentations will now be more expensive.",
|
||||||
"effect until they are installed. To install your augmentations, go to the " +
|
|
||||||
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
|
|
||||||
"augmentations will now be more expensive.",
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,8 +33,8 @@ export function purchaseTorRouter(p: IPlayer): void {
|
|||||||
p.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
|
p.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
|
||||||
darkweb.serversOnNetwork.push(p.getHomeComputer().hostname);
|
darkweb.serversOnNetwork.push(p.getHomeComputer().hostname);
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You have purchased a TOR router!<br>" +
|
"You have purchased a TOR router!\n" +
|
||||||
"You now have access to the dark web from your home computer.<br>" +
|
"You now have access to the dark web from your home computer.\n" +
|
||||||
"Use the scan/scan-analyze commands to search for the dark web connection.",
|
"Use the scan/scan-analyze commands to search for the dark web connection.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ function travel(p: IPlayer, router: IRouter, to: CityName): void {
|
|||||||
|
|
||||||
p.loseMoney(cost, "other");
|
p.loseMoney(cost, "other");
|
||||||
p.travel(to);
|
p.travel(to);
|
||||||
dialogBoxCreate(<>You are now in {to}!</>);
|
dialogBoxCreate(`You are now in ${to}!`);
|
||||||
router.toCity();
|
router.toCity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import React from "react";
|
||||||
import { Message } from "./Message";
|
import { Message } from "./Message";
|
||||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||||
import { Router } from "../ui/GameRoot";
|
import { Router } from "../ui/GameRoot";
|
||||||
@ -22,15 +23,12 @@ function sendMessage(msg: Message, forced = false): void {
|
|||||||
function showMessage(name: MessageFilenames): void {
|
function showMessage(name: MessageFilenames): void {
|
||||||
const msg = Messages[name];
|
const msg = Messages[name];
|
||||||
if (!(msg instanceof Message)) throw new Error("trying to display unexistent message");
|
if (!(msg instanceof Message)) throw new Error("trying to display unexistent message");
|
||||||
const txt =
|
dialogBoxCreate(
|
||||||
"Message received from unknown sender: <br><br>" +
|
<>
|
||||||
"<i>" +
|
Message received from unknown sender:<i>{msg.msg}</i>This message was saved as {msg.filename} onto your home
|
||||||
msg.msg +
|
computer.
|
||||||
"</i><br><br>" +
|
</>,
|
||||||
"This message was saved as " +
|
);
|
||||||
msg.filename +
|
|
||||||
" onto your home computer.";
|
|
||||||
dialogBoxCreate(txt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Adds a message to a server
|
//Adds a message to a server
|
||||||
@ -127,20 +125,20 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
MessageFilenames.Jumper0,
|
MessageFilenames.Jumper0,
|
||||||
"I know you can sense it. I know you're searching for it. " +
|
"I know you can sense it. I know you're searching for it. " +
|
||||||
"It's why you spend night after " +
|
"It's why you spend night after " +
|
||||||
"night at your computer. <br><br>It's real, I've seen it. And I can " +
|
"night at your computer. \n\nIt's real, I've seen it. And I can " +
|
||||||
"help you find it. But not right now. You're not ready yet.<br><br>" +
|
"help you find it. But not right now. You're not ready yet.\n\n" +
|
||||||
"Use this program to track your progress<br><br>" +
|
"Use this program to track your progress\n\n" +
|
||||||
"The fl1ght.exe program was added to your home computer<br><br>" +
|
"The fl1ght.exe program was added to your home computer\n\n" +
|
||||||
"-jump3R",
|
"-jump3R",
|
||||||
),
|
),
|
||||||
|
|
||||||
[MessageFilenames.Jumper1]: new Message(
|
[MessageFilenames.Jumper1]: new Message(
|
||||||
MessageFilenames.Jumper1,
|
MessageFilenames.Jumper1,
|
||||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
||||||
"They can help you with your search. <br><br>" +
|
"They can help you with your search. \n\n" +
|
||||||
"You should join them, garner their favor, and " +
|
"You should join them, garner their favor, and " +
|
||||||
"exploit them for their Augmentations. But do not trust them. " +
|
"exploit them for their Augmentations. But do not trust them. " +
|
||||||
"They are not what they seem. No one is.<br><br>" +
|
"They are not what they seem. No one is.\n\n" +
|
||||||
"-jump3R",
|
"-jump3R",
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -148,21 +146,21 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
MessageFilenames.Jumper2,
|
MessageFilenames.Jumper2,
|
||||||
"Do not try to save the world. There is no world to save. If " +
|
"Do not try to save the world. There is no world to save. If " +
|
||||||
"you want to find the truth, worry only about yourself. Ethics and " +
|
"you want to find the truth, worry only about yourself. Ethics and " +
|
||||||
`morals will get you killed. <br><br>Watch out for a hacking group known as ${FactionNames.NiteSec}.` +
|
`morals will get you killed. \n\nWatch out for a hacking group known as ${FactionNames.NiteSec}.` +
|
||||||
"<br><br>-jump3R",
|
"\n\n-jump3R",
|
||||||
),
|
),
|
||||||
|
|
||||||
[MessageFilenames.Jumper3]: new Message(
|
[MessageFilenames.Jumper3]: new Message(
|
||||||
MessageFilenames.Jumper3,
|
MessageFilenames.Jumper3,
|
||||||
"You must learn to walk before you can run. And you must " +
|
"You must learn to walk before you can run. And you must " +
|
||||||
`run before you can fly. Look for ${FactionNames.TheBlackHand}. <br><br>` +
|
`run before you can fly. Look for ${FactionNames.TheBlackHand}. \n\n` +
|
||||||
"I.I.I.I <br><br>-jump3R",
|
"I.I.I.I \n\n-jump3R",
|
||||||
),
|
),
|
||||||
|
|
||||||
[MessageFilenames.Jumper4]: new Message(
|
[MessageFilenames.Jumper4]: new Message(
|
||||||
MessageFilenames.Jumper4,
|
MessageFilenames.Jumper4,
|
||||||
"To find what you are searching for, you must understand the bits. " +
|
"To find what you are searching for, you must understand the bits. " +
|
||||||
"The bits are all around us. The runners will help you.<br><br>" +
|
"The bits are all around us. The runners will help you.\n\n" +
|
||||||
"-jump3R",
|
"-jump3R",
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -171,8 +169,8 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
MessageFilenames.CyberSecTest,
|
MessageFilenames.CyberSecTest,
|
||||||
"We've been watching you. Your skills are very impressive. But you're wasting " +
|
"We've been watching you. Your skills are very impressive. But you're wasting " +
|
||||||
"your talents. If you join us, you can put your skills to good use and change " +
|
"your talents. If you join us, you can put your skills to good use and change " +
|
||||||
"the world for the better. If you join us, we can unlock your full potential. <br><br>" +
|
"the world for the better. If you join us, we can unlock your full potential. \n\n" +
|
||||||
"But first, you must pass our test. Find and install the backdoor on our server. <br><br>" +
|
"But first, you must pass our test. Find and install the backdoor on our server. \n\n" +
|
||||||
`-${FactionNames.CyberSec}`,
|
`-${FactionNames.CyberSec}`,
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -181,17 +179,17 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
"People say that the corrupted governments and corporations rule the world. " +
|
"People say that the corrupted governments and corporations rule the world. " +
|
||||||
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
||||||
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
||||||
"and ideas with bullets. <br><br>" +
|
"and ideas with bullets. \n\n" +
|
||||||
"Join us, and people will fear you, too. <br><br>" +
|
"Join us, and people will fear you, too. \n\n" +
|
||||||
"Find and install the backdoor on our server, avmnite-02h. Then, we will contact you again." +
|
"Find and install the backdoor on our server, avmnite-02h. Then, we will contact you again." +
|
||||||
`<br><br>-${FactionNames.NiteSec}`,
|
`\n\n-${FactionNames.NiteSec}`,
|
||||||
),
|
),
|
||||||
|
|
||||||
[MessageFilenames.BitRunnersTest]: new Message(
|
[MessageFilenames.BitRunnersTest]: new Message(
|
||||||
MessageFilenames.BitRunnersTest,
|
MessageFilenames.BitRunnersTest,
|
||||||
"We know what you are doing. We know what drives you. We know " +
|
"We know what you are doing. We know what drives you. We know " +
|
||||||
"what you are looking for. <br><br> " +
|
"what you are looking for. \n\n " +
|
||||||
"We can help you find the answers.<br><br>" +
|
"We can help you find the answers.\n\n" +
|
||||||
"run4theh111z",
|
"run4theh111z",
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -199,18 +197,18 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
[MessageFilenames.TruthGazer]: new Message(
|
[MessageFilenames.TruthGazer]: new Message(
|
||||||
MessageFilenames.TruthGazer,
|
MessageFilenames.TruthGazer,
|
||||||
//"THE TRUTH CAN NO LONGER ESCAPE YOUR GAZE"
|
//"THE TRUTH CAN NO LONGER ESCAPE YOUR GAZE"
|
||||||
"@&*($#@&__TH3__#@A&#@*)__TRU1H__(*)&*)($#@&()E&R)W&<br>" +
|
"@&*($#@&__TH3__#@A&#@*)__TRU1H__(*)&*)($#@&()E&R)W&\n" +
|
||||||
"%@*$^$()@&$)$*@__CAN__()(@^#)@&@)#__N0__(#@&#)@&@&(<br>" +
|
"%@*$^$()@&$)$*@__CAN__()(@^#)@&@)#__N0__(#@&#)@&@&(\n" +
|
||||||
"*(__LON6ER__^#)@)(()*#@)@__ESCAP3__)#(@(#@*@()@(#*$<br>" +
|
"*(__LON6ER__^#)@)(()*#@)@__ESCAP3__)#(@(#@*@()@(#*$\n" +
|
||||||
"()@)#$*%)$#()$#__Y0UR__(*)$#()%(&(%)*!)($__GAZ3__#(",
|
"()@)#$*%)$#()$#__Y0UR__(*)$#()%(&(%)*!)($__GAZ3__#(",
|
||||||
),
|
),
|
||||||
|
|
||||||
[MessageFilenames.RedPill]: new Message(
|
[MessageFilenames.RedPill]: new Message(
|
||||||
MessageFilenames.RedPill,
|
MessageFilenames.RedPill,
|
||||||
//"FIND THE-CAVE"
|
//"FIND THE-CAVE"
|
||||||
"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%<br>" +
|
"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%\n" +
|
||||||
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)<br>" +
|
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)\n" +
|
||||||
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
|
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB\n" +
|
||||||
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
||||||
),
|
),
|
||||||
};
|
};
|
@ -41,7 +41,7 @@ function wrapFunction(
|
|||||||
const functionPath = tree.join(".");
|
const functionPath = tree.join(".");
|
||||||
const functionName = tree.pop();
|
const functionName = tree.pop();
|
||||||
if (typeof functionName !== "string") {
|
if (typeof functionName !== "string") {
|
||||||
throw helpers.makeRuntimeRejectMsg(workerScript, "Failure occured while wrapping netscript api");
|
throw helpers.makeBasicErrorMsg(workerScript, "Failure occured while wrapping netscript api");
|
||||||
}
|
}
|
||||||
const ctx = {
|
const ctx = {
|
||||||
workerScript,
|
workerScript,
|
||||||
|
@ -3,7 +3,6 @@ import { WorkerScript } from "./WorkerScript";
|
|||||||
import { GetAllServers, GetServer } from "../Server/AllServers";
|
import { GetAllServers, GetServer } from "../Server/AllServers";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { ScriptDeath } from "./ScriptDeath";
|
import { ScriptDeath } from "./ScriptDeath";
|
||||||
import { isString } from "../utils/helpers/isString";
|
|
||||||
import { numeralWrapper } from "../ui/numeralFormat";
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
import { ScriptArg } from "./ScriptArg";
|
import { ScriptArg } from "./ScriptArg";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
@ -40,8 +39,7 @@ export const helpers = {
|
|||||||
number,
|
number,
|
||||||
scriptArgs,
|
scriptArgs,
|
||||||
argsToString,
|
argsToString,
|
||||||
isScriptErrorMessage,
|
makeBasicErrorMsg,
|
||||||
makeRuntimeRejectMsg,
|
|
||||||
makeRuntimeErrorMsg,
|
makeRuntimeErrorMsg,
|
||||||
resolveNetscriptRequestedThreads,
|
resolveNetscriptRequestedThreads,
|
||||||
checkEnvFlags,
|
checkEnvFlags,
|
||||||
@ -114,15 +112,6 @@ function scriptArgs(ctx: NetscriptContext, args: unknown) {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines if the given msg string is an error created by makeRuntimeRejectMsg. */
|
|
||||||
function isScriptErrorMessage(msg: string): boolean {
|
|
||||||
if (!isString(msg)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const splitMsg = msg.split("|DELIMITER|");
|
|
||||||
return splitMsg.length == 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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 {
|
||||||
let out = "";
|
let out = "";
|
||||||
@ -143,12 +132,11 @@ function argsToString(args: unknown[]): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates an error message string containing hostname, scriptname, and the error message msg */
|
/** Creates an error message string containing hostname, scriptname, and the error message msg */
|
||||||
function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
|
function makeBasicErrorMsg(workerScript: WorkerScript, msg: string): string {
|
||||||
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
||||||
msg = msg.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename);
|
msg = msg.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename);
|
||||||
}
|
}
|
||||||
|
return msg;
|
||||||
return "|DELIMITER|" + workerScript.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates an error message string with a stack trace. */
|
/** Creates an error message string with a stack trace. */
|
||||||
@ -156,9 +144,9 @@ function makeRuntimeErrorMsg(ctx: NetscriptContext, msg: string): string {
|
|||||||
const errstack = new Error().stack;
|
const errstack = new Error().stack;
|
||||||
if (errstack === undefined) throw new Error("how did we not throw an error?");
|
if (errstack === undefined) throw new Error("how did we not throw an error?");
|
||||||
const stack = errstack.split("\n").slice(1);
|
const stack = errstack.split("\n").slice(1);
|
||||||
const workerScript = ctx.workerScript;
|
const ws = ctx.workerScript;
|
||||||
const caller = ctx.function;
|
const caller = ctx.functionPath;
|
||||||
const scripts = workerScript.getServer().scripts;
|
const scripts = ws.getServer().scripts;
|
||||||
const userstack = [];
|
const userstack = [];
|
||||||
for (const stackline of stack) {
|
for (const stackline of stack) {
|
||||||
let filename;
|
let filename;
|
||||||
@ -216,10 +204,10 @@ function makeRuntimeErrorMsg(ctx: NetscriptContext, msg: string): string {
|
|||||||
userstack.push(`${filename}:L${call.line}@${call.func}`);
|
userstack.push(`${filename}:L${call.line}@${call.func}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
workerScript.log(caller, () => msg);
|
log(ctx, () => msg);
|
||||||
let rejectMsg = `${caller}: ${msg}`;
|
let rejectMsg = `${caller}: ${msg}`;
|
||||||
if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`;
|
if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`;
|
||||||
return makeRuntimeRejectMsg(workerScript, rejectMsg);
|
return makeBasicErrorMsg(ws, rejectMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Validate requested number of threads for h/g/w options */
|
/** Validate requested number of threads for h/g/w options */
|
||||||
@ -230,14 +218,14 @@ function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThread
|
|||||||
}
|
}
|
||||||
const requestedThreadsAsInt = requestedThreads | 0;
|
const requestedThreadsAsInt = requestedThreads | 0;
|
||||||
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
||||||
throw makeRuntimeRejectMsg(
|
throw makeRuntimeErrorMsg(
|
||||||
ctx.workerScript,
|
ctx,
|
||||||
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
|
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (requestedThreadsAsInt > threads) {
|
if (requestedThreadsAsInt > threads) {
|
||||||
throw makeRuntimeRejectMsg(
|
throw makeRuntimeErrorMsg(
|
||||||
ctx.workerScript,
|
ctx,
|
||||||
`Too many threads requested by ${ctx.function}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
`Too many threads requested by ${ctx.function}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -258,17 +246,21 @@ function checkSingularityAccess(ctx: NetscriptContext): void {
|
|||||||
/** Create an error if a script is dead or if concurrent ns function calls are made */
|
/** Create an error if a script is dead or if concurrent ns function calls are made */
|
||||||
function checkEnvFlags(ctx: NetscriptContext): void {
|
function checkEnvFlags(ctx: NetscriptContext): void {
|
||||||
const ws = ctx.workerScript;
|
const ws = ctx.workerScript;
|
||||||
if (ws.env.stopFlag) throw new ScriptDeath(ws);
|
if (ws.env.stopFlag) {
|
||||||
|
log(ctx, () => "Failed to run due to script being killed.");
|
||||||
|
throw new ScriptDeath(ws);
|
||||||
|
}
|
||||||
if (ws.env.runningFn && ctx.function !== "asleep") {
|
if (ws.env.runningFn && ctx.function !== "asleep") {
|
||||||
ws.errorMessage = makeRuntimeRejectMsg(
|
//This one has no error message so it will not create a dialog
|
||||||
|
if (ws.delayReject) ws.delayReject(new ScriptDeath(ws));
|
||||||
|
ws.errorMessage = makeBasicErrorMsg(
|
||||||
ws,
|
ws,
|
||||||
`Concurrent calls to Netscript functions are not allowed!
|
`Concurrent calls to Netscript functions are not allowed!
|
||||||
Did you forget to await hack(), grow(), or some other
|
Did you forget to await hack(), grow(), or some other
|
||||||
promise-returning function?
|
promise-returning function?
|
||||||
Currently running: ${ws.env.runningFn} tried to run: ${ctx.function}`,
|
Currently running: ${ws.env.runningFn} tried to run: ${ctx.function}`,
|
||||||
);
|
);
|
||||||
if (ws.delayReject) ws.delayReject(new ScriptDeath(ws));
|
throw new ScriptDeath(ws);
|
||||||
throw new ScriptDeath(ws); //No idea if this is the right thing to throw
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +294,8 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
|
|||||||
}
|
}
|
||||||
ws.dynamicRamUsage += ramCost;
|
ws.dynamicRamUsage += ramCost;
|
||||||
if (ws.dynamicRamUsage > 1.01 * ws.ramUsage) {
|
if (ws.dynamicRamUsage > 1.01 * ws.ramUsage) {
|
||||||
ws.errorMessage = makeRuntimeRejectMsg(
|
log(ctx, () => "Insufficient static ram available.");
|
||||||
|
ws.errorMessage = makeBasicErrorMsg(
|
||||||
ws,
|
ws,
|
||||||
`Dynamic RAM usage calculated to be greater than initial RAM usage on fn: ${fnName}.
|
`Dynamic RAM usage calculated to be greater than initial RAM usage on fn: ${fnName}.
|
||||||
This is probably because you somehow circumvented the static RAM calculation.
|
This is probably because you somehow circumvented the static RAM calculation.
|
||||||
@ -605,7 +598,7 @@ function getRunningScriptByArgs(
|
|||||||
scriptArgs: ScriptArg[],
|
scriptArgs: ScriptArg[],
|
||||||
): RunningScript | null {
|
): RunningScript | null {
|
||||||
if (!Array.isArray(scriptArgs)) {
|
if (!Array.isArray(scriptArgs)) {
|
||||||
throw helpers.makeRuntimeRejectMsg(
|
throw helpers.makeBasicErrorMsg(
|
||||||
ctx.workerScript,
|
ctx.workerScript,
|
||||||
`Invalid scriptArgs argument passed into getRunningScript() from ${ctx.function}(). ` +
|
`Invalid scriptArgs argument passed into getRunningScript() from ${ctx.function}(). ` +
|
||||||
`This is probably a bug. Please report to game developer`,
|
`This is probably a bug. Please report to game developer`,
|
||||||
|
@ -10,7 +10,7 @@ import { WorkerScriptStartStopEventEmitter } from "./WorkerScriptStartStopEventE
|
|||||||
import { RunningScript } from "../Script/RunningScript";
|
import { RunningScript } from "../Script/RunningScript";
|
||||||
import { GetServer } from "../Server/AllServers";
|
import { GetServer } from "../Server/AllServers";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
import { errorDialog } from "../ui/React/DialogBox";
|
||||||
import { AddRecentScript } from "./RecentScripts";
|
import { AddRecentScript } from "./RecentScripts";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { ITutorial } from "../InteractiveTutorial";
|
import { ITutorial } from "../InteractiveTutorial";
|
||||||
@ -66,12 +66,7 @@ function stopAndCleanUpWorkerScript(ws: WorkerScript): void {
|
|||||||
ws.env.stopFlag = false;
|
ws.env.stopFlag = false;
|
||||||
ws.atExit();
|
ws.atExit();
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
let message = e instanceof ScriptDeath ? e.errorMessage : String(e);
|
errorDialog(e, `Error during atExit ${ws.name}@${ws.hostname} (PID - ${ws.pid}\n\n`);
|
||||||
message = message.replace(/.*\|DELIMITER\|/, "");
|
|
||||||
dialogBoxCreate(
|
|
||||||
`Error trying to call atExit for script ${[ws.name, ...ws.args].join(" ")} on ${ws.hostname}\n ${message}`,
|
|
||||||
);
|
|
||||||
console.error(e);
|
|
||||||
}
|
}
|
||||||
ws.atExit = undefined;
|
ws.atExit = undefined;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ export async function executeJSScript(
|
|||||||
const ns = workerScript.env.vars;
|
const ns = workerScript.env.vars;
|
||||||
|
|
||||||
if (!loadedModule) {
|
if (!loadedModule) {
|
||||||
throw helpers.makeRuntimeRejectMsg(
|
throw helpers.makeBasicErrorMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`${script.filename} cannot be run because the script module won't load`,
|
`${script.filename} cannot be run because the script module won't load`,
|
||||||
);
|
);
|
||||||
@ -79,18 +79,19 @@ export async function executeJSScript(
|
|||||||
// TODO: putting await in a non-async function yields unhelpful
|
// TODO: putting await in a non-async function yields unhelpful
|
||||||
// "SyntaxError: unexpected reserved word" with no line number information.
|
// "SyntaxError: unexpected reserved word" with no line number information.
|
||||||
if (!loadedModule.main) {
|
if (!loadedModule.main) {
|
||||||
throw helpers.makeRuntimeRejectMsg(
|
throw helpers.makeBasicErrorMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`${script.filename} cannot be run because it does not have a main function.`,
|
`${script.filename} cannot be run because it does not have a main function.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!ns) {
|
if (!ns) {
|
||||||
throw helpers.makeRuntimeRejectMsg(
|
throw helpers.makeBasicErrorMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`${script.filename} cannot be run because the NS object hasn't been constructed properly.`,
|
`${script.filename} cannot be run because the NS object hasn't been constructed properly.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return loadedModule.main(ns);
|
await loadedModule.main(ns);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDependencyOutOfDate(filename: string, scripts: Script[], scriptModuleSequenceNumber: number): boolean {
|
function isDependencyOutOfDate(filename: string, scripts: Script[], scriptModuleSequenceNumber: number): boolean {
|
||||||
|
@ -24,10 +24,9 @@ import { Settings } from "./Settings/Settings";
|
|||||||
|
|
||||||
import { generate } from "escodegen";
|
import { generate } from "escodegen";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
import { dialogBoxCreate, errorDialog } from "./ui/React/DialogBox";
|
||||||
import { arrayToString } from "./utils/helpers/arrayToString";
|
import { arrayToString } from "./utils/helpers/arrayToString";
|
||||||
import { roundToTwo } from "./utils/helpers/roundToTwo";
|
import { roundToTwo } from "./utils/helpers/roundToTwo";
|
||||||
import { isString } from "./utils/helpers/isString";
|
|
||||||
|
|
||||||
import { parse } from "acorn";
|
import { parse } from "acorn";
|
||||||
import { simple as walksimple } from "acorn-walk";
|
import { simple as walksimple } from "acorn-walk";
|
||||||
@ -35,7 +34,6 @@ import { areFilesEqual } from "./Terminal/DirectoryHelpers";
|
|||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
import { Terminal } from "./Terminal";
|
import { Terminal } from "./Terminal";
|
||||||
import { ScriptArg } from "./Netscript/ScriptArg";
|
import { ScriptArg } from "./Netscript/ScriptArg";
|
||||||
import { helpers } from "./Netscript/NetscriptHelpers";
|
|
||||||
|
|
||||||
export const NetscriptPorts: Map<number, IPort> = new Map();
|
export const NetscriptPorts: Map<number, IPort> = new Map();
|
||||||
|
|
||||||
@ -54,39 +52,8 @@ export function prestigeWorkerScripts(): void {
|
|||||||
// JS script promises need a little massaging to have the same guarantees as netscript
|
// JS script promises need a little massaging to have the same guarantees as netscript
|
||||||
// promises. This does said massaging and kicks the script off. It returns a promise
|
// promises. This does said massaging and kicks the script off. It returns a promise
|
||||||
// that resolves or rejects when the corresponding worker script is done.
|
// that resolves or rejects when the corresponding worker script is done.
|
||||||
function startNetscript2Script(workerScript: WorkerScript): Promise<void> {
|
const startNetscript2Script = (workerScript: WorkerScript): Promise<void> =>
|
||||||
return new Promise<void>((resolve, reject) => {
|
executeJSScript(Player, workerScript.getServer().scripts, workerScript);
|
||||||
executeJSScript(Player, workerScript.getServer().scripts, workerScript)
|
|
||||||
.then(() => {
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.catch((e) => reject(e));
|
|
||||||
}).catch((e) => {
|
|
||||||
if (e instanceof Error) {
|
|
||||||
if (e instanceof SyntaxError) {
|
|
||||||
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(
|
|
||||||
workerScript,
|
|
||||||
e.message + " (sorry we can't be more helpful)",
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(
|
|
||||||
workerScript,
|
|
||||||
e.message + ((e.stack && "\nstack:\n" + e.stack.toString()) || ""),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
throw new ScriptDeath(workerScript);
|
|
||||||
} else if (helpers.isScriptErrorMessage(e)) {
|
|
||||||
workerScript.errorMessage = e;
|
|
||||||
throw new ScriptDeath(workerScript);
|
|
||||||
} else if (e instanceof ScriptDeath) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't know what to do with it, let's try making an error message out of it
|
|
||||||
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(workerScript, "" + e);
|
|
||||||
throw new ScriptDeath(workerScript);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
||||||
const code = workerScript.code;
|
const code = workerScript.code;
|
||||||
@ -98,18 +65,16 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
codeWithImports = importProcessingRes.code;
|
codeWithImports = importProcessingRes.code;
|
||||||
codeLineOffset = importProcessingRes.lineOffset;
|
codeLineOffset = importProcessingRes.lineOffset;
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
dialogBoxCreate("Error processing Imports in " + workerScript.name + ":<br>" + String(e));
|
dialogBoxCreate(`Error processing Imports in ${workerScript.name} on ${workerScript.hostname}:\n\n${e}`);
|
||||||
workerScript.env.stopFlag = true;
|
workerScript.env.stopFlag = true;
|
||||||
killWorkerScript(workerScript);
|
killWorkerScript(workerScript);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapNS1Layer(int: Interpreter, intLayer: unknown, path: string[] = []) {
|
|
||||||
//TODO: Better typing layers of interpreter scope and ns
|
|
||||||
interface BasicObject {
|
interface BasicObject {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
const nsLayer = path.reduce((prev, newPath) => prev[newPath], workerScript.env.vars as BasicObject);
|
function wrapNS1Layer(int: Interpreter, intLayer: unknown, nsLayer = workerScript.env.vars as BasicObject) {
|
||||||
for (const [name, entry] of Object.entries(nsLayer)) {
|
for (const [name, entry] of Object.entries(nsLayer)) {
|
||||||
if (typeof entry === "function") {
|
if (typeof entry === "function") {
|
||||||
// Async functions need to be wrapped. See JS-Interpreter documentation
|
// Async functions need to be wrapped. See JS-Interpreter documentation
|
||||||
@ -121,22 +86,12 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
const result = await entry(...args.map((arg) => int.pseudoToNative(arg)));
|
const result = await entry(...args.map((arg) => int.pseudoToNative(arg)));
|
||||||
return callback(int.nativeToPseudo(result));
|
return callback(int.nativeToPseudo(result));
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
// TODO: Unify error handling, this was stolen from previous async handler
|
// NS1 interpreter doesn't cleanly handle throwing. Need to show dialog here.
|
||||||
if (typeof e === "string") {
|
errorDialog(e, `RUNTIME ERROR:\n${workerScript.name}@${workerScript.hostname}\n\n`);
|
||||||
console.error(e);
|
|
||||||
const errorTextArray = e.split("|DELIMITER|");
|
|
||||||
const hostname = errorTextArray[1];
|
|
||||||
const scriptName = errorTextArray[2];
|
|
||||||
const errorMsg = errorTextArray[3];
|
|
||||||
let msg = `${scriptName}@${hostname}<br>`;
|
|
||||||
msg += "<br>";
|
|
||||||
msg += errorMsg;
|
|
||||||
dialogBoxCreate(msg);
|
|
||||||
workerScript.env.stopFlag = true;
|
workerScript.env.stopFlag = true;
|
||||||
killWorkerScript(workerScript);
|
killWorkerScript(workerScript);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
int.setProperty(intLayer, name, int.createAsyncFunction(wrapper));
|
int.setProperty(intLayer, name, int.createAsyncFunction(wrapper));
|
||||||
} else if (Array.isArray(entry) || typeof entry !== "object") {
|
} else if (Array.isArray(entry) || typeof entry !== "object") {
|
||||||
@ -145,7 +100,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
} else {
|
} else {
|
||||||
// new object layer, e.g. bladeburner
|
// new object layer, e.g. bladeburner
|
||||||
int.setProperty(intLayer, name, int.nativeToPseudo({}));
|
int.setProperty(intLayer, name, int.nativeToPseudo({}));
|
||||||
wrapNS1Layer(int, (intLayer as BasicObject).properties[name], [...path, name]);
|
wrapNS1Layer(int, (intLayer as BasicObject).properties[name], nsLayer[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,18 +109,15 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
try {
|
try {
|
||||||
interpreter = new Interpreter(codeWithImports, wrapNS1Layer, codeLineOffset);
|
interpreter = new Interpreter(codeWithImports, wrapNS1Layer, codeLineOffset);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
dialogBoxCreate("Syntax ERROR in " + workerScript.name + ":<br>" + String(e));
|
dialogBoxCreate(`Syntax ERROR in ${workerScript.name} on ${workerScript.hostname}:\n\n${String(e)}`);
|
||||||
workerScript.env.stopFlag = true;
|
workerScript.env.stopFlag = true;
|
||||||
killWorkerScript(workerScript);
|
killWorkerScript(workerScript);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise((resolve) => {
|
||||||
function runInterpreter(): void {
|
function runInterpreter(): void {
|
||||||
try {
|
if (workerScript.env.stopFlag) resolve();
|
||||||
if (workerScript.env.stopFlag) {
|
|
||||||
return reject(new ScriptDeath(workerScript));
|
|
||||||
}
|
|
||||||
|
|
||||||
let more = true;
|
let more = true;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -179,29 +131,8 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
} catch (_e: unknown) {
|
|
||||||
let e = String(_e);
|
|
||||||
if (!helpers.isScriptErrorMessage(e)) {
|
|
||||||
e = helpers.makeRuntimeRejectMsg(workerScript, e);
|
|
||||||
}
|
}
|
||||||
workerScript.errorMessage = e;
|
|
||||||
return reject(new ScriptDeath(workerScript));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
runInterpreter();
|
runInterpreter();
|
||||||
} catch (e: unknown) {
|
|
||||||
if (isString(e)) {
|
|
||||||
workerScript.errorMessage = e;
|
|
||||||
return reject(new ScriptDeath(workerScript));
|
|
||||||
} else if (e instanceof ScriptDeath) {
|
|
||||||
return reject(e);
|
|
||||||
} else {
|
|
||||||
console.error(e);
|
|
||||||
return reject(new ScriptDeath(workerScript));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,58 +361,19 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
|
|||||||
// running status to false
|
// running status to false
|
||||||
scriptExecution
|
scriptExecution
|
||||||
.then(function () {
|
.then(function () {
|
||||||
workerScript.env.stopFlag = true;
|
|
||||||
// On natural death, the earnings are transfered to the parent if it still exists.
|
// On natural death, the earnings are transfered to the parent if it still exists.
|
||||||
if (parent !== undefined && !parent.env.stopFlag) {
|
if (parent && !parent.env.stopFlag) {
|
||||||
parent.scriptRef.onlineExpGained += runningScriptObj.onlineExpGained;
|
parent.scriptRef.onlineExpGained += runningScriptObj.onlineExpGained;
|
||||||
parent.scriptRef.onlineMoneyMade += runningScriptObj.onlineMoneyMade;
|
parent.scriptRef.onlineMoneyMade += runningScriptObj.onlineMoneyMade;
|
||||||
}
|
}
|
||||||
|
|
||||||
killWorkerScript(workerScript);
|
killWorkerScript(workerScript);
|
||||||
workerScript.log("", () => "Script finished running");
|
workerScript.log("", () => "Script finished running");
|
||||||
})
|
})
|
||||||
.catch(function (e) {
|
.catch(function (e) {
|
||||||
if (e instanceof Error) {
|
errorDialog(e, `RUNTIME ERROR\n${workerScript.name}@${workerScript.hostname} (PID - ${workerScript.pid})\n\n`);
|
||||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
let logText = "Script crashed due to an error.";
|
||||||
console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + e.toString());
|
if (e instanceof ScriptDeath) logText = "Script killed.";
|
||||||
return;
|
workerScript.log("", () => logText);
|
||||||
} else if (e instanceof ScriptDeath) {
|
|
||||||
if (helpers.isScriptErrorMessage(workerScript.errorMessage)) {
|
|
||||||
const errorTextArray = workerScript.errorMessage.split("|DELIMITER|");
|
|
||||||
if (errorTextArray.length != 4) {
|
|
||||||
console.error("ERROR: Something wrong with Error text in evaluator...");
|
|
||||||
console.error("Error text: " + workerScript.errorMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const hostname = errorTextArray[1];
|
|
||||||
const scriptName = errorTextArray[2];
|
|
||||||
const errorMsg = errorTextArray[3];
|
|
||||||
|
|
||||||
let msg = `RUNTIME ERROR<br>${scriptName}@${hostname} (PID - ${workerScript.pid})<br>`;
|
|
||||||
if (workerScript.args.length > 0) {
|
|
||||||
msg += `Args: ${arrayToString(workerScript.args)}<br>`;
|
|
||||||
}
|
|
||||||
msg += "<br>";
|
|
||||||
msg += errorMsg;
|
|
||||||
|
|
||||||
dialogBoxCreate(msg);
|
|
||||||
workerScript.log("", () => "Script crashed with runtime error");
|
|
||||||
} else {
|
|
||||||
workerScript.log("", () => "Script killed");
|
|
||||||
return; // Already killed, so stop here
|
|
||||||
}
|
|
||||||
} else if (helpers.isScriptErrorMessage(e)) {
|
|
||||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
|
||||||
console.error(
|
|
||||||
"ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " +
|
|
||||||
e.toString(),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev");
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
killWorkerScript(workerScript);
|
killWorkerScript(workerScript);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ import { AwardNFG, v1APIBreak } from "./utils/v1APIBreak";
|
|||||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||||
import { PlayerOwnedAugmentation } from "./Augmentation/PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation } from "./Augmentation/PlayerOwnedAugmentation";
|
||||||
import { LocationName } from "./Locations/data/LocationNames";
|
import { LocationName } from "./Locations/data/LocationNames";
|
||||||
import { SxProps } from "@mui/system";
|
|
||||||
import { PlayerObject } from "./PersonObjects/Player/PlayerObject";
|
import { PlayerObject } from "./PersonObjects/Player/PlayerObject";
|
||||||
import { pushGameSaved } from "./Electron";
|
import { pushGameSaved } from "./Electron";
|
||||||
import { defaultMonacoTheme } from "./ScriptEditor/ui/themes";
|
import { defaultMonacoTheme } from "./ScriptEditor/ui/themes";
|
||||||
@ -759,27 +758,14 @@ function createScamUpdateText(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resets: SxProps = {
|
|
||||||
"& h1, & h2, & h3, & h4, & p, & a, & ul": {
|
|
||||||
margin: 0,
|
|
||||||
color: Settings.theme.primary,
|
|
||||||
whiteSpace: "initial",
|
|
||||||
},
|
|
||||||
"& ul": {
|
|
||||||
paddingLeft: "1.5em",
|
|
||||||
lineHeight: 1.5,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function createNewUpdateText(): void {
|
function createNewUpdateText(): void {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() =>
|
() =>
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"New update!<br>" +
|
"New update!\n" +
|
||||||
"Please report any bugs/issues through the GitHub repository " +
|
"Please report any bugs/issues through the GitHub repository " +
|
||||||
"or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
|
"or the Bitburner subreddit (reddit.com/r/bitburner).\n\n" +
|
||||||
CONSTANTS.LatestUpdate,
|
CONSTANTS.LatestUpdate,
|
||||||
resets,
|
|
||||||
),
|
),
|
||||||
1000,
|
1000,
|
||||||
);
|
);
|
||||||
@ -788,11 +774,10 @@ function createNewUpdateText(): void {
|
|||||||
function createBetaUpdateText(): void {
|
function createBetaUpdateText(): void {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You are playing on the beta environment! This branch of the game " +
|
"You are playing on the beta environment! This branch of the game " +
|
||||||
"features the latest developments in the game. This version may be unstable.<br>" +
|
"features the latest developments in the game. This version may be unstable.\n" +
|
||||||
"Please report any bugs/issues through the github repository (https://github.com/danielyxie/bitburner/issues) " +
|
"Please report any bugs/issues through the github repository (https://github.com/danielyxie/bitburner/issues) " +
|
||||||
"or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
|
"or the Bitburner subreddit (reddit.com/r/bitburner).\n\n" +
|
||||||
CONSTANTS.LatestUpdate,
|
CONSTANTS.LatestUpdate,
|
||||||
resets,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { AutocompleteData, NS } from "../ScriptEditor/NetscriptDefinitions";
|
import { AutocompleteData, NS } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
|
|
||||||
export interface ScriptModule {
|
export interface ScriptModule {
|
||||||
main?: (ns: NS) => Promise<void>;
|
main?: (ns: NS) => unknown;
|
||||||
autocomplete?: (data: AutocompleteData, flags: string[]) => unknown;
|
autocomplete?: (data: AutocompleteData, flags: string[]) => unknown;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,7 @@
|
|||||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
import { errorDialog } from "./ui/React/DialogBox";
|
||||||
import { helpers } from "./Netscript/NetscriptHelpers";
|
|
||||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
|
||||||
|
|
||||||
export function setupUncaughtPromiseHandler(): void {
|
export function setupUncaughtPromiseHandler(): void {
|
||||||
window.addEventListener("unhandledrejection", function (e) {
|
window.addEventListener("unhandledrejection", (e) =>
|
||||||
if (helpers.isScriptErrorMessage(e.reason)) {
|
errorDialog(e.reason, "UNCAUGHT PROMISE ERROR\nYou forgot to await a promise\nmaybe hack / grow / weaken ?\n"),
|
||||||
const errorTextArray = e.reason.split("|DELIMITER|");
|
);
|
||||||
const hostname = errorTextArray[1];
|
|
||||||
const scriptName = errorTextArray[2];
|
|
||||||
const errorMsg = errorTextArray[3];
|
|
||||||
|
|
||||||
let msg = `UNCAUGHT PROMISE ERROR<br>You forgot to await a promise<br>${scriptName}@${hostname}<br>`;
|
|
||||||
msg += "<br>";
|
|
||||||
msg += errorMsg;
|
|
||||||
dialogBoxCreate(msg);
|
|
||||||
} else if (e.reason instanceof ScriptDeath) {
|
|
||||||
const msg =
|
|
||||||
`UNCAUGHT PROMISE ERROR<br>You forgot to await a promise<br>${e.reason.name}@${e.reason.hostname} (PID - ${e.reason.pid})<br>` +
|
|
||||||
`Maybe hack / grow / weaken ?`;
|
|
||||||
dialogBoxCreate(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
import { AlertEvents } from "./AlertManager";
|
import { AlertEvents } from "./AlertManager";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { SxProps } from "@mui/system";
|
|
||||||
import { Typography } from "@mui/material";
|
import { Typography } from "@mui/material";
|
||||||
|
import { ScriptDeath } from "../../Netscript/ScriptDeath";
|
||||||
|
|
||||||
export function dialogBoxCreate(txt: string | JSX.Element, styles?: SxProps): void {
|
export function dialogBoxCreate(txt: string | JSX.Element): void {
|
||||||
if (typeof txt !== "string") {
|
AlertEvents.emit(typeof txt === "string" ? <Typography component="span">{txt}</Typography> : txt);
|
||||||
AlertEvents.emit(txt);
|
}
|
||||||
} else {
|
|
||||||
AlertEvents.emit(<Typography component="span" sx={styles} dangerouslySetInnerHTML={{ __html: txt }} />);
|
export function errorDialog(e: unknown, initialText = "") {
|
||||||
}
|
let errorText = "";
|
||||||
|
if (typeof e === "string") errorText = e;
|
||||||
|
else if (e instanceof ScriptDeath) {
|
||||||
|
if (!e.errorMessage) return; //No need for a dialog for an empty ScriptDeath
|
||||||
|
errorText = e.errorMessage;
|
||||||
|
} else if (e instanceof SyntaxError) errorText = e.message + " (sorry we can't be more helpful)";
|
||||||
|
else if (e instanceof Error) errorText = e.message + (e.stack ? `\nstack:\n${e.stack.toString()}` : "");
|
||||||
|
else {
|
||||||
|
errorText = "An unknown error was thrown, see console.";
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!initialText) {
|
||||||
|
if (e instanceof ScriptDeath) initialText = `${e.name}@${e.hostname} (PID - ${e.pid})\n\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogBoxCreate(initialText + errorText);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user