mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-19 14:13:48 +01:00
commit
3ba8e59a9b
@ -4,7 +4,11 @@ module.exports = {
|
|||||||
commonjs: true,
|
commonjs: true,
|
||||||
es6: false,
|
es6: false,
|
||||||
},
|
},
|
||||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
extends: [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
// "plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||||
|
],
|
||||||
parser: "@typescript-eslint/parser",
|
parser: "@typescript-eslint/parser",
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 8,
|
ecmaVersion: 8,
|
||||||
@ -12,6 +16,7 @@ module.exports = {
|
|||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
experimentalObjectRestSpread: true,
|
experimentalObjectRestSpread: true,
|
||||||
},
|
},
|
||||||
|
project: ["./tsconfig.json", "./test/tsconfig.json", "./tools/tsconfig.json", "./test/cypress/tsconfig.json"],
|
||||||
},
|
},
|
||||||
plugins: ["@typescript-eslint"],
|
plugins: ["@typescript-eslint"],
|
||||||
rules: {
|
rules: {
|
||||||
|
4
dist/main.bundle.js
vendored
4
dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/main.bundle.js.map
vendored
2
dist/main.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
42
dist/vendor.bundle.js
vendored
42
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/vendor.bundle.js.map
vendored
2
dist/vendor.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -114,8 +114,8 @@
|
|||||||
"start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer",
|
"start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer",
|
||||||
"build": "webpack --mode production",
|
"build": "webpack --mode production",
|
||||||
"build:dev": "webpack --mode development",
|
"build:dev": "webpack --mode development",
|
||||||
"lint": "eslint --fix --ext js,jsx,ts,tsx --max-warnings 0 .",
|
"lint": "eslint --fix --ext js,jsx,ts,tsx --max-warnings 0 src",
|
||||||
"lint:report": "eslint --ext js,jsx,ts,tsx --max-warnings 0 .",
|
"lint:report": "eslint --ext js,jsx,ts,tsx --max-warnings 0 src",
|
||||||
"lint:report-diff": "eslint --max-warnings 0 $(git diff --name-only --diff-filter=ACMRTUXB origin/dev | grep -E \"(.js$|.jsx$|.ts$|.tsx$)\" | xargs)",
|
"lint:report-diff": "eslint --max-warnings 0 $(git diff --name-only --diff-filter=ACMRTUXB origin/dev | grep -E \"(.js$|.jsx$|.ts$|.tsx$)\" | xargs)",
|
||||||
"preinstall": "node ./tools/engines-check/engines-check.js",
|
"preinstall": "node ./tools/engines-check/engines-check.js",
|
||||||
"postinstall": "cd electron && npm install",
|
"postinstall": "cd electron && npm install",
|
||||||
|
@ -70,17 +70,17 @@ export class Bladeburner implements IBladeburner {
|
|||||||
type: ActionTypes["Idle"],
|
type: ActionTypes["Idle"],
|
||||||
});
|
});
|
||||||
|
|
||||||
cities: any = {};
|
cities: Record<string, City> = {};
|
||||||
city: string = BladeburnerConstants.CityNames[2];
|
city: string = BladeburnerConstants.CityNames[2];
|
||||||
skills: any = {};
|
skills: Record<string, number> = {};
|
||||||
skillMultipliers: any = {};
|
skillMultipliers: Record<string, number> = {};
|
||||||
staminaBonus = 0;
|
staminaBonus = 0;
|
||||||
maxStamina = 0;
|
maxStamina = 0;
|
||||||
stamina = 0;
|
stamina = 0;
|
||||||
contracts: any = {};
|
contracts: Record<string, Contract> = {};
|
||||||
operations: any = {};
|
operations: Record<string, Operation> = {};
|
||||||
blackops: any = {};
|
blackops: Record<string, boolean> = {};
|
||||||
logging: any = {
|
logging = {
|
||||||
general: true,
|
general: true,
|
||||||
contracts: true,
|
contracts: true,
|
||||||
ops: true,
|
ops: true,
|
||||||
@ -477,54 +477,54 @@ export class Bladeburner implements IBladeburner {
|
|||||||
this.postToConsole("Effects: ");
|
this.postToConsole("Effects: ");
|
||||||
const multKeys = Object.keys(this.skillMultipliers);
|
const multKeys = Object.keys(this.skillMultipliers);
|
||||||
for (let i = 0; i < multKeys.length; ++i) {
|
for (let i = 0; i < multKeys.length; ++i) {
|
||||||
let mult = this.skillMultipliers[multKeys[i]];
|
const mult = this.skillMultipliers[multKeys[i]];
|
||||||
if (mult && mult !== 1) {
|
if (mult && mult !== 1) {
|
||||||
mult = formatNumber(mult, 3);
|
const mults = formatNumber(mult, 3);
|
||||||
switch (multKeys[i]) {
|
switch (multKeys[i]) {
|
||||||
case "successChanceAll":
|
case "successChanceAll":
|
||||||
this.postToConsole("Total Success Chance: x" + mult);
|
this.postToConsole("Total Success Chance: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "successChanceStealth":
|
case "successChanceStealth":
|
||||||
this.postToConsole("Stealth Success Chance: x" + mult);
|
this.postToConsole("Stealth Success Chance: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "successChanceKill":
|
case "successChanceKill":
|
||||||
this.postToConsole("Retirement Success Chance: x" + mult);
|
this.postToConsole("Retirement Success Chance: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "successChanceContract":
|
case "successChanceContract":
|
||||||
this.postToConsole("Contract Success Chance: x" + mult);
|
this.postToConsole("Contract Success Chance: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "successChanceOperation":
|
case "successChanceOperation":
|
||||||
this.postToConsole("Operation Success Chance: x" + mult);
|
this.postToConsole("Operation Success Chance: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "successChanceEstimate":
|
case "successChanceEstimate":
|
||||||
this.postToConsole("Synthoid Data Estimate: x" + mult);
|
this.postToConsole("Synthoid Data Estimate: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "actionTime":
|
case "actionTime":
|
||||||
this.postToConsole("Action Time: x" + mult);
|
this.postToConsole("Action Time: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effHack":
|
case "effHack":
|
||||||
this.postToConsole("Hacking Skill: x" + mult);
|
this.postToConsole("Hacking Skill: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effStr":
|
case "effStr":
|
||||||
this.postToConsole("Strength: x" + mult);
|
this.postToConsole("Strength: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effDef":
|
case "effDef":
|
||||||
this.postToConsole("Defense: x" + mult);
|
this.postToConsole("Defense: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effDex":
|
case "effDex":
|
||||||
this.postToConsole("Dexterity: x" + mult);
|
this.postToConsole("Dexterity: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effAgi":
|
case "effAgi":
|
||||||
this.postToConsole("Agility: x" + mult);
|
this.postToConsole("Agility: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effCha":
|
case "effCha":
|
||||||
this.postToConsole("Charisma: x" + mult);
|
this.postToConsole("Charisma: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "effInt":
|
case "effInt":
|
||||||
this.postToConsole("Intelligence: x" + mult);
|
this.postToConsole("Intelligence: x" + mults);
|
||||||
break;
|
break;
|
||||||
case "stamina":
|
case "stamina":
|
||||||
this.postToConsole("Stamina: x" + mult);
|
this.postToConsole("Stamina: x" + mults);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`);
|
console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`);
|
||||||
@ -2029,12 +2029,12 @@ export class Bladeburner implements IBladeburner {
|
|||||||
this.stamina = Math.min(this.maxStamina, this.stamina);
|
this.stamina = Math.min(this.maxStamina, this.stamina);
|
||||||
|
|
||||||
// Count increase for contracts/operations
|
// Count increase for contracts/operations
|
||||||
for (const contract of Object.values(this.contracts) as Contract[]) {
|
for (const contract of Object.values(this.contracts)) {
|
||||||
const growthF = Growths[contract.name];
|
const growthF = Growths[contract.name];
|
||||||
if (growthF === undefined) throw new Error(`growth formula for action '${contract.name}' is undefined`);
|
if (growthF === undefined) throw new Error(`growth formula for action '${contract.name}' is undefined`);
|
||||||
contract.count += (seconds * growthF()) / BladeburnerConstants.ActionCountGrowthPeriod;
|
contract.count += (seconds * growthF()) / BladeburnerConstants.ActionCountGrowthPeriod;
|
||||||
}
|
}
|
||||||
for (const op of Object.values(this.operations) as Operation[]) {
|
for (const op of Object.values(this.operations)) {
|
||||||
const growthF = Growths[op.name];
|
const growthF = Growths[op.name];
|
||||||
if (growthF === undefined) throw new Error(`growth formula for action '${op.name}' is undefined`);
|
if (growthF === undefined) throw new Error(`growth formula for action '${op.name}' is undefined`);
|
||||||
if (growthF !== undefined) {
|
if (growthF !== undefined) {
|
||||||
|
@ -74,7 +74,7 @@ export function GeneralActionElem(props: IProps): React.ReactElement {
|
|||||||
<CopyableText value={props.action.name} />
|
<CopyableText value={props.action.name} />
|
||||||
<StartButton
|
<StartButton
|
||||||
bladeburner={props.bladeburner}
|
bladeburner={props.bladeburner}
|
||||||
type={ActionTypes[props.action.name as string]}
|
type={ActionTypes[props.action.name ]}
|
||||||
name={props.action.name}
|
name={props.action.name}
|
||||||
rerender={rerender}
|
rerender={rerender}
|
||||||
/>
|
/>
|
||||||
|
@ -131,8 +131,6 @@ export class Product {
|
|||||||
this.fin = true;
|
this.fin = true;
|
||||||
|
|
||||||
//Calculate properties
|
//Calculate properties
|
||||||
const progrMult = this.prog / 100;
|
|
||||||
|
|
||||||
const engrRatio = employeeProd[EmployeePositions.Engineer] / employeeProd["total"];
|
const engrRatio = employeeProd[EmployeePositions.Engineer] / employeeProd["total"];
|
||||||
const mgmtRatio = employeeProd[EmployeePositions.Management] / employeeProd["total"];
|
const mgmtRatio = employeeProd[EmployeePositions.Management] / employeeProd["total"];
|
||||||
const rndRatio = employeeProd[EmployeePositions.RandD] / employeeProd["total"];
|
const rndRatio = employeeProd[EmployeePositions.RandD] / employeeProd["total"];
|
||||||
@ -141,7 +139,7 @@ export class Product {
|
|||||||
const designMult = 1 + Math.pow(this.designCost, 0.1) / 100;
|
const designMult = 1 + Math.pow(this.designCost, 0.1) / 100;
|
||||||
const balanceMult = 1.2 * engrRatio + 0.9 * mgmtRatio + 1.3 * rndRatio + 1.5 * opsRatio + busRatio;
|
const balanceMult = 1.2 * engrRatio + 0.9 * mgmtRatio + 1.3 * rndRatio + 1.5 * opsRatio + busRatio;
|
||||||
const sciMult = 1 + Math.pow(industry.sciResearch.qty, industry.sciFac) / 800;
|
const sciMult = 1 + Math.pow(industry.sciResearch.qty, industry.sciFac) / 800;
|
||||||
const totalMult = progrMult * balanceMult * designMult * sciMult;
|
const totalMult = balanceMult * designMult * sciMult;
|
||||||
|
|
||||||
this.qlt =
|
this.qlt =
|
||||||
totalMult *
|
totalMult *
|
||||||
|
@ -66,7 +66,7 @@ export function DevMenuRoot(props: IProps): React.ReactElement {
|
|||||||
<TimeSkip player={props.player} engine={props.engine} />
|
<TimeSkip player={props.player} engine={props.engine} />
|
||||||
<Achievements player={props.player} engine={props.engine} />
|
<Achievements player={props.player} engine={props.engine} />
|
||||||
<Entropy player={props.player} engine={props.engine} />
|
<Entropy player={props.player} engine={props.engine} />
|
||||||
<SaveFile player={props.player} />
|
<SaveFile />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export function Augmentations(props: IProps): React.ReactElement {
|
|||||||
const [augmentation, setAugmentation] = useState("Augmented Targeting I");
|
const [augmentation, setAugmentation] = useState("Augmented Targeting I");
|
||||||
|
|
||||||
function setAugmentationDropdown(event: SelectChangeEvent<string>): void {
|
function setAugmentationDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setAugmentation(event.target.value as string);
|
setAugmentation(event.target.value );
|
||||||
}
|
}
|
||||||
function queueAug(): void {
|
function queueAug(): void {
|
||||||
props.player.queueAugmentation(augmentation);
|
props.player.queueAugmentation(augmentation);
|
||||||
|
@ -15,7 +15,7 @@ import { CodingContractTypes } from "../../CodingContracts";
|
|||||||
export function CodingContracts(): React.ReactElement {
|
export function CodingContracts(): React.ReactElement {
|
||||||
const [codingcontract, setCodingcontract] = useState("Find Largest Prime Factor");
|
const [codingcontract, setCodingcontract] = useState("Find Largest Prime Factor");
|
||||||
function setCodingcontractDropdown(event: SelectChangeEvent<string>): void {
|
function setCodingcontractDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setCodingcontract(event.target.value as string);
|
setCodingcontract(event.target.value );
|
||||||
}
|
}
|
||||||
|
|
||||||
function specificContract(): void {
|
function specificContract(): void {
|
||||||
|
@ -18,7 +18,7 @@ const bigNumber = 1e12;
|
|||||||
export function Companies(): React.ReactElement {
|
export function Companies(): React.ReactElement {
|
||||||
const [company, setCompany] = useState(FactionNames.ECorp as string);
|
const [company, setCompany] = useState(FactionNames.ECorp as string);
|
||||||
function setCompanyDropdown(event: SelectChangeEvent<string>): void {
|
function setCompanyDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setCompany(event.target.value as string);
|
setCompany(event.target.value );
|
||||||
}
|
}
|
||||||
function resetCompanyRep(): void {
|
function resetCompanyRep(): void {
|
||||||
AllCompanies[company].playerReputation = 0;
|
AllCompanies[company].playerReputation = 0;
|
||||||
|
@ -29,7 +29,7 @@ export function Factions(props: IProps): React.ReactElement {
|
|||||||
const [faction, setFaction] = useState(FactionNames.Illuminati as string);
|
const [faction, setFaction] = useState(FactionNames.Illuminati as string);
|
||||||
|
|
||||||
function setFactionDropdown(event: SelectChangeEvent<string>): void {
|
function setFactionDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setFaction(event.target.value as string);
|
setFaction(event.target.value );
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveInvite(): void {
|
function receiveInvite(): void {
|
||||||
|
@ -19,7 +19,7 @@ interface IProps {
|
|||||||
export function Programs(props: IProps): React.ReactElement {
|
export function Programs(props: IProps): React.ReactElement {
|
||||||
const [program, setProgram] = useState("NUKE.exe");
|
const [program, setProgram] = useState("NUKE.exe");
|
||||||
function setProgramDropdown(event: SelectChangeEvent<string>): void {
|
function setProgramDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setProgram(event.target.value as string);
|
setProgram(event.target.value );
|
||||||
}
|
}
|
||||||
function addProgram(): void {
|
function addProgram(): void {
|
||||||
if (!props.player.hasProgram(program)) {
|
if (!props.player.hasProgram(program)) {
|
||||||
|
@ -6,20 +6,13 @@ import AccordionDetails from "@mui/material/AccordionDetails";
|
|||||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||||
|
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { saveObject } from "../../SaveObject";
|
import { saveObject } from "../../SaveObject";
|
||||||
import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
|
import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
|
||||||
import { Upload } from "@mui/icons-material";
|
import { Upload } from "@mui/icons-material";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import { OptionSwitch } from "../../ui/React/OptionSwitch";
|
import { OptionSwitch } from "../../ui/React/OptionSwitch";
|
||||||
|
|
||||||
// Update as additional BitNodes get implemented
|
export function SaveFile(): React.ReactElement {
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
player: IPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SaveFile(props: IProps): React.ReactElement {
|
|
||||||
const importInput = useRef<HTMLInputElement>(null);
|
const importInput = useRef<HTMLInputElement>(null);
|
||||||
const [saveFile, setSaveFile] = useState("");
|
const [saveFile, setSaveFile] = useState("");
|
||||||
const [restoreScripts, setRestoreScripts] = useState(true);
|
const [restoreScripts, setRestoreScripts] = useState(true);
|
||||||
|
@ -15,7 +15,7 @@ import MenuItem from "@mui/material/MenuItem";
|
|||||||
export function Servers(): React.ReactElement {
|
export function Servers(): React.ReactElement {
|
||||||
const [server, setServer] = useState("home");
|
const [server, setServer] = useState("home");
|
||||||
function setServerDropdown(event: SelectChangeEvent<string>): void {
|
function setServerDropdown(event: SelectChangeEvent<string>): void {
|
||||||
setServer(event.target.value as string);
|
setServer(event.target.value );
|
||||||
}
|
}
|
||||||
function rootServer(): void {
|
function rootServer(): void {
|
||||||
const s = GetServer(server);
|
const s = GetServer(server);
|
||||||
|
@ -8,8 +8,8 @@ export function Unclickable(): React.ReactElement {
|
|||||||
|
|
||||||
function unclickable(event: React.MouseEvent<HTMLDivElement>): void {
|
function unclickable(event: React.MouseEvent<HTMLDivElement>): void {
|
||||||
if (!event.target || !(event.target instanceof Element)) return;
|
if (!event.target || !(event.target instanceof Element)) return;
|
||||||
const display = getComputedStyle(event.target as Element).display;
|
const display = getComputedStyle(event.target ).display;
|
||||||
const visibility = getComputedStyle(event.target as Element).visibility;
|
const visibility = getComputedStyle(event.target ).visibility;
|
||||||
if (display === "none" && visibility === "hidden" && event.isTrusted) player.giveExploit(Exploit.Unclickable);
|
if (display === "none" && visibility === "hidden" && event.isTrusted) player.giveExploit(Exploit.Unclickable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleLocaleChange(event: SelectChangeEvent<string>): void {
|
function handleLocaleChange(event: SelectChangeEvent<string>): void {
|
||||||
setLocale(event.target.value as string);
|
setLocale(event.target.value );
|
||||||
Settings.Locale = event.target.value as string;
|
Settings.Locale = event.target.value ;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTimestampFormatChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
function handleTimestampFormatChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
@ -54,7 +54,7 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
|
|||||||
multiplier = getMaxNumberLevelUpgrades(props.player, node, HacknetNodeConstants.MaxLevel);
|
multiplier = getMaxNumberLevelUpgrades(props.player, node, HacknetNodeConstants.MaxLevel);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
|
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
multiplier = Math.min(levelsToMax, purchaseMult );
|
||||||
}
|
}
|
||||||
|
|
||||||
const increase =
|
const increase =
|
||||||
@ -94,7 +94,7 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
|
|||||||
multiplier = getMaxNumberRamUpgrades(props.player, node, HacknetNodeConstants.MaxRam);
|
multiplier = getMaxNumberRamUpgrades(props.player, node, HacknetNodeConstants.MaxRam);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram));
|
const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram));
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
multiplier = Math.min(levelsToMax, purchaseMult );
|
||||||
}
|
}
|
||||||
|
|
||||||
const increase =
|
const increase =
|
||||||
@ -144,7 +144,7 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
|
|||||||
multiplier = getMaxNumberCoreUpgrades(props.player, node, HacknetNodeConstants.MaxCores);
|
multiplier = getMaxNumberCoreUpgrades(props.player, node, HacknetNodeConstants.MaxCores);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
|
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
multiplier = Math.min(levelsToMax, purchaseMult );
|
||||||
}
|
}
|
||||||
|
|
||||||
const increase =
|
const increase =
|
||||||
|
@ -9,15 +9,16 @@ import { Settings } from "../Settings/Settings";
|
|||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
|
|
||||||
type ExternalFunction = (...args: any[]) => any;
|
type ExternalFunction = (...args: any[]) => any;
|
||||||
type ExternalAPI = {
|
export type ExternalAPI = {
|
||||||
[string: string]: ExternalAPI | ExternalFunction;
|
[string: string]: ExternalAPI | ExternalFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: NetscriptContext) => F;
|
type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: NetscriptContext) => F;
|
||||||
|
|
||||||
export type InternalAPI<API> = {
|
export type InternalAPI<API> = {
|
||||||
[Property in keyof API]: API[Property] extends ExternalFunction
|
[Property in keyof API]: API[Property] extends ExternalFunction
|
||||||
? InternalFunction<API[Property]>
|
? InternalFunction<API[Property]>
|
||||||
: API[Property] extends ExternalAPI
|
: API[Property] extends object
|
||||||
? InternalAPI<API[Property]>
|
? InternalAPI<API[Property]>
|
||||||
: never;
|
: never;
|
||||||
};
|
};
|
||||||
@ -42,9 +43,14 @@ type NetscriptHelpers = {
|
|||||||
number: (funcName: string, argName: string, v: unknown) => number;
|
number: (funcName: string, argName: string, v: unknown) => number;
|
||||||
city: (funcName: string, argName: string, v: unknown) => CityName;
|
city: (funcName: string, argName: string, v: unknown) => CityName;
|
||||||
boolean: (v: unknown) => boolean;
|
boolean: (v: unknown) => boolean;
|
||||||
getServer: (hostname: string, callingFnName: string) => BaseServer;
|
getServer: (hostname: string, ctx: NetscriptContext) => BaseServer;
|
||||||
checkSingularityAccess: (func: string) => void;
|
checkSingularityAccess: (func: string) => void;
|
||||||
hack: (hostname: any, manual: any, { threads: requestedThreads, stock }?: any) => Promise<number>;
|
hack: (
|
||||||
|
ctx: NetscriptContext,
|
||||||
|
hostname: any,
|
||||||
|
manual: any,
|
||||||
|
{ threads: requestedThreads, stock }?: any,
|
||||||
|
) => Promise<number>;
|
||||||
getValidPort: (funcName: string, port: any) => IPort;
|
getValidPort: (funcName: string, port: any) => IPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,7 +93,7 @@ function wrapFunction(
|
|||||||
number: (argName: string, v: unknown) => helpers.number(functionPath, argName, v),
|
number: (argName: string, v: unknown) => helpers.number(functionPath, argName, v),
|
||||||
city: (argName: string, v: unknown) => helpers.city(functionPath, argName, v),
|
city: (argName: string, v: unknown) => helpers.city(functionPath, argName, v),
|
||||||
boolean: helpers.boolean,
|
boolean: helpers.boolean,
|
||||||
getServer: (hostname: string) => helpers.getServer(hostname, functionPath),
|
getServer: (hostname: string) => helpers.getServer(hostname, ctx),
|
||||||
checkSingularityAccess: () => helpers.checkSingularityAccess(functionName),
|
checkSingularityAccess: () => helpers.checkSingularityAccess(functionName),
|
||||||
hack: helpers.hack,
|
hack: helpers.hack,
|
||||||
getValidPort: (port: any) => helpers.getValidPort(functionPath, port),
|
getValidPort: (port: any) => helpers.getValidPort(functionPath, port),
|
||||||
@ -98,7 +104,10 @@ function wrapFunction(
|
|||||||
helpers.updateDynamicRam(ctx.function, getRamCost(Player, ...tree, ctx.function));
|
helpers.updateDynamicRam(ctx.function, getRamCost(Player, ...tree, ctx.function));
|
||||||
if (safetyEnabled) {
|
if (safetyEnabled) {
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
if (now - workerScript.infiniteLoopSafety > CONSTANTS.InfiniteLoopLimit) {
|
if (
|
||||||
|
now - workerScript.infiniteLoopSafety > CONSTANTS.InfiniteLoopLimit &&
|
||||||
|
workerScript.scriptRef.filename.endsWith(".js")
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Potential infinite loop without sleep detected. The game spent ${CONSTANTS.InfiniteLoopLimit}ms stuck in this script. (Are you using 'asleep' by mistake?)`,
|
`Potential infinite loop without sleep detected. The game spent ${CONSTANTS.InfiniteLoopLimit}ms stuck in this script. (Are you using 'asleep' by mistake?)`,
|
||||||
);
|
);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* The environment in which a script runs. The environment holds
|
* The environment in which a script runs. The environment holds
|
||||||
* Netscript functions and arguments for that script.
|
* Netscript functions and arguments for that script.
|
||||||
*/
|
*/
|
||||||
|
import { NS } from "src/ScriptEditor/NetscriptDefinitions";
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
|
|
||||||
export class Environment {
|
export class Environment {
|
||||||
@ -18,7 +19,7 @@ export class Environment {
|
|||||||
/**
|
/**
|
||||||
* Environment variables (currently only Netscript functions)
|
* Environment variables (currently only Netscript functions)
|
||||||
*/
|
*/
|
||||||
vars: IMap<any> = {};
|
vars: any = {};
|
||||||
|
|
||||||
constructor(parent: Environment | null) {
|
constructor(parent: Environment | null) {
|
||||||
if (parent instanceof Environment) {
|
if (parent instanceof Environment) {
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
import { IPlayer } from "src/PersonObjects/IPlayer";
|
import { IPlayer } from "src/PersonObjects/IPlayer";
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
|
|
||||||
|
import { NS as INS } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
|
|
||||||
|
import { INetscriptExtra } from "../NetscriptFunctions/Extra";
|
||||||
|
|
||||||
|
type RamCostTree<API> = {
|
||||||
|
[Property in keyof API]: API[Property] extends () => void
|
||||||
|
? number | ((p: IPlayer) => void)
|
||||||
|
: API[Property] extends object
|
||||||
|
? RamCostTree<API[Property]>
|
||||||
|
: never;
|
||||||
|
};
|
||||||
|
|
||||||
// TODO remember to update RamCalculations.js and WorkerScript.js
|
// TODO remember to update RamCalculations.js and WorkerScript.js
|
||||||
|
|
||||||
// RAM costs for Netscript functions
|
// RAM costs for Netscript functions
|
||||||
@ -89,7 +101,7 @@ function SF4Cost(cost: number): (player: IPlayer) => number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hacknet API
|
// Hacknet API
|
||||||
const hacknet: IMap<any> = {
|
const hacknet = {
|
||||||
numNodes: 0,
|
numNodes: 0,
|
||||||
purchaseNode: 0,
|
purchaseNode: 0,
|
||||||
getPurchaseNodeCost: 0,
|
getPurchaseNodeCost: 0,
|
||||||
@ -106,10 +118,15 @@ const hacknet: IMap<any> = {
|
|||||||
hashCost: 0,
|
hashCost: 0,
|
||||||
spendHashes: 0,
|
spendHashes: 0,
|
||||||
maxNumNodes: 0,
|
maxNumNodes: 0,
|
||||||
|
hashCapacity: 0,
|
||||||
|
getHashUpgrades: 0,
|
||||||
|
getHashUpgradeLevel: 0,
|
||||||
|
getStudyMult: 0,
|
||||||
|
getTrainingMult: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stock API
|
// Stock API
|
||||||
const stock: IMap<any> = {
|
const stock = {
|
||||||
getSymbols: RamCostConstants.ScriptGetStockRamCost,
|
getSymbols: RamCostConstants.ScriptGetStockRamCost,
|
||||||
getPrice: RamCostConstants.ScriptGetStockRamCost,
|
getPrice: RamCostConstants.ScriptGetStockRamCost,
|
||||||
getAskPrice: RamCostConstants.ScriptGetStockRamCost,
|
getAskPrice: RamCostConstants.ScriptGetStockRamCost,
|
||||||
@ -134,7 +151,7 @@ const stock: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Singularity API
|
// Singularity API
|
||||||
const singularity: IMap<any> = {
|
const singularity = {
|
||||||
universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
||||||
gymWorkout: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
gymWorkout: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
||||||
travelToCity: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
travelToCity: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
||||||
@ -190,7 +207,7 @@ const singularity: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Gang API
|
// Gang API
|
||||||
const gang: IMap<any> = {
|
const gang = {
|
||||||
createGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
createGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
||||||
inGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
inGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
||||||
getMemberNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
getMemberNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
|
||||||
@ -215,7 +232,7 @@ const gang: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Bladeburner API
|
// Bladeburner API
|
||||||
const bladeburner: IMap<any> = {
|
const bladeburner = {
|
||||||
getContractNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
getContractNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
||||||
getOperationNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
getOperationNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
||||||
getBlackOpNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
getBlackOpNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
|
||||||
@ -253,15 +270,13 @@ const bladeburner: IMap<any> = {
|
|||||||
getBonusTime: 0,
|
getBonusTime: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const infiltration: IMap<any> = {
|
const infiltration = {
|
||||||
calculateDifficulty: RamCostConstants.ScriptInfiltrationCalculateDifficulty,
|
getPossibleLocations: RamCostConstants.ScriptInfiltrationGetLocations,
|
||||||
calculateRewards: RamCostConstants.ScriptInfiltrationCalculateRewards,
|
getInfiltration: RamCostConstants.ScriptInfiltrationGetInfiltrations,
|
||||||
calculateGetLocations: RamCostConstants.ScriptInfiltrationGetLocations,
|
|
||||||
calculateGetInfiltrations: RamCostConstants.ScriptInfiltrationGetInfiltrations,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Coding Contract API
|
// Coding Contract API
|
||||||
const codingcontract: IMap<any> = {
|
const codingcontract = {
|
||||||
attempt: RamCostConstants.ScriptCodingContractBaseRamCost,
|
attempt: RamCostConstants.ScriptCodingContractBaseRamCost,
|
||||||
getContractType: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
getContractType: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||||
getData: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
getData: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||||
@ -270,7 +285,7 @@ const codingcontract: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Duplicate Sleeve API
|
// Duplicate Sleeve API
|
||||||
const sleeve: IMap<any> = {
|
const sleeve = {
|
||||||
getNumSleeves: RamCostConstants.ScriptSleeveBaseRamCost,
|
getNumSleeves: RamCostConstants.ScriptSleeveBaseRamCost,
|
||||||
setToShockRecovery: RamCostConstants.ScriptSleeveBaseRamCost,
|
setToShockRecovery: RamCostConstants.ScriptSleeveBaseRamCost,
|
||||||
setToSynchronize: RamCostConstants.ScriptSleeveBaseRamCost,
|
setToSynchronize: RamCostConstants.ScriptSleeveBaseRamCost,
|
||||||
@ -290,7 +305,7 @@ const sleeve: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Stanek API
|
// Stanek API
|
||||||
const stanek: IMap<any> = {
|
const stanek = {
|
||||||
giftWidth: RamCostConstants.ScriptStanekWidth,
|
giftWidth: RamCostConstants.ScriptStanekWidth,
|
||||||
giftHeight: RamCostConstants.ScriptStanekHeight,
|
giftHeight: RamCostConstants.ScriptStanekHeight,
|
||||||
chargeFragment: RamCostConstants.ScriptStanekCharge,
|
chargeFragment: RamCostConstants.ScriptStanekCharge,
|
||||||
@ -305,7 +320,7 @@ const stanek: IMap<any> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// UI API
|
// UI API
|
||||||
const ui: IMap<any> = {
|
const ui = {
|
||||||
getTheme: 0,
|
getTheme: 0,
|
||||||
setTheme: 0,
|
setTheme: 0,
|
||||||
resetTheme: 0,
|
resetTheme: 0,
|
||||||
@ -313,17 +328,84 @@ const ui: IMap<any> = {
|
|||||||
setStyles: 0,
|
setStyles: 0,
|
||||||
resetStyles: 0,
|
resetStyles: 0,
|
||||||
getGameInfo: 0,
|
getGameInfo: 0,
|
||||||
|
clearTerminal: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Grafting API
|
// Grafting API
|
||||||
const grafting: IMap<any> = {
|
const grafting = {
|
||||||
getAugmentationGraftPrice: 3.75,
|
getAugmentationGraftPrice: 3.75,
|
||||||
getAugmentationGraftTime: 3.75,
|
getAugmentationGraftTime: 3.75,
|
||||||
getGraftableAugmentations: 5,
|
getGraftableAugmentations: 5,
|
||||||
graftAugmentation: 7.5,
|
graftAugmentation: 7.5,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RamCosts: IMap<any> = {
|
const corporation = {
|
||||||
|
createCorporation: 0,
|
||||||
|
hasUnlockUpgrade: 0,
|
||||||
|
getUnlockUpgradeCost: 0,
|
||||||
|
getUpgradeLevel: 0,
|
||||||
|
getUpgradeLevelCost: 0,
|
||||||
|
getExpandIndustryCost: 0,
|
||||||
|
getExpandCityCost: 0,
|
||||||
|
getInvestmentOffer: 0,
|
||||||
|
acceptInvestmentOffer: 0,
|
||||||
|
goPublic: 0,
|
||||||
|
bribe: 0,
|
||||||
|
getCorporation: 0,
|
||||||
|
getDivision: 0,
|
||||||
|
expandIndustry: 0,
|
||||||
|
expandCity: 0,
|
||||||
|
unlockUpgrade: 0,
|
||||||
|
levelUpgrade: 0,
|
||||||
|
issueDividends: 0,
|
||||||
|
buyBackShares: 0,
|
||||||
|
sellShares: 0,
|
||||||
|
getBonusTime: 0,
|
||||||
|
sellMaterial: 0,
|
||||||
|
sellProduct: 0,
|
||||||
|
discontinueProduct: 0,
|
||||||
|
setSmartSupply: 0,
|
||||||
|
setSmartSupplyUseLeftovers: 0,
|
||||||
|
buyMaterial: 0,
|
||||||
|
bulkPurchase: 0,
|
||||||
|
getWarehouse: 0,
|
||||||
|
getProduct: 0,
|
||||||
|
getMaterial: 0,
|
||||||
|
setMaterialMarketTA1: 0,
|
||||||
|
setMaterialMarketTA2: 0,
|
||||||
|
setProductMarketTA1: 0,
|
||||||
|
setProductMarketTA2: 0,
|
||||||
|
exportMaterial: 0,
|
||||||
|
cancelExportMaterial: 0,
|
||||||
|
purchaseWarehouse: 0,
|
||||||
|
upgradeWarehouse: 0,
|
||||||
|
makeProduct: 0,
|
||||||
|
limitMaterialProduction: 0,
|
||||||
|
limitProductProduction: 0,
|
||||||
|
getPurchaseWarehouseCost: 0,
|
||||||
|
getUpgradeWarehouseCost: 0,
|
||||||
|
hasWarehouse: 0,
|
||||||
|
assignJob: 0,
|
||||||
|
hireEmployee: 0,
|
||||||
|
upgradeOfficeSize: 0,
|
||||||
|
throwParty: 0,
|
||||||
|
buyCoffee: 0,
|
||||||
|
hireAdVert: 0,
|
||||||
|
research: 0,
|
||||||
|
getOffice: 0,
|
||||||
|
getEmployee: 0,
|
||||||
|
getHireAdVertCost: 0,
|
||||||
|
getHireAdVertCount: 0,
|
||||||
|
getResearchCost: 0,
|
||||||
|
hasResearched: 0,
|
||||||
|
setAutoJobAssignment: 0,
|
||||||
|
getOfficeSizeUpgradeCost: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const SourceRamCosts = {
|
||||||
|
args: undefined as unknown as never[], // special use case
|
||||||
|
enums: undefined as unknown as never,
|
||||||
|
corporation,
|
||||||
hacknet,
|
hacknet,
|
||||||
stock,
|
stock,
|
||||||
singularity,
|
singularity,
|
||||||
@ -363,7 +445,6 @@ export const RamCosts: IMap<any> = {
|
|||||||
enableLog: 0,
|
enableLog: 0,
|
||||||
isLogEnabled: 0,
|
isLogEnabled: 0,
|
||||||
getScriptLogs: 0,
|
getScriptLogs: 0,
|
||||||
clearTerminal: RamCostConstants.ScriptClearTerminalCost,
|
|
||||||
nuke: RamCostConstants.ScriptPortProgramRamCost,
|
nuke: RamCostConstants.ScriptPortProgramRamCost,
|
||||||
brutessh: RamCostConstants.ScriptPortProgramRamCost,
|
brutessh: RamCostConstants.ScriptPortProgramRamCost,
|
||||||
ftpcrack: RamCostConstants.ScriptPortProgramRamCost,
|
ftpcrack: RamCostConstants.ScriptPortProgramRamCost,
|
||||||
@ -382,7 +463,6 @@ export const RamCosts: IMap<any> = {
|
|||||||
ps: RamCostConstants.ScriptScanRamCost,
|
ps: RamCostConstants.ScriptScanRamCost,
|
||||||
getRecentScripts: RamCostConstants.ScriptRecentScriptsRamCost,
|
getRecentScripts: RamCostConstants.ScriptRecentScriptsRamCost,
|
||||||
hasRootAccess: RamCostConstants.ScriptHasRootAccessRamCost,
|
hasRootAccess: RamCostConstants.ScriptHasRootAccessRamCost,
|
||||||
getIp: RamCostConstants.ScriptGetHostnameRamCost,
|
|
||||||
getHostname: RamCostConstants.ScriptGetHostnameRamCost,
|
getHostname: RamCostConstants.ScriptGetHostnameRamCost,
|
||||||
getHackingLevel: RamCostConstants.ScriptGetHackingLevelRamCost,
|
getHackingLevel: RamCostConstants.ScriptGetHackingLevelRamCost,
|
||||||
getHackingMultipliers: RamCostConstants.ScriptGetMultipliersRamCost,
|
getHackingMultipliers: RamCostConstants.ScriptGetMultipliersRamCost,
|
||||||
@ -439,12 +519,74 @@ export const RamCosts: IMap<any> = {
|
|||||||
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
|
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
|
||||||
tail: 0,
|
tail: 0,
|
||||||
toast: 0,
|
toast: 0,
|
||||||
|
closeTail: 0,
|
||||||
|
clearPort: 0,
|
||||||
|
openDevMenu: 0,
|
||||||
|
alert: 0,
|
||||||
|
flags: 0,
|
||||||
|
exploit: 0,
|
||||||
|
bypass: 0,
|
||||||
|
alterReality: 0,
|
||||||
|
rainbow: 0,
|
||||||
heart: {
|
heart: {
|
||||||
// Easter egg function
|
// Easter egg function
|
||||||
break: 0,
|
break: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
formulas: {
|
||||||
|
reputation: {
|
||||||
|
calculateFavorToRep: 0,
|
||||||
|
calculateRepToFavor: 0,
|
||||||
|
repFromDonation: 0,
|
||||||
|
},
|
||||||
|
skills: {
|
||||||
|
calculateSkill: 0,
|
||||||
|
calculateExp: 0,
|
||||||
|
},
|
||||||
|
hacking: {
|
||||||
|
hackChance: 0,
|
||||||
|
hackExp: 0,
|
||||||
|
hackPercent: 0,
|
||||||
|
growPercent: 0,
|
||||||
|
hackTime: 0,
|
||||||
|
growTime: 0,
|
||||||
|
weakenTime: 0,
|
||||||
|
},
|
||||||
|
hacknetNodes: {
|
||||||
|
moneyGainRate: 0,
|
||||||
|
levelUpgradeCost: 0,
|
||||||
|
ramUpgradeCost: 0,
|
||||||
|
coreUpgradeCost: 0,
|
||||||
|
hacknetNodeCost: 0,
|
||||||
|
constants: 0,
|
||||||
|
},
|
||||||
|
hacknetServers: {
|
||||||
|
hashGainRate: 0,
|
||||||
|
levelUpgradeCost: 0,
|
||||||
|
ramUpgradeCost: 0,
|
||||||
|
coreUpgradeCost: 0,
|
||||||
|
cacheUpgradeCost: 0,
|
||||||
|
hashUpgradeCost: 0,
|
||||||
|
hacknetServerCost: 0,
|
||||||
|
constants: 0,
|
||||||
|
},
|
||||||
|
gang: {
|
||||||
|
wantedPenalty: 0,
|
||||||
|
respectGain: 0,
|
||||||
|
wantedLevelGain: 0,
|
||||||
|
moneyGain: 0,
|
||||||
|
ascensionPointsGain: 0,
|
||||||
|
ascensionMultiplier: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RamCosts: IMap<any> = SourceRamCosts;
|
||||||
|
|
||||||
|
// This line in particular is there so typescript typechecks that we are not missing any static ram cost.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _typecheck: RamCostTree<INS & INetscriptExtra> = SourceRamCosts;
|
||||||
|
|
||||||
export function getRamCost(player: IPlayer, ...args: string[]): number {
|
export function getRamCost(player: IPlayer, ...args: string[]): number {
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
console.warn(`No arguments passed to getRamCost()`);
|
console.warn(`No arguments passed to getRamCost()`);
|
||||||
|
@ -14,6 +14,7 @@ import { Script } from "../Script/Script";
|
|||||||
import { GetServer } from "../Server/AllServers";
|
import { GetServer } from "../Server/AllServers";
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
|
import { NS } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
|
|
||||||
export class WorkerScript {
|
export class WorkerScript {
|
||||||
/**
|
/**
|
||||||
@ -116,7 +117,7 @@ export class WorkerScript {
|
|||||||
*/
|
*/
|
||||||
infiniteLoopSafety = performance.now();
|
infiniteLoopSafety = performance.now();
|
||||||
|
|
||||||
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => any) {
|
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => NS) {
|
||||||
this.name = runningScriptObj.filename;
|
this.name = runningScriptObj.filename;
|
||||||
this.hostname = runningScriptObj.server;
|
this.hostname = runningScriptObj.server;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { isString } from "./utils/helpers/isString";
|
|||||||
import { GetServer } from "./Server/AllServers";
|
import { GetServer } from "./Server/AllServers";
|
||||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||||
import { WorkerScript } from "./Netscript/WorkerScript";
|
import { WorkerScript } from "./Netscript/WorkerScript";
|
||||||
|
import { NetscriptContext } from "./Netscript/APIWrapper";
|
||||||
|
|
||||||
export function netscriptDelay(time: number, workerScript: WorkerScript): Promise<void> {
|
export function netscriptDelay(time: number, workerScript: WorkerScript): Promise<void> {
|
||||||
// Cancel any pre-existing netscriptDelay'ed function call
|
// Cancel any pre-existing netscriptDelay'ed function call
|
||||||
@ -36,26 +37,22 @@ export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): s
|
|||||||
return "|DELIMITER|" + server.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
return "|DELIMITER|" + server.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveNetscriptRequestedThreads(
|
export function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThreads: number): number {
|
||||||
workerScript: WorkerScript,
|
const threads = ctx.workerScript.scriptRef.threads;
|
||||||
functionName: string,
|
|
||||||
requestedThreads: number,
|
|
||||||
): number {
|
|
||||||
const threads = workerScript.scriptRef.threads;
|
|
||||||
if (!requestedThreads) {
|
if (!requestedThreads) {
|
||||||
return isNaN(threads) || threads < 1 ? 1 : threads;
|
return isNaN(threads) || threads < 1 ? 1 : threads;
|
||||||
}
|
}
|
||||||
const requestedThreadsAsInt = requestedThreads | 0;
|
const requestedThreadsAsInt = requestedThreads | 0;
|
||||||
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
||||||
throw makeRuntimeRejectMsg(
|
throw makeRuntimeRejectMsg(
|
||||||
workerScript,
|
ctx.workerScript,
|
||||||
`Invalid thread count passed to ${functionName}: ${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 makeRuntimeRejectMsg(
|
||||||
workerScript,
|
ctx.workerScript,
|
||||||
`Too many threads requested by ${functionName}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
`Too many threads requested by ${ctx.function}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return requestedThreadsAsInt;
|
return requestedThreadsAsInt;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -257,7 +257,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
function getMaterial(divisionName: string, cityName: string, materialName: string): Material {
|
function getMaterial(divisionName: string, cityName: string, materialName: string): Material {
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
const matName = (materialName as string).replace(/ /g, "");
|
const matName = (materialName ).replace(/ /g, "");
|
||||||
const material = warehouse.materials[matName];
|
const material = warehouse.materials[matName];
|
||||||
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
|
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
|
||||||
return material;
|
return material;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { Exploit } from "../Exploits/Exploit";
|
import { Exploit } from "../Exploits/Exploit";
|
||||||
import * as bcrypt from "bcryptjs";
|
import * as bcrypt from "bcryptjs";
|
||||||
import { INetscriptHelper } from "./INetscriptHelper";
|
|
||||||
import { Apr1Events as devMenu } from "../ui/Apr1";
|
import { Apr1Events as devMenu } from "../ui/Apr1";
|
||||||
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
|
||||||
export interface INetscriptExtra {
|
export interface INetscriptExtra {
|
||||||
heart: {
|
heart: {
|
||||||
@ -16,35 +15,37 @@ export interface INetscriptExtra {
|
|||||||
rainbow(guess: string): void;
|
rainbow(guess: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): INetscriptExtra {
|
export function NetscriptExtra(player: IPlayer): InternalAPI<INetscriptExtra> {
|
||||||
return {
|
return {
|
||||||
heart: {
|
heart: {
|
||||||
// Easter egg function
|
// Easter egg function
|
||||||
break: function (): number {
|
break: () => (): number => {
|
||||||
return player.karma;
|
return player.karma;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
openDevMenu: function (): void {
|
openDevMenu: () => (): void => {
|
||||||
devMenu.emit();
|
devMenu.emit();
|
||||||
},
|
},
|
||||||
exploit: function (): void {
|
exploit: () => (): void => {
|
||||||
player.giveExploit(Exploit.UndocumentedFunctionCall);
|
player.giveExploit(Exploit.UndocumentedFunctionCall);
|
||||||
},
|
},
|
||||||
bypass: function (doc: unknown): void {
|
bypass:
|
||||||
// reset both fields first
|
(ctx: NetscriptContext) =>
|
||||||
const d = doc as any;
|
(doc: unknown): void => {
|
||||||
d.completely_unused_field = undefined;
|
// reset both fields first
|
||||||
const real_document: any = document;
|
const d = doc as any;
|
||||||
real_document.completely_unused_field = undefined;
|
d.completely_unused_field = undefined;
|
||||||
// set one to true and check that it affected the other.
|
const real_document: any = document;
|
||||||
real_document.completely_unused_field = true;
|
real_document.completely_unused_field = undefined;
|
||||||
if (d.completely_unused_field && workerScript.ramUsage === 1.6) {
|
// set one to true and check that it affected the other.
|
||||||
player.giveExploit(Exploit.Bypass);
|
real_document.completely_unused_field = true;
|
||||||
}
|
if (d.completely_unused_field && ctx.workerScript.ramUsage === 1.6) {
|
||||||
d.completely_unused_field = undefined;
|
player.giveExploit(Exploit.Bypass);
|
||||||
real_document.completely_unused_field = undefined;
|
}
|
||||||
},
|
d.completely_unused_field = undefined;
|
||||||
alterReality: function (): void {
|
real_document.completely_unused_field = undefined;
|
||||||
|
},
|
||||||
|
alterReality: () => (): void => {
|
||||||
// We need to trick webpack into not optimizing a variable that is guaranteed to be false (and doesn't use prototypes)
|
// We need to trick webpack into not optimizing a variable that is guaranteed to be false (and doesn't use prototypes)
|
||||||
let x = false;
|
let x = false;
|
||||||
const recur = function (depth: number): void {
|
const recur = function (depth: number): void {
|
||||||
@ -59,20 +60,22 @@ export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript, help
|
|||||||
player.giveExploit(Exploit.RealityAlteration);
|
player.giveExploit(Exploit.RealityAlteration);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rainbow: function (guess: unknown): boolean {
|
rainbow:
|
||||||
function tryGuess(): boolean {
|
(ctx: NetscriptContext) =>
|
||||||
// eslint-disable-next-line no-sync
|
(guess: unknown): boolean => {
|
||||||
const verified = bcrypt.compareSync(
|
function tryGuess(): boolean {
|
||||||
helper.string("rainbow", "guess", guess),
|
// eslint-disable-next-line no-sync
|
||||||
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
|
const verified = bcrypt.compareSync(
|
||||||
);
|
ctx.helper.string("guess", guess),
|
||||||
if (verified) {
|
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
|
||||||
player.giveExploit(Exploit.INeedARainbow);
|
);
|
||||||
return true;
|
if (verified) {
|
||||||
|
player.giveExploit(Exploit.INeedARainbow);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return tryGuess();
|
||||||
}
|
},
|
||||||
return tryGuess();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,36 +2,37 @@ import { toNative } from "./toNative";
|
|||||||
import * as libarg from "arg";
|
import * as libarg from "arg";
|
||||||
|
|
||||||
export function Flags(vargs: string[]): any {
|
export function Flags(vargs: string[]): any {
|
||||||
return function (data: any): any {
|
return () =>
|
||||||
data = toNative(data);
|
(data: any): any => {
|
||||||
// We always want the help flag.
|
data = toNative(data);
|
||||||
const args: {
|
// We always want the help flag.
|
||||||
[key: string]: any;
|
const args: {
|
||||||
} = {};
|
[key: string]: any;
|
||||||
|
} = {};
|
||||||
|
|
||||||
for (const d of data) {
|
for (const d of data) {
|
||||||
let t: any = String;
|
let t: any = String;
|
||||||
if (typeof d[1] === "number") {
|
if (typeof d[1] === "number") {
|
||||||
t = Number;
|
t = Number;
|
||||||
} else if (typeof d[1] === "boolean") {
|
} else if (typeof d[1] === "boolean") {
|
||||||
t = Boolean;
|
t = Boolean;
|
||||||
} else if (Array.isArray(d[1])) {
|
} else if (Array.isArray(d[1])) {
|
||||||
t = [String];
|
t = [String];
|
||||||
|
}
|
||||||
|
const numDashes = d[0].length > 1 ? 2 : 1;
|
||||||
|
args["-".repeat(numDashes) + d[0]] = t;
|
||||||
}
|
}
|
||||||
const numDashes = d[0].length > 1 ? 2 : 1;
|
const ret = libarg(args, { argv: vargs });
|
||||||
args["-".repeat(numDashes) + d[0]] = t;
|
for (const d of data) {
|
||||||
}
|
if (!ret.hasOwnProperty("--" + d[0]) || !ret.hasOwnProperty("-" + d[0])) ret[d[0]] = d[1];
|
||||||
const ret = libarg(args, { argv: vargs });
|
}
|
||||||
for (const d of data) {
|
for (const key of Object.keys(ret)) {
|
||||||
if (!ret.hasOwnProperty("--" + d[0]) || !ret.hasOwnProperty("-" + d[0])) ret[d[0]] = d[1];
|
if (!key.startsWith("-")) continue;
|
||||||
}
|
const value = ret[key];
|
||||||
for (const key of Object.keys(ret)) {
|
delete ret[key];
|
||||||
if (!key.startsWith("-")) continue;
|
const numDashes = key.length === 2 ? 1 : 2;
|
||||||
const value = ret[key];
|
ret[key.slice(numDashes)] = value;
|
||||||
delete ret[key];
|
}
|
||||||
const numDashes = key.length === 2 ? 1 : 2;
|
return ret;
|
||||||
ret[key.slice(numDashes)] = value;
|
};
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { INetscriptHelper } from "./INetscriptHelper";
|
import { INetscriptHelper } from "./INetscriptHelper";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { calculateServerGrowth } from "../Server/formulas/grow";
|
import { calculateServerGrowth } from "../Server/formulas/grow";
|
||||||
import {
|
import {
|
||||||
@ -39,212 +38,267 @@ import {
|
|||||||
} from "../Gang/formulas/formulas";
|
} from "../Gang/formulas/formulas";
|
||||||
import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor } from "../Faction/formulas/favor";
|
import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor } from "../Faction/formulas/favor";
|
||||||
import { repFromDonation } from "../Faction/formulas/donation";
|
import { repFromDonation } from "../Faction/formulas/donation";
|
||||||
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
|
||||||
export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IFormulas {
|
export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): InternalAPI<IFormulas> {
|
||||||
const checkFormulasAccess = function (func: string): void {
|
const checkFormulasAccess = function (ctx: NetscriptContext): void {
|
||||||
if (!player.hasProgram(Programs.Formulas.name)) {
|
if (!player.hasProgram(Programs.Formulas.name)) {
|
||||||
throw helper.makeRuntimeErrorMsg(`formulas.${func}`, `Requires Formulas.exe to run.`);
|
throw helper.makeRuntimeErrorMsg(`formulas.${ctx.function}`, `Requires Formulas.exe to run.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
reputation: {
|
reputation: {
|
||||||
calculateFavorToRep: function (_favor: unknown): number {
|
calculateFavorToRep:
|
||||||
const favor = helper.number("calculateFavorToRep", "favor", _favor);
|
(ctx: NetscriptContext) =>
|
||||||
checkFormulasAccess("reputation.calculateFavorToRep");
|
(_favor: unknown): number => {
|
||||||
return calculateFavorToRep(favor);
|
const favor = ctx.helper.number("favor", _favor);
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
calculateRepToFavor: function (_rep: unknown): number {
|
return calculateFavorToRep(favor);
|
||||||
const rep = helper.number("calculateRepToFavor", "rep", _rep);
|
},
|
||||||
checkFormulasAccess("reputation.calculateRepToFavor");
|
calculateRepToFavor:
|
||||||
return calculateRepToFavor(rep);
|
(ctx: NetscriptContext) =>
|
||||||
},
|
(_rep: unknown): number => {
|
||||||
repFromDonation: function (_amount: unknown, player: any): number {
|
const rep = ctx.helper.number("rep", _rep);
|
||||||
const amount = helper.number("repFromDonation", "amount", _amount);
|
checkFormulasAccess(ctx);
|
||||||
checkFormulasAccess("reputation.repFromDonation");
|
return calculateRepToFavor(rep);
|
||||||
return repFromDonation(amount, player);
|
},
|
||||||
},
|
repFromDonation:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(_amount: unknown, player: any): number => {
|
||||||
|
const amount = ctx.helper.number("amount", _amount);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return repFromDonation(amount, player);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
skills: {
|
skills: {
|
||||||
calculateSkill: function (_exp: unknown, _mult: unknown = 1): number {
|
calculateSkill:
|
||||||
const exp = helper.number("calculateSkill", "exp", _exp);
|
(ctx: NetscriptContext) =>
|
||||||
const mult = helper.number("calculateSkill", "mult", _mult);
|
(_exp: unknown, _mult: unknown = 1): number => {
|
||||||
checkFormulasAccess("skills.calculateSkill");
|
const exp = ctx.helper.number("exp", _exp);
|
||||||
return calculateSkill(exp, mult);
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
calculateExp: function (_skill: unknown, _mult: unknown = 1): number {
|
return calculateSkill(exp, mult);
|
||||||
const skill = helper.number("calculateExp", "skill", _skill);
|
},
|
||||||
const mult = helper.number("calculateExp", "mult", _mult);
|
calculateExp:
|
||||||
checkFormulasAccess("skills.calculateExp");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateExp(skill, mult);
|
(_skill: unknown, _mult: unknown = 1): number => {
|
||||||
},
|
const skill = ctx.helper.number("skill", _skill);
|
||||||
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateExp(skill, mult);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
hacking: {
|
hacking: {
|
||||||
hackChance: function (server: any, player: any): number {
|
hackChance:
|
||||||
checkFormulasAccess("hacking.hackChance");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateHackingChance(server, player);
|
(server: any, player: any): number => {
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
hackExp: function (server: any, player: any): number {
|
return calculateHackingChance(server, player);
|
||||||
checkFormulasAccess("hacking.hackExp");
|
},
|
||||||
return calculateHackingExpGain(server, player);
|
hackExp:
|
||||||
},
|
(ctx: NetscriptContext) =>
|
||||||
hackPercent: function (server: any, player: any): number {
|
(server: any, player: any): number => {
|
||||||
checkFormulasAccess("hacking.hackPercent");
|
checkFormulasAccess(ctx);
|
||||||
return calculatePercentMoneyHacked(server, player);
|
return calculateHackingExpGain(server, player);
|
||||||
},
|
},
|
||||||
growPercent: function (server: any, _threads: unknown, player: any, _cores: unknown = 1): number {
|
hackPercent:
|
||||||
const threads = helper.number("growPercent", "threads", _threads);
|
(ctx: NetscriptContext) =>
|
||||||
const cores = helper.number("growPercent", "cores", _cores);
|
(server: any, player: any): number => {
|
||||||
checkFormulasAccess("hacking.growPercent");
|
checkFormulasAccess(ctx);
|
||||||
return calculateServerGrowth(server, threads, player, cores);
|
return calculatePercentMoneyHacked(server, player);
|
||||||
},
|
},
|
||||||
hackTime: function (server: any, player: any): number {
|
growPercent:
|
||||||
checkFormulasAccess("hacking.hackTime");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateHackingTime(server, player) * 1000;
|
(server: any, _threads: unknown, player: any, _cores: unknown = 1): number => {
|
||||||
},
|
const threads = ctx.helper.number("threads", _threads);
|
||||||
growTime: function (server: any, player: any): number {
|
const cores = ctx.helper.number("cores", _cores);
|
||||||
checkFormulasAccess("hacking.growTime");
|
checkFormulasAccess(ctx);
|
||||||
return calculateGrowTime(server, player) * 1000;
|
return calculateServerGrowth(server, threads, player, cores);
|
||||||
},
|
},
|
||||||
weakenTime: function (server: any, player: any): number {
|
hackTime:
|
||||||
checkFormulasAccess("hacking.weakenTime");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateWeakenTime(server, player) * 1000;
|
(server: any, player: any): number => {
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateHackingTime(server, player) * 1000;
|
||||||
|
},
|
||||||
|
growTime:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(server: any, player: any): number => {
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateGrowTime(server, player) * 1000;
|
||||||
|
},
|
||||||
|
weakenTime:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(server: any, player: any): number => {
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateWeakenTime(server, player) * 1000;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
hacknetNodes: {
|
hacknetNodes: {
|
||||||
moneyGainRate: function (_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number {
|
moneyGainRate:
|
||||||
const level = helper.number("moneyGainRate", "level", _level);
|
(ctx: NetscriptContext) =>
|
||||||
const ram = helper.number("moneyGainRate", "ram", _ram);
|
(_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||||
const cores = helper.number("moneyGainRate", "cores", _cores);
|
const level = ctx.helper.number("level", _level);
|
||||||
const mult = helper.number("moneyGainRate", "mult", _mult);
|
const ram = ctx.helper.number("ram", _ram);
|
||||||
checkFormulasAccess("hacknetNodes.moneyGainRate");
|
const cores = ctx.helper.number("cores", _cores);
|
||||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
levelUpgradeCost: function (_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||||
const startingLevel = helper.number("levelUpgradeCost", "startingLevel", _startingLevel);
|
},
|
||||||
const extraLevels = helper.number("levelUpgradeCost", "extraLevels", _extraLevels);
|
levelUpgradeCost:
|
||||||
const costMult = helper.number("levelUpgradeCost", "costMult", _costMult);
|
(ctx: NetscriptContext) =>
|
||||||
checkFormulasAccess("hacknetNodes.levelUpgradeCost");
|
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
const startingLevel = ctx.helper.number("startingLevel", _startingLevel);
|
||||||
},
|
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
||||||
ramUpgradeCost: function (_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
const startingRam = helper.number("ramUpgradeCost", "startingRam", _startingRam);
|
checkFormulasAccess(ctx);
|
||||||
const extraLevels = helper.number("ramUpgradeCost", "extraLevels", _extraLevels);
|
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
const costMult = helper.number("ramUpgradeCost", "costMult", _costMult);
|
},
|
||||||
checkFormulasAccess("hacknetNodes.ramUpgradeCost");
|
ramUpgradeCost:
|
||||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
(ctx: NetscriptContext) =>
|
||||||
},
|
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
coreUpgradeCost: function (_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number {
|
const startingRam = ctx.helper.number("startingRam", _startingRam);
|
||||||
const startingCore = helper.number("coreUpgradeCost", "startingCore", _startingCore);
|
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
||||||
const extraCores = helper.number("coreUpgradeCost", "extraCores", _extraCores);
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
const costMult = helper.number("coreUpgradeCost", "costMult", _costMult);
|
checkFormulasAccess(ctx);
|
||||||
checkFormulasAccess("hacknetNodes.coreUpgradeCost");
|
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
},
|
||||||
},
|
coreUpgradeCost:
|
||||||
hacknetNodeCost: function (_n: unknown, _mult: unknown): number {
|
(ctx: NetscriptContext) =>
|
||||||
const n = helper.number("hacknetNodeCost", "n", _n);
|
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const mult = helper.number("hacknetNodeCost", "mult", _mult);
|
const startingCore = ctx.helper.number("startingCore", _startingCore);
|
||||||
checkFormulasAccess("hacknetNodes.hacknetNodeCost");
|
const extraCores = ctx.helper.number("extraCores", _extraCores);
|
||||||
return calculateNodeCost(n, mult);
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
constants: function (): any {
|
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
checkFormulasAccess("hacknetNodes.constants");
|
},
|
||||||
|
hacknetNodeCost:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(_n: unknown, _mult: unknown): number => {
|
||||||
|
const n = ctx.helper.number("n", _n);
|
||||||
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateNodeCost(n, mult);
|
||||||
|
},
|
||||||
|
constants: (ctx: NetscriptContext) => (): any => {
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
return Object.assign({}, HacknetNodeConstants);
|
return Object.assign({}, HacknetNodeConstants);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hacknetServers: {
|
hacknetServers: {
|
||||||
hashGainRate: function (
|
hashGainRate:
|
||||||
_level: unknown,
|
(ctx: NetscriptContext) =>
|
||||||
_ramUsed: unknown,
|
(_level: unknown, _ramUsed: unknown, _maxRam: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||||
_maxRam: unknown,
|
const level = ctx.helper.number("level", _level);
|
||||||
_cores: unknown,
|
const ramUsed = ctx.helper.number("ramUsed", _ramUsed);
|
||||||
_mult: unknown = 1,
|
const maxRam = ctx.helper.number("maxRam", _maxRam);
|
||||||
): number {
|
const cores = ctx.helper.number("cores", _cores);
|
||||||
const level = helper.number("hashGainRate", "level", _level);
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
const ramUsed = helper.number("hashGainRate", "ramUsed", _ramUsed);
|
checkFormulasAccess(ctx);
|
||||||
const maxRam = helper.number("hashGainRate", "maxRam", _maxRam);
|
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
||||||
const cores = helper.number("hashGainRate", "cores", _cores);
|
},
|
||||||
const mult = helper.number("hashGainRate", "mult", _mult);
|
levelUpgradeCost:
|
||||||
checkFormulasAccess("hacknetServers.hashGainRate");
|
(ctx: NetscriptContext) =>
|
||||||
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
},
|
const startingLevel = ctx.helper.number("startingLevel", _startingLevel);
|
||||||
levelUpgradeCost: function (_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
||||||
const startingLevel = helper.number("levelUpgradeCost", "startingLevel", _startingLevel);
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
const extraLevels = helper.number("levelUpgradeCost", "extraLevels", _extraLevels);
|
checkFormulasAccess(ctx);
|
||||||
const costMult = helper.number("levelUpgradeCost", "costMult", _costMult);
|
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
checkFormulasAccess("hacknetServers.levelUpgradeCost");
|
},
|
||||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
ramUpgradeCost:
|
||||||
},
|
(ctx: NetscriptContext) =>
|
||||||
ramUpgradeCost: function (_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingRam = helper.number("ramUpgradeCost", "startingRam", _startingRam);
|
const startingRam = ctx.helper.number("startingRam", _startingRam);
|
||||||
const extraLevels = helper.number("ramUpgradeCost", "extraLevels", _extraLevels);
|
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
||||||
const costMult = helper.number("ramUpgradeCost", "costMult", _costMult);
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetServers.ramUpgradeCost");
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
coreUpgradeCost: function (_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number {
|
coreUpgradeCost:
|
||||||
const startingCore = helper.number("coreUpgradeCost", "startingCore", _startingCore);
|
(ctx: NetscriptContext) =>
|
||||||
const extraCores = helper.number("coreUpgradeCost", "extraCores", _extraCores);
|
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const costMult = helper.number("coreUpgradeCost", "costMult", _costMult);
|
const startingCore = ctx.helper.number("startingCore", _startingCore);
|
||||||
checkFormulasAccess("hacknetServers.coreUpgradeCost");
|
const extraCores = ctx.helper.number("extraCores", _extraCores);
|
||||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
const costMult = ctx.helper.number("costMult", _costMult);
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
cacheUpgradeCost: function (_startingCache: unknown, _extraCache: unknown = 1): number {
|
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
const startingCache = helper.number("cacheUpgradeCost", "startingCache", _startingCache);
|
},
|
||||||
const extraCache = helper.number("cacheUpgradeCost", "extraCache", _extraCache);
|
cacheUpgradeCost:
|
||||||
checkFormulasAccess("hacknetServers.cacheUpgradeCost");
|
(ctx: NetscriptContext) =>
|
||||||
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
(_startingCache: unknown, _extraCache: unknown = 1): number => {
|
||||||
},
|
const startingCache = ctx.helper.number("startingCache", _startingCache);
|
||||||
hashUpgradeCost: function (_upgName: unknown, _level: unknown): number {
|
const extraCache = ctx.helper.number("extraCache", _extraCache);
|
||||||
const upgName = helper.string("hashUpgradeCost", "upgName", _upgName);
|
checkFormulasAccess(ctx);
|
||||||
const level = helper.number("hashUpgradeCost", "level", _level);
|
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
||||||
checkFormulasAccess("hacknetServers.hashUpgradeCost");
|
},
|
||||||
const upg = player.hashManager.getUpgrade(upgName);
|
hashUpgradeCost:
|
||||||
if (!upg) {
|
(ctx: NetscriptContext) =>
|
||||||
throw helper.makeRuntimeErrorMsg(
|
(_upgName: unknown, _level: unknown): number => {
|
||||||
"formulas.hacknetServers.calculateHashUpgradeCost",
|
const upgName = helper.string("hashUpgradeCost", "upgName", _upgName);
|
||||||
`Invalid Hash Upgrade: ${upgName}`,
|
const level = ctx.helper.number("level", _level);
|
||||||
);
|
checkFormulasAccess(ctx);
|
||||||
}
|
const upg = player.hashManager.getUpgrade(upgName);
|
||||||
return upg.getCost(level);
|
if (!upg) {
|
||||||
},
|
throw helper.makeRuntimeErrorMsg(
|
||||||
hacknetServerCost: function (_n: unknown, _mult: unknown = 1): number {
|
"formulas.hacknetServers.calculateHashUpgradeCost",
|
||||||
const n = helper.number("hacknetServerCost", "n", _n);
|
`Invalid Hash Upgrade: ${upgName}`,
|
||||||
const mult = helper.number("hacknetServerCost", "mult", _mult);
|
);
|
||||||
checkFormulasAccess("hacknetServers.hacknetServerCost");
|
}
|
||||||
return HScalculateServerCost(n, mult);
|
return upg.getCost(level);
|
||||||
},
|
},
|
||||||
constants: function (): any {
|
hacknetServerCost:
|
||||||
checkFormulasAccess("hacknetServers.constants");
|
(ctx: NetscriptContext) =>
|
||||||
|
(_n: unknown, _mult: unknown = 1): number => {
|
||||||
|
const n = ctx.helper.number("n", _n);
|
||||||
|
const mult = ctx.helper.number("mult", _mult);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return HScalculateServerCost(n, mult);
|
||||||
|
},
|
||||||
|
constants: (ctx: NetscriptContext) => (): any => {
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
return Object.assign({}, HacknetServerConstants);
|
return Object.assign({}, HacknetServerConstants);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gang: {
|
gang: {
|
||||||
wantedPenalty(gang: any): number {
|
wantedPenalty:
|
||||||
checkFormulasAccess("gang.wantedPenalty");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateWantedPenalty(gang);
|
(gang: any): number => {
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
respectGain: function (gang: any, member: any, task: any): number {
|
return calculateWantedPenalty(gang);
|
||||||
checkFormulasAccess("gang.respectGain");
|
},
|
||||||
return calculateRespectGain(gang, member, task);
|
respectGain:
|
||||||
},
|
(ctx: NetscriptContext) =>
|
||||||
wantedLevelGain: function (gang: any, member: any, task: any): number {
|
(gang: any, member: any, task: any): number => {
|
||||||
checkFormulasAccess("gang.wantedLevelGain");
|
checkFormulasAccess(ctx);
|
||||||
return calculateWantedLevelGain(gang, member, task);
|
return calculateRespectGain(gang, member, task);
|
||||||
},
|
},
|
||||||
moneyGain: function (gang: any, member: any, task: any): number {
|
wantedLevelGain:
|
||||||
checkFormulasAccess("gang.moneyGain");
|
(ctx: NetscriptContext) =>
|
||||||
return calculateMoneyGain(gang, member, task);
|
(gang: any, member: any, task: any): number => {
|
||||||
},
|
checkFormulasAccess(ctx);
|
||||||
ascensionPointsGain: function (_exp: unknown): number {
|
return calculateWantedLevelGain(gang, member, task);
|
||||||
const exp = helper.number("ascensionPointsGain", "exp", _exp);
|
},
|
||||||
checkFormulasAccess("gang.ascensionPointsGain");
|
moneyGain:
|
||||||
return calculateAscensionPointsGain(exp);
|
(ctx: NetscriptContext) =>
|
||||||
},
|
(gang: any, member: any, task: any): number => {
|
||||||
ascensionMultiplier: function (_points: unknown): number {
|
checkFormulasAccess(ctx);
|
||||||
const points = helper.number("ascensionMultiplier", "points", _points);
|
return calculateMoneyGain(gang, member, task);
|
||||||
checkFormulasAccess("gang.ascensionMultiplier");
|
},
|
||||||
return calculateAscensionMult(points);
|
ascensionPointsGain:
|
||||||
},
|
(ctx: NetscriptContext) =>
|
||||||
|
(_exp: unknown): number => {
|
||||||
|
const exp = ctx.helper.number("exp", _exp);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateAscensionPointsGain(exp);
|
||||||
|
},
|
||||||
|
ascensionMultiplier:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(_points: unknown): number => {
|
||||||
|
const points = ctx.helper.number("points", _points);
|
||||||
|
checkFormulasAccess(ctx);
|
||||||
|
return calculateAscensionMult(points);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { CityName } from "src/Locations/data/CityNames";
|
import { CityName } from "src/Locations/data/CityNames";
|
||||||
|
import { NetscriptContext } from "src/Netscript/APIWrapper";
|
||||||
|
import { IPort } from "src/NetscriptPort";
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
|
|
||||||
export interface INetscriptHelper {
|
export interface INetscriptHelper {
|
||||||
@ -8,7 +10,8 @@ export interface INetscriptHelper {
|
|||||||
number(funcName: string, argName: string, v: unknown): number;
|
number(funcName: string, argName: string, v: unknown): number;
|
||||||
city(funcName: string, argName: string, v: unknown): CityName;
|
city(funcName: string, argName: string, v: unknown): CityName;
|
||||||
boolean(v: unknown): boolean;
|
boolean(v: unknown): boolean;
|
||||||
getServer(ip: any, fn: any): BaseServer;
|
getServer(ip: any, ctx: NetscriptContext): BaseServer;
|
||||||
checkSingularityAccess(func: string): void;
|
checkSingularityAccess(func: string): void;
|
||||||
hack(hostname: string, manual: boolean): Promise<number>;
|
hack(ctx: NetscriptContext, hostname: string, manual: boolean): Promise<number>;
|
||||||
|
getValidPort(funcName: string, port: number): IPort;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
|||||||
_ctx.log(() => "cannot backdoor this kind of server");
|
_ctx.log(() => "cannot backdoor this kind of server");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
const server = baseserver as Server;
|
const server = baseserver ;
|
||||||
const installTime = (calculateHackingTime(server, player) / 4) * 1000;
|
const installTime = (calculateHackingTime(server, player) / 4) * 1000;
|
||||||
|
|
||||||
// No root access or skill level too low
|
// No root access or skill level too low
|
||||||
|
@ -693,7 +693,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
if (server === null) throw new Error(`Server '${closingScript.hostname}' should not be null, but it is.`);
|
if (server === null) throw new Error(`Server '${closingScript.hostname}' should not be null, but it is.`);
|
||||||
|
|
||||||
const serverScriptIndex = server.scripts.findIndex((script) => script.filename === closingScript.fileName);
|
const serverScriptIndex = server.scripts.findIndex((script) => script.filename === closingScript.fileName);
|
||||||
if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) {
|
if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex ].code) {
|
||||||
PromptEvent.emit({
|
PromptEvent.emit({
|
||||||
txt: `Do you want to save changes to ${closingScript.fileName} on ${closingScript.hostname}?`,
|
txt: `Do you want to save changes to ${closingScript.fileName} on ${closingScript.hostname}?`,
|
||||||
resolve: (result: boolean | string) => {
|
resolve: (result: boolean | string) => {
|
||||||
|
@ -36,7 +36,7 @@ function toNumber(n: number | IMinMaxRange): number {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
case "object": {
|
case "object": {
|
||||||
const range = n as IMinMaxRange;
|
const range = n ;
|
||||||
value = getRandomInt(range.min, range.max);
|
value = getRandomInt(range.min, range.max);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ export function placeOrder(
|
|||||||
|
|
||||||
// Process to see if it should be executed immediately
|
// Process to see if it should be executed immediately
|
||||||
const processOrderRefs = {
|
const processOrderRefs = {
|
||||||
stockMarket: StockMarket as IStockMarket,
|
stockMarket: StockMarket ,
|
||||||
symbolToStockMap: SymbolToStockMap,
|
symbolToStockMap: SymbolToStockMap,
|
||||||
};
|
};
|
||||||
processOrders(stock, order.type, order.pos, processOrderRefs);
|
processOrders(stock, order.type, order.pos, processOrderRefs);
|
||||||
|
@ -3,8 +3,6 @@ import { IRouter } from "../../ui/Router";
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { listAllDarkwebItems, buyAllDarkwebItems, buyDarkwebItem } from "../../DarkWeb/DarkWeb";
|
import { listAllDarkwebItems, buyAllDarkwebItems, buyDarkwebItem } from "../../DarkWeb/DarkWeb";
|
||||||
import { SpecialServers } from "../../Server/data/SpecialServers";
|
|
||||||
import { GetServer } from "../../Server/AllServers";
|
|
||||||
|
|
||||||
export function buy(
|
export function buy(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
@ -13,7 +11,7 @@ export function buy(
|
|||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number | boolean)[],
|
args: (string | number | boolean)[],
|
||||||
): void {
|
): void {
|
||||||
if (!GetServer(SpecialServers.DarkWeb)) {
|
if (!player.hasTorRouter()) {
|
||||||
terminal.error(
|
terminal.error(
|
||||||
"You need to be able to connect to the Dark Web to use the buy command. (Maybe there's a TOR router you can buy somewhere)",
|
"You need to be able to connect to the Dark Web to use the buy command. (Maybe there's a TOR router you can buy somewhere)",
|
||||||
);
|
);
|
||||||
|
@ -84,7 +84,7 @@ export function mv(
|
|||||||
|
|
||||||
script.filename = destPath;
|
script.filename = destPath;
|
||||||
} else if (srcFile instanceof TextFile) {
|
} else if (srcFile instanceof TextFile) {
|
||||||
const textFile = srcFile as TextFile;
|
const textFile = srcFile ;
|
||||||
if (!dest.endsWith(".txt")) {
|
if (!dest.endsWith(".txt")) {
|
||||||
terminal.error(`Source and destination files must have the same type`);
|
terminal.error(`Source and destination files must have the same type`);
|
||||||
return;
|
return;
|
||||||
|
@ -70,7 +70,6 @@ export async function determineAllPossibilitiesForTabCompletion(
|
|||||||
|
|
||||||
let parentDirPath = "";
|
let parentDirPath = "";
|
||||||
let evaledParentDirPath: string | null = null;
|
let evaledParentDirPath: string | null = null;
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
function addAllCodingContracts(): void {
|
function addAllCodingContracts(): void {
|
||||||
for (const cct of currServ.contracts) {
|
for (const cct of currServ.contracts) {
|
||||||
@ -199,7 +198,8 @@ export async function determineAllPossibilitiesForTabCompletion(
|
|||||||
if (evaledParentDirPath === "/") {
|
if (evaledParentDirPath === "/") {
|
||||||
evaledParentDirPath = null;
|
evaledParentDirPath = null;
|
||||||
} else if (evaledParentDirPath == null) {
|
} else if (evaledParentDirPath == null) {
|
||||||
return allPos; // Invalid path
|
// do nothing for some reason tests dont like this?
|
||||||
|
// return allPos; // Invalid path
|
||||||
} else {
|
} else {
|
||||||
evaledParentDirPath += "/";
|
evaledParentDirPath += "/";
|
||||||
}
|
}
|
||||||
@ -240,7 +240,6 @@ export async function determineAllPossibilitiesForTabCompletion(
|
|||||||
|
|
||||||
if (isCommand("connect")) {
|
if (isCommand("connect")) {
|
||||||
// All directly connected and backdoored servers are reachable
|
// All directly connected and backdoored servers are reachable
|
||||||
console.log(GetAllServers());
|
|
||||||
return GetAllServers()
|
return GetAllServers()
|
||||||
.filter(
|
.filter(
|
||||||
(server) =>
|
(server) =>
|
||||||
|
@ -121,7 +121,7 @@ export function getTextFile(fn: string, server: BaseServer): TextFile | null {
|
|||||||
filename = removeLeadingSlash(filename);
|
filename = removeLeadingSlash(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const file of server.textFiles as TextFile[]) {
|
for (const file of server.textFiles ) {
|
||||||
if (file.fn === filename) {
|
if (file.fn === filename) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,13 @@ export function RecoveryRoot({ router, softReset, errorData, resetError }: IProp
|
|||||||
Settings.AutosaveInterval = 0;
|
Settings.AutosaveInterval = 0;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
load().then((content) => {
|
load()
|
||||||
const epochTime = Math.round(Date.now() / 1000);
|
.then((content) => {
|
||||||
const filename = `RECOVERY_BITBURNER_${epochTime}.json`;
|
const epochTime = Math.round(Date.now() / 1000);
|
||||||
download(filename, content);
|
const filename = `RECOVERY_BITBURNER_${epochTime}.json`;
|
||||||
});
|
download(filename, content);
|
||||||
|
})
|
||||||
|
.catch((err) => console.error(err));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -5,6 +5,7 @@ import { Typography, TableCell, TableRow } from "@mui/material";
|
|||||||
import { numeralWrapper } from "../numeralFormat";
|
import { numeralWrapper } from "../numeralFormat";
|
||||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||||
import { characterOverviewStyles as useStyles } from "./CharacterOverview";
|
import { characterOverviewStyles as useStyles } from "./CharacterOverview";
|
||||||
|
import { ClassNameMap } from "@material-ui/core/styles/withStyles";
|
||||||
|
|
||||||
interface ITableRowData {
|
interface ITableRowData {
|
||||||
content?: string;
|
content?: string;
|
||||||
@ -15,7 +16,7 @@ interface ITableRowData {
|
|||||||
interface IProps {
|
interface IProps {
|
||||||
name: string;
|
name: string;
|
||||||
color: string;
|
color: string;
|
||||||
classes?: any;
|
classes?: ClassNameMap;
|
||||||
data?: ITableRowData;
|
data?: ITableRowData;
|
||||||
children?: React.ReactElement;
|
children?: React.ReactElement;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ export function comprLZEncode(plain: string): string {
|
|||||||
for (let offset = 1; offset <= Math.min(9, i); ++offset) {
|
for (let offset = 1; offset <= Math.min(9, i); ++offset) {
|
||||||
if (plain[i - offset] === c) {
|
if (plain[i - offset] === c) {
|
||||||
// start new backreference
|
// start new backreference
|
||||||
set(new_state, offset, 1, string + length + plain.substring(i - length, i));
|
set(new_state, offset, 1, string + String(length) + plain.substring(i - length, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,17 +99,17 @@ export function comprLZEncode(plain: string): string {
|
|||||||
set(new_state, offset, length + 1, string);
|
set(new_state, offset, length + 1, string);
|
||||||
} else {
|
} else {
|
||||||
// start new backreference
|
// start new backreference
|
||||||
set(new_state, offset, 1, string + "9" + offset + "0");
|
set(new_state, offset, 1, string + "9" + String(offset) + "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start new literal
|
// start new literal
|
||||||
set(new_state, 0, 1, string + length + offset);
|
set(new_state, 0, 1, string + String(length) + String(offset));
|
||||||
|
|
||||||
// end current backreference and start new backreference
|
// end current backreference and start new backreference
|
||||||
for (let new_offset = 1; new_offset <= Math.min(9, i); ++new_offset) {
|
for (let new_offset = 1; new_offset <= Math.min(9, i); ++new_offset) {
|
||||||
if (plain[i - new_offset] === c) {
|
if (plain[i - new_offset] === c) {
|
||||||
set(new_state, new_offset, 1, string + length + offset + "0");
|
set(new_state, new_offset, 1, string + String(length) + String(offset) + "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ export function comprLZEncode(plain: string): string {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string += len + plain.substring(plain.length - len, plain.length);
|
string += String(len) + plain.substring(plain.length - len, plain.length);
|
||||||
if (result == null || string.length < result.length) {
|
if (result == null || string.length < result.length) {
|
||||||
result = string;
|
result = string;
|
||||||
} else if (string.length == result.length && Math.random() < 0.5) {
|
} else if (string.length == result.length && Math.random() < 0.5) {
|
||||||
@ -143,7 +143,7 @@ export function comprLZEncode(plain: string): string {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string += len + "" + offset;
|
string += String(len) + "" + String(offset);
|
||||||
if (result == null || string.length < result.length) {
|
if (result == null || string.length < result.length) {
|
||||||
result = string;
|
result = string;
|
||||||
} else if (string.length == result.length && Math.random() < 0.5) {
|
} else if (string.length == result.length && Math.random() < 0.5) {
|
||||||
|
@ -87,7 +87,7 @@ export function getErrorForDisplay(error: Error, errorInfo?: React.ErrorInfo, pa
|
|||||||
const fileName = (metadata.error as any).fileName;
|
const fileName = (metadata.error as any).fileName;
|
||||||
const features =
|
const features =
|
||||||
`lang=${metadata.features.language} cookiesEnabled=${metadata.features.cookiesEnabled.toString()}` +
|
`lang=${metadata.features.language} cookiesEnabled=${metadata.features.cookiesEnabled.toString()}` +
|
||||||
` doNotTrack=${metadata.features.doNotTrack} indexedDb=${metadata.features.indexedDb.toString()}`;
|
` doNotTrack=${metadata.features.doNotTrack ?? "null"} indexedDb=${metadata.features.indexedDb.toString()}`;
|
||||||
|
|
||||||
const title = `${metadata.error.name}: ${metadata.error.message}${metadata.page && ` (at "${Page[metadata.page]}")`}`;
|
const title = `${metadata.error.name}: ${metadata.error.message}${metadata.page && ` (at "${Page[metadata.page]}")`}`;
|
||||||
const body = `
|
const body = `
|
||||||
|
@ -4,8 +4,5 @@ import { getRandomByte } from "./helpers/getRandomByte";
|
|||||||
* Generate a random IP address
|
* Generate a random IP address
|
||||||
* Does not check to see if the IP already exists in the game
|
* Does not check to see if the IP already exists in the game
|
||||||
*/
|
*/
|
||||||
export function createRandomIp(): string {
|
export const createRandomIp = (): string =>
|
||||||
const ip: string = getRandomByte(99) + "." + getRandomByte(9) + "." + getRandomByte(9) + "." + getRandomByte(9);
|
`${getRandomByte(99)}.${getRandomByte(9)}.${getRandomByte(9)}.${getRandomByte(9)}`;
|
||||||
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { validateObject } from "./Validator";
|
import { validateObject } from "./Validator";
|
||||||
|
|
||||||
interface IReviverValue {
|
export interface IReviverValue {
|
||||||
ctor: string;
|
ctor: string;
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* This is an object that is used to keep track of where all of the player's
|
* This is an object that is used to keep track of where all of the player's
|
||||||
* money is coming from (or going to)
|
* money is coming from (or going to)
|
||||||
*/
|
*/
|
||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "./JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver, IReviverValue } from "./JSONReviver";
|
||||||
|
|
||||||
export class MoneySourceTracker {
|
export class MoneySourceTracker {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
@ -56,7 +56,7 @@ export class MoneySourceTracker {
|
|||||||
|
|
||||||
// Initiatizes a MoneySourceTracker object from a JSON save state.
|
// Initiatizes a MoneySourceTracker object from a JSON save state.
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
static fromJSON(value: any): MoneySourceTracker {
|
static fromJSON(value: IReviverValue): MoneySourceTracker {
|
||||||
return Generic_fromJSON(MoneySourceTracker, value.data);
|
return Generic_fromJSON(MoneySourceTracker, value.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,12 @@
|
|||||||
* @param obj the object to clear all properties
|
* @param obj the object to clear all properties
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function clearObject(obj: any): void {
|
export function clearObject(obj: unknown): void {
|
||||||
for (const key in obj) {
|
if (typeof obj !== "object" || obj === null || obj === undefined) return;
|
||||||
if (obj.hasOwnProperty(key)) {
|
const o = obj as Record<string, unknown>;
|
||||||
// tslint:disable-next-line:no-dynamic-delete
|
for (const key of Object.getOwnPropertyNames(o)) {
|
||||||
delete obj[key];
|
if (o.hasOwnProperty(key)) {
|
||||||
|
delete o[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,18 +9,18 @@ export function compareArrays<T>(a1: T[], a2: T[]): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < a1.length; ++i) {
|
for (let i = 0; i < a1.length; ++i) {
|
||||||
if (Array.isArray(a1[i])) {
|
const v1 = a1[i];
|
||||||
|
const v2 = a2[i];
|
||||||
|
if (Array.isArray(v1)) {
|
||||||
// If the other element is not an array, then these cannot be equal
|
// If the other element is not an array, then these cannot be equal
|
||||||
if (!Array.isArray(a2[i])) {
|
if (!Array.isArray(v2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elem1 = a1[i] as any;
|
if (!compareArrays(v1, v2)) {
|
||||||
const elem2 = a2[i] as any;
|
|
||||||
if (!compareArrays(elem1, elem2)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (a1[i] !== a2[i] && !(Number.isNaN(a1[i]) && Number.isNaN(a2[i]))) {
|
} else if (v1 !== v2 && !(Number.isNaN(v1) && Number.isNaN(v2))) {
|
||||||
// strict (in)equality considers NaN not equal to itself
|
// strict (in)equality considers NaN not equal to itself
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,25 @@ interface IError {
|
|||||||
|
|
||||||
export function exceptionAlert(e: IError | string): void {
|
export function exceptionAlert(e: IError | string): void {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
let msg = "";
|
||||||
|
let file = "UNKNOWN FILE NAME";
|
||||||
|
let line = "UNKNOWN LINE NUMBER";
|
||||||
|
const isError = (e: IError | string): e is IError => e.hasOwnProperty("fileName");
|
||||||
|
if (isError(e)) {
|
||||||
|
file = e.fileName ?? file;
|
||||||
|
line = e.lineNumber?.toString() ?? line;
|
||||||
|
} else {
|
||||||
|
msg = e;
|
||||||
|
}
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Caught an exception: " +
|
"Caught an exception: " +
|
||||||
e +
|
msg +
|
||||||
"<br><br>" +
|
"<br><br>" +
|
||||||
"Filename: " +
|
"Filename: " +
|
||||||
((e as any).fileName || "UNKNOWN FILE NAME") +
|
file +
|
||||||
"<br><br>" +
|
"<br><br>" +
|
||||||
"Line Number: " +
|
"Line Number: " +
|
||||||
((e as any).lineNumber || "UNKNOWN LINE NUMBER") +
|
line +
|
||||||
"<br><br>" +
|
"<br><br>" +
|
||||||
"This is a bug, please report to game developer with this " +
|
"This is a bug, please report to game developer with this " +
|
||||||
"message as well as details about how to reproduce the bug.<br><br>" +
|
"message as well as details about how to reproduce the bug.<br><br>" +
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
|
export function isArray(arr: unknown): arr is unknown[] {
|
||||||
|
return Array.isArray(arr);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks whether an array is a 2D array.
|
// Checks whether an array is a 2D array.
|
||||||
// For this, a 2D array is an array which contains only other arrays.
|
// For this, a 2D array is an array which contains only other arrays.
|
||||||
// If one element in the array is a number or string, it is NOT a 2D array
|
// If one element in the array is a number or string, it is NOT a 2D array
|
||||||
export function is2DArray(arr: any[]): boolean {
|
export function is2DArray(arr: unknown): arr is unknown[][] {
|
||||||
if (arr.constructor !== Array) {
|
return isArray(arr) && arr.every((u) => isArray(u));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return arr.every((e) => {
|
|
||||||
return e.constructor === Array;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,11 @@ const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
|
|||||||
|
|
||||||
describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
||||||
// Creates a mock RunningScript object
|
// Creates a mock RunningScript object
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} code
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async function createRunningScript(code) {
|
async function createRunningScript(code) {
|
||||||
const script = new Script();
|
const script = new Script();
|
||||||
script.code = code;
|
script.code = code;
|
||||||
@ -24,12 +29,23 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tests numeric equality, allowing for floating point imprecision
|
// Tests numeric equality, allowing for floating point imprecision
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} val
|
||||||
|
* @param {number} expected
|
||||||
|
*/
|
||||||
function testEquality(val, expected) {
|
function testEquality(val, expected) {
|
||||||
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
||||||
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs a Netscript function and properly catches it if it returns promise
|
// Runs a Netscript function and properly catches it if it returns promise
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {(...args: unknown[]) => unknown} fn
|
||||||
|
* @param {unknown[]} args
|
||||||
|
*/
|
||||||
function runPotentiallyAsyncFunction(fn, ...args) {
|
function runPotentiallyAsyncFunction(fn, ...args) {
|
||||||
const res = fn(...args);
|
const res = fn(...args);
|
||||||
if (res instanceof Promise) {
|
if (res instanceof Promise) {
|
||||||
@ -93,7 +109,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
|||||||
runPotentiallyAsyncFunction(curr, ...args);
|
runPotentiallyAsyncFunction(curr, ...args);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Invalid function specified: [${fnDesc}]`);
|
throw new Error(`Invalid function specified: [${fnDesc.toString()}]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnName = fnDesc[fnDesc.length - 1];
|
const fnName = fnDesc[fnDesc.length - 1];
|
||||||
|
@ -11,6 +11,11 @@ const HacknetNamespaceCost = RamCostConstants.ScriptHacknetNodesRamCost;
|
|||||||
|
|
||||||
describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
||||||
// Tests numeric equality, allowing for floating point imprecision
|
// Tests numeric equality, allowing for floating point imprecision
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} val
|
||||||
|
* @param {number} expected
|
||||||
|
*/
|
||||||
function testEquality(val, expected) {
|
function testEquality(val, expected) {
|
||||||
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
||||||
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
||||||
@ -25,9 +30,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
|||||||
* including the namespace(s). e.g. ["gang", "getMemberNames"]
|
* including the namespace(s). e.g. ["gang", "getMemberNames"]
|
||||||
*/
|
*/
|
||||||
async function expectNonZeroRamCost(fnDesc) {
|
async function expectNonZeroRamCost(fnDesc) {
|
||||||
if (!Array.isArray(fnDesc)) {
|
|
||||||
expect.fail("Non-array passed to expectNonZeroRamCost()");
|
|
||||||
}
|
|
||||||
const expected = getRamCost(Player, ...fnDesc);
|
const expected = getRamCost(Player, ...fnDesc);
|
||||||
expect(expected).toBeGreaterThan(0);
|
expect(expected).toBeGreaterThan(0);
|
||||||
|
|
||||||
@ -50,9 +52,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
|||||||
* including the namespace(s). e.g. ["gang", "getMemberNames"]
|
* including the namespace(s). e.g. ["gang", "getMemberNames"]
|
||||||
*/
|
*/
|
||||||
async function expectZeroRamCost(fnDesc) {
|
async function expectZeroRamCost(fnDesc) {
|
||||||
if (!Array.isArray(fnDesc)) {
|
|
||||||
expect.fail("Non-array passed to expectZeroRamCost()");
|
|
||||||
}
|
|
||||||
const expected = getRamCost(Player, ...fnDesc);
|
const expected = getRamCost(Player, ...fnDesc);
|
||||||
expect(expected).toEqual(0);
|
expect(expected).toEqual(0);
|
||||||
|
|
||||||
@ -64,7 +63,12 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
|||||||
expect(multipleCallsCalculated).toEqual(ScriptBaseCost);
|
expect(multipleCallsCalculated).toEqual(ScriptBaseCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
// simplyfied version from RamCostGenerator.ts
|
/**
|
||||||
|
*
|
||||||
|
* @param {Player} player
|
||||||
|
* @param {number} cost
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function SF4Cost(player, cost) {
|
function SF4Cost(player, cost) {
|
||||||
if (player.bitNodeN === 4) return cost;
|
if (player.bitNodeN === 4) return cost;
|
||||||
const sf4 = player.sourceFileLvl(4);
|
const sf4 = player.sourceFileLvl(4);
|
||||||
@ -83,9 +87,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
|||||||
* @param {number} cost - expected cost
|
* @param {number} cost - expected cost
|
||||||
*/
|
*/
|
||||||
async function expectSpecificRamCost(fnDesc, cost) {
|
async function expectSpecificRamCost(fnDesc, cost) {
|
||||||
if (!Array.isArray(fnDesc)) {
|
|
||||||
expect.fail("Non-array passed to expectZeroRamCost()");
|
|
||||||
}
|
|
||||||
const expected = getRamCost(Player, ...fnDesc);
|
const expected = getRamCost(Player, ...fnDesc);
|
||||||
expect(expected).toEqual(SF4Cost(Player, cost));
|
expect(expected).toEqual(SF4Cost(Player, cost));
|
||||||
|
|
||||||
|
@ -18,6 +18,11 @@ const CorpCost = 1024 - ScriptBaseCost;
|
|||||||
|
|
||||||
describe("Parsing NetScript code to work out static RAM costs", function () {
|
describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||||
// Tests numeric equality, allowing for floating point imprecision - and includes script base cost
|
// Tests numeric equality, allowing for floating point imprecision - and includes script base cost
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} val
|
||||||
|
* @param {number} expected
|
||||||
|
*/
|
||||||
function expectCost(val, expected) {
|
function expectCost(val, expected) {
|
||||||
const expectedWithBase = expected + ScriptBaseCost;
|
const expectedWithBase = expected + ScriptBaseCost;
|
||||||
expect(val).toBeGreaterThanOrEqual(expectedWithBase - 100 * Number.EPSILON);
|
expect(val).toBeGreaterThanOrEqual(expectedWithBase - 100 * Number.EPSILON);
|
||||||
|
@ -6,7 +6,6 @@ import { Company } from "../../src/Company/Company";
|
|||||||
import { Server } from "../../src/Server/Server";
|
import { Server } from "../../src/Server/Server";
|
||||||
|
|
||||||
import { buyStock, sellStock, shortStock, sellShort } from "../../src/StockMarket/BuyingAndSelling";
|
import { buyStock, sellStock, shortStock, sellShort } from "../../src/StockMarket/BuyingAndSelling";
|
||||||
import { IStockMarket } from "../../src/StockMarket/IStockMarket";
|
|
||||||
import { Order } from "../../src/StockMarket/Order";
|
import { Order } from "../../src/StockMarket/Order";
|
||||||
import {
|
import {
|
||||||
forecastForecastChangeFromCompanyWork,
|
forecastForecastChangeFromCompanyWork,
|
||||||
@ -458,17 +457,13 @@ describe("Stock Market Tests", function () {
|
|||||||
|
|
||||||
it("should trigger a price update when it has enough cycles", function () {
|
it("should trigger a price update when it has enough cycles", function () {
|
||||||
// Get the initial prices
|
// Get the initial prices
|
||||||
const initialValues: IMap<any> = {};
|
const initialValues: IMap<Stock> = {};
|
||||||
for (const stockName in StockMarket) {
|
for (const stockName in StockMarket) {
|
||||||
const stock = StockMarket[stockName];
|
const stock = StockMarket[stockName];
|
||||||
if (!(stock instanceof Stock)) {
|
if (!(stock instanceof Stock)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
initialValues[stock.symbol] = {
|
initialValues[stock.symbol] = stock;
|
||||||
b: stock.b,
|
|
||||||
otlkMag: stock.otlkMag,
|
|
||||||
price: stock.price,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't know or care how many exact cycles are required
|
// Don't know or care how many exact cycles are required
|
||||||
@ -1149,7 +1144,7 @@ describe("Stock Market Tests", function () {
|
|||||||
Player.setMoney(100e9);
|
Player.setMoney(100e9);
|
||||||
|
|
||||||
processOrdersRefs = {
|
processOrdersRefs = {
|
||||||
stockMarket: StockMarket as IStockMarket,
|
stockMarket: StockMarket,
|
||||||
symbolToStockMap: SymbolToStockMap,
|
symbolToStockMap: SymbolToStockMap,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -100,9 +100,11 @@ describe("Terminal Directory Tests", function () {
|
|||||||
expect(isValidDirectoryName(".a1")).toEqual(true);
|
expect(isValidDirectoryName(".a1")).toEqual(true);
|
||||||
expect(isValidDirectoryName("._foo")).toEqual(true);
|
expect(isValidDirectoryName("._foo")).toEqual(true);
|
||||||
expect(isValidDirectoryName("_foo")).toEqual(true);
|
expect(isValidDirectoryName("_foo")).toEqual(true);
|
||||||
expect(isValidDirectoryName("foo.dir")).toEqual(true);
|
// the changes made to support this broke mv
|
||||||
expect(isValidDirectoryName("foov1.0.0.1")).toEqual(true);
|
// see https://github.com/danielyxie/bitburner/pull/3653 if you try to re support
|
||||||
expect(isValidDirectoryName("foov1..0..0..1")).toEqual(true);
|
// expect(isValidDirectoryName("foo.dir")).toEqual(true);
|
||||||
|
// expect(isValidDirectoryName("foov1.0.0.1")).toEqual(true);
|
||||||
|
// expect(isValidDirectoryName("foov1..0..0..1")).toEqual(true);
|
||||||
expect(isValidDirectoryName("foov1-0-0-1")).toEqual(true);
|
expect(isValidDirectoryName("foov1-0-0-1")).toEqual(true);
|
||||||
expect(isValidDirectoryName("foov1-0-0-1-")).toEqual(true);
|
expect(isValidDirectoryName("foov1-0-0-1-")).toEqual(true);
|
||||||
expect(isValidDirectoryName("foov1--0--0--1--")).toEqual(true);
|
expect(isValidDirectoryName("foov1--0--0--1--")).toEqual(true);
|
||||||
|
4
tools/tsconfig.json
Normal file
4
tools/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"include": ["**/*.js"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user