mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-07 08:07:57 +02:00
DARKNET: Darkweb Expansion Project & Bitnode (#2139)
This is BN15. It is a really big change; see the PR for all the details.
This commit is contained in:
committed by
GitHub
parent
a674633f6c
commit
6073964768
@@ -56,7 +56,7 @@ import { hasScriptExtension, ScriptFilePath } from "../Paths/ScriptFilePath";
|
||||
import { CustomBoundary } from "../ui/Components/CustomBoundary";
|
||||
import { ServerConstants } from "../Server/data/Constants";
|
||||
import { errorMessage, log } from "./ErrorMessages";
|
||||
import { assertStringWithNSContext, debugType, userFriendlyString } from "./TypeAssertion";
|
||||
import { assertStringWithNSContext, debugType, missingKey, userFriendlyString } from "./TypeAssertion";
|
||||
import {
|
||||
canAccessBitNodeFeature,
|
||||
getDefaultBitNodeOptions,
|
||||
@@ -64,6 +64,9 @@ import {
|
||||
} from "../BitNode/BitNodeUtils";
|
||||
import { JSONMap } from "../Types/Jsonable";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { Programs } from "../Programs/Programs";
|
||||
import { getRecordKeys } from "../Types/Record";
|
||||
import { DarknetServer } from "../Server/DarknetServer";
|
||||
import { getFriendlyType } from "../utils/TypeAssertion";
|
||||
|
||||
export const helpers = {
|
||||
@@ -494,16 +497,16 @@ function scriptIdentifier(
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server with a specific hostname/ip. Throw an error if the server does not exist or it is an isolated
|
||||
* Gets the server with a specific hostname/ip. Throw an error if the server does not exist or is an isolated non-dnet
|
||||
* server (e.g., pre-TOR darkweb, pre-TRP WD).
|
||||
*
|
||||
* @param {NetscriptContext} ctx - Context from which getServer is being called. For logging purposes.
|
||||
* @param {string} hostname - Hostname of the server
|
||||
* @returns {BaseServer} The specified server as a BaseServer
|
||||
*/
|
||||
function getServer(ctx: NetscriptContext, hostname: string): BaseServer {
|
||||
export function getServer(ctx: NetscriptContext, hostname: string): BaseServer {
|
||||
const server = GetServer(hostname);
|
||||
if (server == null || server.serversOnNetwork.length === 0) {
|
||||
if (server == null || (server.serversOnNetwork.length == 0 && !(server instanceof DarknetServer))) {
|
||||
const str = hostname === "" ? "'' (empty string)" : "'" + hostname + "'";
|
||||
throw errorMessage(ctx, `Invalid hostname: ${str}`);
|
||||
}
|
||||
@@ -519,6 +522,8 @@ function getNormalServer(ctx: NetscriptContext, host: string): Server {
|
||||
let errorMessage = `Cannot be executed on ${host}.`;
|
||||
if (server instanceof HacknetServer) {
|
||||
errorMessage += " The server must not be a hacknet server.";
|
||||
} else if (server instanceof DarknetServer) {
|
||||
errorMessage += " The server must not be a darknet server.";
|
||||
}
|
||||
throw helpers.errorMessage(ctx, errorMessage);
|
||||
}
|
||||
@@ -651,6 +656,9 @@ function person(ctx: NetscriptContext, p: unknown): IPerson {
|
||||
return p as IPerson;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used by non-dnet formulas APIs to check if the server data contains properties of a normal server.
|
||||
*/
|
||||
function server(ctx: NetscriptContext, s: unknown): IServer {
|
||||
const fakeServer = {
|
||||
hostname: undefined,
|
||||
@@ -669,20 +677,22 @@ function server(ctx: NetscriptContext, s: unknown): IServer {
|
||||
purchasedByPlayer: undefined,
|
||||
};
|
||||
const error = missingKey(fakeServer, s);
|
||||
if (error) throw errorMessage(ctx, `server should be a Server.\n${error}`, "TYPE");
|
||||
if (error) {
|
||||
let errorMessagePrefix = "Server must be a normal server.";
|
||||
if (s != null && typeof s === "object") {
|
||||
if ("hostname" in s) {
|
||||
errorMessagePrefix += ` Server's hostname is ${s.hostname}.`;
|
||||
}
|
||||
if ("modelId" in s) {
|
||||
errorMessagePrefix += " Server data looks like darknet server data.";
|
||||
}
|
||||
}
|
||||
// throw errorMessage(ctx, `Server should be a normal server.\n${error}`, "TYPE");
|
||||
throw errorMessage(ctx, `${errorMessagePrefix}\n${error}`, "TYPE");
|
||||
}
|
||||
return s as IServer;
|
||||
}
|
||||
|
||||
function missingKey(expect: object, actual: unknown): string | false {
|
||||
if (typeof actual !== "object" || actual === null) {
|
||||
return `Expected to be an object, was ${actual === null ? "null" : typeof actual}.`;
|
||||
}
|
||||
for (const key in expect) {
|
||||
if (!(key in actual)) return `Property ${key} was expected but not present.`;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function gang(ctx: NetscriptContext, g: unknown): FormulaGang {
|
||||
const error = missingKey({ respect: 0, territory: 0, wantedLevel: 0 }, g);
|
||||
if (error) throw errorMessage(ctx, `gang should be a Gang.\n${error}`, "TYPE");
|
||||
@@ -708,10 +718,19 @@ export function filePath(ctx: NetscriptContext, argName: string, filename: unkno
|
||||
throw errorMessage(ctx, `Invalid ${argName}, was not a valid path: ${filename}`);
|
||||
}
|
||||
|
||||
export function scriptPath(ctx: NetscriptContext, argName: string, filename: unknown): ScriptFilePath {
|
||||
export function scriptPath(
|
||||
ctx: NetscriptContext,
|
||||
argName: string,
|
||||
filename: unknown,
|
||||
showExeErrorHint = false,
|
||||
): ScriptFilePath {
|
||||
const path = filePath(ctx, argName, filename);
|
||||
if (hasScriptExtension(path)) return path;
|
||||
throw errorMessage(ctx, `Invalid ${argName}, must be a script: ${filename}`);
|
||||
|
||||
const programName = getRecordKeys(Programs).find((name) => name.toLowerCase() === path.toLowerCase());
|
||||
const nsMethod = programName ? Programs[programName].nsMethod : "";
|
||||
const hint = nsMethod && showExeErrorHint ? `Did you mean to use ns.${nsMethod} ?` : "";
|
||||
throw errorMessage(ctx, `Invalid ${argName}, must be a script (js, jsx, ts, tsx): ${filename} ${hint}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -234,6 +234,34 @@ const cloud = {
|
||||
deleteServer: 2.25,
|
||||
} as const;
|
||||
|
||||
// Darknet API
|
||||
const dnet = {
|
||||
authenticate: 0.4,
|
||||
connectToSession: 0.05,
|
||||
heartbleed: 0.6,
|
||||
openCache: 2,
|
||||
probe: RamCostConstants.Scan,
|
||||
setStasisLink: 12,
|
||||
getStasisLinkLimit: 0,
|
||||
getStasisLinkedServers: 0,
|
||||
getServer: 2,
|
||||
getServerAuthDetails: RamCostConstants.GetServer,
|
||||
packetCapture: 6,
|
||||
induceServerMigration: 4,
|
||||
unleashStormSeed: 0.1,
|
||||
isDarknetServer: RamCostConstants.GetServer,
|
||||
memoryReallocation: 1,
|
||||
getBlockedRam: 0,
|
||||
getDepth: RamCostConstants.GetServer,
|
||||
promoteStock: 2,
|
||||
phishingAttack: 2,
|
||||
getDarknetInstability: 0,
|
||||
nextMutation: RamCostConstants.CycleTiming,
|
||||
getServerRequiredCharismaLevel: RamCostConstants.GetServer,
|
||||
labreport: 0,
|
||||
labradar: 0,
|
||||
} as const;
|
||||
|
||||
const format = {
|
||||
number: 0,
|
||||
ram: 0,
|
||||
@@ -515,6 +543,7 @@ export const RamCosts: RamCostTree<NSFull> = {
|
||||
cloud,
|
||||
gang,
|
||||
go,
|
||||
dnet,
|
||||
bladeburner,
|
||||
infiltration,
|
||||
codingcontract,
|
||||
@@ -699,6 +728,11 @@ export const RamCosts: RamCostTree<NSFull> = {
|
||||
bladeburner: {
|
||||
skillMaxUpgradeCount: 0,
|
||||
},
|
||||
dnet: {
|
||||
getAuthenticateTime: 0,
|
||||
getHeartbleedTime: 0,
|
||||
getExpectedRamBlockRemoved: 0,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { exampleDarknetServerData } from "../DarkNet/Enums";
|
||||
import type { DarknetServerData } from "@nsdefs";
|
||||
import type { NetscriptContext } from "./APIWrapper";
|
||||
import { errorMessage } from "./ErrorMessages";
|
||||
|
||||
@@ -55,3 +57,20 @@ export function assertFunctionWithNSContext(
|
||||
): asserts v is () => void {
|
||||
if (typeof v !== "function") throw errorMessage(ctx, `${argName} expected to be a function ${debugType(v)}`, "TYPE");
|
||||
}
|
||||
|
||||
export function missingKey(expect: object, actual: unknown): string | false {
|
||||
if (typeof actual !== "object" || actual === null) {
|
||||
return `Expected to be an object, was ${actual === null ? "null" : typeof actual}.`;
|
||||
}
|
||||
for (const key in expect) {
|
||||
if (!(key in actual)) return `Property ${key} was expected but not present.`;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function assertDarknetServerData(ctx: NetscriptContext, data: unknown): asserts data is DarknetServerData {
|
||||
const error = missingKey(exampleDarknetServerData, data);
|
||||
if (error) {
|
||||
throw errorMessage(ctx, `Invalid darknet server data.\n${error}`, "TYPE");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ITutorial } from "../InteractiveTutorial";
|
||||
import { AlertEvents } from "../ui/React/AlertManager";
|
||||
import { handleUnknownError } from "../utils/ErrorHandler";
|
||||
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
||||
import { BaseServer } from "../Server/BaseServer";
|
||||
|
||||
export function killWorkerScript(ws: WorkerScript): boolean {
|
||||
if (ITutorial.isRunning) {
|
||||
@@ -35,15 +36,30 @@ export function killWorkerScriptByPid(pid: number, killer?: WorkerScript): boole
|
||||
}
|
||||
|
||||
export const killAllScripts = () => {
|
||||
for (const server of GetAllServers()) {
|
||||
for (const byPid of server.runningScriptMap.values()) {
|
||||
for (const pid of byPid.keys()) {
|
||||
killWorkerScriptByPid(pid);
|
||||
}
|
||||
for (const server of GetAllServers(true)) {
|
||||
killServerScripts(server, "Script killed.");
|
||||
}
|
||||
};
|
||||
|
||||
export const killServerScripts = (server: BaseServer, message: string) => {
|
||||
const scripts = server.runningScriptMap.values();
|
||||
for (const byPid of scripts) {
|
||||
for (const runningScript of byPid.values()) {
|
||||
killWorkerScriptWithMessage(runningScript.pid, message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function killWorkerScriptWithMessage(pid: number, message: string): boolean {
|
||||
const ws = workerScripts.get(pid);
|
||||
if (ws) {
|
||||
ws.log("", () => message);
|
||||
stopAndCleanUpWorkerScript(ws);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function stopAndCleanUpWorkerScript(ws: WorkerScript): void {
|
||||
// Only clean up once.
|
||||
// Important: Only this function can set stopFlag!
|
||||
|
||||
Reference in New Issue
Block a user