Merge pull request #4205 from Snarling/ramTestFix

TESTS: Refined ram calculation tests
This commit is contained in:
hydroflame
2022-10-09 00:23:04 -04:00
committed by GitHub
153 changed files with 851 additions and 4069 deletions
+3 -9
View File
@@ -5,19 +5,13 @@ import { NS } from "../ScriptEditor/NetscriptDefinitions";
* Netscript functions and arguments for that script.
*/
export class Environment {
/**
* Whether or not the script that uses this Environment should stop running
*/
/** Whether or not the script that uses this Environment should stop running */
stopFlag = false;
/**
* The currently running function
*/
/** The currently running function */
runningFn = "";
/**
* Environment variables (currently only Netscript functions)
*/
/** Environment variables (currently only Netscript functions) */
vars: NS | null = null;
}
+1 -3
View File
@@ -2,9 +2,7 @@ import { workerScripts } from "./WorkerScripts";
let pidCounter = 1;
/**
* Find and return the next availble PID for a script
*/
/** Find and return the next availble PID for a script */
export function generateNextPid(): number {
let tempCounter = pidCounter;
+25 -38
View File
@@ -1,21 +1,13 @@
import { Player } from "../Player";
import { IMap } from "../types";
import { NS as INS } from "../ScriptEditor/NetscriptDefinitions";
import { INetscriptExtra } from "../NetscriptFunctions/Extra";
import { NSFull } from "../NetscriptFunctions";
/** This type assumes any value that isn't an API layer or a function has been omitted (args and enum) */
type RamCostTree<API> = {
[Property in keyof API]: API[Property] extends () => void
? number | (() => void)
: API[Property] extends object
? RamCostTree<API[Property]>
: never;
[Property in keyof API]: API[Property] extends () => unknown ? number | (() => number) : RamCostTree<API[Property]>;
};
// TODO remember to update RamCalculations.js and WorkerScript.js
// RAM costs for Netscript functions
export const RamCostConstants: IMap<number> = {
/** Constants for assigning costs to ns functions */
export const RamCostConstants: Record<string, number> = {
ScriptBaseRamCost: 1.6,
ScriptDomRamCost: 25,
ScriptCorporationRamCost: 1024 - 1.6,
@@ -121,7 +113,7 @@ const hacknet = {
getHashUpgradeLevel: 0,
getStudyMult: 0,
getTrainingMult: 0,
};
} as const;
// Stock API
const stock = {
@@ -150,7 +142,7 @@ const stock = {
purchase4SMarketDataTixApi: RamCostConstants.ScriptBuySellStockRamCost,
purchaseWseAccount: RamCostConstants.ScriptBuySellStockRamCost,
purchaseTixApi: RamCostConstants.ScriptBuySellStockRamCost,
};
} as const;
// Singularity API
const singularity = {
@@ -209,7 +201,7 @@ const singularity = {
b1tflum3: SF4Cost(16),
destroyW0r1dD43m0n: SF4Cost(32),
getCurrentWork: SF4Cost(0.5),
};
} as const;
// Gang API
const gang = {
@@ -234,7 +226,7 @@ const gang = {
setTerritoryWarfare: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getChanceToWinClash: RamCostConstants.ScriptGangApiBaseRamCost,
getBonusTime: 0,
};
} as const;
// Bladeburner API
const bladeburner = {
@@ -273,12 +265,12 @@ const bladeburner = {
joinBladeburnerFaction: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
joinBladeburnerDivision: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getBonusTime: 0,
};
} as const;
const infiltration = {
getPossibleLocations: RamCostConstants.ScriptInfiltrationGetLocations,
getInfiltration: RamCostConstants.ScriptInfiltrationGetInfiltrations,
};
} as const;
// Coding Contract API
const codingcontract = {
@@ -287,7 +279,7 @@ const codingcontract = {
getData: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getDescription: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getNumTriesRemaining: RamCostConstants.ScriptCodingContractBaseRamCost / 5,
};
} as const;
// Duplicate Sleeve API
const sleeve = {
@@ -309,7 +301,7 @@ const sleeve = {
setToBladeburnerAction: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveAugmentationPrice: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveAugmentationRepReq: RamCostConstants.ScriptSleeveBaseRamCost,
};
} as const;
// Stanek API
const stanek = {
@@ -324,7 +316,7 @@ const stanek = {
getFragment: RamCostConstants.ScriptStanekFragmentAt,
removeFragment: RamCostConstants.ScriptStanekDeleteAt,
acceptGift: RamCostConstants.ScriptStanekAcceptGift,
};
} as const;
// UI API
const ui = {
@@ -337,7 +329,7 @@ const ui = {
getGameInfo: 0,
clearTerminal: 0,
windowSize: 0,
};
} as const;
// Grafting API
const grafting = {
@@ -345,7 +337,7 @@ const grafting = {
getAugmentationGraftTime: 3.75,
getGraftableAugmentations: 5,
graftAugmentation: 7.5,
};
} as const;
const corporation = {
getMaterialNames: 0,
@@ -413,16 +405,17 @@ const corporation = {
hasResearched: 0,
setAutoJobAssignment: 0,
getOfficeSizeUpgradeCost: 0,
};
} as const;
const SourceRamCosts = {
args: undefined as unknown as never[], // special use case
enums: undefined as unknown as never,
/** RamCosts guaranteed to match ns structure 1:1 (aside from args and enums).
* An error will be generated if there are missing OR additional ram costs defined.
* To avoid errors, define every function in NetscriptDefinition.d.ts and NetscriptFunctions,
* and have a ram cost associated here. */
export const RamCosts: RamCostTree<Omit<NSFull, "args" | "enums">> = {
corporation,
hacknet,
stock,
singularity,
...singularity, // singularity is in namespace & toplevel
gang,
bladeburner,
infiltration,
@@ -602,13 +595,7 @@ const SourceRamCosts = {
factionGains: 0,
},
},
};
export const RamCosts: IMap<any> = SourceRamCosts;
// This line in particular is there so typescript typechecks that we are not missing any static ram cost.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _typecheck: RamCostTree<INS & INetscriptExtra> = SourceRamCosts;
} as const;
export function getRamCost(...args: string[]): number {
if (args.length === 0) {
@@ -616,7 +603,7 @@ export function getRamCost(...args: string[]): number {
return 0;
}
let curr = RamCosts[args[0]];
let curr = RamCosts[args[0] as keyof typeof RamCosts];
for (let i = 1; i < args.length; ++i) {
if (curr == null) {
console.warn(`Invalid function passed to getRamCost: ${args}`);
@@ -628,7 +615,7 @@ export function getRamCost(...args: string[]): number {
break;
}
curr = curr[args[i]];
curr = curr[args[i] as keyof typeof curr];
}
if (typeof curr === "number") {
+17 -46
View File
@@ -13,20 +13,15 @@ import { RunningScript } from "../Script/RunningScript";
import { Script } from "../Script/Script";
import { GetServer } from "../Server/AllServers";
import { BaseServer } from "../Server/BaseServer";
import { IMap } from "../types";
import { NS } from "../ScriptEditor/NetscriptDefinitions";
import { ScriptDeath } from "./ScriptDeath";
import { ScriptArg } from "./ScriptArg";
export class WorkerScript {
/**
* Script's arguments
*/
/** Script's arguments */
args: ScriptArg[];
/**
* Copy of the script's code
*/
/** Copy of the script's code */
code = "";
/**
@@ -35,52 +30,38 @@ export class WorkerScript {
*/
delay: number | null = null;
/**
* Holds the Promise reject() function while the script is "blocked" by an async op
*/
/** Holds the Promise reject() function while the script is "blocked" by an async op */
delayReject?: (reason?: ScriptDeath) => void;
/**
* Stores names of all functions that have logging disabled
*/
disableLogs: IMap<boolean> = {};
/** Stores names of all functions that have logging disabled */
disableLogs: Record<string, boolean> = {};
/**
* Used for dynamic RAM calculation. Stores names of all functions that have
* already been checked by this script.
* TODO: Could probably just combine this with loadedFns?
*/
dynamicLoadedFns: IMap<boolean> = {};
dynamicLoadedFns: Record<string, boolean> = {};
/**
* Tracks dynamic RAM usage
*/
/** Tracks dynamic RAM usage */
dynamicRamUsage: number = RamCostConstants.ScriptBaseRamCost;
/**
* Netscript Environment for this script
*/
/** Netscript Environment for this script */
env: Environment;
/**
* Status message in case of script error.
*/
/** Status message in case of script error. */
errorMessage = "";
/**
* Used for static RAM calculation. Stores names of all functions that have
* already been checked by this script
*/
loadedFns: IMap<boolean> = {};
loadedFns: Record<string, boolean> = {};
/**
* Filename of script
*/
/** Filename of script */
name: string;
/**
* Script's output/return value. Currently not used or implemented
*/
/** Script's output/return value. Currently not used or implemented */
output = "";
/**
@@ -89,24 +70,16 @@ export class WorkerScript {
*/
pid: number;
/**
* Script's Static RAM usage. Equivalent to underlying script's RAM usage
*/
/** Script's Static RAM usage. Equivalent to underlying script's RAM usage */
ramUsage = 0;
/**
* Reference to underlying RunningScript object
*/
/** Reference to underlying RunningScript object */
scriptRef: RunningScript;
/**
* hostname on which this script is running
*/
/** hostname on which this script is running */
hostname: string;
/**
* Function called when the script ends.
*/
/** Function called when the script ends. */
atExit?: () => void;
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => NS) {
@@ -143,9 +116,7 @@ export class WorkerScript {
}
}
/**
* Returns the Server on which this script is running
*/
/** Returns the Server on which this script is running */
getServer(): BaseServer {
const server = GetServer(this.hostname);
if (server == null) throw new Error(`Script ${this.name} pid ${this.pid} is running on non-existent server?`);
@@ -1,6 +1,4 @@
/**
* Event emitter that triggers when scripts are started/stopped
*/
import { EventEmitter } from "../utils/EventEmitter";
/** Event emitter that triggers when scripts are started/stopped */
export const WorkerScriptStartStopEventEmitter = new EventEmitter<[]>();
+1 -3
View File
@@ -1,6 +1,4 @@
/**
* Global pool of all active scripts (scripts that are currently running)
*/
import { WorkerScript } from "./WorkerScript";
/** Global pool of all active scripts (scripts that are currently running) */
export const workerScripts: Map<number, WorkerScript> = new Map();