Merge pull request #1949 from danielyxie/dev

build
This commit is contained in:
hydroflame 2021-12-16 12:58:30 -05:00 committed by GitHub
commit c38992be8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 442 additions and 244 deletions

32
dist/bitburner.d.ts vendored

@ -2124,6 +2124,27 @@ export declare interface NodeStats {
/**
* Collection of all functions passed to scripts
* @public
* @remarks
* <b>Basic ns1 usage example:</b>
* ```ts
* // Basic ns functions can be used directly
* methodName();
* // Some related functions are gathered within a common namespace
* property.methodName();
* ```
* {@link https://bitburner.readthedocs.io/en/latest/netscript/netscript1.html| ns1 in-game docs}
* <hr>
* <b>Basic ns2 usage example:</b>
* ```ts
* export async function main(ns) {
* // Basic ns functions can be accessed on the ns object
* await ns.methodName;
* // Some related functions are gathered under a sub-property of the ns object
* await ns.property.methodName;
* }
* ```
* {@link https://bitburner.readthedocs.io/en/latest/netscript/netscriptjs.html| ns2 in-game docs}
* <hr>
*/
export declare interface NS extends Singularity {
/**
@ -2321,9 +2342,9 @@ export declare interface NS extends Singularity {
*
* @example
* ```ts
* //For example, assume the following returns 1:
* //For example, assume the following returns 0.01:
* hackAnalyze("foodnstuff");
* //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N% of its total money.
* //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N*0.01% of its total money.
* ```
* @param host - Hostname of the target server.
* @returns The percentage of money you will steal from the target server with a single hack.
@ -3259,13 +3280,12 @@ export declare interface NS extends Singularity {
deleteServer(host: string): boolean;
/**
* Returns an array with either the hostnames or IPs of all of the servers you have purchased.
* Returns an array with the hostnames of all of the servers you have purchased.
*
* @remarks 2.25 GB
* @param hostnameMode - Optional. Defaults to true. Returns hostnames if true, and IPs if false.
* @returns Returns an array with either the hostnames or IPs of all of the servers you have purchased.
* @returns Returns an array with the hostnames of all of the servers you have purchased.
*/
getPurchasedServers(hostnameMode?: boolean): string[];
getPurchasedServers(): string[];
/**
* Returns the maximum number of servers you can purchase.

26
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -9,14 +9,15 @@ if (greenworks.init()) {
const debug = false;
function createWindow() {
function createWindow(killall) {
const win = new BrowserWindow({
show: false,
});
win.removeMenu();
win.maximize();
win.loadFile("index.html");
noScripts = killall ? { query: { noScripts: killall } } : {};
win.loadFile("index.html", noScripts);
win.show();
if (debug) win.webContents.openDevTools();
@ -75,7 +76,7 @@ function createWindow() {
if (intervalID) clearInterval(intervalID);
win.webContents.forcefullyCrashRenderer();
win.close();
createWindow();
createWindow(true);
},
},
],
@ -110,5 +111,5 @@ function createWindow() {
}
app.whenReady().then(() => {
createWindow();
createWindow(false);
});

@ -14221,7 +14221,7 @@
{
"kind": "Interface",
"canonicalReference": "bitburner!NS:interface",
"docComment": "/**\n * Collection of all functions passed to scripts\n *\n * @public\n */\n",
"docComment": "/**\n * Collection of all functions passed to scripts\n *\n * @remarks\n *\n * <b>Basic ns1 usage example:</b>\n * ```ts\n * // Basic ns functions can be used directly\n * methodName();\n * // Some related functions are gathered within a common namespace\n * property.methodName();\n * ```\n *\n * {@link https://bitburner.readthedocs.io/en/latest/netscript/netscript1.html | ns1 in-game docs} <hr> <b>Basic ns2 usage example:</b>\n * ```ts\n * export async function main(ns) {\n * // Basic ns functions can be accessed on the ns object\n * await ns.methodName;\n * // Some related functions are gathered under a sub-property of the ns object\n * await ns.property.methodName;\n * }\n * ```\n *\n * {@link https://bitburner.readthedocs.io/en/latest/netscript/netscriptjs.html | ns2 in-game docs} <hr>\n *\n * @public\n */\n",
"excerptTokens": [
{
"kind": "Content",
@ -15562,19 +15562,11 @@
{
"kind": "MethodSignature",
"canonicalReference": "bitburner!NS#getPurchasedServers:member(1)",
"docComment": "/**\n * Returns an array with either the hostnames or IPs of all of the servers you have purchased.\n *\n * @remarks\n *\n * 2.25 GB\n *\n * @param hostnameMode - Optional. Defaults to true. Returns hostnames if true, and IPs if false.\n *\n * @returns Returns an array with either the hostnames or IPs of all of the servers you have purchased.\n */\n",
"docComment": "/**\n * Returns an array with the hostnames of all of the servers you have purchased.\n *\n * @remarks\n *\n * 2.25 GB\n *\n * @returns Returns an array with the hostnames of all of the servers you have purchased.\n */\n",
"excerptTokens": [
{
"kind": "Content",
"text": "getPurchasedServers(hostnameMode?: "
},
{
"kind": "Content",
"text": "boolean"
},
{
"kind": "Content",
"text": "): "
"text": "getPurchasedServers(): "
},
{
"kind": "Content",
@ -15587,20 +15579,12 @@
],
"isOptional": false,
"returnTypeTokenRange": {
"startIndex": 3,
"endIndex": 4
"startIndex": 1,
"endIndex": 2
},
"releaseTag": "Public",
"overloadIndex": 1,
"parameters": [
{
"parameterName": "hostnameMode",
"parameterTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
}
}
],
"parameters": [],
"name": "getPurchasedServers"
},
{
@ -16839,7 +16823,7 @@
{
"kind": "MethodSignature",
"canonicalReference": "bitburner!NS#hackAnalyze:member(1)",
"docComment": "/**\n * Get the percent of money stolen with a single thread.\n *\n * @remarks\n *\n * RAM cost: 1 GB\n *\n * Returns the percentage of the specified servers money you will steal with a single hack. This value is returned in percentage form, not decimal (Netscript functions typically return in decimal form, but not this one).\n *\n * @param host - Hostname of the target server.\n *\n * @returns The percentage of money you will steal from the target server with a single hack.\n *\n * @example\n * ```ts\n * //For example, assume the following returns 1:\n * hackAnalyze(\"foodnstuff\");\n * //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N% of its total money.\n * ```\n *\n */\n",
"docComment": "/**\n * Get the percent of money stolen with a single thread.\n *\n * @remarks\n *\n * RAM cost: 1 GB\n *\n * Returns the percentage of the specified servers money you will steal with a single hack. This value is returned in percentage form, not decimal (Netscript functions typically return in decimal form, but not this one).\n *\n * @param host - Hostname of the target server.\n *\n * @returns The percentage of money you will steal from the target server with a single hack.\n *\n * @example\n * ```ts\n * //For example, assume the following returns 0.01:\n * hackAnalyze(\"foodnstuff\");\n * //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N*0.01% of its total money.\n * ```\n *\n */\n",
"excerptTokens": [
{
"kind": "Content",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -4,25 +4,18 @@
## NS.getPurchasedServers() method
Returns an array with either the hostnames or IPs of all of the servers you have purchased.
Returns an array with the hostnames of all of the servers you have purchased.
<b>Signature:</b>
```typescript
getPurchasedServers(hostnameMode?: boolean): string[];
getPurchasedServers(): string[];
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| hostnameMode | boolean | Optional. Defaults to true. Returns hostnames if true, and IPs if false. |
<b>Returns:</b>
string\[\]
Returns an array with either the hostnames or IPs of all of the servers you have purchased.
Returns an array with the hostnames of all of the servers you have purchased.
## Remarks

@ -22,7 +22,7 @@ getWeakenTime(host: string): number;
number
Returns the amount of time in milliseconds it takes to execute the weaken Netscript function. Returns Infinity if called on a Hacknet Server.
Returns the amount of time in milliseconds it takes to execute the grow Netscript function. Returns Infinity if called on a Hacknet Server.
## Remarks

@ -34,8 +34,8 @@ Returns the percentage of the specified servers money you will steal with a s
```ts
//For example, assume the following returns 1:
//For example, assume the following returns 0.01:
hackAnalyze("foodnstuff");
//This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N% of its total money.
//This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N*0.01% of its total money.
```

@ -11,12 +11,37 @@ Collection of all functions passed to scripts
```typescript
export interface NS extends Singularity
```
<b>Extends:</b> [Singularity](./bitburner.singularity.md)
## Remarks
<b>Basic ns1 usage example:</b>
```ts
// Basic ns functions can be used directly
methodName();
// Some related functions are gathered within a common namespace
property.methodName();
```
[ns1 in-game docs](https://bitburner.readthedocs.io/en/latest/netscript/netscript1.html) <hr> <b>Basic ns2 usage example:</b>
```ts
export async function main(ns) {
// Basic ns functions can be accessed on the ns object
await ns.methodName;
// Some related functions are gathered under a sub-property of the ns object
await ns.property.methodName;
}
```
[ns2 in-game docs](https://bitburner.readthedocs.io/en/latest/netscript/netscriptjs.html) <hr>
## Properties
| Property | Type | Description |
| --- | --- | --- |
| -------------------------------------------------- | ----------------------------------------------- | --------------------------------------------------- |
| [args](./bitburner.ns.args.md) | (string \| number \| boolean)\[\] | Arguments passed into the script. |
| [bladeburner](./bitburner.ns.bladeburner.md) | [Bladeburner](./bitburner.bladeburner.md) | Namespace for bladeburner functions. |
| [codingcontract](./bitburner.ns.codingcontract.md) | [CodingContract](./bitburner.codingcontract.md) | Namespace for codingcontract functions. |
@ -31,7 +56,7 @@ export interface NS extends Singularity
## Methods
| Method | Description |
| --- | --- |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| [alert(msg)](./bitburner.ns.alert.md) | Open up a message box. |
| [asleep(millis)](./bitburner.ns.asleep.md) | Suspends the script for n milliseconds. Doesn't block with concurrent calls. |
| [atExit(f)](./bitburner.ns.atexit.md) | Add callback function when the script dies |
@ -61,7 +86,7 @@ export interface NS extends Singularity
| [getPurchasedServerCost(ram)](./bitburner.ns.getpurchasedservercost.md) | Get cost of purchasing a server. |
| [getPurchasedServerLimit()](./bitburner.ns.getpurchasedserverlimit.md) | Returns the maximum number of servers you can purchase. |
| [getPurchasedServerMaxRam()](./bitburner.ns.getpurchasedservermaxram.md) | Returns the maximum RAM that a purchased server can have. |
| [getPurchasedServers(hostnameMode)](./bitburner.ns.getpurchasedservers.md) | Returns an array with either the hostnames or IPs of all of the servers you have purchased. |
| [getPurchasedServers()](./bitburner.ns.getpurchasedservers.md) | Returns an array with the hostnames of all of the servers you have purchased. |
| [getRunningScript(filename, hostname, args)](./bitburner.ns.getrunningscript.md) | Get general info about a running script. |
| [getScriptExpGain(script, host, args)](./bitburner.ns.getscriptexpgain.md) | Get the exp gain of a script. |
| [getScriptIncome(script, host, args)](./bitburner.ns.getscriptincome.md) | Get the income of a script. |
@ -130,4 +155,3 @@ export interface NS extends Singularity
| [wget(url, target, host)](./bitburner.ns.wget.md) | Download a file from the internet. |
| [write(handle, data, mode)](./bitburner.ns.write.md) | Write data to a file. |
| [writePort(port, data)](./bitburner.ns.writeport.md) | Write data to a port. |

1
package-lock.json generated

@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
"name": "bitburner",
"version": "1.1.0",
"hasInstallScript": true,
"license": "SEE LICENSE IN license.txt",

@ -109,6 +109,6 @@
"test:watch": "jest --watch",
"watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development",
"electron": "cp -r electron/* .package && cp index.html .package && cp main.bundle.js .package && cp dist/vendor.bundle.js .package/dist && cp -r dist/ext .package/dist/ext && electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png"
"electron": "cp -r electron/* .package && cp index.html .package && cp main.bundle.js .package && cp dist/vendor.bundle.js .package/dist/ && cp -r dist/ext .package/dist/ && electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png"
}
}

@ -82,16 +82,24 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
setGangOpen(true);
}
function startWork(): void {
player.startFocusing();
router.toWork();
}
function startFieldWork(faction: Faction): void {
player.startFactionFieldWork(router, faction);
player.startFactionFieldWork(faction);
startWork();
}
function startHackingContracts(faction: Faction): void {
player.startFactionHackWork(router, faction);
player.startFactionHackWork(faction);
startWork();
}
function startSecurityWork(faction: Faction): void {
player.startFactionSecurityWork(router, faction);
player.startFactionSecurityWork(faction);
startWork();
}
// We have a special flag for whether the player this faction is the player's

@ -171,10 +171,11 @@ export function CompanyLocation(props: IProps): React.ReactElement {
const pos = companyPosition;
if (pos instanceof CompanyPosition) {
if (pos.isPartTimeJob() || pos.isSoftwareConsultantJob() || pos.isBusinessConsultantJob()) {
p.startWorkPartTime(router, props.locName);
p.startWorkPartTime(props.locName);
} else {
p.startWork(router, props.locName);
p.startWork(props.locName);
}
p.startFocusing();
router.toWork();
}
}

@ -941,6 +941,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return runScriptFromScript("run", scriptServer, scriptname, args, workerScript, threads);
},
exec: function (scriptname: any, hostname: any, threads: any = 1, ...args: any[]): any {
console.log(`${scriptname} ${hostname} ${threads} ${JSON.stringify(args)}`);
updateDynamicRam("exec", getRamCost("exec"));
if (scriptname === undefined || hostname === undefined) {
throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
@ -1061,11 +1062,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("scp", "No scripts to copy");
}
let res = true;
await Promise.all(scripts.map(async function(script) {
if (!await NetscriptFunctions(workerScript).scp(script, hostname1, hostname2)) {
await Promise.all(
scripts.map(async function (script) {
if (!(await NetscriptFunctions(workerScript).scp(script, hostname1, hostname2))) {
res = false;
}
}));
}),
);
return Promise.resolve(res);
}
@ -2120,12 +2123,15 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return Player.playtimeSinceLastAug;
},
alert: function (message: any): void {
dialogBoxCreate(message);
message = toNative(message);
dialogBoxCreate(JSON.stringify(message));
},
toast: function (message: any, variant: any = "success"): void {
if (!["success", "info", "warning", "error"].includes(variant))
throw new Error(`variant must be one of "success", "info", "warning", or "error"`);
SnackbarEvents.emit(message, variant);
message = toNative(message);
SnackbarEvents.emit(JSON.stringify(message), variant);
},
prompt: function (txt: any): any {
if (!isString(txt)) {

@ -622,6 +622,38 @@ export function NetscriptSingularity(
return Promise.resolve();
});
},
isFocused: function (): boolean {
helper.updateDynamicRam("isFocused", getRamCost("isFocused"));
helper.checkSingularityAccess("isFocused", 2);
return player.focus;
},
setFocus: function (afocus: any): boolean {
const focus = helper.boolean(afocus);
helper.updateDynamicRam("setFocus", getRamCost("setFocus"));
helper.checkSingularityAccess("setFocus", 2);
if (!player.isWorking) {
throw helper.makeRuntimeErrorMsg("setFocus", "Not currently working");
}
if (
!(
player.workType == CONSTANTS.WorkTypeFaction ||
player.workType == CONSTANTS.WorkTypeCompany ||
player.workType == CONSTANTS.WorkTypeCompanyPartTime
)
) {
throw helper.makeRuntimeErrorMsg("setFocus", "Cannot change focus for current job");
}
if (!player.focus && focus) {
player.startFocusing();
Router.toWork();
return true;
} else if (player.focus && !focus) {
player.stopFocusing();
Router.toTerminal();
return true;
}
return false;
},
getStats: function (): any {
helper.updateDynamicRam("getStats", getRamCost("getStats"));
helper.checkSingularityAccess("getStats", 1);
@ -703,7 +735,9 @@ export function NetscriptSingularity(
helper.updateDynamicRam("stopAction", getRamCost("stopAction"));
helper.checkSingularityAccess("stopAction", 1);
if (player.isWorking) {
if (player.focus) {
Router.toTerminal();
}
const txt = player.singularityStopWork();
workerScript.log("stopAction", () => txt);
return true;
@ -814,16 +848,21 @@ export function NetscriptSingularity(
return false;
}
const wasWorking = player.isWorking;
const wasFocused = player.focus;
if (player.isWorking) {
const txt = player.singularityStopWork();
workerScript.log("workForCompany", () => txt);
}
if (companyPosition.isPartTimeJob()) {
player.startWorkPartTime(Router, companyName);
player.startWorkPartTime(companyName);
} else {
player.startWork(Router, companyName);
player.startWork(companyName);
}
if (!wasWorking || (wasWorking && !wasFocused)) player.stopFocusing();
else if (wasWorking && wasFocused) player.startFocusing();
workerScript.log(
"workForCompany",
() => `Began working at '${player.companyName}' as a '${companyPositionName}'`,
@ -963,6 +1002,8 @@ export function NetscriptSingularity(
return false;
}
const wasWorking = player.isWorking;
const wasFocused = player.focus;
if (player.isWorking) {
const txt = player.singularityStopWork();
workerScript.log("workForFaction", () => txt);
@ -1060,7 +1101,9 @@ export function NetscriptSingularity(
workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with hacking contracts.`);
return false;
}
player.startFactionHackWork(Router, fac);
player.startFactionHackWork(fac);
if (!wasWorking || (wasWorking && !wasFocused)) player.stopFocusing();
else if (wasWorking && wasFocused) player.startFocusing();
workerScript.log("workForFaction", () => `Started carrying out hacking contracts for '${fac.name}'`);
return true;
case "field":
@ -1070,7 +1113,9 @@ export function NetscriptSingularity(
workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with field missions.`);
return false;
}
player.startFactionFieldWork(Router, fac);
player.startFactionFieldWork(fac);
if (!wasWorking || (wasWorking && !wasFocused)) player.stopFocusing();
else if (wasWorking && wasFocused) player.startFocusing();
workerScript.log("workForFaction", () => `Started carrying out field missions for '${fac.name}'`);
return true;
case "security":
@ -1080,7 +1125,9 @@ export function NetscriptSingularity(
workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with security work.`);
return false;
}
player.startFactionSecurityWork(Router, fac);
player.startFactionSecurityWork(fac);
if (!wasWorking || (wasWorking && !wasFocused)) player.stopFocusing();
else if (wasWorking && wasFocused) player.startFocusing();
workerScript.log("workForFaction", () => `Started carrying out security work for '${fac.name}'`);
return true;
default:

@ -709,6 +709,7 @@ export function runScriptFromScript(
);
const runningScriptObj = new RunningScript(script, args);
runningScriptObj.threads = threads;
runningScriptObj.server = server.hostname;
return startWorkerScript(runningScriptObj, server, workerScript);
}

@ -211,7 +211,7 @@ export interface IPlayer {
setMoney(amt: number): void;
singularityStopWork(): string;
startBladeburner(p: any): void;
startFactionWork(router: IRouter, faction: Faction): void;
startFactionWork(faction: Faction): void;
startClass(router: IRouter, costMult: number, expMult: number, className: string): void;
startCorporation(corpName: string, additionalShares?: number): void;
startCrime(
@ -227,13 +227,13 @@ export interface IPlayer {
time: number,
singParams: any,
): void;
startFactionFieldWork(router: IRouter, faction: Faction): void;
startFactionHackWork(router: IRouter, faction: Faction): void;
startFactionSecurityWork(router: IRouter, faction: Faction): void;
startFactionFieldWork(faction: Faction): void;
startFactionHackWork(faction: Faction): void;
startFactionSecurityWork(faction: Faction): void;
startFocusing(): void;
startGang(facName: string, isHacking: boolean): void;
startWork(router: IRouter, companyName: string): void;
startWorkPartTime(router: IRouter, companyName: string): void;
startWork(companyName: string): void;
startWorkPartTime(companyName: string): void;
takeDamage(amt: number): boolean;
travel(to: CityName): boolean;
giveExploit(exploit: Exploit): void;

@ -216,7 +216,7 @@ export class PlayerObject implements IPlayer {
setMoney: (amt: number) => void;
singularityStopWork: () => string;
startBladeburner: (p: any) => void;
startFactionWork: (router: IRouter, faction: Faction) => void;
startFactionWork: (faction: Faction) => void;
startClass: (router: IRouter, costMult: number, expMult: number, className: string) => void;
startCorporation: (corpName: string, additionalShares?: number) => void;
startCrime: (
@ -232,13 +232,13 @@ export class PlayerObject implements IPlayer {
time: number,
singParams: any,
) => void;
startFactionFieldWork: (router: IRouter, faction: Faction) => void;
startFactionHackWork: (router: IRouter, faction: Faction) => void;
startFactionSecurityWork: (router: IRouter, faction: Faction) => void;
startFactionFieldWork: (faction: Faction) => void;
startFactionHackWork: (faction: Faction) => void;
startFactionSecurityWork: (faction: Faction) => void;
startFocusing: () => void;
startGang: (facName: string, isHacking: boolean) => void;
startWork: (router: IRouter, companyName: string) => void;
startWorkPartTime: (router: IRouter, companyName: string) => void;
startWork: (companyName: string) => void;
startWorkPartTime: (companyName: string) => void;
takeDamage: (amt: number) => boolean;
travel: (to: CityName) => boolean;
giveExploit: (exploit: Exploit) => void;

@ -554,10 +554,9 @@ export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
}
/* Working for Company */
export function startWork(this: IPlayer, router: IRouter, companyName: string): void {
export function startWork(this: IPlayer, companyName: string): void {
this.resetWorkStatus(CONSTANTS.WorkTypeCompany, companyName);
this.isWorking = true;
this.focus = true;
this.companyName = companyName;
this.workType = CONSTANTS.WorkTypeCompany;
@ -571,7 +570,6 @@ export function startWork(this: IPlayer, router: IRouter, companyName: string):
this.workMoneyGainRate = this.getWorkMoneyGain();
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
router.toWork();
}
export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
@ -723,10 +721,9 @@ export function finishWork(this: IPlayer, cancelled: boolean, sing = false): str
return "";
}
export function startWorkPartTime(this: IPlayer, router: IRouter, companyName: string): void {
export function startWorkPartTime(this: IPlayer, companyName: string): void {
this.resetWorkStatus(CONSTANTS.WorkTypeCompanyPartTime, companyName);
this.isWorking = true;
this.focus = true;
this.companyName = companyName;
this.workType = CONSTANTS.WorkTypeCompanyPartTime;
@ -740,7 +737,6 @@ export function startWorkPartTime(this: IPlayer, router: IRouter, companyName: s
this.workMoneyGainRate = this.getWorkMoneyGain();
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
router.toWork();
}
export function workPartTime(this: IPlayer, numCycles: number): boolean {
@ -832,7 +828,7 @@ export function stopFocusing(this: IPlayer): void {
}
/* Working for Faction */
export function startFactionWork(this: IPlayer, router: IRouter, faction: Faction): void {
export function startFactionWork(this: IPlayer, faction: Faction): void {
//Update reputation gain rate to account for faction favor
let favorMult = 1 + faction.favor / 100;
if (isNaN(favorMult)) {
@ -842,15 +838,13 @@ export function startFactionWork(this: IPlayer, router: IRouter, faction: Factio
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeFaction;
this.currentWorkFactionName = faction.name;
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer20Hours;
router.toWork();
}
export function startFactionHackWork(this: IPlayer, router: IRouter, faction: Faction): void {
export function startFactionHackWork(this: IPlayer, faction: Faction): void {
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkHacking);
this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
@ -859,10 +853,10 @@ export function startFactionHackWork(this: IPlayer, router: IRouter, faction: Fa
this.factionWorkType = CONSTANTS.FactionWorkHacking;
this.currentWorkFactionDescription = "carrying out hacking contracts";
this.startFactionWork(router, faction);
this.startFactionWork(faction);
}
export function startFactionFieldWork(this: IPlayer, router: IRouter, faction: Faction): void {
export function startFactionFieldWork(this: IPlayer, faction: Faction): void {
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkField);
this.workHackExpGainRate = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
@ -876,10 +870,10 @@ export function startFactionFieldWork(this: IPlayer, router: IRouter, faction: F
this.factionWorkType = CONSTANTS.FactionWorkField;
this.currentWorkFactionDescription = "carrying out field missions";
this.startFactionWork(router, faction);
this.startFactionWork(faction);
}
export function startFactionSecurityWork(this: IPlayer, router: IRouter, faction: Faction): void {
export function startFactionSecurityWork(this: IPlayer, faction: Faction): void {
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkSecurity);
this.workHackExpGainRate = 0.05 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
@ -893,7 +887,7 @@ export function startFactionSecurityWork(this: IPlayer, router: IRouter, faction
this.factionWorkType = CONSTANTS.FactionWorkSecurity;
this.currentWorkFactionDescription = "performing security detail";
this.startFactionWork(router, faction);
this.startFactionWork(faction);
}
export function workForFaction(this: IPlayer, numCycles: number): boolean {

@ -168,6 +168,13 @@ export function prestigeSourceFile(flume: boolean): void {
const homeComp = Player.getHomeComputer();
// Stop a Terminal action if there is one.
if (Terminal.action !== null) {
Terminal.finishAction(Router, Player, true);
}
Terminal.clear();
LogBoxClearEvents.emit();
// Delete all servers except home computer
prestigeAllServers(); // Must be done before initForeignServers()

@ -1985,6 +1985,25 @@ export interface Singularity {
* @returns True if the installation was successful.
*/
installBackdoor(): Promise<void>;
/**
* SF4.2 - Check if the player is focused.
* @remarks
* RAM cost: 0.1 GB
*
*
* @returns True if the player is focused.
*/
isFocused(): boolean;
/**
* SF4.2 - Set the players focus.
* @remarks
* RAM cost: 0.1 GB
*
* @returns True if the focus was changed.
*/
setFocus(focus: boolean): boolean;
}
/**
@ -2831,9 +2850,9 @@ export interface CodingContract {
*
* @param filename - Filename of the contract.
* @param host - Host of the server containing the contract. Optional. Defaults to current server if not provided.
* @returns The specified contracts data;
* @returns The specified contracts data, data type depends on contract type.;
*/
getData(filename: string, host?: string): string;
getData(filename: string, host?: string): any;
/**
* Get the number of attempt remaining.
@ -3707,6 +3726,27 @@ interface Stanek {
/**
* Collection of all functions passed to scripts
* @public
* @remarks
* <b>Basic ns1 usage example:</b>
* ```ts
* // Basic ns functions can be used directly
* getHostname();
* // Some related functions are gathered within a common namespace
* stock.getPrice();
* ```
* {@link https://bitburner.readthedocs.io/en/latest/netscript/netscript1.html| ns1 in-game docs}
* <hr>
* <b>Basic ns2 usage example:</b>
* ```ts
* export async function main(ns) {
* // Basic ns functions can be accessed on the ns object
* await ns.getHostname();
* // Some related functions are gathered under a sub-property of the ns object
* await ns.stock.getPrice();
* }
* ```
* {@link https://bitburner.readthedocs.io/en/latest/netscript/netscriptjs.html| ns2 in-game docs}
* <hr>
*/
export interface NS extends Singularity {
/**
@ -3906,7 +3946,7 @@ export interface NS extends Singularity {
* ```ts
* //For example, assume the following returns 0.01:
* hackAnalyze("foodnstuff");
* //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N*0.01% of its total money.
* //This means that if hack the foodnstuff server, then you will steal 1% of its total money. If you hack using N threads, then you will steal N*0.01 times its total money.
* ```
* @param host - Hostname of the target server.
* @returns The percentage of money you will steal from the target server with a single hack.
@ -4584,7 +4624,7 @@ export interface NS extends Singularity {
* RAM cost: 0.1 GB
*
* Returns the servers instrinsic growth parameter. This growth
* parameter is a number between 1 and 100 that represents how
* parameter is a number between 0 and 100 that represents how
* quickly the servers money grows. This parameter affects the
* percentage by which the servers money is increased when using the
* grow function. A higher growth parameter will result in a

@ -178,7 +178,7 @@ export const defaultSettings: IDefaultSettings = {
Locale: "en",
MaxLogCapacity: 50,
MaxPortCapacity: 50,
MaxTerminalCapacity: 200,
MaxTerminalCapacity: 500,
SaveGameOnFileSave: true,
SuppressBuyAugmentationConfirmation: false,
SuppressFactionInvites: false,

@ -169,6 +169,45 @@ export function getAllParentDirectories(path: string): string {
return t_path.slice(0, lastSlash + 1);
}
/**
* Given a destination that only contains a directory part, returns the
* path to the source filename inside the new destination directory.
* Otherwise, returns the path to the destination file.
* @param destination The destination path or file name
* @param source The source path
* @param cwd The current working directory
* @returns A file path which may be absolute or relative
*/
export function getDestinationFilepath(destination: string, source: string, cwd: string) {
const dstDir = evaluateDirectoryPath(destination, cwd);
// If evaluating the directory for this destination fails, we have a filename or full path.
if (dstDir === null) {
return destination;
} else {
// Append the filename to the directory provided.
let t_path = removeTrailingSlash(dstDir);
const fileName = getFileName(source);
return t_path + "/" + fileName;
}
}
/**
* Given a filepath, returns the file name (e.g. without directory parts)
* For example:
* /home/var/test.js -> test.js
* ./var/test.js -> test.js
* test.js -> test.js
*/
export function getFileName(path: string): string {
const t_path = path;
const lastSlash = t_path.lastIndexOf("/");
if (lastSlash === -1) {
return t_path;
}
return t_path.slice(lastSlash + 1);
}
/**
* Checks if a file path refers to a file in the root directory.
*/

@ -254,9 +254,8 @@ export class Terminal implements ITerminal {
const expGain = calculateHackingExpGain(server, player);
server.weaken(CONSTANTS.ServerWeakenAmount);
this.print(
`'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(
expGain,
)} hacking exp.`,
`'${server.hostname}' security level weakened to ${server.hackDifficulty.toFixed(3)} ` +
`and Gained ${numeralWrapper.formatExp(expGain)} hacking exp.`,
);
}

@ -3,6 +3,7 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import { isScriptFilename } from "../../Script/isScriptFilename";
import { getDestinationFilepath, areFilesEqual } from "../DirectoryHelpers";
export function cp(
terminal: ITerminal,
@ -16,9 +17,23 @@ export function cp(
terminal.error("Incorrect usage of cp command. Usage: cp [src] [dst]");
return;
}
const src = args[0] + "";
const dst = args[1] + "";
if (src === dst) {
// Convert a relative path source file to the absolute path.
const src = terminal.getFilepath(args[0] + "");
if (src === null) {
terminal.error("src cannot be a directory");
return;
}
// Get the destination based on the source file and the current directory
const t_dst = getDestinationFilepath(args[1] + "", src, terminal.cwd());
if (t_dst === null) {
terminal.error("error parsing dst file");
return;
}
// Convert a relative path destination file to the absolute path.
const dst = terminal.getFilepath(t_dst);
if (areFilesEqual(src, dst)) {
terminal.error("src and dst cannot be the same");
return;
}
@ -50,7 +65,7 @@ export function cp(
const tRes = server.writeToTextFile(dst, txtFile.text);
if (!tRes.success) {
terminal.error("scp failed");
terminal.error("cp failed");
return;
}
if (tRes.overwritten) {
@ -71,13 +86,13 @@ export function cp(
}
}
if (sourceScript == null) {
terminal.error("cp() failed. No such script exists");
terminal.error("cp failed. No such script exists");
return;
}
const sRes = server.writeToScriptFile(dst, sourceScript.code);
if (!sRes.success) {
terminal.error(`scp failed`);
terminal.error(`cp failed`);
return;
}
if (sRes.overwritten) {

@ -5,6 +5,7 @@ import { BaseServer } from "../../Server/BaseServer";
import { isScriptFilename } from "../../Script/isScriptFilename";
import { TextFile } from "../../TextFile";
import { Script } from "../../Script/Script";
import { getDestinationFilepath, areFilesEqual } from "../DirectoryHelpers";
export function mv(
terminal: ITerminal,
@ -20,7 +21,7 @@ export function mv(
try {
const source = args[0] + "";
const dest = args[1] + "";
const t_dest = args[1] + "";
if (!isScriptFilename(source) && !source.endsWith(".txt")) {
terminal.error(`'mv' can only be used on scripts and text files (.txt)`);
@ -34,9 +35,19 @@ export function mv(
}
const sourcePath = terminal.getFilepath(source);
const destPath = terminal.getFilepath(dest);
// Get the destination based on the source file and the current directory
const dest = getDestinationFilepath(t_dest, source, terminal.cwd());
if (dest === null) {
terminal.error("error parsing dst file");
return;
}
const destFile = terminal.getFile(player, dest);
const destPath = terminal.getFilepath(dest);
if (areFilesEqual(sourcePath, destPath)) {
terminal.error(`Source and destination files are the same file`);
return;
}
// 'mv' command only works on scripts and txt files.
// Also, you can't convert between different file types
@ -55,7 +66,7 @@ export function mv(
if (destFile != null) {
// Already exists, will be overwritten, so we'll delete it
const status = server.removeFile(destPath);
const status = server.removeFile(dest);
if (!status.res) {
terminal.error(`Something went wrong...please contact game dev (probably a bug)`);
return;

@ -20,7 +20,11 @@ export function runProgram(
const programName = args[0] + "";
if (!player.hasProgram(programName)) {
terminal.error("No such executable on home computer (Only programs that exist on your home computer can be run)");
terminal.error(
`No such (exe, script, js, ns, or cct) file! (Only programs that exist on your home computer or scripts on ${
player.getCurrentServer().hostname
} can be run)`,
);
return;
}

@ -14,7 +14,7 @@ export function scp(
): void {
try {
if (args.length !== 2) {
terminal.error("Incorrect usage of scp command. Usage: scp [file] [destination hostname/ip]");
terminal.error("Incorrect usage of scp command. Usage: scp [file] [destination hostname]");
return;
}
const scriptname = terminal.getFilepath(args[0] + "");

@ -41,7 +41,7 @@ export function ScriptProduction(): React.ReactElement {
<TableBody>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
<Typography variant="body2">Total production:</Typography>
<Typography variant="body2">Total production since last Augment Installation:</Typography>
</TableCell>
<TableCell align="left" classes={{ root: classes.cell }}>
<Typography variant="body2">

@ -443,8 +443,11 @@ export function InteractiveTutorialRoot(): React.ReactElement {
<Typography color={"primary"}>Tutorial</Typography>
</ListItem>
<Typography>
in the main navigation menu to look at the documentation. If you are an experienced JavaScript developer, I
would highly suggest you check out the section on NetscriptJS/Netscript 2.0, it's faster and more powerful.
in the main navigation menu to look at the documentation.
<br />
<br />
If you know even a little bit of programming it is highly recommended you use NS2 instead. You will enjoy
the game much more.
<br />
<br />
For now, let's move on to something else!