bitburner-src/src/Server/AllServers.ts

231 lines
6.5 KiB
TypeScript
Raw Normal View History

import { Server } from "./Server";
2021-10-07 22:04:04 +02:00
import { BaseServer } from "./BaseServer";
import { serverMetadata } from "./data/servers";
import { HacknetServer } from "../Hacknet/HacknetServer";
import { IMap } from "../types";
2021-09-25 20:42:57 +02:00
import { createRandomIp } from "../utils/IPAddress";
import { getRandomInt } from "../utils/helpers/getRandomInt";
import { Reviver } from "../utils/JSONReviver";
2021-10-07 22:56:01 +02:00
import { isValidIPAddress } from "../utils/helpers/isValidIPAddress";
import { SpecialServers } from "./data/SpecialServers";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
2019-03-03 04:15:10 +01:00
/**
* Map of all Servers that exist in the game
* Key (string) = IP
* Value = Server object
*/
2021-10-07 22:04:04 +02:00
let AllServers: IMap<Server | HacknetServer> = {};
2021-10-07 22:56:01 +02:00
function GetServerByIP(ip: string): BaseServer | undefined {
2022-01-16 01:45:03 +01:00
for (const key of Object.keys(AllServers)) {
2021-10-07 22:56:01 +02:00
const server = AllServers[key];
if (server.ip !== ip) continue;
return server;
}
}
//Returns server object with corresponding hostname
// Relatively slow, would rather not use this a lot
function GetServerByHostname(hostname: string): BaseServer | null {
2022-01-16 01:45:03 +01:00
for (const key of Object.keys(AllServers)) {
2021-10-07 22:56:01 +02:00
const server = AllServers[key];
if (server.hostname == hostname) {
return server;
}
}
return null;
}
//Get server by IP or hostname. Returns null if invalid
export function GetServer(s: string): BaseServer | null {
2022-01-29 22:30:13 +01:00
if (AllServers.hasOwnProperty(s)) {
const server = AllServers[s];
if (server) return server;
}
2021-10-07 22:56:01 +02:00
if (!isValidIPAddress(s)) {
return GetServerByHostname(s);
}
const ipserver = GetServerByIP(s);
if (ipserver !== undefined) {
return ipserver;
}
return null;
2021-10-07 22:04:04 +02:00
}
export function GetAllServers(): BaseServer[] {
const servers: BaseServer[] = [];
2022-01-16 01:45:03 +01:00
for (const key of Object.keys(AllServers)) {
2021-10-07 22:04:04 +02:00
servers.push(AllServers[key]);
}
return servers;
}
export function DeleteServer(serverkey: string): void {
2022-01-16 01:45:03 +01:00
for (const key of Object.keys(AllServers)) {
2021-10-07 22:04:04 +02:00
const server = AllServers[key];
if (server.ip !== serverkey && server.hostname !== serverkey) continue;
delete AllServers[key];
break;
}
}
2019-03-03 04:15:10 +01:00
2021-05-01 09:17:31 +02:00
export function ipExists(ip: string): boolean {
2022-06-13 08:07:21 +02:00
for (const hostName in AllServers) {
if (AllServers[hostName].ip === ip) {
return true
}
}
return false
}
export function createUniqueRandomIp(): string {
let ip: string;
// Repeat generating ip, until unique one is found
do {
ip = createRandomIp();
} while (ipExists(ip));
2021-09-05 01:09:30 +02:00
return ip;
}
2019-03-03 04:15:10 +01:00
// Saftely add a Server to the AllServers map
export function AddToAllServers(server: Server | HacknetServer): void {
2021-10-07 23:04:32 +02:00
if (GetServer(server.hostname)) {
2021-09-09 05:47:34 +02:00
console.warn(`Hostname of the server thats being added: ${server.hostname}`);
2021-10-07 23:04:32 +02:00
console.warn(`The server that already has this IP is: ${AllServers[server.hostname].hostname}`);
2021-09-05 01:09:30 +02:00
throw new Error("Error: Trying to add a server with an existing IP");
}
2021-10-07 23:04:32 +02:00
AllServers[server.hostname] = server;
2019-03-03 04:15:10 +01:00
}
interface IServerParams {
2021-09-05 01:09:30 +02:00
hackDifficulty?: number;
hostname: string;
ip: string;
maxRam?: number;
moneyAvailable?: number;
numOpenPortsRequired: number;
organizationName: string;
requiredHackingSkill?: number;
serverGrowth?: number;
[key: string]: any;
}
2021-05-01 09:17:31 +02:00
export function initForeignServers(homeComputer: Server): void {
2021-09-05 01:09:30 +02:00
/* Create a randomized network for all the foreign servers */
//Groupings for creating a randomized network
const networkLayers: Server[][] = [];
for (let i = 0; i < 15; i++) {
networkLayers.push([]);
}
// Essentially any property that is of type 'number | IMinMaxRange'
const propertiesToPatternMatch: string[] = [
"hackDifficulty",
"moneyAvailable",
"requiredHackingSkill",
"serverGrowth",
];
const toNumber = (value: any): any => {
switch (typeof value) {
case "number":
return value;
case "object":
return getRandomInt(value.min, value.max);
default:
2021-09-09 05:47:34 +02:00
throw Error(`Do not know how to convert the type '${typeof value}' to a number`);
2019-03-03 04:15:10 +01:00
}
2021-09-05 01:09:30 +02:00
};
for (const metadata of serverMetadata) {
const serverParams: IServerParams = {
hostname: metadata.hostname,
ip: createUniqueRandomIp(),
numOpenPortsRequired: metadata.numOpenPortsRequired,
organizationName: metadata.organizationName,
};
2019-03-03 04:15:10 +01:00
2021-09-05 01:09:30 +02:00
if (metadata.maxRamExponent !== undefined) {
serverParams.maxRam = Math.pow(2, toNumber(metadata.maxRamExponent));
2019-03-03 04:15:10 +01:00
}
2021-09-05 01:09:30 +02:00
for (const prop of propertiesToPatternMatch) {
if (metadata[prop] !== undefined) {
serverParams[prop] = toNumber(metadata[prop]);
}
2019-03-03 04:15:10 +01:00
}
2021-09-05 01:09:30 +02:00
const server = new Server(serverParams);
for (const filename of metadata.literature || []) {
server.messages.push(filename);
}
2019-03-03 04:15:10 +01:00
if (server.hostname === SpecialServers.WorldDaemon) {
server.requiredHackingSkill *= BitNodeMultipliers.WorldDaemonDifficulty;
}
2021-09-05 01:09:30 +02:00
AddToAllServers(server);
if (metadata.networkLayer !== undefined) {
networkLayers[toNumber(metadata.networkLayer) - 1].push(server);
2019-03-03 04:15:10 +01:00
}
2021-09-05 01:09:30 +02:00
}
/* Create a randomized network for all the foreign servers */
const linkComputers = (server1: Server, server2: Server): void => {
2021-10-07 23:55:49 +02:00
server1.serversOnNetwork.push(server2.hostname);
server2.serversOnNetwork.push(server1.hostname);
2021-09-05 01:09:30 +02:00
};
2021-09-06 21:06:08 +02:00
const getRandomArrayItem = (arr: any[]): any => arr[Math.floor(Math.random() * arr.length)];
2021-09-05 01:09:30 +02:00
2021-09-09 05:47:34 +02:00
const linkNetworkLayers = (network1: Server[], selectServer: () => Server): void => {
2021-09-05 01:09:30 +02:00
for (const server of network1) {
linkComputers(server, selectServer());
}
};
// Connect the first tier of servers to the player's home computer
linkNetworkLayers(networkLayers[0], () => homeComputer);
for (let i = 1; i < networkLayers.length; i++) {
2021-09-09 05:47:34 +02:00
linkNetworkLayers(networkLayers[i], () => getRandomArrayItem(networkLayers[i - 1]));
2021-09-05 01:09:30 +02:00
}
2019-03-03 04:15:10 +01:00
}
2021-05-01 09:17:31 +02:00
export function prestigeAllServers(): void {
2022-01-16 01:45:03 +01:00
for (const member of Object.keys(AllServers)) {
2021-09-05 01:09:30 +02:00
delete AllServers[member];
}
AllServers = {};
2019-03-03 04:15:10 +01:00
}
2021-05-01 09:17:31 +02:00
export function loadAllServers(saveString: string): void {
2021-09-05 01:09:30 +02:00
AllServers = JSON.parse(saveString, Reviver);
2021-10-07 22:04:04 +02:00
}
export function saveAllServers(excludeRunningScripts = false): string {
2021-10-07 22:04:04 +02:00
const TempAllServers = JSON.parse(JSON.stringify(AllServers), Reviver);
2022-01-16 01:45:03 +01:00
for (const key of Object.keys(TempAllServers)) {
2021-10-07 22:04:04 +02:00
const server = TempAllServers[key];
if (excludeRunningScripts) {
server.runningScripts = [];
continue;
}
2021-10-07 22:04:04 +02:00
for (let i = 0; i < server.runningScripts.length; ++i) {
const runningScriptObj = server.runningScripts[i];
runningScriptObj.logs.length = 0;
runningScriptObj.logs = [];
}
}
return JSON.stringify(TempAllServers);
2019-03-03 04:15:10 +01:00
}