From f761eed377add81b48294e355003b6991d13c7ef Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 11 Apr 2023 15:12:55 -0400 Subject: [PATCH] NETSCRIPT: Type correctness for getServer (#476) --- markdown/bitburner.md | 2 +- .../bitburner.server.backdoorinstalled.md | 2 +- markdown/bitburner.server.basedifficulty.md | 4 +- markdown/bitburner.server.cpucores.md | 2 +- markdown/bitburner.server.ftpportopen.md | 2 +- markdown/bitburner.server.hackdifficulty.md | 2 +- markdown/bitburner.server.httpportopen.md | 2 +- markdown/bitburner.server.md | 38 ++++----- markdown/bitburner.server.mindifficulty.md | 2 +- markdown/bitburner.server.moneyavailable.md | 2 +- markdown/bitburner.server.moneymax.md | 2 +- .../bitburner.server.numopenportsrequired.md | 2 +- markdown/bitburner.server.openportcount.md | 2 +- markdown/bitburner.server.organizationname.md | 2 +- .../bitburner.server.requiredhackingskill.md | 2 +- markdown/bitburner.server.servergrowth.md | 4 +- markdown/bitburner.server.smtpportopen.md | 2 +- markdown/bitburner.server.sqlportopen.md | 2 +- markdown/bitburner.server.sshportopen.md | 2 +- src/Hacking.ts | 59 ++++++------- src/Netscript/NetscriptHelpers.ts | 34 +++----- src/NetscriptFunctions.ts | 75 +++++++++++------ src/ScriptEditor/NetscriptDefinitions.d.ts | 82 ++++++++----------- src/Server/BaseServer.ts | 14 +++- src/Server/ServerHelpers.ts | 17 ++-- src/Server/formulas/grow.ts | 9 +- 26 files changed, 189 insertions(+), 179 deletions(-) diff --git a/markdown/bitburner.md b/markdown/bitburner.md index 7039f9f4c..07415a3ba 100644 --- a/markdown/bitburner.md +++ b/markdown/bitburner.md @@ -88,7 +88,7 @@ | [ReputationFormulas](./bitburner.reputationformulas.md) | Reputation formulas | | [RunningScript](./bitburner.runningscript.md) | | | [RunOptions](./bitburner.runoptions.md) | | -| [Server](./bitburner.server.md) | A single server. | +| [Server](./bitburner.server.md) | A server. Not all servers have all of these properties - optional properties are missing on certain servers. | | [Singularity](./bitburner.singularity.md) | Singularity API | | [Skills](./bitburner.skills.md) | | | [SkillsFormulas](./bitburner.skillsformulas.md) | Skills formulas | diff --git a/markdown/bitburner.server.backdoorinstalled.md b/markdown/bitburner.server.backdoorinstalled.md index 01374d889..c31048b84 100644 --- a/markdown/bitburner.server.backdoorinstalled.md +++ b/markdown/bitburner.server.backdoorinstalled.md @@ -9,5 +9,5 @@ Flag indicating whether this server has a backdoor installed by a player **Signature:** ```typescript -backdoorInstalled: boolean; +backdoorInstalled?: boolean; ``` diff --git a/markdown/bitburner.server.basedifficulty.md b/markdown/bitburner.server.basedifficulty.md index c19160de1..561e95cce 100644 --- a/markdown/bitburner.server.basedifficulty.md +++ b/markdown/bitburner.server.basedifficulty.md @@ -4,10 +4,10 @@ ## Server.baseDifficulty property -Initial server security level (i.e. security level when the server was created) +Server's initial server security level at creation. **Signature:** ```typescript -baseDifficulty: number; +baseDifficulty?: number; ``` diff --git a/markdown/bitburner.server.cpucores.md b/markdown/bitburner.server.cpucores.md index e70b3970a..cce7a1a05 100644 --- a/markdown/bitburner.server.cpucores.md +++ b/markdown/bitburner.server.cpucores.md @@ -4,7 +4,7 @@ ## Server.cpuCores property -How many CPU cores this server has. Maximum of 8. Affects magnitude of grow and weaken. +How many CPU cores this server has. Affects magnitude of grow and weaken ran from this server. **Signature:** diff --git a/markdown/bitburner.server.ftpportopen.md b/markdown/bitburner.server.ftpportopen.md index 156e38ad8..9dd12c997 100644 --- a/markdown/bitburner.server.ftpportopen.md +++ b/markdown/bitburner.server.ftpportopen.md @@ -4,7 +4,7 @@ ## Server.ftpPortOpen property -Flag indicating whether the FTP port is open +Whether or not the FTP port is open **Signature:** diff --git a/markdown/bitburner.server.hackdifficulty.md b/markdown/bitburner.server.hackdifficulty.md index 4d17c60c9..d12658769 100644 --- a/markdown/bitburner.server.hackdifficulty.md +++ b/markdown/bitburner.server.hackdifficulty.md @@ -9,5 +9,5 @@ Server Security Level **Signature:** ```typescript -hackDifficulty: number; +hackDifficulty?: number; ``` diff --git a/markdown/bitburner.server.httpportopen.md b/markdown/bitburner.server.httpportopen.md index 4434a5b4d..54f759053 100644 --- a/markdown/bitburner.server.httpportopen.md +++ b/markdown/bitburner.server.httpportopen.md @@ -4,7 +4,7 @@ ## Server.httpPortOpen property -Flag indicating whether HTTP Port is open +Whether or not the HTTP Port is open **Signature:** diff --git a/markdown/bitburner.server.md b/markdown/bitburner.server.md index d2a488892..6308a36bd 100644 --- a/markdown/bitburner.server.md +++ b/markdown/bitburner.server.md @@ -4,40 +4,40 @@ ## Server interface -A single server. +A server. Not all servers have all of these properties - optional properties are missing on certain servers. **Signature:** ```typescript -interface Server +export interface Server ``` ## Properties | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [backdoorInstalled](./bitburner.server.backdoorinstalled.md) | | boolean | Flag indicating whether this server has a backdoor installed by a player | -| [baseDifficulty](./bitburner.server.basedifficulty.md) | | number | Initial server security level (i.e. security level when the server was created) | -| [cpuCores](./bitburner.server.cpucores.md) | | number | How many CPU cores this server has. Maximum of 8. Affects magnitude of grow and weaken. | -| [ftpPortOpen](./bitburner.server.ftpportopen.md) | | boolean | Flag indicating whether the FTP port is open | -| [hackDifficulty](./bitburner.server.hackdifficulty.md) | | number | Server Security Level | +| [backdoorInstalled?](./bitburner.server.backdoorinstalled.md) | | boolean | _(Optional)_ Flag indicating whether this server has a backdoor installed by a player | +| [baseDifficulty?](./bitburner.server.basedifficulty.md) | | number | _(Optional)_ Server's initial server security level at creation. | +| [cpuCores](./bitburner.server.cpucores.md) | | number | How many CPU cores this server has. Affects magnitude of grow and weaken ran from this server. | +| [ftpPortOpen](./bitburner.server.ftpportopen.md) | | boolean | Whether or not the FTP port is open | +| [hackDifficulty?](./bitburner.server.hackdifficulty.md) | | number | _(Optional)_ Server Security Level | | [hasAdminRights](./bitburner.server.hasadminrights.md) | | boolean | Flag indicating whether player has admin/root access to this server | | [hostname](./bitburner.server.hostname.md) | | string | Hostname. Must be unique | -| [httpPortOpen](./bitburner.server.httpportopen.md) | | boolean | Flag indicating whether HTTP Port is open | +| [httpPortOpen](./bitburner.server.httpportopen.md) | | boolean | Whether or not the HTTP Port is open | | [ip](./bitburner.server.ip.md) | | string | IP Address. Must be unique | | [isConnectedTo](./bitburner.server.isconnectedto.md) | | boolean | Flag indicating whether player is currently connected to this server | | [maxRam](./bitburner.server.maxram.md) | | number | RAM (GB) available on this server | -| [minDifficulty](./bitburner.server.mindifficulty.md) | | number | Minimum server security level that this server can be weakened to | -| [moneyAvailable](./bitburner.server.moneyavailable.md) | | number | How much money currently resides on the server and can be hacked | -| [moneyMax](./bitburner.server.moneymax.md) | | number | Maximum amount of money that this server can hold | -| [numOpenPortsRequired](./bitburner.server.numopenportsrequired.md) | | number | Number of open ports required in order to gain admin/root access | -| [openPortCount](./bitburner.server.openportcount.md) | | number | How many ports are currently opened on the server | -| [organizationName](./bitburner.server.organizationname.md) | | string | Name of company/faction/etc. that this server belongs to. Optional, not applicable to all Servers | +| [minDifficulty?](./bitburner.server.mindifficulty.md) | | number | _(Optional)_ Minimum server security level that this server can be weakened to | +| [moneyAvailable?](./bitburner.server.moneyavailable.md) | | number | _(Optional)_ How much money currently resides on the server and can be hacked | +| [moneyMax?](./bitburner.server.moneymax.md) | | number | _(Optional)_ Maximum amount of money that this server can hold | +| [numOpenPortsRequired?](./bitburner.server.numopenportsrequired.md) | | number | _(Optional)_ Number of open ports required in order to gain admin/root access | +| [openPortCount?](./bitburner.server.openportcount.md) | | number | _(Optional)_ How many ports are currently opened on the server | +| [organizationName](./bitburner.server.organizationname.md) | | string | Name of company/faction/etc. that this server belongs to, not applicable to all Servers | | [purchasedByPlayer](./bitburner.server.purchasedbyplayer.md) | | boolean | Flag indicating whether this is a purchased server | | [ramUsed](./bitburner.server.ramused.md) | | number | RAM (GB) used. i.e. unavailable RAM | -| [requiredHackingSkill](./bitburner.server.requiredhackingskill.md) | | number | Hacking level required to hack this server | -| [serverGrowth](./bitburner.server.servergrowth.md) | | number | Parameter that affects how effectively this server's money can be increased using the grow() Netscript function | -| [smtpPortOpen](./bitburner.server.smtpportopen.md) | | boolean | Flag indicating whether SMTP Port is open | -| [sqlPortOpen](./bitburner.server.sqlportopen.md) | | boolean | Flag indicating whether SQL Port is open | -| [sshPortOpen](./bitburner.server.sshportopen.md) | | boolean | Flag indicating whether the SSH Port is open | +| [requiredHackingSkill?](./bitburner.server.requiredhackingskill.md) | | number | _(Optional)_ Hacking level required to hack this server | +| [serverGrowth?](./bitburner.server.servergrowth.md) | | number | _(Optional)_ Growth effectiveness statistic. Higher values produce more growth with ns.grow() | +| [smtpPortOpen](./bitburner.server.smtpportopen.md) | | boolean | Whether or not the SMTP Port is open | +| [sqlPortOpen](./bitburner.server.sqlportopen.md) | | boolean | Whether or not the SQL Port is open | +| [sshPortOpen](./bitburner.server.sshportopen.md) | | boolean | Whether or not the SSH Port is open | diff --git a/markdown/bitburner.server.mindifficulty.md b/markdown/bitburner.server.mindifficulty.md index 1bcbf958f..272b44f0c 100644 --- a/markdown/bitburner.server.mindifficulty.md +++ b/markdown/bitburner.server.mindifficulty.md @@ -9,5 +9,5 @@ Minimum server security level that this server can be weakened to **Signature:** ```typescript -minDifficulty: number; +minDifficulty?: number; ``` diff --git a/markdown/bitburner.server.moneyavailable.md b/markdown/bitburner.server.moneyavailable.md index 2612fd1c8..b1dea9bee 100644 --- a/markdown/bitburner.server.moneyavailable.md +++ b/markdown/bitburner.server.moneyavailable.md @@ -9,5 +9,5 @@ How much money currently resides on the server and can be hacked **Signature:** ```typescript -moneyAvailable: number; +moneyAvailable?: number; ``` diff --git a/markdown/bitburner.server.moneymax.md b/markdown/bitburner.server.moneymax.md index 8118387a0..9ef54f67d 100644 --- a/markdown/bitburner.server.moneymax.md +++ b/markdown/bitburner.server.moneymax.md @@ -9,5 +9,5 @@ Maximum amount of money that this server can hold **Signature:** ```typescript -moneyMax: number; +moneyMax?: number; ``` diff --git a/markdown/bitburner.server.numopenportsrequired.md b/markdown/bitburner.server.numopenportsrequired.md index e145d607a..b4ca3b0cf 100644 --- a/markdown/bitburner.server.numopenportsrequired.md +++ b/markdown/bitburner.server.numopenportsrequired.md @@ -9,5 +9,5 @@ Number of open ports required in order to gain admin/root access **Signature:** ```typescript -numOpenPortsRequired: number; +numOpenPortsRequired?: number; ``` diff --git a/markdown/bitburner.server.openportcount.md b/markdown/bitburner.server.openportcount.md index a206af08a..1bb3e65e2 100644 --- a/markdown/bitburner.server.openportcount.md +++ b/markdown/bitburner.server.openportcount.md @@ -9,5 +9,5 @@ How many ports are currently opened on the server **Signature:** ```typescript -openPortCount: number; +openPortCount?: number; ``` diff --git a/markdown/bitburner.server.organizationname.md b/markdown/bitburner.server.organizationname.md index cdaed7c20..5929b10dd 100644 --- a/markdown/bitburner.server.organizationname.md +++ b/markdown/bitburner.server.organizationname.md @@ -4,7 +4,7 @@ ## Server.organizationName property -Name of company/faction/etc. that this server belongs to. Optional, not applicable to all Servers +Name of company/faction/etc. that this server belongs to, not applicable to all Servers **Signature:** diff --git a/markdown/bitburner.server.requiredhackingskill.md b/markdown/bitburner.server.requiredhackingskill.md index cc2081490..f07dcd4d8 100644 --- a/markdown/bitburner.server.requiredhackingskill.md +++ b/markdown/bitburner.server.requiredhackingskill.md @@ -9,5 +9,5 @@ Hacking level required to hack this server **Signature:** ```typescript -requiredHackingSkill: number; +requiredHackingSkill?: number; ``` diff --git a/markdown/bitburner.server.servergrowth.md b/markdown/bitburner.server.servergrowth.md index cf6f60045..a6c63e2d3 100644 --- a/markdown/bitburner.server.servergrowth.md +++ b/markdown/bitburner.server.servergrowth.md @@ -4,10 +4,10 @@ ## Server.serverGrowth property -Parameter that affects how effectively this server's money can be increased using the grow() Netscript function +Growth effectiveness statistic. Higher values produce more growth with ns.grow() **Signature:** ```typescript -serverGrowth: number; +serverGrowth?: number; ``` diff --git a/markdown/bitburner.server.smtpportopen.md b/markdown/bitburner.server.smtpportopen.md index c1d4fddda..f882b75be 100644 --- a/markdown/bitburner.server.smtpportopen.md +++ b/markdown/bitburner.server.smtpportopen.md @@ -4,7 +4,7 @@ ## Server.smtpPortOpen property -Flag indicating whether SMTP Port is open +Whether or not the SMTP Port is open **Signature:** diff --git a/markdown/bitburner.server.sqlportopen.md b/markdown/bitburner.server.sqlportopen.md index d7c74757b..c0584fa45 100644 --- a/markdown/bitburner.server.sqlportopen.md +++ b/markdown/bitburner.server.sqlportopen.md @@ -4,7 +4,7 @@ ## Server.sqlPortOpen property -Flag indicating whether SQL Port is open +Whether or not the SQL Port is open **Signature:** diff --git a/markdown/bitburner.server.sshportopen.md b/markdown/bitburner.server.sshportopen.md index 3e6b01ab9..47c7e3950 100644 --- a/markdown/bitburner.server.sshportopen.md +++ b/markdown/bitburner.server.sshportopen.md @@ -4,7 +4,7 @@ ## Server.sshPortOpen property -Flag indicating whether the SSH Port is open +Whether or not the SSH Port is open **Signature:** diff --git a/src/Hacking.ts b/src/Hacking.ts index 0770754bb..10ed92aff 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -1,42 +1,37 @@ import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import { Person as IPerson } from "@nsdefs"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; -import { Server } from "./Server/Server"; +import { Server as IServer } from "@nsdefs"; /** Returns the chance the person has to successfully hack a server */ -export function calculateHackingChance(server: Server, person: IPerson): number { +export function calculateHackingChance(server: IServer, person: IPerson): number { + const hackDifficulty = server.hackDifficulty ?? 100; + const requiredHackingSkill = server.requiredHackingSkill ?? 1e9; + // Unrooted or unhackable server + if (!server.hasAdminRights || hackDifficulty >= 100) return 0; const hackFactor = 1.75; - const difficultyMult = (100 - server.hackDifficulty) / 100; + const difficultyMult = (100 - hackDifficulty) / 100; const skillMult = hackFactor * person.skills.hacking; - const skillChance = (skillMult - server.requiredHackingSkill) / skillMult; + const skillChance = (skillMult - requiredHackingSkill) / skillMult; const chance = skillChance * difficultyMult * person.mults.hacking_chance * calculateIntelligenceBonus(person.skills.intelligence, 1); - if (chance > 1) { - return 1; - } - if (chance < 0) { - return 0; - } - - return chance; + return Math.min(1, Math.max(chance, 0)); } /** * Returns the amount of hacking experience the person will gain upon * successfully hacking a server */ -export function calculateHackingExpGain(server: Server, person: IPerson): number { +export function calculateHackingExpGain(server: IServer, person: IPerson): number { + const baseDifficulty = server.baseDifficulty; + if (!baseDifficulty) return 0; const baseExpGain = 3; const diffFactor = 0.3; - if (server.baseDifficulty == null) { - server.baseDifficulty = server.hackDifficulty; - } let expGain = baseExpGain; - expGain += server.baseDifficulty * diffFactor; - + expGain += baseDifficulty * diffFactor; return expGain * person.mults.hacking_exp * BitNodeMultipliers.HackExpGain; } @@ -44,27 +39,27 @@ export function calculateHackingExpGain(server: Server, person: IPerson): number * Returns the percentage of money that will be stolen from a server if * it is successfully hacked (returns the decimal form, not the actual percent value) */ -export function calculatePercentMoneyHacked(server: Server, person: IPerson): number { +export function calculatePercentMoneyHacked(server: IServer, person: IPerson): number { + const hackDifficulty = server.hackDifficulty ?? 100; + if (hackDifficulty >= 100) return 0; + const requiredHackingSkill = server.requiredHackingSkill ?? 1e9; // Adjust if needed for balancing. This is the divisor for the final calculation const balanceFactor = 240; - const difficultyMult = (100 - server.hackDifficulty) / 100; - const skillMult = (person.skills.hacking - (server.requiredHackingSkill - 1)) / person.skills.hacking; + const difficultyMult = (100 - hackDifficulty) / 100; + const skillMult = (person.skills.hacking - (requiredHackingSkill - 1)) / person.skills.hacking; const percentMoneyHacked = (difficultyMult * skillMult * person.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney) / balanceFactor; - if (percentMoneyHacked < 0) { - return 0; - } - if (percentMoneyHacked > 1) { - return 1; - } - return percentMoneyHacked; + return Math.min(1, Math.max(percentMoneyHacked, 0)); } /** Returns time it takes to complete a hack on a server, in seconds */ -export function calculateHackingTime(server: Server, person: IPerson): number { - const difficultyMult = server.requiredHackingSkill * server.hackDifficulty; +export function calculateHackingTime(server: IServer, person: IPerson): number { + const hackDifficulty = server.hackDifficulty; + const requiredHackingSkill = server.requiredHackingSkill; + if (!hackDifficulty || !requiredHackingSkill) return Infinity; + const difficultyMult = requiredHackingSkill * hackDifficulty; const baseDiff = 500; const baseSkill = 50; @@ -82,14 +77,14 @@ export function calculateHackingTime(server: Server, person: IPerson): number { } /** Returns time it takes to complete a grow operation on a server, in seconds */ -export function calculateGrowTime(server: Server, person: IPerson): number { +export function calculateGrowTime(server: IServer, person: IPerson): number { const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2 return growTimeMultiplier * calculateHackingTime(server, person); } /** Returns time it takes to complete a weaken operation on a server, in seconds */ -export function calculateWeakenTime(server: Server, person: IPerson): number { +export function calculateWeakenTime(server: IServer, person: IPerson): number { const weakenTimeMultiplier = 4; // Relative to hacking time return weakenTimeMultiplier * calculateHackingTime(server, person); diff --git a/src/Netscript/NetscriptHelpers.ts b/src/Netscript/NetscriptHelpers.ts index eed6c5a0f..7220a8d72 100644 --- a/src/Netscript/NetscriptHelpers.ts +++ b/src/Netscript/NetscriptHelpers.ts @@ -6,7 +6,7 @@ import { ScriptDeath } from "./ScriptDeath"; import { formatExp, formatMoney, formatRam, formatThreads } from "../ui/formatNumber"; import { ScriptArg } from "./ScriptArg"; import { CityName } from "../Enums"; -import { BasicHGWOptions, RunningScript as IRunningScript, Person as IPerson } from "@nsdefs"; +import { BasicHGWOptions, RunningScript as IRunningScript, Person as IPerson, Server as IServer } from "@nsdefs"; import { Server } from "../Server/Server"; import { calculateHackingChance, @@ -597,36 +597,26 @@ function person(ctx: NetscriptContext, p: unknown): IPerson { return p as IPerson; } -function server(ctx: NetscriptContext, s: unknown): Server { +function server(ctx: NetscriptContext, s: unknown): IServer { const fakeServer = { - cpuCores: undefined, - ftpPortOpen: undefined, - hasAdminRights: undefined, hostname: undefined, - httpPortOpen: undefined, ip: undefined, + sshPortOpen: undefined, + ftpPortOpen: undefined, + smtpPortOpen: undefined, + httpPortOpen: undefined, + sqlPortOpen: undefined, + hasAdminRights: undefined, + cpuCores: undefined, isConnectedTo: undefined, + ramUsed: undefined, maxRam: undefined, organizationName: undefined, - ramUsed: undefined, - smtpPortOpen: undefined, - sqlPortOpen: undefined, - sshPortOpen: undefined, purchasedByPlayer: undefined, - backdoorInstalled: undefined, - baseDifficulty: undefined, - hackDifficulty: undefined, - minDifficulty: undefined, - moneyAvailable: undefined, - moneyMax: undefined, - numOpenPortsRequired: undefined, - openPortCount: undefined, - requiredHackingSkill: undefined, - serverGrowth: undefined, }; const error = missingKey(fakeServer, s); - if (error) throw makeRuntimeErrorMsg(ctx, `server should be a hackable Server.\n${error}`, "TYPE"); - return s as Server; + if (error) throw makeRuntimeErrorMsg(ctx, `server should be a Server.\n${error}`, "TYPE"); + return s as IServer; } function missingKey(expect: object, actual: unknown): string | false { diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 5471ed69c..c82d383d8 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -985,31 +985,56 @@ export const ns: InternalAPI = { return Object.assign({}, getBitNodeMultipliers(n, lvl)); }, - getServer: - (ctx) => - (_hostname = ctx.workerScript.hostname) => { - const hostname = helpers.string(ctx, "hostname", _hostname); - const server = helpers.getServer(ctx, hostname); - const copy = Object.assign({}, server) as Server; - // These fields should be hidden. - copy.contracts = []; - copy.messages = []; - copy.runningScripts = []; - copy.scripts = []; - copy.textFiles = []; - copy.programs = []; - copy.serversOnNetwork = []; - if (!copy.baseDifficulty) copy.baseDifficulty = 0; - if (!copy.hackDifficulty) copy.hackDifficulty = 0; - if (!copy.minDifficulty) copy.minDifficulty = 0; - if (!copy.moneyAvailable) copy.moneyAvailable = 0; - if (!copy.moneyMax) copy.moneyMax = 0; - if (!copy.numOpenPortsRequired) copy.numOpenPortsRequired = 0; - if (!copy.openPortCount) copy.openPortCount = 0; - if (!copy.requiredHackingSkill) copy.requiredHackingSkill = 0; - if (!copy.serverGrowth) copy.serverGrowth = 0; - return copy; - }, + getServer: (ctx) => (_hostname) => { + const hostname = helpers.string(ctx, "hostname", _hostname ?? ctx.workerScript.hostname); + const server = helpers.getServer(ctx, hostname); + return { + hostname: server.hostname, + ip: server.ip, + sshPortOpen: server.sshPortOpen, + ftpPortOpen: server.ftpPortOpen, + smtpPortOpen: server.smtpPortOpen, + httpPortOpen: server.httpPortOpen, + sqlPortOpen: server.sqlPortOpen, + hasAdminRights: server.hasAdminRights, + cpuCores: server.cpuCores, + isConnectedTo: server.isConnectedTo, + ramUsed: server.ramUsed, + maxRam: server.maxRam, + organizationName: server.organizationName, + purchasedByPlayer: server.purchasedByPlayer, + backdoorInstalled: server.backdoorInstalled, + baseDifficulty: server.baseDifficulty, + hackDifficulty: server.hackDifficulty, + minDifficulty: server.minDifficulty, + moneyAvailable: server.moneyAvailable, + moneyMax: server.moneyMax, + numOpenPortsRequired: server.numOpenPortsRequired, + openPortCount: server.openPortCount, + requiredHackingSkill: server.requiredHackingSkill, + serverGrowth: server.serverGrowth, + }; + + const copy = Object.assign({}, server) as Server; + // These fields should be hidden. + copy.contracts = []; + copy.messages = []; + copy.runningScripts = []; + copy.scripts = []; + copy.textFiles = []; + copy.programs = []; + copy.serversOnNetwork = []; + if (!copy.baseDifficulty) copy.baseDifficulty = 0; + if (!copy.hackDifficulty) copy.hackDifficulty = 0; + if (!copy.minDifficulty) copy.minDifficulty = 0; + if (!copy.moneyAvailable) copy.moneyAvailable = 0; + if (!copy.moneyMax) copy.moneyMax = 0; + if (!copy.numOpenPortsRequired) copy.numOpenPortsRequired = 0; + if (!copy.openPortCount) copy.openPortCount = 0; + if (!copy.requiredHackingSkill) copy.requiredHackingSkill = 0; + if (!copy.serverGrowth) copy.serverGrowth = 0; + return copy; + }, getServerMoneyAvailable: (ctx) => (_hostname) => { const hostname = helpers.string(ctx, "hostname", _hostname); const server = helpers.getServer(ctx, hostname); diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 104aadbb8..f1f6baf71 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -454,93 +454,75 @@ interface HacknetServerConstants { } /** - * A single server. + * A server. Not all servers have all of these properties - optional properties are missing on certain servers. * @public */ -interface Server { - /** - * How many CPU cores this server has. Maximum of 8. - * Affects magnitude of grow and weaken. - */ - cpuCores: number; +export interface Server { + /** Hostname. Must be unique */ + hostname: string; + /** IP Address. Must be unique */ + ip: string; - /** Flag indicating whether the FTP port is open */ + /** Whether or not the SSH Port is open */ + sshPortOpen: boolean; + /** Whether or not the FTP port is open */ ftpPortOpen: boolean; + /** Whether or not the SMTP Port is open */ + smtpPortOpen: boolean; + /** Whether or not the HTTP Port is open */ + httpPortOpen: boolean; + /** Whether or not the SQL Port is open */ + sqlPortOpen: boolean; /** Flag indicating whether player has admin/root access to this server */ hasAdminRights: boolean; - /** Hostname. Must be unique */ - hostname: string; - - /** Flag indicating whether HTTP Port is open */ - httpPortOpen: boolean; - - /** IP Address. Must be unique */ - ip: string; + /** How many CPU cores this server has. Affects magnitude of grow and weaken ran from this server. */ + cpuCores: number; /** Flag indicating whether player is currently connected to this server */ isConnectedTo: boolean; + /** RAM (GB) used. i.e. unavailable RAM */ + ramUsed: number; /** RAM (GB) available on this server */ maxRam: number; - /** - * Name of company/faction/etc. that this server belongs to. - * Optional, not applicable to all Servers - */ + /** Name of company/faction/etc. that this server belongs to, not applicable to all Servers */ organizationName: string; - /** RAM (GB) used. i.e. unavailable RAM */ - ramUsed: number; - - /** Flag indicating whether SMTP Port is open */ - smtpPortOpen: boolean; - - /** Flag indicating whether SQL Port is open */ - sqlPortOpen: boolean; - - /** Flag indicating whether the SSH Port is open */ - sshPortOpen: boolean; - /** Flag indicating whether this is a purchased server */ purchasedByPlayer: boolean; /** Flag indicating whether this server has a backdoor installed by a player */ - backdoorInstalled: boolean; + backdoorInstalled?: boolean; - /** - * Initial server security level - * (i.e. security level when the server was created) - */ - baseDifficulty: number; + /** Server's initial server security level at creation. */ + baseDifficulty?: number; /** Server Security Level */ - hackDifficulty: number; + hackDifficulty?: number; /** Minimum server security level that this server can be weakened to */ - minDifficulty: number; + minDifficulty?: number; /** How much money currently resides on the server and can be hacked */ - moneyAvailable: number; + moneyAvailable?: number; /** Maximum amount of money that this server can hold */ - moneyMax: number; + moneyMax?: number; /** Number of open ports required in order to gain admin/root access */ - numOpenPortsRequired: number; + numOpenPortsRequired?: number; /** How many ports are currently opened on the server */ - openPortCount: number; + openPortCount?: number; /** Hacking level required to hack this server */ - requiredHackingSkill: number; + requiredHackingSkill?: number; - /** - * Parameter that affects how effectively this server's money can - * be increased using the grow() Netscript function - */ - serverGrowth: number; + /** Growth effectiveness statistic. Higher values produce more growth with ns.grow() */ + serverGrowth?: number; } /** diff --git a/src/Server/BaseServer.ts b/src/Server/BaseServer.ts index fcd4293d8..7e5bbeba5 100644 --- a/src/Server/BaseServer.ts +++ b/src/Server/BaseServer.ts @@ -1,3 +1,4 @@ +import type { Server as IServer } from "@nsdefs"; import { CodingContract } from "../CodingContracts"; import { RunningScript } from "../Script/RunningScript"; import { Script } from "../Script/Script"; @@ -26,7 +27,7 @@ interface writeResult { } /** Abstract Base Class for any Server object */ -export abstract class BaseServer { +export abstract class BaseServer implements IServer { // Coding Contract files on this server contracts: CodingContract[] = []; @@ -93,8 +94,17 @@ export abstract class BaseServer { // Flag indicating whether this is a purchased server purchasedByPlayer = false; - // Variables that exist only on some types of servers can just be optional. + // Optional, listed just so they can be accessed on a BaseServer. These will be undefined for HacknetServers. backdoorInstalled?: boolean; + baseDifficulty?: number; + hackDifficulty?: number; + minDifficulty?: number; + moneyAvailable?: number; + moneyMax?: number; + numOpenPortsRequired?: number; + openPortCount?: number; + requiredHackingSkill?: number; + serverGrowth?: number; constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) { this.ip = params.ip ? params.ip : createRandomIp(); diff --git a/src/Server/ServerHelpers.ts b/src/Server/ServerHelpers.ts index e938ab1bf..c90b468e3 100644 --- a/src/Server/ServerHelpers.ts +++ b/src/Server/ServerHelpers.ts @@ -10,6 +10,7 @@ import { Programs } from "../Programs/Programs"; import { LiteratureNames } from "../Literature/data/LiteratureNames"; import { Person as IPerson } from "@nsdefs"; import { isValidNumber } from "../utils/helpers/isValidNumber"; +import { Server as IServer } from "@nsdefs"; /** * Constructs a new server, while also ensuring that the new server @@ -48,8 +49,10 @@ export function safelyCreateUniqueServer(params: IConstructorParams): Server { * @param p - Reference to Player object * @returns Number of "growth cycles" needed */ -export function numCycleForGrowth(server: Server, growth: number, cores = 1): number { - let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty; +export function numCycleForGrowth(server: IServer, growth: number, cores = 1): number { + if (!server.serverGrowth) return Infinity; + const hackDifficulty = server.hackDifficulty ?? 100; + let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / hackDifficulty; if (ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) { ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate; } @@ -79,18 +82,22 @@ export function numCycleForGrowth(server: Server, growth: number, cores = 1): nu * @returns Integer threads needed by a single ns.grow call to reach targetMoney from startMoney. */ export function numCycleForGrowthCorrected( - server: Server, + server: IServer, targetMoney: number, startMoney: number, cores = 1, person: IPerson = Player, ): number { + if (!server.serverGrowth) return Infinity; + const moneyMax = server.moneyMax ?? 1; + const hackDifficulty = server.hackDifficulty ?? 100; + if (startMoney < 0) startMoney = 0; // servers "can't" have less than 0 dollars on them - if (targetMoney > server.moneyMax) targetMoney = server.moneyMax; // can't grow a server to more than its moneyMax + if (targetMoney > moneyMax) targetMoney = moneyMax; // can't grow a server to more than its moneyMax if (targetMoney <= startMoney) return 0; // no growth --> no threads // exponential base adjusted by security - const adjGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty; + const adjGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / hackDifficulty; const exponentialBase = Math.min(adjGrowthRate, CONSTANTS.ServerMaxGrowthRate); // cap growth rate // total of all grow thread multipliers diff --git a/src/Server/formulas/grow.ts b/src/Server/formulas/grow.ts index 980d69c75..17ed99056 100644 --- a/src/Server/formulas/grow.ts +++ b/src/Server/formulas/grow.ts @@ -1,14 +1,15 @@ import { CONSTANTS } from "../../Constants"; -import { Server } from "../Server"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; -import { Person as IPerson } from "@nsdefs"; +import { Person as IPerson, Server as IServer } from "@nsdefs"; -export function calculateServerGrowth(server: Server, threads: number, p: IPerson, cores = 1): number { +export function calculateServerGrowth(server: IServer, threads: number, p: IPerson, cores = 1): number { + if (!server.serverGrowth) return 0; + const hackDifficulty = server.hackDifficulty ?? 100; const numServerGrowthCycles = Math.max(Math.floor(threads), 0); //Get adjusted growth rate, which accounts for server security const growthRate = CONSTANTS.ServerBaseGrowthRate; - let adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty; + let adjGrowthRate = 1 + (growthRate - 1) / hackDifficulty; if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) { adjGrowthRate = CONSTANTS.ServerMaxGrowthRate; }