Merge branch 'dev' into mychanges

This commit is contained in:
hydroflame 2021-12-22 16:16:24 -05:00 committed by GitHub
commit bfdfee2a68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 933 additions and 179 deletions

@ -1,4 +1,3 @@
# This is a basic workflow to help you get started with Actions
name: CI
on:
@ -13,39 +12,44 @@ on:
jobs:
build:
# The type of runner that the job will run on
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.13.1]
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- uses: actions/checkout@v2
- run: echo "The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install npm dependencies
run: npm ci
- name: Run unit tests
run: npm run test
- name: Run linter
run: npm run lint:report
- name: Build the web app
run: npm run build
# Cannot build the electron app by default using ubuntu
# Wrapper command 'wine64' not found on the system. Consult your Linux distribution's package manager to determine how to install Wine.
# - name: Build the electron app
# run: ./package.sh
# Unable to properly run the cypress tests for now, they are throwing errors.
# - name: Run the integration tests
# run: npm run cy:test
- uses: actions/checkout@v2
- name: Use Node.js 16.13.1
uses: actions/setup-node@v2
with:
node-version: 16.13.1
cache: 'npm'
- name: Install npm dependencies
run: npm ci
- name: Build the production app
run: npm run build
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 16.13.1
uses: actions/setup-node@v2
with:
node-version: 16.13.1
cache: 'npm'
- name: Install npm dependencies
run: npm ci
- name: Run linter
run: npm run lint:report
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 16.13.1
uses: actions/setup-node@v2
with:
node-version: 16.13.1
cache: 'npm'
- name: Install npm dependencies
run: npm ci
- name: Run linter
run: npm run test

@ -1,11 +1,21 @@
/* eslint-disable no-process-exit */
/* eslint-disable @typescript-eslint/no-var-requires */
const { app, BrowserWindow, Menu, shell } = require("electron");
const { app, BrowserWindow, Menu, shell, dialog } = require("electron");
const log = require('electron-log');
const greenworks = require("./greenworks");
log.catchErrors();
log.info(`Started app: ${JSON.stringify(process.argv)}`);
process.on('uncaughtException', function () {
// The exception will already have been logged by electron-log
process.exit(1);
});
if (greenworks.init()) {
console.log("Steam API has been initialized.");
log.info("Steam API has been initialized.");
} else {
console.log("Steam API has failed to initialize.");
log.warn("Steam API has failed to initialize.");
}
const debug = false;
@ -66,6 +76,37 @@ function createWindow(killall) {
}, 1000);
win.achievementsIntervalID = intervalID;
const reloadAndKill = (killScripts = true) => {
log.info('Reloading & Killing all scripts...');
setStopProcessHandler(app, win, false);
if (intervalID) clearInterval(intervalID);
win.webContents.forcefullyCrashRenderer();
win.close();
createWindow(killScripts);
};
const promptForReload = () => {
win.off('unresponsive', promptForReload);
dialog.showMessageBox({
type: 'error',
title: 'Bitburner > Application Unresponsive',
message: 'The application is unresponsive, possibly due to an infinite loop in your scripts.',
detail:' Did you forget a ns.sleep(x)?\n\n' +
'The application will be restarted for you, do you want to kill all running scripts?',
buttons: ['Restart', 'Cancel'],
defaultId: 0,
checkboxLabel: 'Kill all running scripts',
checkboxChecked: true,
noLink: true,
}).then(({response, checkboxChecked}) => {
if (response === 0) {
reloadAndKill(checkboxChecked);
} else {
win.on('unresponsive', promptForReload)
}
});
}
win.on('unresponsive', promptForReload);
// Create the Application's main menu
Menu.setApplicationMenu(
Menu.buildFromTemplate([
@ -93,13 +134,7 @@ function createWindow(killall) {
},
{
label: "reload & kill all scripts",
click: () => {
setStopProcessHandler(app, win, false);
if (intervalID) clearInterval(intervalID);
win.webContents.forcefullyCrashRenderer();
win.close();
createWindow(true);
},
click: reloadAndKill
},
],
},
@ -143,6 +178,7 @@ function setStopProcessHandler(app, window, enabled) {
};
const stopProcessHandler = () => {
log.info('Quitting the app...');
app.isQuiting = true;
app.quit();
// eslint-disable-next-line no-process-exit
@ -159,6 +195,7 @@ function setStopProcessHandler(app, window, enabled) {
}
app.whenReady().then(() => {
log.info('Application is ready!');
const win = createWindow(process.argv.includes("--no-scripts"));
setStopProcessHandler(app, win, true);
});

14
package-lock.json generated

@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
"name": "bitburner",
"version": "1.2.0",
"hasInstallScript": true,
"license": "SEE LICENSE IN license.txt",
@ -62,6 +63,7 @@
"babel-loader": "^8.0.5",
"cypress": "^8.3.1",
"electron": "^14.0.2",
"electron-log": "^4.4.3",
"electron-packager": "^15.4.0",
"eslint": "^7.24.0",
"fork-ts-checker-webpack-plugin": "^6.3.3",
@ -7629,6 +7631,12 @@
"node": ">= 8.6"
}
},
"node_modules/electron-log": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.3.tgz",
"integrity": "sha512-IWxkiVLSpbI4if61kTSLMErYwz+Jq/gnHeTtQ8jcAjtlU8rgTIScWBgZJxk3fVnyvW6M+Ci3Bn9ogHgjgDSvNg==",
"dev": true
},
"node_modules/electron-notarize": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.1.1.tgz",
@ -27696,6 +27704,12 @@
}
}
},
"electron-log": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.3.tgz",
"integrity": "sha512-IWxkiVLSpbI4if61kTSLMErYwz+Jq/gnHeTtQ8jcAjtlU8rgTIScWBgZJxk3fVnyvW6M+Ci3Bn9ogHgjgDSvNg==",
"dev": true
},
"electron-notarize": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.1.1.tgz",

@ -64,6 +64,7 @@
"babel-loader": "^8.0.5",
"cypress": "^8.3.1",
"electron": "^14.0.2",
"electron-log": "^4.4.3",
"electron-packager": "^15.4.0",
"eslint": "^7.24.0",
"fork-ts-checker-webpack-plugin": "^6.3.3",
@ -112,8 +113,8 @@
"test:watch": "jest --watch",
"watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development",
"package-electron": "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",
"electron": "sh ./package.sh",
"electron:packager": "electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png --no-prune",
"allbuild": "npm run build && npm run electron && git add --all && git commit --amend --no-edit && git push -f -u origin dev"
}
}

