From 5d4b72e1d1bee42f872e9792c0daf3da58bbaa55 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sun, 9 Oct 2022 02:32:13 -0400 Subject: [PATCH] Added some purchased server functions --- src/Alias.ts | 2 - src/Netscript/RamCostGenerator.ts | 3 ++ src/NetscriptFunctions.ts | 58 +++++++++++++++++++--- src/Script/RamCalculations.ts | 2 +- src/ScriptEditor/NetscriptDefinitions.d.ts | 33 ++++++++++++ src/Server/AllServers.ts | 5 ++ src/Server/ServerPurchases.ts | 44 +++++++++++++++- src/Terminal/commands/scan.ts | 1 - 8 files changed, 135 insertions(+), 13 deletions(-) diff --git a/src/Alias.ts b/src/Alias.ts index f1cc157b2..585315c86 100644 --- a/src/Alias.ts +++ b/src/Alias.ts @@ -35,10 +35,8 @@ export function printAliases(): void { // Returns true if successful, false otherwise export function parseAliasDeclaration(dec: string, global = false): boolean { - console.log(dec); const re = /^([\w|!%,@-]+)=(.+)$/; const matches = dec.match(re); - console.log(matches); if (matches == null || matches.length != 3) { return false; } diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index 8f140aea5..08edc907f 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -492,6 +492,9 @@ export const RamCosts: RamCostTree> = { getPurchasedServerLimit: RamCostConstants.ScriptGetPurchasedServerLimit, getPurchasedServerMaxRam: RamCostConstants.ScriptGetPurchasedServerMaxRam, getPurchasedServerCost: RamCostConstants.ScriptGetPurchaseServerRamCost, + getPurchasedServerUpgradeCost: 0.1, + upgradePurchasedServer: 0.25, + renamePurchasedServer: 2, purchaseServer: RamCostConstants.ScriptPurchaseServerRamCost, deleteServer: RamCostConstants.ScriptPurchaseServerRamCost, getPurchasedServers: RamCostConstants.ScriptPurchaseServerRamCost, diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index b785438f8..245a76a0d 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -26,7 +26,14 @@ import { processSingleServerGrowth, safelyCreateUniqueServer, } from "./Server/ServerHelpers"; -import { getPurchaseServerCost, getPurchaseServerLimit, getPurchaseServerMaxRam } from "./Server/ServerPurchases"; +import { + getPurchasedServerUpgradeCost, + getPurchaseServerCost, + getPurchaseServerLimit, + getPurchaseServerMaxRam, + renamePurchasedServer, + upgradePurchasedServer, +} from "./Server/ServerPurchases"; import { Server } from "./Server/Server"; import { influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing"; import { isValidFilePath, removeLeadingSlash } from "./Terminal/DirectoryHelpers"; @@ -1042,13 +1049,7 @@ const base: InternalAPI = { const server = helpers.getServer(ctx, hostname); return server.hasAdminRights; }, - getHostname: (ctx: NetscriptContext) => (): string => { - const scriptServer = GetServer(ctx.workerScript.hostname); - if (scriptServer == null) { - throw helpers.makeRuntimeErrorMsg(ctx, "Could not find server. This is a bug. Report to dev."); - } - return scriptServer.hostname; - }, + getHostname: (ctx: NetscriptContext) => (): string => ctx.workerScript.hostname, getHackingLevel: (ctx: NetscriptContext) => (): number => { Player.updateSkillLevels(); helpers.log(ctx, () => `returned ${Player.skills.hacking}`); @@ -1385,6 +1386,47 @@ const base: InternalAPI = { ); return newServ.hostname; }, + + getPurchasedServerUpgradeCost: + (ctx: NetscriptContext) => + (_hostname: unknown, _ram: unknown): number => { + const hostname = helpers.string(ctx, "hostname", _hostname); + const ram = helpers.number(ctx, "ram", _ram); + try { + return getPurchasedServerUpgradeCost(hostname, ram); + } catch (err) { + helpers.log(ctx, () => String(err)); + return -1; + } + }, + upgradePurchasedServer: + (ctx: NetscriptContext) => + (_hostname: unknown, _ram: unknown): boolean => { + const hostname = helpers.string(ctx, "hostname", _hostname); + const ram = helpers.number(ctx, "ram", _ram); + try { + upgradePurchasedServer(hostname, ram); + return true; + } catch (err) { + helpers.log(ctx, () => String(err)); + return false; + } + }, + renamePurchasedServer: + (ctx: NetscriptContext) => + (_hostname: unknown, _newName: unknown): boolean => { + const hostname = helpers.string(ctx, "hostname", _hostname); + const newName = helpers.string(ctx, "newName", _newName); + try { + renamePurchasedServer(hostname, newName); + return true; + } catch (err) { + helpers.log(ctx, () => String(err)); + return false; + } + return false; + }, + deleteServer: (ctx: NetscriptContext) => (_name: unknown): boolean => { diff --git a/src/Script/RamCalculations.ts b/src/Script/RamCalculations.ts index aae7dcf17..58b2cdc17 100644 --- a/src/Script/RamCalculations.ts +++ b/src/Script/RamCalculations.ts @@ -192,7 +192,7 @@ function parseOnlyRamCalculate(otherScripts: Script[], code: string): RamCalcula ram += fnRam; detailedCosts.push({ type: "fn", name: details?.refDetail ?? "", cost: fnRam }); } catch (error) { - console.log(error); + console.error(error); continue; } } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index c88860304..0850bdd7e 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -6035,6 +6035,39 @@ export interface NS { */ purchaseServer(hostname: string, ram: number): string; + /** + * Get cost of upgrading a purchased server to the given ram. + * @remarks + * RAM cost: 0.1 GB + * + * @param hostname - Hostname of the server to upgrade. + * @param ram - Amount of RAM of the purchased server, in GB. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20). + * @returns The price to upgrade. + */ + getPurchasedServerUpgradeCost(hostname: string, ram: number): number; + + /** + * Upgrade a purchased servers ram. + * @remarks + * RAM cost: 0.25 GB + * + * @param hostname - Hostname of the server to upgrade. + * @param ram - Amount of RAM of the purchased server, in GB. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20). + * @returns True if the upgrade succeeded. + */ + upgradePurchasedServer(hostname: string, ram: number): boolean; + + /** + * Rename a purchased server. + * @remarks + * RAM cost: 2.00 GB + * + * @param hostname - current server hostname + * @param newName - new server hostname + * @returns True if the upgrade succeeded. + */ + renamePurchasedServer(hostname: string, newName: string): boolean; + /** * Delete a purchased server. * @remarks diff --git a/src/Server/AllServers.ts b/src/Server/AllServers.ts index 61952267b..0d77d03a9 100644 --- a/src/Server/AllServers.ts +++ b/src/Server/AllServers.ts @@ -106,6 +106,11 @@ export function AddToAllServers(server: Server | HacknetServer): void { AllServers[server.hostname] = server; } +export const renameServer = (hostname: string, newName: string): void => { + AllServers[newName] = AllServers[hostname]; + delete AllServers[hostname]; +}; + interface IServerParams { hackDifficulty?: number; hostname: string; diff --git a/src/Server/ServerPurchases.ts b/src/Server/ServerPurchases.ts index df4d5bf7d..338342fb3 100644 --- a/src/Server/ServerPurchases.ts +++ b/src/Server/ServerPurchases.ts @@ -2,7 +2,7 @@ * Implements functions for purchasing servers or purchasing more RAM for * the home computer */ -import { AddToAllServers, createUniqueRandomIp } from "./AllServers"; +import { AddToAllServers, createUniqueRandomIp, GetServer, renameServer } from "./AllServers"; import { safelyCreateUniqueServer } from "./ServerHelpers"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; @@ -11,6 +11,7 @@ import { Player } from "../Player"; import { dialogBoxCreate } from "../ui/React/DialogBox"; import { isPowerOfTwo } from "../utils/helpers/isPowerOfTwo"; +import { workerScripts } from "../Netscript/WorkerScripts"; // Returns the cost of purchasing a server with the given RAM // Returns Infinity for invalid 'ram' arguments @@ -38,6 +39,47 @@ export function getPurchaseServerCost(ram: number): number { ); } +export const getPurchasedServerUpgradeCost = (hostname: string, ram: number): number => { + const server = GetServer(hostname); + if (!server) throw new Error(`Server '${hostname}' not found.`); + if (!Player.purchasedServers.includes(hostname)) throw new Error(`Server '${hostname}' not a purchased server.`); + if (isNaN(ram) || !isPowerOfTwo(ram) || !(Math.sign(ram) === 1)) + throw new Error(`${ram} is not a positive power of 2`); + if (server.maxRam >= ram) + throw new Error(`'${hostname}' current ram (${server.maxRam}) is not bigger than new ram (${ram})`); + return getPurchaseServerCost(ram) - getPurchaseServerCost(server.maxRam); +}; + +export const upgradePurchasedServer = (hostname: string, ram: number): void => { + const server = GetServer(hostname); + if (!server) throw new Error(`Server '${hostname}' not found.`); + const cost = getPurchasedServerUpgradeCost(hostname, ram); + if (!Player.canAfford(cost)) throw new Error(`You don't have enough money to upgrade '${hostname}'.`); + Player.loseMoney(cost, "servers"); + server.maxRam = ram; +}; + +export const renamePurchasedServer = (hostname: string, newName: string): void => { + const server = GetServer(hostname); + if (!server) throw new Error(`Server '${newName}' doesn't exists.`); + if (GetServer(newName)) throw new Error(`Server '${newName}' already exists.`); + if (!Player.purchasedServers.includes(hostname)) throw new Error(`Server '${hostname}' is not a player server.`); + const replace = (arr: string[], old: string, next: string): string[] => { + return arr.map((v) => (v === old ? next : v)); + }; + Player.purchasedServers = replace(Player.purchasedServers, hostname, newName); + const home = Player.getHomeComputer(); + home.serversOnNetwork = replace(home.serversOnNetwork, hostname, newName); + server.serversOnNetwork = replace(server.serversOnNetwork, hostname, newName); + server.runningScripts.forEach((r) => (r.server = newName)); + server.scripts.forEach((r) => (r.server = newName)); + server.hostname = newName; + workerScripts.forEach((w) => { + if (w.hostname === hostname) w.hostname = newName; + }); + renameServer(hostname, newName); +}; + export function getPurchaseServerLimit(): number { return Math.round(CONSTANTS.PurchasedServerLimit * BitNodeMultipliers.PurchasedServerLimit); } diff --git a/src/Terminal/commands/scan.ts b/src/Terminal/commands/scan.ts index f6c61093a..2912c58b2 100644 --- a/src/Terminal/commands/scan.ts +++ b/src/Terminal/commands/scan.ts @@ -7,7 +7,6 @@ export function scan(args: (string | number | boolean)[], currServ: BaseServer): Terminal.error("Incorrect usage of scan command. Usage: scan"); return; } - // Displays available network connections using TCP const servers = currServ.serversOnNetwork.map((_, i) => { const server = getServerOnNetwork(currServ, i);