2021-09-05 01:09:30 +02:00
|
|
|
import { CONSTANTS } from "../Constants";
|
2022-10-10 00:42:14 +02:00
|
|
|
import { Player } from "@player";
|
2021-09-24 22:34:21 +02:00
|
|
|
import { BaseServer } from "../Server/BaseServer";
|
|
|
|
import { Server } from "../Server/Server";
|
2022-03-06 05:05:55 +01:00
|
|
|
import { RunningScript } from "./RunningScript";
|
2021-10-07 22:56:01 +02:00
|
|
|
import { processSingleServerGrowth } from "../Server/ServerHelpers";
|
|
|
|
import { GetServer } from "../Server/AllServers";
|
2023-02-11 19:18:50 +01:00
|
|
|
import { formatPercent } from "../ui/formatNumber";
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
import { workerScripts } from "../Netscript/WorkerScripts";
|
2023-04-28 00:21:06 +02:00
|
|
|
import { scriptKey } from "../utils/helpers/scriptKey";
|
|
|
|
|
|
|
|
import type { ScriptFilePath } from "../Paths/ScriptFilePath";
|
2018-05-06 00:13:35 +02:00
|
|
|
|
2021-09-25 07:26:03 +02:00
|
|
|
export function scriptCalculateOfflineProduction(runningScript: RunningScript): void {
|
2021-09-05 01:09:30 +02:00
|
|
|
//The Player object stores the last update time from when we were online
|
|
|
|
const thisUpdate = new Date().getTime();
|
|
|
|
const lastUpdate = Player.lastUpdate;
|
|
|
|
const timePassed = (thisUpdate - lastUpdate) / 1000; //Seconds
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
//Calculate the "confidence" rating of the script's true production. This is based
|
|
|
|
//entirely off of time. We will arbitrarily say that if a script has been running for
|
|
|
|
//4 hours (14400 sec) then we are completely confident in its ability
|
2021-09-24 22:34:21 +02:00
|
|
|
let confidence = runningScript.onlineRunningTime / 14400;
|
2021-09-05 01:09:30 +02:00
|
|
|
if (confidence >= 1) {
|
|
|
|
confidence = 1;
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
//Data map: [MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken]
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Grow
|
2022-01-16 01:45:03 +01:00
|
|
|
for (const hostname of Object.keys(runningScript.dataMap)) {
|
2021-10-07 23:55:49 +02:00
|
|
|
if (runningScript.dataMap.hasOwnProperty(hostname)) {
|
|
|
|
if (runningScript.dataMap[hostname][2] == 0 || runningScript.dataMap[hostname][2] == null) {
|
2021-09-05 01:09:30 +02:00
|
|
|
continue;
|
|
|
|
}
|
2021-10-07 23:55:49 +02:00
|
|
|
const serv = GetServer(hostname);
|
2021-09-05 01:09:30 +02:00
|
|
|
if (serv == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const timesGrown = Math.round(
|
2021-10-07 23:55:49 +02:00
|
|
|
((0.5 * runningScript.dataMap[hostname][2]) / runningScript.onlineRunningTime) * timePassed,
|
2021-09-05 01:09:30 +02:00
|
|
|
);
|
2021-09-24 22:34:21 +02:00
|
|
|
runningScript.log(`Called on ${serv.hostname} ${timesGrown} times while offline`);
|
2021-10-07 22:56:01 +02:00
|
|
|
const host = GetServer(runningScript.server);
|
2021-10-07 22:04:04 +02:00
|
|
|
if (host === null) throw new Error("getServer of null key?");
|
2021-09-24 22:34:21 +02:00
|
|
|
if (!(serv instanceof Server)) throw new Error("trying to grow a non-normal server");
|
2022-09-18 03:09:15 +02:00
|
|
|
const growth = processSingleServerGrowth(serv, timesGrown, host.cpuCores);
|
2023-02-11 19:18:50 +01:00
|
|
|
runningScript.log(`'${serv.hostname}' grown by ${formatPercent(growth - 1, 6)} while offline`);
|
2017-05-10 19:42:46 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
}
|
2017-05-10 19:42:46 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Offline EXP gain
|
|
|
|
// A script's offline production will always be at most half of its online production.
|
2021-09-24 22:34:21 +02:00
|
|
|
const expGain = confidence * (runningScript.onlineExpGained / runningScript.onlineRunningTime) * timePassed;
|
2021-09-05 01:09:30 +02:00
|
|
|
Player.gainHackingExp(expGain);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Update script stats
|
2021-09-24 22:34:21 +02:00
|
|
|
runningScript.offlineRunningTime += timePassed;
|
|
|
|
runningScript.offlineExpGained += expGain;
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Weaken
|
2022-01-16 01:45:03 +01:00
|
|
|
for (const hostname of Object.keys(runningScript.dataMap)) {
|
2021-10-07 23:55:49 +02:00
|
|
|
if (runningScript.dataMap.hasOwnProperty(hostname)) {
|
|
|
|
if (runningScript.dataMap[hostname][3] == 0 || runningScript.dataMap[hostname][3] == null) {
|
2021-09-05 01:09:30 +02:00
|
|
|
continue;
|
|
|
|
}
|
2021-10-07 23:55:49 +02:00
|
|
|
const serv = GetServer(hostname);
|
2021-09-05 01:09:30 +02:00
|
|
|
if (serv == null) {
|
|
|
|
continue;
|
|
|
|
}
|
2021-09-24 22:34:21 +02:00
|
|
|
|
|
|
|
if (!(serv instanceof Server)) throw new Error("trying to weaken a non-normal server");
|
2021-10-07 22:56:01 +02:00
|
|
|
const host = GetServer(runningScript.server);
|
2021-10-07 22:04:04 +02:00
|
|
|
if (host === null) throw new Error("getServer of null key?");
|
2021-09-05 01:09:30 +02:00
|
|
|
const timesWeakened = Math.round(
|
2021-10-07 23:55:49 +02:00
|
|
|
((0.5 * runningScript.dataMap[hostname][3]) / runningScript.onlineRunningTime) * timePassed,
|
2021-09-05 01:09:30 +02:00
|
|
|
);
|
2021-09-24 22:34:21 +02:00
|
|
|
runningScript.log(`Called weaken() on ${serv.hostname} ${timesWeakened} times while offline`);
|
2021-09-05 01:09:30 +02:00
|
|
|
const coreBonus = 1 + (host.cpuCores - 1) / 16;
|
|
|
|
serv.weaken(CONSTANTS.ServerWeakenAmount * timesWeakened * coreBonus);
|
2017-06-01 03:57:49 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
}
|
2017-05-10 19:42:46 +02:00
|
|
|
}
|
|
|
|
|
2023-04-28 00:21:06 +02:00
|
|
|
//Returns a RunningScript map containing scripts matching the filename and
|
|
|
|
//arguments on the designated server, or null if none were found
|
|
|
|
export function findRunningScripts(
|
|
|
|
path: ScriptFilePath,
|
2021-12-03 20:44:32 +01:00
|
|
|
args: (string | number | boolean)[],
|
2021-09-25 07:26:03 +02:00
|
|
|
server: BaseServer,
|
2023-04-28 00:21:06 +02:00
|
|
|
): Map<number, RunningScript> | null {
|
|
|
|
return server.runningScriptMap.get(scriptKey(path, args)) ?? null;
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
2021-04-21 14:20:26 +02:00
|
|
|
|
|
|
|
//Returns a RunningScript object matching the pid on the
|
|
|
|
//designated server, and false otherwise
|
2021-09-25 07:26:03 +02:00
|
|
|
export function findRunningScriptByPid(pid: number, server: BaseServer): RunningScript | null {
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
const ws = workerScripts.get(pid);
|
|
|
|
// Return null if no ws found or if it's on a different server.
|
|
|
|
if (!ws) return null;
|
|
|
|
if (ws.scriptRef.server !== server.hostname) return null;
|
|
|
|
return ws.scriptRef;
|
2021-04-29 02:07:26 +02:00
|
|
|
}
|