@ -1,11 +1,13 @@
# npm install electron --save-dev
# npm install electron-packager --save-dev
#!/bin/sh
mkdir -p .package/dist/src/ThirdParty || true
mkdir -p .package/src/ThirdParty || true
mkdir -p .package/node_modules || true
cp index.html .package
cp electron/* .package
cp -r electron/* .package
cp -r dist/ext .package/dist
# The css files
cp dist/vendor.css .package/dist
cp main.css .package/main.css
@ -14,6 +16,7 @@ cp main.css .package/main.css
cp dist/vendor.bundle.js .package/dist/vendor.bundle.js
cp main.bundle.js .package/main.bundle.js
cp src/ThirdParty/raphael.min.js .package/src/ThirdParty/raphael.min.js
# Adding electron-log dependency
cp -r node_modules/electron-log .package/node_modules/electron-log
npm run package-electron
npm run electron:packager

@ -6,7 +6,6 @@ import { Terminal } from "../Terminal";
import { SpecialServers } from "../Server/data/SpecialServers";
import { Money } from "../ui/React/Money";
import { DarkWebItem } from "./DarkWebItem";
import Typography from "@mui/material/Typography";
//Posts a "help" message if connected to DarkWeb
export function checkIfConnectedToDarkweb(): void {
@ -31,9 +30,9 @@ export function listAllDarkwebItems(): void {
);
Terminal.printRaw(
<Typography>
<>
<span>{item.program}</span> - <span>{cost}</span> - <span>{item.description}</span>
</Typography>,
</>,
);
}
}

@ -71,6 +71,20 @@ export function Servers(): React.ReactElement {
}
}
function minMoney(): void {
const s = GetServer(server);
if (s === null) return;
if (!(s instanceof Server)) return;
s.moneyAvailable = 0;
}
function minAllMoney(): void {
for (const s of GetAllServers()) {
if (!(s instanceof Server)) return;
s.moneyAvailable = 0;
}
}
return (
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
@ -119,6 +133,12 @@ export function Servers(): React.ReactElement {
<td>
<Typography>Money:</Typography>
</td>
<td>
<Button onClick={minMoney}>Min one</Button>
</td>
<td>
<Button onClick={minAllMoney}>Min all</Button>
</td>
<td>
<Button onClick={maxMoney}>Max one</Button>
</td>

@ -509,6 +509,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
if (hackAmount < 0 || hackAmount > server.moneyAvailable) {
return -1;
} else if (hackAmount === 0) {
return 0;
}
const percentHacked = calculatePercentMoneyHacked(server, Player);

@ -819,7 +819,7 @@ export function NetscriptSingularity(
return player.getUpgradeHomeRamCost();
},
workForCompany: function (companyName: any, focus: boolean = true): any {
workForCompany: function (companyName: any, focus = true): any {
helper.updateDynamicRam("workForCompany", getRamCost("workForCompany"));
helper.checkSingularityAccess("workForCompany", 2);
@ -991,7 +991,7 @@ export function NetscriptSingularity(
workerScript.log("joinFaction", () => `Joined the '${name}' faction.`);
return true;
},
workForFaction: function (name: any, type: any, focus: boolean = true): any {
workForFaction: function (name: any, type: any, focus = true): any {
helper.updateDynamicRam("workForFaction", getRamCost("workForFaction"));
helper.checkSingularityAccess("workForFaction", 2);
getFaction("workForFaction", name);

@ -34,6 +34,7 @@ import { parse } from "acorn";
import { simple as walksimple } from "acorn-walk";
import { areFilesEqual } from "./Terminal/DirectoryHelpers";
import { Player } from "./Player";
import { Terminal } from "./Terminal";
// Netscript Ports are instantiated here
export const NetscriptPorts: IPort[] = [];
@ -609,6 +610,7 @@ export function updateOnlineScriptTimes(numCycles = 1): void {
export function loadAllRunningScripts(): void {
const skipScriptLoad = window.location.href.toLowerCase().indexOf("?noscripts") !== -1;
if (skipScriptLoad) {
Terminal.warn('Skipped loading player scripts during startup');
console.info("Skipping the load of any scripts during startup");
}
for (const server of GetAllServers()) {

@ -952,7 +952,13 @@ export interface TIX {
*
* @example
* ```ts
* getPrice("FISG");
* // NS1
* stock.getPrice("FISG");
* ```
* @example
* ```ts
* // NS2
* ns.stock.getPrice("FISG");
* ```
* @param sym - Stock symbol.
* @returns The price of a stock.
@ -995,11 +1001,17 @@ export interface TIX {
*
* @example
* ```ts
* pos = getPosition("ECP");
* shares = pos[0];
* avgPx = pos[1];
* sharesShort = pos[2];
* avgPxShort = pos[3];
* // NS1
* var pos = stock.getPosition("ECP");
* var shares = pos[0];
* var avgPx = pos[1];
* var sharesShort = pos[2];
* var avgPxShort = pos[3];
* ```
* @example
* ```ts
* // NS2
* const [shares, avgPx, sharesShort, avgPxShort] = ns.stock.getPosition("ECP");
* ```
* @param sym - Stock symbol.
* @returns Array of four elements that represents the players position in a stock.
@ -1369,8 +1381,14 @@ export interface Singularity {
*
* @example
* ```ts
* // NS1
* purchaseProgram("brutessh.exe");
* ```
* @example
* ```ts
* // NS2
* ns.purchaseProgram("brutessh.exe");
* ```
* @param programName - Name of program to purchase.
* @returns True if the specified program is purchased, and false otherwise.
*/
@ -1485,6 +1503,7 @@ export interface Singularity {
*
* @example
* ```ts
* // NS1:
* //If you only want to work until you get 100,000 company reputation. One small hack to get around this is to continuously restart the action to receive your earnings:
* while (getCompanyRep(COMPANY HERE) < VALUE) {
* workForCompany();
@ -1492,6 +1511,16 @@ export interface Singularity {
* }
* //This way, your company reputation will be updated every minute.
* ```
* @example
* ```ts
* // NS2:
* //If you only want to work until you get 100,000 company reputation. One small hack to get around this is to continuously restart the action to receive your earnings:
* while (ns.getCompanyRep(COMPANY HERE) < VALUE) {
* ns.workForCompany();
* await ns.sleep(60000);
* }
* //This way, your company reputation will be updated every minute.
* ```
* @param companyName - Name of company to work for. Must be an exact match. Optional. If not specified, this argument defaults to the last job that you worked
* @param focus - Acquire player focus on this work operation. Optional. Defaults to true.
* @returns True if the player starts working, and false otherwise.
@ -1604,6 +1633,7 @@ export interface Singularity {
*
* @example
* ```ts
* // NS1:
* //If you only want to work until you get 100,000 faction reputation. One small hack to get around this is to continuously restart the action to receive your earnings:
* while (getFactionRep(FACTION NAME) < VALUE) {
* workForFaction(FACNAME, WORKTYPE);
@ -1611,6 +1641,16 @@ export interface Singularity {
* }
* //This way, your faction reputation will be updated every minute.
* ```
* @example
* ```ts
* // NS2:
* //If you only want to work until you get 100,000 faction reputation. One small hack to get around this is to continuously restart the action to receive your earnings:
* while (ns.getFactionRep(FACTION NAME) < VALUE) {
* ns.workForFaction(FACNAME, WORKTYPE);
* await ns.sleep(60000);
* }
* //This way, your faction reputation will be updated every minute.
* ```
* @param faction - Name of faction to work for.
* @param workType - Type of work to perform for the faction.
* @param focus - Acquire player focus on this work operation. Optional. Defaults to true.
@ -1700,8 +1740,14 @@ export interface Singularity {
*
* @example
* ```ts
* // NS1:
* createProgram(relaysmtp.exe);
* ```
* @example
* ```ts
* // NS2:
* ns.createProgram(relaysmtp.exe);
* ```
* @param program - Name of program to create.
* @returns True if you successfully start working on the specified program, and false otherwise.
*/
@ -1719,9 +1765,9 @@ export interface Singularity {
* function will automatically cancel that action and give you your
* earnings.
*
* This function returns the number of seconds it takes to attempt the specified
* crime (e.g It takes 60 seconds to attempt the Rob Store crime, so running
* `commitCrime('rob store')` will return 60).
* This function returns the number of milliseconds it takes to attempt the
* specified crime (e.g It takes 60 seconds to attempt the Rob Store crime,
* so running `commitCrime('rob store')` will return 60000).
*
* Warning: I do not recommend using the time returned from this function to try
* and schedule your crime attempts. Instead, I would use the isBusy Singularity
@ -2259,11 +2305,20 @@ export interface Hacknet {
*
* @example
* ```ts
* // NS1:
* var upgradeName = "Sell for Corporation Funds";
* if (hacknet.numHashes() > hacknet.hashCost(upgradeName)) {
* hacknet.spendHashes(upgName);
* }
* ```
* @example
* ```ts
* // NS2:
* const upgradeName = "Sell for Corporation Funds";
* if (ns.hacknet.numHashes() > ns.hacknet.hashCost(upgradeName)) {
* ns.hacknet.spendHashes(upgName);
* }
* ```
* @param upgName - Name of the upgrade of Hacknet Node.
* @returns Number of hashes required for the specified upgrade.
*/
@ -2285,9 +2340,16 @@ export interface Hacknet {
*
* @example
* ```ts
* // NS1:
* hacknet.spendHashes("Sell for Corporation Funds");
* hacknet.spendHashes("Increase Maximum Money", "foodnstuff");
* ```
* @example
* ```ts
* NS2:
* ns.hacknet.spendHashes("Sell for Corporation Funds");
* ns.hacknet.spendHashes("Increase Maximum Money", "foodnstuff");
* ```
* @param upgName - Name of the upgrade of Hacknet Node.
* @param upgTarget - Object to which upgrade applies. Required for certain upgrades.
* @returns True if the upgrade is successfully purchased, and false otherwise..
@ -2304,7 +2366,13 @@ export interface Hacknet {
* Returns the list of all available hash upgrades that can be used in the spendHashes function.
* @example
* ```ts
* const upgrades = hacknet.getHashUpgrades(); // ["Sell for Money","Sell for Corporation Funds",...]
* // NS1:
* var upgrades = hacknet.getHashUpgrades(); // ["Sell for Money","Sell for Corporation Funds",...]
* ```
* @example
* ```ts
* // NS2:
* const upgrades = ns.hacknet.getHashUpgrades(); // ["Sell for Money","Sell for Corporation Funds",...]
* ```
* @returns An array containing the available upgrades
*/
@ -2756,11 +2824,20 @@ export interface Bladeburner {
* * [Current stamina, Max stamina]
* @example
* ```ts
* // NS1:
* function getStaminaPercentage() {
* let res = bladeburner.getStamina();
* var res = bladeburner.getStamina();
* return res[0] / res[1];
* }
* ```
* @example
* ```ts
* // NS2:
* function getStaminaPercentage() {
* const [current, max] = ns.bladeburner.getStamina();
* return current / max;
* }
* ```
* @returns Array containing current stamina and max stamina.
*/
getStamina(): [number, number];
@ -3867,7 +3944,7 @@ export interface NS extends Singularity {
*
* Function that is used to try and hack servers to steal money and gain hacking experience.
* The runtime for this command depends on your hacking level and the target servers
* security level. In order to hack a server you must first gain root access to that server
* security level when this function is called. In order to hack a server you must first gain root access to that server
* and also have the required hacking level.
*
* A script can hack a server from anywhere. It does not need to be running on the same
@ -3878,8 +3955,15 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* hack("foodnstuff");
* hack("foodnstuff", { threads: 5 }); // Only use 5 threads to hack
* // NS1:
* var earnedMoney = hack("foodnstuff");
* earnedMoney = earnedMoney + hack("foodnstuff", { threads: 5 }); // Only use 5 threads to hack
* ```
* @example
* ```ts
* // NS2:
* let earnedMoney = await ns.hack("foodnstuff");
* earnedMoney += await ns.hack("foodnstuff", { threads: 5 }); // Only use 5 threads to hack
* ```
* @param host - Hostname of the target server to hack.
* @param opts - Optional parameters for configuring function behavior.
@ -3906,8 +3990,17 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* grow("foodnstuff");
* grow("foodnstuff", { threads: 5 }); // Only use 5 threads to grow
* // NS1:
* var availableMoney = getServerMoneyAvailable("foodnstuff");
* currentMoney = currentMoney * (1 + grow("foodnstuff"));
* currentMoney = currentMoney * (1 + grow("foodnstuff", { threads: 5 })); // Only use 5 threads to grow
* ```
* @example
* ```ts
* // NS2:
* let availableMoney = ns.getServerMoneyAvailable("foodnstuff");
* currentMoney *= (1 + await ns.grow("foodnstuff"));
* currentMoney *= (1 + await ns.grow("foodnstuff", { threads: 5 })); // Only use 5 threads to grow
* ```
* @param host - Hostname of the target server to grow.
* @param opts - Optional parameters for configuring function behavior.
@ -3922,7 +4015,7 @@ export interface NS extends Singularity {
*
* Use your hacking skills to attack a servers security, lowering the servers security level.
* The runtime for this command depends on your hacking level and the target servers security
* level. This function lowers the security level of the target server by 0.05.
* level when this function is called. This function lowers the security level of the target server by 0.05.
*
* Like hack and grow, `weaken` can be called on any server, regardless of
* where the script is running. This command requires root access to the target server, but
@ -3930,8 +4023,17 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* weaken("foodnstuff");
* weaken("foodnstuff", { threads: 5 }); // Only use 5 threads to weaken
* // NS1:
* var currentSecurity = getServerSecurityLevel("foodnstuff");
* currentSecurity = currentSecurity - weaken("foodnstuff");
* currentSecurity = currentSecurity - weaken("foodnstuff", { threads: 5 }); // Only use 5 threads to weaken
* ```
* @example
* ```ts
* // NS2:
* let currentSecurity = ns.getServerSecurityLevel("foodnstuff");
* currentSecurity -= await ns.weaken("foodnstuff");
* currentSecurity -= await ns.weaken("foodnstuff", { threads: 5 }); // Only use 5 threads to weaken
* ```
* @param host - Hostname of the target server to weaken.
* @param opts - Optional parameters for configuring function behavior.
@ -3984,11 +4086,20 @@ export interface NS extends Singularity {
* 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).
* This percentage is influenced by the player's hacking skill.
*
* @example
* ```ts
* // NS1:
* //For example, assume the following returns 0.01:
* hackAnalyze("foodnstuff");
* var hackAmount = 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 times its total money.
* ```
* @example
* ```ts
* // NS2:
* //For example, assume the following returns 0.01:
* const hackAmount = ns.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 times its total money.
* ```
* @param host - Hostname of the target server.
@ -4035,8 +4146,16 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //For example, if you want to determine how many grow calls you need to double the amount of money on foodnstuff, you would use:
* growthAnalyze("foodnstuff", 2);
* var growTimes = growthAnalyze("foodnstuff", 2);
* //If this returns 100, then this means you need to call grow 100 times in order to double the money (or once with 100 threads).
* ```
* @example
* ```ts
* // NS2:
* //For example, if you want to determine how many grow calls you need to double the amount of money on foodnstuff, you would use:
* const growTimes = ns.growthAnalyze("foodnstuff", 2);
* //If this returns 100, then this means you need to call grow 100 times in order to double the money (or once with 100 threads).
* ```
* @param host - Hostname of the target server.
@ -4063,6 +4182,24 @@ export interface NS extends Singularity {
* RAM cost: 0 GB
*
* @param millis - Number of milliseconds to sleep.
* @example
* ```ts
* // NS1:
* // This will count from 1 to 10 in your terminal, with one number every 5 seconds
* for (var i=0; i<10; i++) {
* tprint(i + 1);
* sleep(5000);
* }
* ```
* @example
* ```ts
* // NS2:
* // This will count from 1 to 10 in your terminal, with one number every 5 seconds
* for (var i=0; i<10; i++) {
* ns.tprint(i + 1);
* await ns.sleep(5000);
* }
* ```
* @returns
*/
sleep(millis: number): Promise<void>;
@ -4164,18 +4301,27 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //Get logs from foo.script on the current server that was run with no args
* getScriptLogs("foo.script");
* ```
* @example
* ```ts
*
* //Open logs from foo.script on the foodnstuff server that was run with no args
* getScriptLogs("foo.script", "foodnstuff");
*
* //Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* getScriptLogs("foo.script", "foodnstuff", 1, "test");
* ```
* @example
* ```ts
* // NS2:
* //Get logs from foo.script on the current server that was run with no args
* ns.getScriptLogs("foo.script");
*
* //Open logs from foo.script on the foodnstuff server that was run with no args
* ns.getScriptLogs("foo.script", "foodnstuff");
*
* //Open logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* getScriptLogs("foo.script", "foodnstuff", 1, "test");
* ns.getScriptLogs("foo.script", "foodnstuff", 1, "test");
* ```
* @param fn - Optional. Filename of script to get logs from.
* @param host - Optional. Hostname of the server that the script is on.
@ -4198,18 +4344,27 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //Open logs from foo.script on the current server that was run with no args
* tail("foo.script");
* ```
* @example
* ```ts
*
* //Get logs from foo.script on the foodnstuff server that was run with no args
* tail("foo.script", "foodnstuff");
*
* //Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* tail("foo.script", "foodnstuff", 1, "test");
* ```
* @example
* ```ts
* // NS2:
* //Open logs from foo.script on the current server that was run with no args
* ns.tail("foo.script");
*
* //Get logs from foo.script on the foodnstuff server that was run with no args
* ns.tail("foo.script", "foodnstuff");
*
* //Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
* tail("foo.script", "foodnstuff", 1, "test");
* ns.tail("foo.script", "foodnstuff", 1, "test");
* ```
* @param fn - Optional. Filename of the script being tailed. If omitted, the current script is tailed.
* @param host - Optional. Hostname of the script being tailed. Defaults to the server this script is running on. If args are specified, this is not optional.
@ -4240,8 +4395,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* nuke("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.nuke("foodnstuff");
* ```
* @param host - Hostname of the target server.
*/
nuke(host: string): void;
@ -4255,8 +4416,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* brutessh("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.brutessh("foodnstuff");
* ```
* @param host - Hostname of the target server.
*/
brutessh(host: string): void;
@ -4270,8 +4437,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* ftpcrack("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.ftpcrack("foodnstuff");
* ```
* @param host - Hostname of the target server.
*/
ftpcrack(host: string): void;
@ -4285,8 +4458,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* relaysmtp("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.relaysmtp("foodnstuff");
* ```
* @param host - Hostname of the target server.
*/
relaysmtp(host: string): void;
@ -4300,8 +4479,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* httpworm("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.httpworm("foodnstuff");
* ```
* @param host - Hostname of the target server.
*/
httpworm(host: string): void;
@ -4315,8 +4500,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* sqlinject("foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* ns.sqlinject("foodnstuff");
* ```
* @remarks RAM cost: 0.05 GB
* @param host - Hostname of the target server.
*/
@ -4342,18 +4533,27 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
* run("foo.script");
* ```
* @example
* ```ts
*
* //The following example will run foo.script but with 5 threads instead of single-threaded:
* run("foo.script", 5);
*
* //This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
* run("foo.script", 1, 'foodnstuff');
* ```
* @example
* ```ts
* // NS2:
* //The simplest way to use the run command is to call it with just the script name. The following example will run foo.script single-threaded with no arguments:
* ns.run("foo.script");
*
* //The following example will run foo.script but with 5 threads instead of single-threaded:
* ns.run("foo.script", 5);
*
* //This next example will run foo.script single-threaded, and will pass the string foodnstuff into the script as an argument:
* run("foo.script", 1, 'foodnstuff');
* ns.run("foo.script", 1, 'foodnstuff');
* ```
* @param script - Filename of script to run.
* @param numThreads - Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer.
@ -4381,19 +4581,28 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The simplest way to use the exec command is to call it with just the script name and the target server. The following example will try to run generic-hack.script on the foodnstuff server:
* exec("generic-hack.script", "foodnstuff");
* ```
* @example
* ```ts
*
* //The following example will try to run the script generic-hack.script on the joesguns server with 10 threads:
* exec("generic-hack.script", "joesguns", 10);
* ```
* @example
* ```ts
*
* //This last example will try to run the script foo.script on the foodnstuff server with 5 threads. It will also pass the number 1 and the string “test” in as arguments to the script:
* exec("foo.script", "foodnstuff", 5, 1, "test");
* ```
* * @example
* ```ts
* // NS2:
* //The simplest way to use the exec command is to call it with just the script name and the target server. The following example will try to run generic-hack.script on the foodnstuff server:
* ns.exec("generic-hack.script", "foodnstuff");
*
* //The following example will try to run the script generic-hack.script on the joesguns server with 10 threads:
* ns.exec("generic-hack.script", "joesguns", 10);
*
* //This last example will try to run the script foo.script on the foodnstuff server with 5 threads. It will also pass the number 1 and the string “test” in as arguments to the script:
* ns.exec("foo.script", "foodnstuff", 5, 1, "test");
* ```
* @param script - Filename of script to execute.
* @param host - Hostname of the `target server` on which to execute the script.
* @param numThreads - Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer.
@ -4416,9 +4625,16 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
* spawn('foo.script', 10, 'foodnstuff', 90);
* ```
* @example
* ```ts
* // NS2:
* //The following example will execute the script foo.script with 10 threads and the arguments foodnstuff and 90:
* ns.spawn('foo.script', 10, 'foodnstuff', 90);
* ```
* @param script - Filename of script to execute.
* @param numThreads - Number of threads to spawn new script with. Will be rounded to nearest integer.
* @param args - Additional arguments to pass into the new script that is being run.
@ -4437,18 +4653,27 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The following example will try to kill a script named foo.script on the foodnstuff server that was ran with no arguments:
* kill("foo.script", "foodnstuff");
* ```
* @example
* ```ts
*
* //The following will try to kill a script named foo.script on the current server that was ran with no arguments:
* kill("foo.script", getHostname());
*
* //The following will try to kill a script named foo.script on the current server that was ran with the arguments 1 and “foodnstuff”:
* kill("foo.script", getHostname(), 1, "foodnstuff");
* ```
* @example
* ```ts
* // NS2:
* //The following example will try to kill a script named foo.script on the foodnstuff server that was ran with no arguments:
* ns.kill("foo.script", "foodnstuff");
*
* //The following will try to kill a script named foo.script on the current server that was ran with no arguments:
* ns.kill("foo.script", getHostname());
*
* //The following will try to kill a script named foo.script on the current server that was ran with the arguments 1 and “foodnstuff”:
* kill("foo.script", getHostname(), 1, "foodnstuff");
* ns.kill("foo.script", getHostname(), 1, "foodnstuff");
* ```
* @param script - Filename or pid of the script to kill
* @param host - Hostname of the server on which to kill the script.
@ -4488,15 +4713,31 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //Copies foo.lit from the helios server to the home computer:
* scp("foo.lit", "helios", "home");
* ```
* @example
* ```ts
*
* //Tries to copy three files from rothman-uni to home computer:
* files = ["foo1.lit", "foo2.script", "foo3.script"];
* scp(files, "rothman-uni", "home");
* ```
* @example
* ```ts
* // NS2:
* //Copies foo.lit from the helios server to the home computer:
* await ns.scp("foo.lit", "helios", "home");
*
* //Tries to copy three files from rothman-uni to home computer:
* files = ["foo1.lit", "foo2.script", "foo3.script"];
* await ns.scp(files, "rothman-uni", "home");
* ```
* @example
* ```ts
* //ns2, copies files from home to a target server
* const server = ns.args[0];
* const files = ["hack.js","weaken.js","grow.js"];
* await ns.scp(files, "home", server);
* ```
* @param files - Filename or an array of filenames of script/literature files to copy.
* @param source - Host of the source server, which is the server from which the file will be copied. This argument is optional and if its omitted the source will be the current server.
* @param destination - Host of the destination server, which is the server to which the file will be copied.
@ -4527,13 +4768,20 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* //(using NetscriptJS (Netscript 2.0))
* export async function main(ns) {
* const ps = ns.ps("home");
* for (let i = 0; i < ps.length; ++i) {
* ns.tprint(ps[i].filename + ' ' + ps[i].threads);
* ns.tprint(ps[i].args);
* }
* // NS1:
* const scripts = ps("home");
* for (let i = 0; i < scripts.length; ++i) {
* tprint(scripts[i].filename + ' ' + scripts[i].threads);
* tprint(scripts[i].args);
* }
* ```
* @example
* ```ts
* // NS2:
* const ps = ns.ps("home");
* for (script of ps) {
* ns.tprint(`${script.filename} ${ps[i].threads}`);
* ns.tprint(script.args);
* }
* ```
* @param host - Host address of the target server. If not specified, it will be the current servers IP by default.
@ -4550,10 +4798,18 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* if (hasRootAccess("foodnstuff") == false) {
* nuke("foodnstuff");
* }
* ```
* @example
* ```ts
* // NS2:
* if (ns.hasRootAccess("foodnstuff") == false) {
* ns.nuke("foodnstuff");
* }
* ```
* @param host - Host of the target server
* @returns True if player has root access to the specified target server, and false otherwise.
*/
@ -4588,11 +4844,20 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* //Example of how this can be used:
* mults = getHackingMultipliers();
* // NS1:
* // Example of how this can be used:
* var mults = getHackingMultipliers();
* print(mults.chance);
* print(mults.growth);
* ```
* @example
* ```ts
* // NS2:
* // Example of how this can be used:
* const {chance, growth} = ns.getHackingMultipliers();
* print(chance);
* print(growth);
* ```
* @returns Object containing the Players hacking related multipliers.
*/
getHackingMultipliers(): HackingMultipliers;
@ -4608,11 +4873,20 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* //Example of how this can be used:
* mults = getHacknetMultipliers();
* // NS1:
* // Example of how this can be used:
* var mults = getHacknetMultipliers();
* print(mults.production);
* print(mults.purchaseCost);
* ```
* @example
* ```ts
* // NS2:
* // Example of how this can be used:
* const {production, purchaseCost} = ns.getHacknetMultipliers();
* print(production);
* print(purchaseCost);
* ```
* @returns Object containing the Players hacknet related multipliers.
*/
getHacknetMultipliers(): HacknetMultipliers;
@ -4637,9 +4911,16 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* getServerMoneyAvailable("foodnstuff");
* getServerMoneyAvailable("home"); //Returns player's money
* ```
* @example
* ```ts
* // NS2:
* ns.getServerMoneyAvailable("foodnstuff");
* ns.getServerMoneyAvailable("home"); // Returns player's money
* ```
* @param host - Host of target server
* @returns Amount of money available on the server.
*/
@ -4726,9 +5007,15 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* res = getServerRam("helios");
* totalRam = res[0];
* ramUsed = res[1];
* // NS1:
* var serverRam = getServerRam("helios");
* var totalRam = serverRam[0];
* var ramUsed = serverRam[1];
* ```
* @example
* ```ts
* // NS2:
* const [totalRam, ramUsed] = ns.getServerRam("helios");
* ```
* @param host - Host of target server.
* @returns Array with total and used memory on the specified server.
@ -4796,14 +5083,22 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
* fileExists("foo.script", "foodnstuff");
* ```
* @example
* ```ts
*
* //The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
* fileExists("ftpcrack.exe");
* ```
* * @example
* ```ts
* // NS2:
* // The function call will return true if the script named foo.script exists on the foodnstuff server, and false otherwise.
* ns.fileExists("foo.script", "foodnstuff");
*
* // The function call will return true if the current server contains the FTPCrack.exe program, and false otherwise.
* ns.fileExists("ftpcrack.exe");
* ```
* @param filename - Filename of file to check.
* @param host - Host of target server. This is optional. If it is not specified then the function will use the current server as the target server.
* @returns True if specified file exists, and false otherwise.
@ -4820,18 +5115,27 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
* isRunning("foo.script", "foodnstuff");
* ```
* @example
* ```ts
*
* //The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
* isRunning("foo.script", getHostname());
*
* //The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
* isRunning("foo.script", "joesguns", 1, 5, "test");
* ```
* @example
* ```ts
* // NS2:
* //The function call will return true if there is a script named foo.script with no arguments running on the foodnstuff server, and false otherwise:
* ns.isRunning("foo.script", "foodnstuff");
*
* //The function call will return true if there is a script named foo.script with no arguments running on the current server, and false otherwise:
* ns.isRunning("foo.script", ns.getHostname());
*
* //The function call will return true if there is a script named foo.script running with the arguments 1, 5, and “test” (in that order) on the joesguns server, and false otherwise:
* isRunning("foo.script", "joesguns", 1, 5, "test");
* ns.isRunning("foo.script", "joesguns", 1, 5, "test");
* ```
* @param script - Filename of script to check. This is case-sensitive.
* @param host - Host of target server.
@ -4860,10 +5164,18 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* for (i = 1; i <= 20; i++) {
* tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i)));
* }
* ```
* @example
* ```ts
* // NS2:
* for (i = 1; i <= 20; i++) {
* ns.tprint(i + " -- " + ns.getPurchasedServerCost(Math.pow(2, i)));
* }
* ```
* @param ram - Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20).
* @returns The cost to purchase a server with the specified amount of ram.
*/
@ -4895,10 +5207,20 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* ram = 64;
* hn = "pserv-";
* // NS1:
* var ram = 64;
* var prefix = "pserv-";
* for (i = 0; i < 5; ++i) {
* purchaseServer(hn + i, ram);
* purchaseServer(prefix + i, ram);
* }
* ```
* @example
* ```ts
* // NS2:
* const ram = 64;
* const prefix = "pserv-";
* for (i = 0; i < 5; ++i) {
* ns.purchaseServer(prefix + i, ram);
* }
* ```
* @param hostname - Host of the purchased server.
@ -5096,14 +5418,22 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* //The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
* scriptRunning("foo.script", "foodnstuff");
* ```
* @example
* ```ts
*
* //The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
* scriptRunning("foo.script", getHostname());
* ```
* * @example
* ```ts
* // NS2:
* //The function call will return true if there is any script named foo.script running on the foodnstuff server, and false otherwise:
* ns.scriptRunning("foo.script", "foodnstuff");
*
* //The function call will return true if there is any script named “foo.script” running on the current server, and false otherwise:
* ns.scriptRunning("foo.script", ns.getHostname());
* ```
* @param script - Filename of script to check. This is case-sensitive.
* @param host - Host of target server.
* @returns True if the specified script is running, and false otherwise.
@ -5150,9 +5480,10 @@ export interface NS extends Singularity {
* Get the execution time of a hack() call.
* @remarks
* RAM cost: 0.05 GB
*
*When `hack` completes an amount of money is stolen depending on the player's skills.
* Returns the amount of time in milliseconds it takes to execute the hack Netscript function on the target server.
* The function takes in an optional hackLvl parameter that can be specified to see what the hack time would be at different hacking levels.
* The required time is increased by the security level of the target server and decreased by the player's hacking level.
*
* @param host - Host of target server.
* @param hackLvl - Optional hacking level for the calculation. Defaults to players current hacking level.
@ -5168,6 +5499,7 @@ export interface NS extends Singularity {
*
* Returns the amount of time in milliseconds it takes to execute the grow Netscript function on the target server.
* The function takes in an optional hackLvl parameter that can be specified to see what the grow time would be at different hacking levels.
* The required time is increased by the security level of the target server and decreased by the player's hacking level.
*
* @param host - Host of target server.
* @param hackLvl - Optional hacking level for the calculation. Defaults to players current hacking level.
@ -5183,6 +5515,7 @@ export interface NS extends Singularity {
*
* Returns the amount of time in milliseconds it takes to execute the weaken() Netscript function on the target server.
* The function takes in an optional hackLvl parameter that can be specified to see what the weaken time would be at different hacking levels.
* The required time is increased by the security level of the target server and decreased by the player's hacking level.
*
* @param host - Host of target server.
* @param hackLvl - Optional hacking level for the calculation. Defaults to players current hacking level.
@ -5349,8 +5682,14 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* // NS1:
* wget("https://raw.githubusercontent.com/danielyxie/bitburner/master/README.md", "game_readme.txt");
* ```
* @example
* ```ts
* // NS2:
* await ns.wget("https://raw.githubusercontent.com/danielyxie/bitburner/master/README.md", "game_readme.txt");
* ```
* @param url - URL to pull data from.
* @param target - Filename to write data to. Must be script or text file.
* @param host - Optional hostname/ip of server for target file.
@ -5383,10 +5722,18 @@ export interface NS extends Singularity {
*
* @example
* ```ts
* mults = getBitNodeMultipliers();
* // NS1:
* var mults = getBitNodeMultipliers();
* print(mults.ServerMaxMoney);
* print(mults.HackExpGain);
* ```
* @example
* ```ts
* // NS2:
* const {ServerMaxMoney, HackExpGain} = ns.getBitNodeMultipliers();
* print(ServerMaxMoney);
* print(HackExpGain);
* ```
* @returns Object containing the current BitNode multipliers.
*/
getBitNodeMultipliers(): BitNodeMultipliers;
@ -5440,6 +5787,17 @@ export interface NS extends Singularity {
* ['help', false], // a default boolean means this flag is a boolean
* ]);
* tprint(data);
*
* // example.ns
* export async function main(ns) {
* const data = ns.flags([
* ['delay', 0], // a default number means this flag is a number
* ['server', 'foodnstuff'], // a default string means this flag is a string
* ['exclude', []], // a default array means this flag is a default array of string
* ['help', false], // a default boolean means this flag is a boolean
* ]);
* ns.tprint(data);
* }
*
* // [home ~/]> run example.script
* // {"_":[],"delay":0,"server":"foodnstuff","exclude":[],"help":false}

@ -668,6 +668,7 @@ export function Root(props: IProps): React.ReactElement {
// No more scripts are open
setOpenScripts([]);
setCurrentScript(null);
props.router.toTerminal();
}
}

@ -1,3 +1,5 @@
import { IMap } from "../types";
export interface ITheme {
[key: string]: string | undefined;
primarylight: string;
@ -35,6 +37,14 @@ export interface ITheme {
button: string;
}
export interface IPredefinedTheme {
colors: ITheme;
name?: string;
credit?: string;
description?: string;
reference?: string;
}
export const defaultTheme: ITheme = {
primarylight: "#0f0",
primary: "#0c0",
@ -71,40 +81,331 @@ export const defaultTheme: ITheme = {
button: "#333",
};
export interface IPredefinedThemes {
'Default': ITheme;
'Monokai': ITheme;
}
export const getPredefinedThemes = (): IMap<IPredefinedTheme> => ({
Default: {
colors: defaultTheme,
},
Monokai: {
description: "Monokai'ish",
colors: {
primarylight: "#FFF",
primary: "#F8F8F2",
primarydark: "#FAFAEB",
successlight: "#ADE146",
success: "#A6E22E",
successdark: "#98E104",
errorlight: "#FF69A0",
error: "#F92672",
errordark: "#D10F56",
secondarylight: "#AAA",
secondary: "#888",
secondarydark: "#666",
warninglight: "#E1D992",
warning: "#E6DB74",
warningdark: "#EDDD54",
infolight: "#92E1F1",
info: "#66D9EF",
infodark: "#31CDED",
welllight: "#444",
well: "#222",
white: "#fff",
black: "#000",
hp: "#F92672",
money: "#E6DB74",
hack: "#A6E22E",
combat: "#75715E",
cha: "#AE81FF",
int: "#66D9EF",
rep: "#E69F66",
disabled: "#66cfbc",
backgroundprimary: "#272822",
backgroundsecondary: "#1B1C18",
button: "#333",
},
},
export const getPredefinedThemes = (): IPredefinedThemes => ({
'Default': defaultTheme,
'Monokai': {
...defaultTheme,
Warmer: {
credit: "hexnaught",
description: "Warmer, softer theme",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999581020028938",
colors: {
primarylight: "#EA9062",
primary: "#DD7B4A",
primarydark: "#D3591C",
successlight: "#6ACF6A",
success: "#43BF43",
successdark: "#3E913E",
errorlight: "#C15757",
error: "#B34141",
errordark: "#752525",
secondarylight: "#AAA",
secondary: "#888",
secondarydark: "#666",
warninglight: "#E6E69D",
warning: "#DADA56",
warningdark: "#A1A106",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#222",
white: "#fff",
black: "#000",
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#AD84CF",
int: "#6495ed",
rep: "#faffdf",
disabled: "#76C6B7",
backgroundprimary: "#000",
backgroundsecondary: "#000",
button: "#333",
},
},
backgroundprimary: '#272822',
backgroundsecondary: '#1B1C18',
primary: '#F8F8F2',
primarylight: '#FFF',
primarydark: '#FAFAEB',
success: '#A6E22E',
successlight: '#ADE146',
successdark: '#98E104',
error: '#F92672',
errorlight: '#FF69A0',
errordark: '#D10F56',
warning: '#E6DB74',
warninglight: '#E1D992',
warningdark: '#EDDD54',
info: '#66D9EF',
infolight: '#92E1F1',
infodark: '#31CDED',
"Dark+": {
credit: "LoganMD",
description: "VSCode Dark+",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/921999975867617310",
colors: {
primarylight: "#E0E0BC",
primary: "#CCCCAE",
primarydark: "#B8B89C",
successlight: "#00F000",
success: "#00D200",
successdark: "#00B400",
errorlight: "#F00000",
error: "#C80000",
errordark: "#A00000",
secondarylight: "#B4AEAE",
secondary: "#969090",
secondarydark: "#787272",
warninglight: "#F0F000",
warning: "#C8C800",
warningdark: "#A0A000",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#222",
white: "#fff",
black: "#1E1E1E",
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
disabled: "#66cfbc",
backgroundprimary: "#1E1E1E",
backgroundsecondary: "#252525",
button: "#333",
},
},
hp: '#F92672',
money: '#E6DB74',
hack: '#A6E22E',
combat: '#75715E',
cha: '#AE81FF',
int: '#66D9EF',
rep: '#E69F66',
}
"Mayukai Dark": {
credit: "Festive Noire",
description: "Mayukai Dark-esque",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922037502334889994",
colors: {
primarylight: "#DDDFC5",
primary: "#CDCFB6",
primarydark: "#9D9F8C",
successlight: "#00EF00",
success: "#00A500",
successdark: "#007A00",
errorlight: "#F92672",
error: "#CA1C5C",
errordark: "#90274A",
secondarylight: "#AAA",
secondary: "#888",
secondarydark: "#666",
warninglight: "#D3D300",
warning: "#cc0",
warningdark: "#990",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#00010A",
white: "#fff",
black: "#020509",
hp: "#dd3434",
money: "#ffd700",
hack: "#8CCF27",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
disabled: "#66cfbc",
backgroundprimary: "#080C11",
backgroundsecondary: "#03080F",
button: "#00010A",
},
},
Purple: {
credit: "zer0ney",
description: "Essentially all defaults except for purple replacing the main colors",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922091815849570395",
colors: {
primarylight: "#BA55D3",
primary: "#9370DB",
primarydark: "#8A2BE2",
successlight: "#BA55D3",
success: "#9370DB",
successdark: "#8A2BE2",
errorlight: "#f00",
error: "#c00",
errordark: "#900",
secondarylight: "#AAA",
secondary: "#888",
secondarydark: "#666",
warninglight: "#ff0",
warning: "#cc0",
warningdark: "#990",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#222",
white: "#fff",
black: "#000",
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
disabled: "#66cfbc",
backgroundprimary: "#000",
backgroundsecondary: "#000",
button: "#333",
},
},
"Smooth Green": {
credit: "Swidt",
description: "A nice green theme that doesn't hurt your eyes.",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922243957986033725",
colors: {
primarylight: "#E0E0BC",
primary: "#B0D9A3",
primarydark: "#B8B89C",
successlight: "#00F000",
success: "#6BC16B",
successdark: "#00B400",
errorlight: "#F00000",
error: "#3D713D",
errordark: "#A00000",
secondarylight: "#B4AEAE",
secondary: "#8FAF85",
secondarydark: "#787272",
warninglight: "#F0F000",
warning: "#38F100",
warningdark: "#A0A000",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#2F3C2B",
white: "#fff",
black: "#1E1E1E",
hp: "#dd3434",
money: "#4AA52E",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#35A135",
disabled: "#66cfbc",
backgroundprimary: "#1E1E1E",
backgroundsecondary: "#252525",
button: "#2F3C2B",
},
},
Dracula: {
credit: "H3draut3r",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/922296307836678144",
colors: {
primarylight: "#7082B8",
primary: "#F8F8F2",
primarydark: "#FF79C6",
successlight: "#0f0",
success: "#0c0",
successdark: "#090",
errorlight: "#FD4545",
error: "#FF2D2D",
errordark: "#C62424",
secondarylight: "#AAA",
secondary: "#8BE9FD",
secondarydark: "#666",
warninglight: "#FFC281",
warning: "#FFB86C",
warningdark: "#E6A055",
infolight: "#A0A0FF",
info: "#7070FF",
infodark: "#4040FF",
welllight: "#44475A",
well: "#363948",
white: "#fff",
black: "#282A36",
hp: "#D34448",
money: "#50FA7B",
hack: "#F1FA8C",
combat: "#BD93F9",
cha: "#FF79C6",
int: "#6495ed",
rep: "#faffdf",
disabled: "#66cfbc",
backgroundprimary: "#282A36",
backgroundsecondary: "#21222C",
button: "#21222C",
},
},
"Dark Blue": {
credit: "Saynt_Garmo",
reference: "https://discord.com/channels/415207508303544321/921991895230611466/923084732718264340",
colors: {
primarylight: "#023DDE",
primary: "#4A41C8",
primarydark: "#005299",
successlight: "#00FF00",
success: "#D1DAD1",
successdark: "#BFCABF",
errorlight: "#f00",
error: "#c00",
errordark: "#900",
secondarylight: "#AAA",
secondary: "#888",
secondarydark: "#666",
warninglight: "#ff0",
warning: "#cc0",
warningdark: "#990",
infolight: "#69f",
info: "#36c",
infodark: "#039",
welllight: "#444",
well: "#040505",
white: "#fff",
black: "#000000",
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
disabled: "#66cfbc",
backgroundprimary: "#091419",
backgroundsecondary: "#000000",
button: "#000000",
},
},
});

@ -41,7 +41,7 @@ export const TerminalHelpText: string[] = [
"top Displays all running scripts and their RAM usage",
"unalias [alias name] Deletes the specified alias",
"vim [file ...] Text editor - Open up and edit one or more scripts or text files in vim mode",
"weaken [server] Reduce the security of a server",
"weaken Reduce the security of the current machine",
"wget [url] [target file] Retrieves code/text from a web server",
];

@ -19,12 +19,12 @@ function isNs2(filename: string): boolean {
const newNs2Template = `/** @param {NS} ns **/
export async function main(ns) {
}`;
export function commonEditor(
command: string,
{ terminal, router, player, server, args }: EditorParameters,
{ terminal, router, player, args }: EditorParameters,
scriptEditorRouteOptions?: ScriptEditorRouteOptions,
): void {
if (args.length < 1) {

@ -43,17 +43,16 @@ export function cp(
terminal.error("src and dst must have the same extension.");
return;
}
const filename = terminal.getFilepath(src);
if (!isScriptFilename(filename) && !filename.endsWith(".txt")) {
if (!isScriptFilename(src) && !src.endsWith(".txt")) {
terminal.error("cp only works for scripts and .txt files");
return;
}
// Scp for txt files
if (filename.endsWith(".txt")) {
if (src.endsWith(".txt")) {
let txtFile = null;
for (let i = 0; i < server.textFiles.length; ++i) {
if (server.textFiles[i].fn === filename) {
if (areFilesEqual(server.textFiles[i].fn, src)) {
txtFile = server.textFiles[i];
break;
}
@ -80,7 +79,7 @@ export function cp(
// Get the current script
let sourceScript = null;
for (let i = 0; i < server.scripts.length; ++i) {
if (filename == server.scripts[i].filename) {
if (areFilesEqual(server.scripts[i].filename, src)) {
sourceScript = server.scripts[i];
break;
}

@ -69,12 +69,25 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
const predefinedThemes = getPredefinedThemes();
const themes = predefinedThemes && Object.entries(predefinedThemes)
.map(([name, templateTheme]) => (
<Button onClick={() => setTemplateTheme(templateTheme)}
startIcon={<PaletteSharpIcon />} key={name} sx={{ mr: 1 }}>
<Typography>{name}</Typography>
</Button>
)) || <></>;
.map(([key, templateTheme]) => {
const name = templateTheme.name || key;
let inner = <Typography>{name}</Typography>;
let toolTipTitle;
if (templateTheme.credit) {
toolTipTitle = <Typography>{templateTheme.description || name} <em>by {templateTheme.credit}</em></Typography>;
} else if (templateTheme.description) {
toolTipTitle = <Typography>{templateTheme.description}</Typography>;
}
if (toolTipTitle) {
inner = <Tooltip title={toolTipTitle}>{inner}</Tooltip>
}
return (
<Button onClick={() => setTemplateTheme(templateTheme.colors)}
startIcon={<PaletteSharpIcon />} key={key} sx={{ mr: 1, mb: 1 }}>
{inner}
</Button>
);
}) || <></>;
function setTheme(theme: UserInterfaceTheme): void {
setCustomTheme(theme);