Merge branch 'dev' into nan-donation

This commit is contained in:
hydroflame 2022-01-05 10:15:40 -05:00 committed by GitHub
commit f798115259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 717 additions and 750 deletions

26
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -12,3 +12,4 @@ must be unlocked.
Source-Files <advancedgameplay/sourcefiles> Source-Files <advancedgameplay/sourcefiles>
Intelligence <advancedgameplay/intelligence> Intelligence <advancedgameplay/intelligence>
Sleeves <advancedgameplay/sleeves> Sleeves <advancedgameplay/sleeves>
Hacking algorithms <advancedgameplay/hackingalgorithms>

@ -79,7 +79,7 @@ Growth can be made more efficient by dividing it into many processes, instead of
Utilizing `sleep()` or `asleep()` to ensure that your scripts do not all start at the same time can decrease the chance of issues associated with overhacking occurring. Both functions have a ram cost of zero. Utilizing `sleep()` or `asleep()` to ensure that your scripts do not all start at the same time can decrease the chance of issues associated with overhacking occurring. Both functions have a ram cost of zero.
Batch algorithms (HGW, HWGW, or Cycles) Batch algorithms (HGW, HWGW, or Cycles)
------------------------------------- ---------------------------------------
**Difficulty**: Hard **Difficulty**: Hard
Pros: Pros:

@ -28,7 +28,7 @@ List of all Source-Files
|| || * Increases the player's charisma and company salary multipliers by 8%/12%/14%. | || || * Increases the player's charisma and company salary multipliers by 8%/12%/14%. |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|| BitNode-4: The Singularity || * Let the player access and use Netscript Singularity Functions in other BitNodes. | || BitNode-4: The Singularity || * Let the player access and use Netscript Singularity Functions in other BitNodes. |
|| || * Each level of this Source-File opens up more of the Singularity Functions to use. | || || * Each level of this Source-File reduces the RAM cost of singularity functions. |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|| BitNode-5: Artificial Intelligence || * Unlocks :ref:`gameplay_intelligence`. | || BitNode-5: Artificial Intelligence || * Unlocks :ref:`gameplay_intelligence`. |
|| || * Unlocks :js:func:`getBitNodeMultipliers` and start with Formulas.exe. | || || * Unlocks :js:func:`getBitNodeMultipliers` and start with Formulas.exe. |

@ -3,6 +3,93 @@
Changelog Changelog
========= =========
v1.3.0 - 2022-01-04 Cleaning up
-------------------------------
** External IDE integration **
* The Steam version has a webserver that allows integration with external IDEs.
A VSCode extension is available on the market place. (The documentation for the ext. isn't
written yet)
** Source-Files **
* SF4 has been reworked.
* New SF -1.
** UI **
* Fix some edge case with skill bat tooltips (@MartinFournier)
* Made some background match theme color (@Kejikus)
* Fix problem with script editor height not adjusting correctly (@billyvg)
* Fix some formatting issues with Bladeburner (@MartinFournier, @nickofolas)
* Fix some functions like 'alert' format messages better (@MageKing17)
* Many community themes added.
* New script editor theme (@Hedrauta, @Dexalt142)
* Improvements to tail windows (@theit8514)
* Training is more consise (@mikomyazaki)
* Fix Investopedia not displaying properly (@JotaroS)
* Remove alpha from theme editor (@MartinFournier)
* Fix corporation tooltip not displaying properly (@MartinFournier)
* Add tooltip on backdoored location names (@MartinFournier)
* Allow toasts to be dismissed by clicking them (@nickofolas)
* Darkweb item listing now shows what you own. (@hexnaught)
** Bug fix **
* Fix unit tests (@MartinFournier)
* Fixed issue with 'cat' and 'read' not finding foldered files (@Nick-Colclasure)
* Buying on the dark web will remove incomplete exe (@hexnaught)
* Fix bug that would cause the game to crash trying to go to a job without a job (@hexnaught)
* purchaseServer validation (@nickofolas)
* Script Editor focuses code when changing tab (@MartinFournier)
* Fix script editor for .txt files (@65-7a)
* Fix 'buy' command not displaying correctly. (@hexnaught)
* Fix hackAnalyzeThread returning NaN (@mikomyazaki)
* Electron handles exceptions better (@MageKing17)
* Electron will handle 'unresponsive' event and present the opportunity to reload the game with no scripts (@MartinFournier)
* Fix 'cp' between folders (@theit8514)
* Fix throwing null/undefined errors (@nickofolas)
* Allow shortcuts to work when unfocused (@MageKing17)
* Fix some dependency issue (@locriacyber)
* Fix corporation state returning an object instead of a string (@antonvmironov)
* Fix 'mv' overwriting files (@theit8514)
* Fix joesguns not being influenced by hack/grow (@dou867, @MartinFournier)
* Added warning when opening external links. (@MartinFournier)
* Prevent applying for positions that aren't offered (@TheMas3212)
* Import has validation (@MartinFournier)
** Misc. **
* Added vim mode to script editor (@billyvg)
* Clean up script editor code (@Rez855)
* 'cat' works on scripts (@65-7a)
* Add wordWrap for Monaco (@MartinFournier)
* Include map bundles in electron for easier debugging (@MartinFournier)
* Fix importing very large files (@MartinFournier)
* Cache program blob, reducing ram usage of the game (@theit8514)
* Dev menu can set server to $0 (@mikomyazaki)
* 'backdoor' allows direct connect (@mikomyazaki)
* Github workflow work (@MartinFournier)
* workForFaction / workForCompany have a new parameter (@theit8514)
* Alias accept single quotes (@sporkwitch, @FaintSpeaker)
* Add grep options to 'ps' (@maxtimum)
* Added buy all option to 'buy' (@anthonydroberts)
* Added more shortcuts to terminal input (@Frank-py)
* Refactor some port code (@ErzengelLichtes)
* Settings to control GiB vs GB (@ErzengelLichtes)
* Add electron option to export save game (@MartinFournier)
* Electron improvements (@MartinFournier)
* Expose some notifications functions to electron (@MartinFournier)
* Documentation (@MartinFournier, @cyn, @millennIumAMbiguity, @2PacIsAlive,
@TheCoderJT, @hexnaught, @sschmidTU, @FOLLGAD, @Hedrauta, @Xynrati,
@mikomyazaki, @Icehawk78, @aaronransley, @TheMas3212, @Hedrauta, @alkemann,
@ReeseJones, @amclark42, @thadguidry, @jasonhaxstuff, @pan-kuleczka, @jhollowe,
@ApatheticsAnonymous, @erplsf, @daanflore, @nickofolas, @Kebap, @smolgumball,
@woody-lam-cwl)
v1.1.0 - 2021-12-18 You guys are awesome (community because they're god damn awesome) v1.1.0 - 2021-12-18 You guys are awesome (community because they're god damn awesome)
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------

@ -56,7 +56,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = 'Bitburner' project = 'Bitburner'
author = 'Bitburner' author = 'Bitburner'
copyright = '2018, {0}'.format(author) copyright = '2016, {0}'.format(author)
documentation_title = '{0} Documentation'.format(project) documentation_title = '{0} Documentation'.format(project)
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '1.2' version = '1.3'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '1.2.0' release = '1.3.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

@ -1,16 +0,0 @@
canPlace() Netscript Function
=======================================
.. js:function:: canPlace(worldX, worldY, rotation, fragmentId)
:RAM cost: 0.5 GB
:param int worldX: World X against which to align the top left of the fragment.
:param int worldY: World Y against which to align the top left of the fragment.
:param int rotation: A number from 0 to 3, the mount of 90 degree turn to take.
:param int fragmentId: ID of the fragment to place.
:returns: `true` if the fragment can be placed at that position. `false` otherwise.
Example:
.. code-block:: javascript
canPlace(0, 4, 17); // returns true

@ -1,21 +0,0 @@
charge() Netscript Function
=======================================
.. js:function:: charge(worldX, worldY)
:RAM cost: 0.4 GB
:param int worldX: World X of the fragment to charge.
:param int worldY: World Y of the fragment to charge.
Charge a fragment, increasing it's power but also it's heat. The
effectiveness of the charge depends on the amount of ram the running script
consumes as well as the fragments current heat. This operation takes time to
complete.
Example:
.. code-block:: javascript
charge(0, 4); // Finishes 5 seconds later.
.. warning::
Netscript JS users: This function is `async`

@ -1,13 +0,0 @@
clear() Netscript Function
=======================================
.. js:function:: clear()
:RAM cost: 0 GB
Completely clear Stanek's Gift.
Example:
.. code-block:: javascript
clear(); // No more fragments.

@ -1,16 +0,0 @@
deleteAt() Netscript Function
=======================================
.. js:function:: deleteAt(worldX, worldY)
:RAM cost: 0.15 GB
:param int worldX: World X coordinate of the fragment to delete.
:param int worldY: World Y coordinate of the fragment to delete.
:returns: `true` if the fragment was deleted. `false` otherwise.
Delete the fragment located at `[worldX, worldY]`.
Example:
.. code-block:: javascript
deleteAt(0, 4); // returns true

@ -1,28 +0,0 @@
fragmentAt() Netscript Function
=======================================
.. js:function:: fragmentAt(worldX, worldY)
:RAM cost: 2 GB
:param int worldX: World X coordinate of the fragment.
:param int worldY: World Y coordinate of the fragment.
:returns: The fragment located at `[worldX, worldY]` in Stanek's Gift, or null.
.. code-block:: typescript
{
// In world coordinates
x: number;
y: number;
heat: number;
charge: number;
id: number;
shape: boolean[][];
type: string;
magnitude: number;
limit: number;
}
Example:
.. code-block:: javascript
var fragment = fragmentAt(0, 4);
print(fragment); // {'heat': 50, 'charge': 98}

@ -1,23 +0,0 @@
fragmentDefinitions() Netscript Function
=======================================
.. js:function:: fragmentDefinitions()
:RAM cost: 0 GB
:returns: The list of all fragment that can be embedded in Stanek's Gift.
.. code-block:: typescript
[
{
id: number;
shape: boolean[][];
type: string;
magnitude: number;
limit: number;
}
]
Example:
.. code-block:: javascript
var fragments = fragmentDefinitions();
print(fragment); // prints all possible fragments

@ -1,16 +0,0 @@
place() Netscript Function
=======================================
.. js:function:: place(worldX, worldY, fragmentId)
:RAM cost: 5 GB
:param int worldX: World X against which to align the top left of the fragment.
:param int worldY: World Y against which to align the top left of the fragment.
:param int rotation: A number from 0 to 3, the mount of 90 degree turn to take.
:param int fragmentId: ID of the fragment to place.
:returns: `true` if the fragment has been placed at that position. `false` otherwise.
Example:
.. code-block:: javascript
place(0, 4, 17); // returns true

@ -1,26 +0,0 @@
placedFragments() Netscript Function
=======================================
.. js:function:: placedFragments()
:RAM cost: 5 GB
:returns: The list of all fragment that are embedded in Stanek's Gift.
.. code-block:: typescript
[
{
// In world coordinates
x: number;
y: number;
charge: number;
id: number;
shape: boolean[][];
type: string;
power: number;
limit: number;
}
]
Example:
.. code-block:: javascript
var myFragments = placedFragments();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
{ {
"name": "bitburner", "name": "bitburner",
"license": "SEE LICENSE IN license.txt", "license": "SEE LICENSE IN license.txt",
"version": "1.2.0", "version": "1.3.0",
"main": "electron-main.js", "main": "electron-main.js",
"author": { "author": {
"name": "Daniel Xie & Olivier Gagnon" "name": "Daniel Xie & Olivier Gagnon"

@ -165,7 +165,7 @@ BitNodes["BitNode4"] = new BitNode(
<br /> <br />
Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will upgrade its Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File lets you access and use the Singularity Functions in other BitNodes. level up to a maximum of 3. This Source-File lets you access and use the Singularity Functions in other BitNodes.
Each level of this Source-File will open up more Singularity Functions that you can use. Each level of this Source-File reduces the RAM cost of singularity functions.
</> </>
), ),
); );

@ -111,8 +111,8 @@ export const CONSTANTS: {
TotalNumBitNodes: number; TotalNumBitNodes: number;
LatestUpdate: string; LatestUpdate: string;
} = { } = {
VersionString: "1.2.0", VersionString: "1.3.0",
VersionNumber: 8, VersionNumber: 9,
// Speed (in ms) at which the main loop is updated // Speed (in ms) at which the main loop is updated
_idleSpeed: 200, _idleSpeed: 200,
@ -273,103 +273,89 @@ export const CONSTANTS: {
TotalNumBitNodes: 24, TotalNumBitNodes: 24,
LatestUpdate: ` LatestUpdate: `
v1.1.0 - 2021-12-18 You guys are awesome (community because they're god damn awesome) v1.3.0 - 2022-01-04 Cleaning up
------------------------------------------------------------------------------------- -------------------------------
** Script Editor ** ** External IDE integration **
* The Steam version has a webserver that allows integration with external IDEs.
A VSCode extension is available on the market place. (The documentation for the ext. isn't
written yet)
** Source-Files **
* The text editor can open several files at once. (@Rez855 / @Shadow72) * SF4 has been reworked.
It's not perfect so keep the feedback coming. * New SF -1.
** Steam ** ** UI **
* Windows has a new launch option that lets player start with killing all their scripts * Fix some edge case with skill bat tooltips (@MartinFournier)
This is a safety net in case all the other safety nets fail. * Made some background match theme color (@Kejikus)
* Linux has several launch options that use different flags for different OS. * Fix problem with script editor height not adjusting correctly (@billyvg)
* Debug and Fullscreen are available in the window utility bar. * Fix some formatting issues with Bladeburner (@MartinFournier, @nickofolas)
* Tried (and maybe failed) to make the game completely kill itself after closing. * Fix some functions like 'alert' format messages better (@MageKing17)
This one I still don't know wtf is going. * Many community themes added.
* No longer has background throttling. * New script editor theme (@Hedrauta, @Dexalt142)
* Default color should be pitch black when loading * Improvements to tail windows (@theit8514)
* Add BN13: Challenge achievement. * Training is more consise (@mikomyazaki)
* Fix Investopedia not displaying properly (@JotaroS)
* Remove alpha from theme editor (@MartinFournier)
* Fix corporation tooltip not displaying properly (@MartinFournier)
* Add tooltip on backdoored location names (@MartinFournier)
* Allow toasts to be dismissed by clicking them (@nickofolas)
* Darkweb item listing now shows what you own. (@hexnaught)
** Tutorial ** ** Bug fix **
* I watched someone play bitburner on youtube and reworked part of * Fix unit tests (@MartinFournier)
the tutorial to try to make some parts of the game clearer. * Fixed issue with 'cat' and 'read' not finding foldered files (@Nick-Colclasure)
https://www.youtube.com/watch?v=-_JETXff4Zo * Buying on the dark web will remove incomplete exe (@hexnaught)
* Add option to restart tutorial. * Fix bug that would cause the game to crash trying to go to a job without a job (@hexnaught)
* purchaseServer validation (@nickofolas)
** Netscript ** * Script Editor focuses code when changing tab (@MartinFournier)
* Fix script editor for .txt files (@65-7a)
* getGangInformation returns more information. * Fix 'buy' command not displaying correctly. (@hexnaught)
* getAscensionResult added * Fix hackAnalyzeThread returning NaN (@mikomyazaki)
* getMemberInformation returns more info * Electron handles exceptions better (@MageKing17)
* Formulas API has new functions for gang. * Electron will handle 'unresponsive' event and present the opportunity to reload the game with no scripts (@MartinFournier)
* Added documentation for corp API. * Fix 'cp' between folders (@theit8514)
* exec has clearer error message when you send invalid data. * Fix throwing null/undefined errors (@nickofolas)
* getServer returns all defined field for hacknet servers. * Allow shortcuts to work when unfocused (@MageKing17)
* Fix a bug with scp multiple files (@theit8514) * Fix some dependency issue (@locriacyber)
* Stack traces should be smarter at replacing blobs with filenames * Fix corporation state returning an object instead of a string (@antonvmironov)
* Fix a weird error message that would occur when throwing raw strings. * Fix 'mv' overwriting files (@theit8514)
* Fix shortcuts not working. * Fix joesguns not being influenced by hack/grow (@dou867, @MartinFournier)
* Re-added setFocus and isFocused (@theit8514) * Added warning when opening external links. (@MartinFournier)
* new function getHashUpgrades (@MartinFournier) * Prevent applying for positions that aren't offered (@TheMas3212)
* enableLog accepts "ALL" like disableLog (@wynro) * Import has validation (@MartinFournier)
* toast() doesn't crash on invalid data (@ivanjermakov)
* alert() doesn't crash on invalid data (@Siern)
* Fixed an issue where scripts don't run where they should.
* Sleeve getInformation now returns cha
* getServer does work with no argument now
* workForFaction returns false when it mistakenly returned null
** Character Overview **
* The character overview now shows the amount of exp needed to next level (@MartinFournier)
** Misc. ** ** Misc. **
* Add option to supress Game Saved! toasts (@MartinFournier) * Added vim mode to script editor (@billyvg)
* Fix bug where ctrl+alt+j was eaten by the wrong process. (@billyvg) * Clean up script editor code (@Rez855)
* Theme Editor lets you paste colors (@MartinFournier) * 'cat' works on scripts (@65-7a)
* ctrl + u/k/w should work on terminal (@billyvg) * Add wordWrap for Monaco (@MartinFournier)
* Game now shows commit number, this is mostly for me. (@MartinFourier) * Include map bundles in electron for easier debugging (@MartinFournier)
* running a bad script will give a clearer error message (@TheCoderJT) * Fix importing very large files (@MartinFournier)
* Default terminal capacity is maximum (@SayntGarmo) * Cache program blob, reducing ram usage of the game (@theit8514)
* Fix problems with cp and mv (@theit8514) * Dev menu can set server to $0 (@mikomyazaki)
* Make monaco load fully offline for players behind firewalls. * 'backdoor' allows direct connect (@mikomyazaki)
* change beginer guide to use n00dles instead of foodnstuff * Github workflow work (@MartinFournier)
* BN13 is harder * workForFaction / workForCompany have a new parameter (@theit8514)
* nerf int gain from manualHack * Alias accept single quotes (@sporkwitch, @FaintSpeaker)
* Fix UI displaying wrong stats (@DJMatch3000) * Add grep options to 'ps' (@maxtimum)
* Fix button not disabling as it should. * Added buy all option to 'buy' (@anthonydroberts)
* New location in Ishima. * Added more shortcuts to terminal input (@Frank-py)
* Add setting to suppress stock market popups. * Refactor some port code (@ErzengelLichtes)
* Typo fixes (@Hedrauta, @cvr-119, @Ationi, @millennIumAMbiguity * Settings to control GiB vs GB (@ErzengelLichtes)
@TealKoi, @TheCoderJT, @cblte, @2PacIsAlive, @MageKing17, * Add electron option to export save game (@MartinFournier)
@Xynrati, @Adraxas, @pobiega) * Electron improvements (@MartinFournier)
* Fix 100% territory achievement. * Expose some notifications functions to electron (@MartinFournier)
* Reword message on active scripts page. * Documentation (@MartinFournier, @cyn, @millennIumAMbiguity, @2PacIsAlive,
* Fix terminal not clearing after BN @TheCoderJT, @hexnaught, @sschmidTU, @FOLLGAD, @Hedrauta, @Xynrati,
* Remove references to .fconf @mikomyazaki, @Icehawk78, @aaronransley, @TheMas3212, @Hedrauta, @alkemann,
* Augmentation pages shows BN difficulty with SF5 @ReeseJones, @amclark42, @thadguidry, @jasonhaxstuff, @pan-kuleczka, @jhollowe,
* Fix scripts saving on wrong server while 'connect'ing @ApatheticsAnonymous, @erplsf, @daanflore, @nickofolas, @Kebap, @smolgumball,
* Fix gym discount not working. @woody-lam-cwl)
* Fix scan-analyze not working with timestamps
* Hash upgrades remember last choice.
* Save files now sort by date
* The covenant no longer supports negative memory purchases
* Fix corp shares buyback triggering by pressing enter
* Staneks gift display avg / num charges
* Infiltration rewards no longer decay with better stats
* terminal 'true' is parsed as boolean not string
* tail and kill use autocomplete()
* Fix focus for coding contract
* massive boost to noodle bar.
** Special Thanks **
* Special thank you to everyone on Discord who can answer
new player questions so I can focus on more important things.
`, `,
}; };

@ -22,7 +22,7 @@ import { Server } from "./Server/Server";
import { Router } from "./ui/GameRoot"; import { Router } from "./ui/GameRoot";
import { Page } from "./ui/Router"; import { Page } from "./ui/Router";
import { removeLeadingSlash } from "./Terminal/DirectoryHelpers"; import { removeLeadingSlash } from "./Terminal/DirectoryHelpers";
import { Terminal } from './Terminal'; import { Terminal } from "./Terminal";
import { SnackbarEvents } from "./ui/React/Snackbar"; import { SnackbarEvents } from "./ui/React/Snackbar";
import { IMap } from "./types"; import { IMap } from "./types";
@ -418,7 +418,7 @@ function calculateAchievements(): void {
export function initElectron(): void { export function initElectron(): void {
const userAgent = navigator.userAgent.toLowerCase(); const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf(' electron/') > -1) { if (userAgent.indexOf(" electron/") > -1) {
// Electron-specific code // Electron-specific code
setAchievements([]); setAchievements([]);
initWebserver(); initWebserver();
@ -439,14 +439,14 @@ function initWebserver(): void {
//If the current script already exists on the server, overwrite it //If the current script already exists on the server, overwrite it
for (let i = 0; i < home.scripts.length; i++) { for (let i = 0; i < home.scripts.length; i++) {
if (filename == home.scripts[i].filename) { if (filename == home.scripts[i].filename) {
home.scripts[i].saveScript(filename, code, "home", home.scripts); home.scripts[i].saveScript(Player, filename, code, "home", home.scripts);
return "written"; return "written";
} }
} }
//If the current script does NOT exist, create a new one //If the current script does NOT exist, create a new one
const script = new Script(); const script = new Script();
script.saveScript(filename, code, "home", home.scripts); script.saveScript(Player, filename, code, "home", home.scripts);
home.scripts.push(script); home.scripts.push(script);
return "written"; return "written";
} }
@ -463,16 +463,16 @@ function initAppNotifier(): void {
info: Terminal.info, info: Terminal.info,
warn: Terminal.warn, warn: Terminal.warn,
error: Terminal.error, error: Terminal.error,
success: Terminal.success success: Terminal.success,
}; };
let fn; let fn;
if (type) fn = typesFn[type]; if (type) fn = typesFn[type];
if (!fn) fn = Terminal.print; if (!fn) fn = Terminal.print;
fn.bind(Terminal)(message); fn.bind(Terminal)(message);
}, },
toast: (message: string, type: "info" | "success" | "warning" | "error" , duration = 2000) => toast: (message: string, type: "info" | "success" | "warning" | "error", duration = 2000) =>
SnackbarEvents.emit(message, type, duration), SnackbarEvents.emit(message, type, duration),
} };
// Will be consumud by the electron wrapper. // Will be consumud by the electron wrapper.
// @ts-ignore // @ts-ignore

@ -13,20 +13,21 @@ function tampering(): void {
} }
function timeCompression(): void { function timeCompression(): void {
const timer = 1000 * 15;
if (Player.exploits.includes(Exploit.TimeCompression)) return; if (Player.exploits.includes(Exploit.TimeCompression)) return;
// Time compression // Time compression
let last = new Date().getTime(); let last = performance.now();
function minute(): void { function minute(): void {
const now = new Date().getTime(); const now = performance.now();
if (now - last < 500) { if (now - last < 500) {
// time has been compressed. // time has been compressed.
Player.giveExploit(Exploit.TimeCompression); Player.giveExploit(Exploit.TimeCompression);
return; return;
} }
last = now; last = now;
window.setTimeout(minute, 1000 * 60); window.setTimeout(minute, timer);
} }
window.setTimeout(minute, 1000 * 60); window.setTimeout(minute, timer);
} }
export function startExploits(): void { export function startExploits(): void {

@ -1,3 +1,4 @@
import { IPlayer } from "src/PersonObjects/IPlayer";
import { IMap } from "../types"; import { IMap } from "../types";
// TODO remember to update RamCalculations.js and WorkerScript.js // TODO remember to update RamCalculations.js and WorkerScript.js
@ -48,6 +49,7 @@ export const RamCostConstants: IMap<number> = {
ScriptGetFavorToDonate: 0.1, ScriptGetFavorToDonate: 0.1,
ScriptCodingContractBaseRamCost: 10, ScriptCodingContractBaseRamCost: 10,
ScriptSleeveBaseRamCost: 4, ScriptSleeveBaseRamCost: 4,
ScriptGetOwnedSourceFiles: 5,
ScriptSingularityFn1RamCost: 2, ScriptSingularityFn1RamCost: 2,
ScriptSingularityFn2RamCost: 3, ScriptSingularityFn2RamCost: 3,
@ -67,6 +69,16 @@ export const RamCostConstants: IMap<number> = {
ScriptStanekDeleteAt: 0.15, ScriptStanekDeleteAt: 0.15,
}; };
function SF4Cost(cost: number): (player: IPlayer) => number {
return (player: IPlayer): number => {
if (player.bitNodeN === 4) return cost;
const sf4 = player.sourceFileLvl(4);
if (sf4 <= 1) return cost * 64;
if (sf4 === 2) return cost * 8;
return cost;
};
}
export const RamCosts: IMap<any> = { export const RamCosts: IMap<any> = {
hacknet: { hacknet: {
numNodes: 0, numNodes: 0,
@ -194,57 +206,57 @@ export const RamCosts: IMap<any> = {
prompt: 0, prompt: 0,
wget: 0, wget: 0,
getFavorToDonate: RamCostConstants.ScriptGetFavorToDonate, getFavorToDonate: RamCostConstants.ScriptGetFavorToDonate,
getPlayer: RamCostConstants.ScriptSingularityFn1RamCost / 4,
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
// Singularity Functions // Singularity Functions
universityCourse: RamCostConstants.ScriptSingularityFn1RamCost, universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
gymWorkout: RamCostConstants.ScriptSingularityFn1RamCost, gymWorkout: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
travelToCity: RamCostConstants.ScriptSingularityFn1RamCost, travelToCity: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
goToLocation: RamCostConstants.ScriptSingularityFn1RamCost, goToLocation: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
purchaseTor: RamCostConstants.ScriptSingularityFn1RamCost, purchaseTor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
purchaseProgram: RamCostConstants.ScriptSingularityFn1RamCost, purchaseProgram: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getCurrentServer: RamCostConstants.ScriptSingularityFn1RamCost, getCurrentServer: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
connect: RamCostConstants.ScriptSingularityFn1RamCost, connect: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
manualHack: RamCostConstants.ScriptSingularityFn1RamCost, manualHack: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
installBackdoor: RamCostConstants.ScriptSingularityFn1RamCost, installBackdoor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getStats: RamCostConstants.ScriptSingularityFn1RamCost / 4, getStats: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getCharacterInformation: RamCostConstants.ScriptSingularityFn1RamCost / 4, getCharacterInformation: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getPlayer: RamCostConstants.ScriptSingularityFn1RamCost / 4, hospitalize: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
hospitalize: RamCostConstants.ScriptSingularityFn1RamCost / 4, isBusy: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
isBusy: RamCostConstants.ScriptSingularityFn1RamCost / 4, stopAction: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 2),
stopAction: RamCostConstants.ScriptSingularityFn1RamCost / 2, upgradeHomeRam: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
upgradeHomeRam: RamCostConstants.ScriptSingularityFn2RamCost, upgradeHomeCores: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
upgradeHomeCores: RamCostConstants.ScriptSingularityFn2RamCost, getUpgradeHomeRamCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
getUpgradeHomeRamCost: RamCostConstants.ScriptSingularityFn2RamCost / 2, getUpgradeHomeCoresCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
getUpgradeHomeCoresCost: RamCostConstants.ScriptSingularityFn2RamCost / 2, workForCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
workForCompany: RamCostConstants.ScriptSingularityFn2RamCost, applyToCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
applyToCompany: RamCostConstants.ScriptSingularityFn2RamCost, getCompanyRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyRep: RamCostConstants.ScriptSingularityFn2RamCost / 3, getCompanyFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyFavor: RamCostConstants.ScriptSingularityFn2RamCost / 3, getCompanyFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
getCompanyFavorGain: RamCostConstants.ScriptSingularityFn2RamCost / 4, checkFactionInvitations: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
checkFactionInvitations: RamCostConstants.ScriptSingularityFn2RamCost, joinFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
joinFaction: RamCostConstants.ScriptSingularityFn2RamCost, workForFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
workForFaction: RamCostConstants.ScriptSingularityFn2RamCost, getFactionRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionRep: RamCostConstants.ScriptSingularityFn2RamCost / 3, getFactionFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionFavor: RamCostConstants.ScriptSingularityFn2RamCost / 3, getFactionFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
getFactionFavorGain: RamCostConstants.ScriptSingularityFn2RamCost / 4, donateToFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
donateToFaction: RamCostConstants.ScriptSingularityFn3RamCost, createProgram: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
createProgram: RamCostConstants.ScriptSingularityFn3RamCost, commitCrime: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
commitCrime: RamCostConstants.ScriptSingularityFn3RamCost, getCrimeChance: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeChance: RamCostConstants.ScriptSingularityFn3RamCost, getCrimeStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeStats: RamCostConstants.ScriptSingularityFn3RamCost, getOwnedAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getOwnedAugmentations: RamCostConstants.ScriptSingularityFn3RamCost, getAugmentationsFromFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getOwnedSourceFiles: RamCostConstants.ScriptSingularityFn3RamCost, getAugmentationCost: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationsFromFaction: RamCostConstants.ScriptSingularityFn3RamCost, getAugmentationPrereq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationCost: RamCostConstants.ScriptSingularityFn3RamCost, getAugmentationPrice: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationPrereq: RamCostConstants.ScriptSingularityFn3RamCost, getAugmentationRepReq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationPrice: RamCostConstants.ScriptSingularityFn3RamCost / 2, getAugmentationStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationRepReq: RamCostConstants.ScriptSingularityFn3RamCost / 2, purchaseAugmentation: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationStats: RamCostConstants.ScriptSingularityFn3RamCost, softReset: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
purchaseAugmentation: RamCostConstants.ScriptSingularityFn3RamCost, installAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
softReset: RamCostConstants.ScriptSingularityFn3RamCost, isFocused: SF4Cost(0.1),
installAugmentations: RamCostConstants.ScriptSingularityFn3RamCost, setFocus: SF4Cost(0.1),
isFocused: 0.1,
setFocus: 0.1,
// Gang API // Gang API
gang: { gang: {
@ -358,7 +370,7 @@ export const RamCosts: IMap<any> = {
}, },
}; };
export function getRamCost(...args: string[]): number { export function getRamCost(player: IPlayer, ...args: string[]): number {
if (args.length === 0) { if (args.length === 0) {
console.warn(`No arguments passed to getRamCost()`); console.warn(`No arguments passed to getRamCost()`);
return 0; return 0;
@ -383,6 +395,10 @@ export function getRamCost(...args: string[]): number {
return curr; return curr;
} }
if (typeof curr === "function") {
return curr(player);
}
console.warn(`Unexpected type (${curr}) for value [${args}]`); console.warn(`Unexpected type (${curr}) for value [${args}]`);
return 0; return 0;
} }

@ -302,12 +302,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return makeRuntimeRejectMsg(workerScript, rejectMsg); return makeRuntimeRejectMsg(workerScript, rejectMsg);
}; };
const checkSingularityAccess = function (func: any, n: any): void { const checkSingularityAccess = function (func: string): void {
if (Player.bitNodeN !== 4) { if (Player.bitNodeN !== 4) {
if (SourceFileFlags[4] < n) { if (Player.sourceFileLvl(4) === 0) {
throw makeRuntimeErrorMsg( throw makeRuntimeErrorMsg(
func, func,
`This singularity function requires Source-File 4-${n} to run. A power up you obtain later in the game. It will be very obvious when and how you can obtain it.`, `This singularity function requires Source-File 4 to run. A power up you obtain later in the game. It will be very obvious when and how you can obtain it.`,
); );
} }
} }
@ -495,7 +495,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
sprintf: sprintf, sprintf: sprintf,
vsprintf: vsprintf, vsprintf: vsprintf,
scan: function (hostname: any = workerScript.hostname): any { scan: function (hostname: any = workerScript.hostname): any {
updateDynamicRam("scan", getRamCost("scan")); updateDynamicRam("scan", getRamCost(Player, "scan"));
const server = safeGetServer(hostname, "scan"); const server = safeGetServer(hostname, "scan");
const out = []; const out = [];
for (let i = 0; i < server.serversOnNetwork.length; i++) { for (let i = 0; i < server.serversOnNetwork.length; i++) {
@ -509,11 +509,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return out; return out;
}, },
hack: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any { hack: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any {
updateDynamicRam("hack", getRamCost("hack")); updateDynamicRam("hack", getRamCost(Player, "hack"));
return hack(hostname, false, { threads: requestedThreads, stock: stock }); return hack(hostname, false, { threads: requestedThreads, stock: stock });
}, },
hackAnalyzeThreads: function (hostname: any, hackAmount: any): any { hackAnalyzeThreads: function (hostname: any, hackAmount: any): any {
updateDynamicRam("hackAnalyzeThreads", getRamCost("hackAnalyzeThreads")); updateDynamicRam("hackAnalyzeThreads", getRamCost(Player, "hackAnalyzeThreads"));
// Check argument validity // Check argument validity
const server = safeGetServer(hostname, "hackAnalyzeThreads"); const server = safeGetServer(hostname, "hackAnalyzeThreads");
@ -539,7 +539,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return hackAmount / Math.floor(server.moneyAvailable * percentHacked); return hackAmount / Math.floor(server.moneyAvailable * percentHacked);
}, },
hackAnalyze: function (hostname: any): any { hackAnalyze: function (hostname: any): any {
updateDynamicRam("hackAnalyze", getRamCost("hackAnalyze")); updateDynamicRam("hackAnalyze", getRamCost(Player, "hackAnalyze"));
const server = safeGetServer(hostname, "hackAnalyze"); const server = safeGetServer(hostname, "hackAnalyze");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
@ -553,7 +553,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return CONSTANTS.ServerFortifyAmount * threads; return CONSTANTS.ServerFortifyAmount * threads;
}, },
hackAnalyzeChance: function (hostname: any): any { hackAnalyzeChance: function (hostname: any): any {
updateDynamicRam("hackAnalyzeChance", getRamCost("hackAnalyzeChance")); updateDynamicRam("hackAnalyzeChance", getRamCost(Player, "hackAnalyzeChance"));
const server = safeGetServer(hostname, "hackAnalyzeChance"); const server = safeGetServer(hostname, "hackAnalyzeChance");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
@ -582,7 +582,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}); });
}, },
grow: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any { grow: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any {
updateDynamicRam("grow", getRamCost("grow")); updateDynamicRam("grow", getRamCost(Player, "grow"));
const threads = resolveNetscriptRequestedThreads(workerScript, "grow", requestedThreads); const threads = resolveNetscriptRequestedThreads(workerScript, "grow", requestedThreads);
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("grow", "Takes 1 argument."); throw makeRuntimeErrorMsg("grow", "Takes 1 argument.");
@ -640,7 +640,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}); });
}, },
growthAnalyze: function (hostname: any, growth: any, cores: any = 1): any { growthAnalyze: function (hostname: any, growth: any, cores: any = 1): any {
updateDynamicRam("growthAnalyze", getRamCost("growthAnalyze")); updateDynamicRam("growthAnalyze", getRamCost(Player, "growthAnalyze"));
// Check argument validity // Check argument validity
const server = safeGetServer(hostname, "growthAnalyze"); const server = safeGetServer(hostname, "growthAnalyze");
@ -658,7 +658,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return 2 * CONSTANTS.ServerFortifyAmount * threads; return 2 * CONSTANTS.ServerFortifyAmount * threads;
}, },
weaken: function (hostname: any, { threads: requestedThreads }: any = {}): any { weaken: function (hostname: any, { threads: requestedThreads }: any = {}): any {
updateDynamicRam("weaken", getRamCost("weaken")); updateDynamicRam("weaken", getRamCost(Player, "weaken"));
const threads = resolveNetscriptRequestedThreads(workerScript, "weaken", requestedThreads); const threads = resolveNetscriptRequestedThreads(workerScript, "weaken", requestedThreads);
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("weaken", "Takes 1 argument."); throw makeRuntimeErrorMsg("weaken", "Takes 1 argument.");
@ -824,7 +824,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
LogBoxEvents.emit(runningScriptObj); LogBoxEvents.emit(runningScriptObj);
}, },
nuke: function (hostname: any): boolean { nuke: function (hostname: any): boolean {
updateDynamicRam("nuke", getRamCost("nuke")); updateDynamicRam("nuke", getRamCost(Player, "nuke"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("nuke", "Takes 1 argument."); throw makeRuntimeErrorMsg("nuke", "Takes 1 argument.");
} }
@ -848,7 +848,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
brutessh: function (hostname: any): boolean { brutessh: function (hostname: any): boolean {
updateDynamicRam("brutessh", getRamCost("brutessh")); updateDynamicRam("brutessh", getRamCost(Player, "brutessh"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("brutessh", "Takes 1 argument."); throw makeRuntimeErrorMsg("brutessh", "Takes 1 argument.");
} }
@ -870,7 +870,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
ftpcrack: function (hostname: any): boolean { ftpcrack: function (hostname: any): boolean {
updateDynamicRam("ftpcrack", getRamCost("ftpcrack")); updateDynamicRam("ftpcrack", getRamCost(Player, "ftpcrack"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("ftpcrack", "Takes 1 argument."); throw makeRuntimeErrorMsg("ftpcrack", "Takes 1 argument.");
} }
@ -892,7 +892,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
relaysmtp: function (hostname: any): boolean { relaysmtp: function (hostname: any): boolean {
updateDynamicRam("relaysmtp", getRamCost("relaysmtp")); updateDynamicRam("relaysmtp", getRamCost(Player, "relaysmtp"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("relaysmtp", "Takes 1 argument."); throw makeRuntimeErrorMsg("relaysmtp", "Takes 1 argument.");
} }
@ -914,7 +914,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
httpworm: function (hostname: any): boolean { httpworm: function (hostname: any): boolean {
updateDynamicRam("httpworm", getRamCost("httpworm")); updateDynamicRam("httpworm", getRamCost(Player, "httpworm"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("httpworm", "Takes 1 argument"); throw makeRuntimeErrorMsg("httpworm", "Takes 1 argument");
} }
@ -936,7 +936,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
sqlinject: function (hostname: any): boolean { sqlinject: function (hostname: any): boolean {
updateDynamicRam("sqlinject", getRamCost("sqlinject")); updateDynamicRam("sqlinject", getRamCost(Player, "sqlinject"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("sqlinject", "Takes 1 argument."); throw makeRuntimeErrorMsg("sqlinject", "Takes 1 argument.");
} }
@ -958,7 +958,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return true; return true;
}, },
run: function (scriptname: any, threads: any = 1, ...args: any[]): any { run: function (scriptname: any, threads: any = 1, ...args: any[]): any {
updateDynamicRam("run", getRamCost("run")); updateDynamicRam("run", getRamCost(Player, "run"));
if (scriptname === undefined) { if (scriptname === undefined) {
throw makeRuntimeErrorMsg("run", "Usage: run(scriptname, [numThreads], [arg1], [arg2]...)"); throw makeRuntimeErrorMsg("run", "Usage: run(scriptname, [numThreads], [arg1], [arg2]...)");
} }
@ -970,10 +970,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("run", "Could not find server. This is a bug. Report to dev."); throw makeRuntimeErrorMsg("run", "Could not find server. This is a bug. Report to dev.");
} }
return runScriptFromScript("run", scriptServer, scriptname, args, workerScript, threads); return runScriptFromScript(Player, "run", scriptServer, scriptname, args, workerScript, threads);
}, },
exec: function (scriptname: any, hostname: any, threads: any = 1, ...args: any[]): any { exec: function (scriptname: any, hostname: any, threads: any = 1, ...args: any[]): any {
updateDynamicRam("exec", getRamCost("exec")); updateDynamicRam("exec", getRamCost(Player, "exec"));
if (scriptname === undefined || hostname === undefined) { if (scriptname === undefined || hostname === undefined) {
throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)"); throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
} }
@ -981,10 +981,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("exec", `Invalid thread count. Must be numeric and > 0, is ${threads}`); throw makeRuntimeErrorMsg("exec", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
} }
const server = safeGetServer(hostname, "exec"); const server = safeGetServer(hostname, "exec");
return runScriptFromScript("exec", server, scriptname, args, workerScript, threads); return runScriptFromScript(Player, "exec", server, scriptname, args, workerScript, threads);
}, },
spawn: function (scriptname: any, threads: any = 1, ...args: any[]): any { spawn: function (scriptname: any, threads: any = 1, ...args: any[]): any {
updateDynamicRam("spawn", getRamCost("spawn")); updateDynamicRam("spawn", getRamCost(Player, "spawn"));
if (!scriptname || !threads) { if (!scriptname || !threads) {
throw makeRuntimeErrorMsg("spawn", "Usage: spawn(scriptname, threads)"); throw makeRuntimeErrorMsg("spawn", "Usage: spawn(scriptname, threads)");
} }
@ -999,7 +999,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
throw makeRuntimeErrorMsg("spawn", "Could not find server. This is a bug. Report to dev"); throw makeRuntimeErrorMsg("spawn", "Could not find server. This is a bug. Report to dev");
} }
return runScriptFromScript("spawn", scriptServer, scriptname, args, workerScript, threads); return runScriptFromScript(Player, "spawn", scriptServer, scriptname, args, workerScript, threads);
}, spawnDelay * 1e3); }, spawnDelay * 1e3);
workerScript.log("spawn", () => `Will execute '${scriptname}' in ${spawnDelay} seconds`); workerScript.log("spawn", () => `Will execute '${scriptname}' in ${spawnDelay} seconds`);
@ -1010,7 +1010,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
kill: function (filename: any, hostname?: any, ...scriptArgs: any): any { kill: function (filename: any, hostname?: any, ...scriptArgs: any): any {
updateDynamicRam("kill", getRamCost("kill")); updateDynamicRam("kill", getRamCost(Player, "kill"));
let res; let res;
const killByPid = typeof filename === "number"; const killByPid = typeof filename === "number";
@ -1056,7 +1056,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
killall: function (hostname: any = workerScript.hostname): any { killall: function (hostname: any = workerScript.hostname): any {
updateDynamicRam("killall", getRamCost("killall")); updateDynamicRam("killall", getRamCost(Player, "killall"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("killall", "Takes 1 argument"); throw makeRuntimeErrorMsg("killall", "Takes 1 argument");
} }
@ -1082,7 +1082,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
scp: async function (scriptname: any, hostname1: any, hostname2: any): Promise<boolean> { scp: async function (scriptname: any, hostname1: any, hostname2: any): Promise<boolean> {
updateDynamicRam("scp", getRamCost("scp")); updateDynamicRam("scp", getRamCost(Player, "scp"));
if (arguments.length !== 2 && arguments.length !== 3) { if (arguments.length !== 2 && arguments.length !== 3) {
throw makeRuntimeErrorMsg("scp", "Takes 2 or 3 arguments"); throw makeRuntimeErrorMsg("scp", "Takes 2 or 3 arguments");
} }
@ -1224,7 +1224,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
// Create new script if it does not already exist // Create new script if it does not already exist
const newScript = new Script(scriptname); const newScript = new Script(Player, scriptname);
newScript.code = sourceScript.code; newScript.code = sourceScript.code;
newScript.ramUsage = sourceScript.ramUsage; newScript.ramUsage = sourceScript.ramUsage;
newScript.server = destServer.hostname; newScript.server = destServer.hostname;
@ -1235,11 +1235,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
resolve(false); resolve(false);
return; return;
} }
newScript.updateRamUsage(destServer.scripts).then(() => resolve(true)); newScript.updateRamUsage(Player, destServer.scripts).then(() => resolve(true));
}); });
}, },
ls: function (hostname: any, grep: any): any { ls: function (hostname: any, grep: any): any {
updateDynamicRam("ls", getRamCost("ls")); updateDynamicRam("ls", getRamCost(Player, "ls"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("ls", "Usage: ls(hostname/ip, [grep filter])"); throw makeRuntimeErrorMsg("ls", "Usage: ls(hostname/ip, [grep filter])");
} }
@ -1306,7 +1306,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return allFiles; return allFiles;
}, },
ps: function (hostname: any = workerScript.hostname): any { ps: function (hostname: any = workerScript.hostname): any {
updateDynamicRam("ps", getRamCost("ps")); updateDynamicRam("ps", getRamCost(Player, "ps"));
const server = safeGetServer(hostname, "ps"); const server = safeGetServer(hostname, "ps");
const processes = []; const processes = [];
for (const i in server.runningScripts) { for (const i in server.runningScripts) {
@ -1321,7 +1321,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return processes; return processes;
}, },
hasRootAccess: function (hostname: any): any { hasRootAccess: function (hostname: any): any {
updateDynamicRam("hasRootAccess", getRamCost("hasRootAccess")); updateDynamicRam("hasRootAccess", getRamCost(Player, "hasRootAccess"));
if (hostname === undefined) { if (hostname === undefined) {
throw makeRuntimeErrorMsg("hasRootAccess", "Takes 1 argument"); throw makeRuntimeErrorMsg("hasRootAccess", "Takes 1 argument");
} }
@ -1329,7 +1329,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.hasAdminRights; return server.hasAdminRights;
}, },
getHostname: function (): any { getHostname: function (): any {
updateDynamicRam("getHostname", getRamCost("getHostname")); updateDynamicRam("getHostname", getRamCost(Player, "getHostname"));
const scriptServer = GetServer(workerScript.hostname); const scriptServer = GetServer(workerScript.hostname);
if (scriptServer == null) { if (scriptServer == null) {
throw makeRuntimeErrorMsg("getHostname", "Could not find server. This is a bug. Report to dev."); throw makeRuntimeErrorMsg("getHostname", "Could not find server. This is a bug. Report to dev.");
@ -1337,13 +1337,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return scriptServer.hostname; return scriptServer.hostname;
}, },
getHackingLevel: function (): any { getHackingLevel: function (): any {
updateDynamicRam("getHackingLevel", getRamCost("getHackingLevel")); updateDynamicRam("getHackingLevel", getRamCost(Player, "getHackingLevel"));
Player.updateSkillLevels(); Player.updateSkillLevels();
workerScript.log("getHackingLevel", () => `returned ${Player.hacking}`); workerScript.log("getHackingLevel", () => `returned ${Player.hacking}`);
return Player.hacking; return Player.hacking;
}, },
getHackingMultipliers: function (): any { getHackingMultipliers: function (): any {
updateDynamicRam("getHackingMultipliers", getRamCost("getHackingMultipliers")); updateDynamicRam("getHackingMultipliers", getRamCost(Player, "getHackingMultipliers"));
return { return {
chance: Player.hacking_chance_mult, chance: Player.hacking_chance_mult,
speed: Player.hacking_speed_mult, speed: Player.hacking_speed_mult,
@ -1352,7 +1352,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}; };
}, },
getHacknetMultipliers: function (): any { getHacknetMultipliers: function (): any {
updateDynamicRam("getHacknetMultipliers", getRamCost("getHacknetMultipliers")); updateDynamicRam("getHacknetMultipliers", getRamCost(Player, "getHacknetMultipliers"));
return { return {
production: Player.hacknet_node_money_mult, production: Player.hacknet_node_money_mult,
purchaseCost: Player.hacknet_node_purchase_cost_mult, purchaseCost: Player.hacknet_node_purchase_cost_mult,
@ -1362,7 +1362,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}; };
}, },
getBitNodeMultipliers: function (): any { getBitNodeMultipliers: function (): any {
updateDynamicRam("getBitNodeMultipliers", getRamCost("getBitNodeMultipliers")); updateDynamicRam("getBitNodeMultipliers", getRamCost(Player, "getBitNodeMultipliers"));
if (SourceFileFlags[5] <= 0 && Player.bitNodeN !== 5) { if (SourceFileFlags[5] <= 0 && Player.bitNodeN !== 5) {
throw makeRuntimeErrorMsg("getBitNodeMultipliers", "Requires Source-File 5 to run."); throw makeRuntimeErrorMsg("getBitNodeMultipliers", "Requires Source-File 5 to run.");
} }
@ -1370,7 +1370,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return copy; return copy;
}, },
getServer: function (hostname: any = workerScript.hostname): any { getServer: function (hostname: any = workerScript.hostname): any {
updateDynamicRam("getServer", getRamCost("getServer")); updateDynamicRam("getServer", getRamCost(Player, "getServer"));
const server = safeGetServer(hostname, "getServer"); const server = safeGetServer(hostname, "getServer");
const copy = Object.assign({}, server) as any; const copy = Object.assign({}, server) as any;
// These fields should be hidden. // These fields should be hidden.
@ -1393,7 +1393,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return copy; return copy;
}, },
getServerMoneyAvailable: function (hostname: any): any { getServerMoneyAvailable: function (hostname: any): any {
updateDynamicRam("getServerMoneyAvailable", getRamCost("getServerMoneyAvailable")); updateDynamicRam("getServerMoneyAvailable", getRamCost(Player, "getServerMoneyAvailable"));
const server = safeGetServer(hostname, "getServerMoneyAvailable"); const server = safeGetServer(hostname, "getServerMoneyAvailable");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMoneyAvailable", () => "Cannot be executed on this server."); workerScript.log("getServerMoneyAvailable", () => "Cannot be executed on this server.");
@ -1417,7 +1417,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.moneyAvailable; return server.moneyAvailable;
}, },
getServerSecurityLevel: function (hostname: any): any { getServerSecurityLevel: function (hostname: any): any {
updateDynamicRam("getServerSecurityLevel", getRamCost("getServerSecurityLevel")); updateDynamicRam("getServerSecurityLevel", getRamCost(Player, "getServerSecurityLevel"));
const server = safeGetServer(hostname, "getServerSecurityLevel"); const server = safeGetServer(hostname, "getServerSecurityLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerSecurityLevel", () => "Cannot be executed on this server."); workerScript.log("getServerSecurityLevel", () => "Cannot be executed on this server.");
@ -1433,7 +1433,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.hackDifficulty; return server.hackDifficulty;
}, },
getServerBaseSecurityLevel: function (hostname: any): any { getServerBaseSecurityLevel: function (hostname: any): any {
updateDynamicRam("getServerBaseSecurityLevel", getRamCost("getServerBaseSecurityLevel")); updateDynamicRam("getServerBaseSecurityLevel", getRamCost(Player, "getServerBaseSecurityLevel"));
workerScript.log( workerScript.log(
"getServerBaseSecurityLevel", "getServerBaseSecurityLevel",
() => `getServerBaseSecurityLevel is deprecated because it's not useful.`, () => `getServerBaseSecurityLevel is deprecated because it's not useful.`,
@ -1453,7 +1453,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.baseDifficulty; return server.baseDifficulty;
}, },
getServerMinSecurityLevel: function (hostname: any): any { getServerMinSecurityLevel: function (hostname: any): any {
updateDynamicRam("getServerMinSecurityLevel", getRamCost("getServerMinSecurityLevel")); updateDynamicRam("getServerMinSecurityLevel", getRamCost(Player, "getServerMinSecurityLevel"));
const server = safeGetServer(hostname, "getServerMinSecurityLevel"); const server = safeGetServer(hostname, "getServerMinSecurityLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMinSecurityLevel", () => "Cannot be executed on this server."); workerScript.log("getServerMinSecurityLevel", () => "Cannot be executed on this server.");
@ -1469,7 +1469,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.minDifficulty; return server.minDifficulty;
}, },
getServerRequiredHackingLevel: function (hostname: any): any { getServerRequiredHackingLevel: function (hostname: any): any {
updateDynamicRam("getServerRequiredHackingLevel", getRamCost("getServerRequiredHackingLevel")); updateDynamicRam("getServerRequiredHackingLevel", getRamCost(Player, "getServerRequiredHackingLevel"));
const server = safeGetServer(hostname, "getServerRequiredHackingLevel"); const server = safeGetServer(hostname, "getServerRequiredHackingLevel");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerRequiredHackingLevel", () => "Cannot be executed on this server."); workerScript.log("getServerRequiredHackingLevel", () => "Cannot be executed on this server.");
@ -1485,7 +1485,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.requiredHackingSkill; return server.requiredHackingSkill;
}, },
getServerMaxMoney: function (hostname: any): any { getServerMaxMoney: function (hostname: any): any {
updateDynamicRam("getServerMaxMoney", getRamCost("getServerMaxMoney")); updateDynamicRam("getServerMaxMoney", getRamCost(Player, "getServerMaxMoney"));
const server = safeGetServer(hostname, "getServerMaxMoney"); const server = safeGetServer(hostname, "getServerMaxMoney");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerMaxMoney", () => "Cannot be executed on this server."); workerScript.log("getServerMaxMoney", () => "Cannot be executed on this server.");
@ -1501,7 +1501,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.moneyMax; return server.moneyMax;
}, },
getServerGrowth: function (hostname: any): any { getServerGrowth: function (hostname: any): any {
updateDynamicRam("getServerGrowth", getRamCost("getServerGrowth")); updateDynamicRam("getServerGrowth", getRamCost(Player, "getServerGrowth"));
const server = safeGetServer(hostname, "getServerGrowth"); const server = safeGetServer(hostname, "getServerGrowth");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerGrowth", () => "Cannot be executed on this server."); workerScript.log("getServerGrowth", () => "Cannot be executed on this server.");
@ -1514,7 +1514,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.serverGrowth; return server.serverGrowth;
}, },
getServerNumPortsRequired: function (hostname: any): any { getServerNumPortsRequired: function (hostname: any): any {
updateDynamicRam("getServerNumPortsRequired", getRamCost("getServerNumPortsRequired")); updateDynamicRam("getServerNumPortsRequired", getRamCost(Player, "getServerNumPortsRequired"));
const server = safeGetServer(hostname, "getServerNumPortsRequired"); const server = safeGetServer(hostname, "getServerNumPortsRequired");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getServerNumPortsRequired", () => "Cannot be executed on this server."); workerScript.log("getServerNumPortsRequired", () => "Cannot be executed on this server.");
@ -1530,7 +1530,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return server.numOpenPortsRequired; return server.numOpenPortsRequired;
}, },
getServerRam: function (hostname: any): any { getServerRam: function (hostname: any): any {
updateDynamicRam("getServerRam", getRamCost("getServerRam")); updateDynamicRam("getServerRam", getRamCost(Player, "getServerRam"));
workerScript.log( workerScript.log(
"getServerRam", "getServerRam",
() => `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`, () => `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`,
@ -1543,23 +1543,23 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return [server.maxRam, server.ramUsed]; return [server.maxRam, server.ramUsed];
}, },
getServerMaxRam: function (hostname: any): any { getServerMaxRam: function (hostname: any): any {
updateDynamicRam("getServerMaxRam", getRamCost("getServerMaxRam")); updateDynamicRam("getServerMaxRam", getRamCost(Player, "getServerMaxRam"));
const server = safeGetServer(hostname, "getServerMaxRam"); const server = safeGetServer(hostname, "getServerMaxRam");
workerScript.log("getServerMaxRam", () => `returned ${numeralWrapper.formatRAM(server.maxRam)}`); workerScript.log("getServerMaxRam", () => `returned ${numeralWrapper.formatRAM(server.maxRam)}`);
return server.maxRam; return server.maxRam;
}, },
getServerUsedRam: function (hostname: any): any { getServerUsedRam: function (hostname: any): any {
updateDynamicRam("getServerUsedRam", getRamCost("getServerUsedRam")); updateDynamicRam("getServerUsedRam", getRamCost(Player, "getServerUsedRam"));
const server = safeGetServer(hostname, "getServerUsedRam"); const server = safeGetServer(hostname, "getServerUsedRam");
workerScript.log("getServerUsedRam", () => `returned ${numeralWrapper.formatRAM(server.ramUsed)}`); workerScript.log("getServerUsedRam", () => `returned ${numeralWrapper.formatRAM(server.ramUsed)}`);
return server.ramUsed; return server.ramUsed;
}, },
serverExists: function (hostname: any): any { serverExists: function (hostname: any): any {
updateDynamicRam("serverExists", getRamCost("serverExists")); updateDynamicRam("serverExists", getRamCost(Player, "serverExists"));
return GetServer(hostname) !== null; return GetServer(hostname) !== null;
}, },
fileExists: function (filename: any, hostname: any = workerScript.hostname): any { fileExists: function (filename: any, hostname: any = workerScript.hostname): any {
updateDynamicRam("fileExists", getRamCost("fileExists")); updateDynamicRam("fileExists", getRamCost(Player, "fileExists"));
if (filename === undefined) { if (filename === undefined) {
throw makeRuntimeErrorMsg("fileExists", "Usage: fileExists(scriptname, [server])"); throw makeRuntimeErrorMsg("fileExists", "Usage: fileExists(scriptname, [server])");
} }
@ -1586,7 +1586,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return false; return false;
}, },
isRunning: function (fn: any, hostname: any = workerScript.hostname, ...scriptArgs: any): any { isRunning: function (fn: any, hostname: any = workerScript.hostname, ...scriptArgs: any): any {
updateDynamicRam("isRunning", getRamCost("isRunning")); updateDynamicRam("isRunning", getRamCost(Player, "isRunning"));
if (fn === undefined || hostname === undefined) { if (fn === undefined || hostname === undefined) {
throw makeRuntimeErrorMsg("isRunning", "Usage: isRunning(scriptname, server, [arg1], [arg2]...)"); throw makeRuntimeErrorMsg("isRunning", "Usage: isRunning(scriptname, server, [arg1], [arg2]...)");
} }
@ -1597,17 +1597,17 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
getPurchasedServerLimit: function (): any { getPurchasedServerLimit: function (): any {
updateDynamicRam("getPurchasedServerLimit", getRamCost("getPurchasedServerLimit")); updateDynamicRam("getPurchasedServerLimit", getRamCost(Player, "getPurchasedServerLimit"));
return getPurchaseServerLimit(); return getPurchaseServerLimit();
}, },
getPurchasedServerMaxRam: function (): any { getPurchasedServerMaxRam: function (): any {
updateDynamicRam("getPurchasedServerMaxRam", getRamCost("getPurchasedServerMaxRam")); updateDynamicRam("getPurchasedServerMaxRam", getRamCost(Player, "getPurchasedServerMaxRam"));
return getPurchaseServerMaxRam(); return getPurchaseServerMaxRam();
}, },
getPurchasedServerCost: function (ram: any): any { getPurchasedServerCost: function (ram: any): any {
updateDynamicRam("getPurchasedServerCost", getRamCost("getPurchasedServerCost")); updateDynamicRam("getPurchasedServerCost", getRamCost(Player, "getPurchasedServerCost"));
const cost = getPurchaseServerCost(ram); const cost = getPurchaseServerCost(ram);
if (cost === Infinity) { if (cost === Infinity) {
@ -1620,7 +1620,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
purchaseServer: function (aname: any, aram: any): any { purchaseServer: function (aname: any, aram: any): any {
const name = helper.string("purchaseServer", "name", aname); const name = helper.string("purchaseServer", "name", aname);
const ram = helper.number("purchaseServer", "ram", aram); const ram = helper.number("purchaseServer", "ram", aram);
updateDynamicRam("purchaseServer", getRamCost("purchaseServer")); updateDynamicRam("purchaseServer", getRamCost(Player, "purchaseServer"));
let hostnameStr = String(name); let hostnameStr = String(name);
hostnameStr = hostnameStr.replace(/\s+/g, ""); hostnameStr = hostnameStr.replace(/\s+/g, "");
if (hostnameStr == "") { if (hostnameStr == "") {
@ -1673,7 +1673,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return newServ.hostname; return newServ.hostname;
}, },
deleteServer: function (name: any): any { deleteServer: function (name: any): any {
updateDynamicRam("deleteServer", getRamCost("deleteServer")); updateDynamicRam("deleteServer", getRamCost(Player, "deleteServer"));
let hostnameStr = String(name); let hostnameStr = String(name);
hostnameStr = hostnameStr.replace(/\s\s+/g, ""); hostnameStr = hostnameStr.replace(/\s\s+/g, "");
const server = GetServer(hostnameStr); const server = GetServer(hostnameStr);
@ -1749,7 +1749,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return false; return false;
}, },
getPurchasedServers: function (): any { getPurchasedServers: function (): any {
updateDynamicRam("getPurchasedServers", getRamCost("getPurchasedServers")); updateDynamicRam("getPurchasedServers", getRamCost(Player, "getPurchasedServers"));
const res: string[] = []; const res: string[] = [];
Player.purchasedServers.forEach(function (hostname) { Player.purchasedServers.forEach(function (hostname) {
res.push(hostname); res.push(hostname);
@ -1767,7 +1767,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return Promise.resolve(iport.write(data)); return Promise.resolve(iport.write(data));
}, },
write: function (port: any, data: any = "", mode: any = "a"): any { write: function (port: any, data: any = "", mode: any = "a"): any {
updateDynamicRam("write", getRamCost("write")); updateDynamicRam("write", getRamCost(Player, "write"));
if (isString(port)) { if (isString(port)) {
// Write to script or text file // Write to script or text file
let fn = port; let fn = port;
@ -1795,12 +1795,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
let script = workerScript.getScriptOnServer(fn, server); let script = workerScript.getScriptOnServer(fn, server);
if (script == null) { if (script == null) {
// Create a new script // Create a new script
script = new Script(fn, data, server.hostname, server.scripts); script = new Script(Player, fn, data, server.hostname, server.scripts);
server.scripts.push(script); server.scripts.push(script);
return script.updateRamUsage(server.scripts); return script.updateRamUsage(Player, server.scripts);
} }
mode === "w" ? (script.code = data) : (script.code += data); mode === "w" ? (script.code = data) : (script.code += data);
return script.updateRamUsage(server.scripts); return script.updateRamUsage(Player, server.scripts);
} else { } else {
// Write to text file // Write to text file
const txtFile = getTextFile(fn, server); const txtFile = getTextFile(fn, server);
@ -1820,7 +1820,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
tryWritePort: function (port: any, data: any = ""): any { tryWritePort: function (port: any, data: any = ""): any {
updateDynamicRam("tryWritePort", getRamCost("tryWritePort")); updateDynamicRam("tryWritePort", getRamCost(Player, "tryWritePort"));
if (!isNaN(port)) { if (!isNaN(port)) {
port = Math.round(port); port = Math.round(port);
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) { if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
@ -1845,7 +1845,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return x; return x;
}, },
read: function (port: any): any { read: function (port: any): any {
updateDynamicRam("read", getRamCost("read")); updateDynamicRam("read", getRamCost(Player, "read"));
if (isString(port)) { if (isString(port)) {
// Read from script or text file // Read from script or text file
const fn = port; const fn = port;
@ -1874,13 +1874,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
peek: function (port: any): any { peek: function (port: any): any {
updateDynamicRam("peek", getRamCost("peek")); updateDynamicRam("peek", getRamCost(Player, "peek"));
const iport = helper.getValidPort("peek", port); const iport = helper.getValidPort("peek", port);
const x = iport.peek(); const x = iport.peek();
return x; return x;
}, },
clear: function (file: any): any { clear: function (file: any): any {
updateDynamicRam("clear", getRamCost("clear")); updateDynamicRam("clear", getRamCost(Player, "clear"));
if (isString(file)) { if (isString(file)) {
// Clear text file // Clear text file
const fn = file; const fn = file;
@ -1903,12 +1903,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return iport.clear(); return iport.clear();
}, },
getPortHandle: function (port: any): any { getPortHandle: function (port: any): any {
updateDynamicRam("getPortHandle", getRamCost("getPortHandle")); updateDynamicRam("getPortHandle", getRamCost(Player, "getPortHandle"));
const iport = helper.getValidPort("getPortHandle", port); const iport = helper.getValidPort("getPortHandle", port);
return iport; return iport;
}, },
rm: function (fn: any, hostname: any): any { rm: function (fn: any, hostname: any): any {
updateDynamicRam("rm", getRamCost("rm")); updateDynamicRam("rm", getRamCost(Player, "rm"));
if (hostname == null || hostname === "") { if (hostname == null || hostname === "") {
hostname = workerScript.hostname; hostname = workerScript.hostname;
@ -1923,7 +1923,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return status.res; return status.res;
}, },
scriptRunning: function (scriptname: any, hostname: any): any { scriptRunning: function (scriptname: any, hostname: any): any {
updateDynamicRam("scriptRunning", getRamCost("scriptRunning")); updateDynamicRam("scriptRunning", getRamCost(Player, "scriptRunning"));
const server = safeGetServer(hostname, "scriptRunning"); const server = safeGetServer(hostname, "scriptRunning");
for (let i = 0; i < server.runningScripts.length; ++i) { for (let i = 0; i < server.runningScripts.length; ++i) {
if (server.runningScripts[i].filename == scriptname) { if (server.runningScripts[i].filename == scriptname) {
@ -1933,7 +1933,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return false; return false;
}, },
scriptKill: function (scriptname: any, hostname: any): any { scriptKill: function (scriptname: any, hostname: any): any {
updateDynamicRam("scriptKill", getRamCost("scriptKill")); updateDynamicRam("scriptKill", getRamCost(Player, "scriptKill"));
const server = safeGetServer(hostname, "scriptKill"); const server = safeGetServer(hostname, "scriptKill");
let suc = false; let suc = false;
for (let i = 0; i < server.runningScripts.length; i++) { for (let i = 0; i < server.runningScripts.length; i++) {
@ -1949,7 +1949,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return workerScript.name; return workerScript.name;
}, },
getScriptRam: function (scriptname: any, hostname: any = workerScript.hostname): any { getScriptRam: function (scriptname: any, hostname: any = workerScript.hostname): any {
updateDynamicRam("getScriptRam", getRamCost("getScriptRam")); updateDynamicRam("getScriptRam", getRamCost(Player, "getScriptRam"));
const server = safeGetServer(hostname, "getScriptRam"); const server = safeGetServer(hostname, "getScriptRam");
for (let i = 0; i < server.scripts.length; ++i) { for (let i = 0; i < server.scripts.length; ++i) {
if (server.scripts[i].filename == scriptname) { if (server.scripts[i].filename == scriptname) {
@ -1959,7 +1959,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return 0; return 0;
}, },
getRunningScript: function (fn: any, hostname: any, ...args: any[]): any { getRunningScript: function (fn: any, hostname: any, ...args: any[]): any {
updateDynamicRam("getRunningScript", getRamCost("getRunningScript")); updateDynamicRam("getRunningScript", getRamCost(Player, "getRunningScript"));
let runningScript; let runningScript;
if (fn === undefined && hostname === undefined && args.length === 0) { if (fn === undefined && hostname === undefined && args.length === 0) {
@ -1987,7 +1987,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}; };
}, },
getHackTime: function (hostname: any): any { getHackTime: function (hostname: any): any {
updateDynamicRam("getHackTime", getRamCost("getHackTime")); updateDynamicRam("getHackTime", getRamCost(Player, "getHackTime"));
const server = safeGetServer(hostname, "getHackTime"); const server = safeGetServer(hostname, "getHackTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getHackTime", () => "invalid for this kind of server"); workerScript.log("getHackTime", () => "invalid for this kind of server");
@ -2000,7 +2000,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return calculateHackingTime(server, Player) * 1000; return calculateHackingTime(server, Player) * 1000;
}, },
getGrowTime: function (hostname: any): any { getGrowTime: function (hostname: any): any {
updateDynamicRam("getGrowTime", getRamCost("getGrowTime")); updateDynamicRam("getGrowTime", getRamCost(Player, "getGrowTime"));
const server = safeGetServer(hostname, "getGrowTime"); const server = safeGetServer(hostname, "getGrowTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getGrowTime", () => "invalid for this kind of server"); workerScript.log("getGrowTime", () => "invalid for this kind of server");
@ -2013,7 +2013,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return calculateGrowTime(server, Player) * 1000; return calculateGrowTime(server, Player) * 1000;
}, },
getWeakenTime: function (hostname: any): any { getWeakenTime: function (hostname: any): any {
updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime")); updateDynamicRam("getWeakenTime", getRamCost(Player, "getWeakenTime"));
const server = safeGetServer(hostname, "getWeakenTime"); const server = safeGetServer(hostname, "getWeakenTime");
if (!(server instanceof Server)) { if (!(server instanceof Server)) {
workerScript.log("getWeakenTime", () => "invalid for this kind of server"); workerScript.log("getWeakenTime", () => "invalid for this kind of server");
@ -2026,7 +2026,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return calculateWeakenTime(server, Player) * 1000; return calculateWeakenTime(server, Player) * 1000;
}, },
getScriptIncome: function (scriptname?: any, hostname?: any, ...args: any[]): any { getScriptIncome: function (scriptname?: any, hostname?: any, ...args: any[]): any {
updateDynamicRam("getScriptIncome", getRamCost("getScriptIncome")); updateDynamicRam("getScriptIncome", getRamCost(Player, "getScriptIncome"));
if (arguments.length === 0) { if (arguments.length === 0) {
const res = []; const res = [];
@ -2055,7 +2055,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}, },
getScriptExpGain: function (scriptname?: any, hostname?: any, ...args: any[]): any { getScriptExpGain: function (scriptname?: any, hostname?: any, ...args: any[]): any {
updateDynamicRam("getScriptExpGain", getRamCost("getScriptExpGain")); updateDynamicRam("getScriptExpGain", getRamCost(Player, "getScriptExpGain"));
if (arguments.length === 0) { if (arguments.length === 0) {
let total = 0; let total = 0;
for (const ws of workerScripts.values()) { for (const ws of workerScripts.values()) {
@ -2087,7 +2087,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return convertTimeMsToTimeElapsedString(milliseconds, milliPrecision); return convertTimeMsToTimeElapsedString(milliseconds, milliPrecision);
}, },
getTimeSinceLastAug: function (): any { getTimeSinceLastAug: function (): any {
updateDynamicRam("getTimeSinceLastAug", getRamCost("getTimeSinceLastAug")); updateDynamicRam("getTimeSinceLastAug", getRamCost(Player, "getTimeSinceLastAug"));
return Player.playtimeSinceLastAug; return Player.playtimeSinceLastAug;
}, },
alert: function (message: any): void { alert: function (message: any): void {
@ -2125,7 +2125,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
function (data) { function (data) {
let res; let res;
if (isScriptFilename(target)) { if (isScriptFilename(target)) {
res = s.writeToScriptFile(target, data); res = s.writeToScriptFile(Player, target, data);
} else { } else {
res = s.writeToTextFile(target, data); res = s.writeToTextFile(target, data);
} }
@ -2151,11 +2151,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}); });
}, },
getFavorToDonate: function (): any { getFavorToDonate: function (): any {
updateDynamicRam("getFavorToDonate", getRamCost("getFavorToDonate")); updateDynamicRam("getFavorToDonate", getRamCost(Player, "getFavorToDonate"));
return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction); return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
}, },
getOwnedSourceFiles: function (): SourceFileLvl[] { getOwnedSourceFiles: function (): SourceFileLvl[] {
helper.updateDynamicRam("getOwnedSourceFiles", getRamCost("getOwnedSourceFiles")); helper.updateDynamicRam("getOwnedSourceFiles", getRamCost(Player, "getOwnedSourceFiles"));
const res: SourceFileLvl[] = []; const res: SourceFileLvl[] = [];
for (let i = 0; i < Player.sourceFiles.length; ++i) { for (let i = 0; i < Player.sourceFiles.length; ++i) {
res.push({ res.push({
@ -2166,7 +2166,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return res; return res;
}, },
getPlayer: function (): INetscriptPlayer { getPlayer: function (): INetscriptPlayer {
helper.updateDynamicRam("getPlayer", getRamCost("getPlayer")); helper.updateDynamicRam("getPlayer", getRamCost(Player, "getPlayer"));
const data = { const data = {
hacking: Player.hacking, hacking: Player.hacking,

@ -57,48 +57,48 @@ export function NetscriptBladeburner(
return { return {
getContractNames: function (): string[] { getContractNames: function (): string[] {
helper.updateDynamicRam("getContractNames", getRamCost("bladeburner", "getContractNames")); helper.updateDynamicRam("getContractNames", getRamCost(player, "bladeburner", "getContractNames"));
checkBladeburnerAccess("getContractNames"); checkBladeburnerAccess("getContractNames");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getContractNamesNetscriptFn(); return bladeburner.getContractNamesNetscriptFn();
}, },
getOperationNames: function (): string[] { getOperationNames: function (): string[] {
helper.updateDynamicRam("getOperationNames", getRamCost("bladeburner", "getOperationNames")); helper.updateDynamicRam("getOperationNames", getRamCost(player, "bladeburner", "getOperationNames"));
checkBladeburnerAccess("getOperationNames"); checkBladeburnerAccess("getOperationNames");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getOperationNamesNetscriptFn(); return bladeburner.getOperationNamesNetscriptFn();
}, },
getBlackOpNames: function (): string[] { getBlackOpNames: function (): string[] {
helper.updateDynamicRam("getBlackOpNames", getRamCost("bladeburner", "getBlackOpNames")); helper.updateDynamicRam("getBlackOpNames", getRamCost(player, "bladeburner", "getBlackOpNames"));
checkBladeburnerAccess("getBlackOpNames"); checkBladeburnerAccess("getBlackOpNames");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getBlackOpNamesNetscriptFn(); return bladeburner.getBlackOpNamesNetscriptFn();
}, },
getBlackOpRank: function (name: any = ""): number { getBlackOpRank: function (name: any = ""): number {
helper.updateDynamicRam("getBlackOpRank", getRamCost("bladeburner", "getBlackOpRank")); helper.updateDynamicRam("getBlackOpRank", getRamCost(player, "bladeburner", "getBlackOpRank"));
checkBladeburnerAccess("getBlackOpRank"); checkBladeburnerAccess("getBlackOpRank");
const action: any = getBladeburnerActionObject("getBlackOpRank", "blackops", name); const action: any = getBladeburnerActionObject("getBlackOpRank", "blackops", name);
return action.reqdRank; return action.reqdRank;
}, },
getGeneralActionNames: function (): string[] { getGeneralActionNames: function (): string[] {
helper.updateDynamicRam("getGeneralActionNames", getRamCost("bladeburner", "getGeneralActionNames")); helper.updateDynamicRam("getGeneralActionNames", getRamCost(player, "bladeburner", "getGeneralActionNames"));
checkBladeburnerAccess("getGeneralActionNames"); checkBladeburnerAccess("getGeneralActionNames");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getGeneralActionNamesNetscriptFn(); return bladeburner.getGeneralActionNamesNetscriptFn();
}, },
getSkillNames: function (): string[] { getSkillNames: function (): string[] {
helper.updateDynamicRam("getSkillNames", getRamCost("bladeburner", "getSkillNames")); helper.updateDynamicRam("getSkillNames", getRamCost(player, "bladeburner", "getSkillNames"));
checkBladeburnerAccess("getSkillNames"); checkBladeburnerAccess("getSkillNames");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getSkillNamesNetscriptFn(); return bladeburner.getSkillNamesNetscriptFn();
}, },
startAction: function (type: any = "", name: any = ""): boolean { startAction: function (type: any = "", name: any = ""): boolean {
helper.updateDynamicRam("startAction", getRamCost("bladeburner", "startAction")); helper.updateDynamicRam("startAction", getRamCost(player, "bladeburner", "startAction"));
checkBladeburnerAccess("startAction"); checkBladeburnerAccess("startAction");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -109,21 +109,21 @@ export function NetscriptBladeburner(
} }
}, },
stopBladeburnerAction: function (): void { stopBladeburnerAction: function (): void {
helper.updateDynamicRam("stopBladeburnerAction", getRamCost("bladeburner", "stopBladeburnerAction")); helper.updateDynamicRam("stopBladeburnerAction", getRamCost(player, "bladeburner", "stopBladeburnerAction"));
checkBladeburnerAccess("stopBladeburnerAction"); checkBladeburnerAccess("stopBladeburnerAction");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.resetAction(); return bladeburner.resetAction();
}, },
getCurrentAction: function (): BladeburnerCurAction { getCurrentAction: function (): BladeburnerCurAction {
helper.updateDynamicRam("getCurrentAction", getRamCost("bladeburner", "getCurrentAction")); helper.updateDynamicRam("getCurrentAction", getRamCost(player, "bladeburner", "getCurrentAction"));
checkBladeburnerAccess("getCurrentAction"); checkBladeburnerAccess("getCurrentAction");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.getTypeAndNameFromActionId(bladeburner.action); return bladeburner.getTypeAndNameFromActionId(bladeburner.action);
}, },
getActionTime: function (type: any = "", name: any = ""): number { getActionTime: function (type: any = "", name: any = ""): number {
helper.updateDynamicRam("getActionTime", getRamCost("bladeburner", "getActionTime")); helper.updateDynamicRam("getActionTime", getRamCost(player, "bladeburner", "getActionTime"));
checkBladeburnerAccess("getActionTime"); checkBladeburnerAccess("getActionTime");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -136,7 +136,7 @@ export function NetscriptBladeburner(
getActionEstimatedSuccessChance: function (type: any = "", name: any = ""): [number, number] { getActionEstimatedSuccessChance: function (type: any = "", name: any = ""): [number, number] {
helper.updateDynamicRam( helper.updateDynamicRam(
"getActionEstimatedSuccessChance", "getActionEstimatedSuccessChance",
getRamCost("bladeburner", "getActionEstimatedSuccessChance"), getRamCost(player, "bladeburner", "getActionEstimatedSuccessChance"),
); );
checkBladeburnerAccess("getActionEstimatedSuccessChance"); checkBladeburnerAccess("getActionEstimatedSuccessChance");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
@ -148,7 +148,7 @@ export function NetscriptBladeburner(
} }
}, },
getActionRepGain: function (type: any = "", name: any = "", level: any): number { getActionRepGain: function (type: any = "", name: any = "", level: any): number {
helper.updateDynamicRam("getActionRepGain", getRamCost("bladeburner", "getActionRepGain")); helper.updateDynamicRam("getActionRepGain", getRamCost(player, "bladeburner", "getActionRepGain"));
checkBladeburnerAccess("getActionRepGain"); checkBladeburnerAccess("getActionRepGain");
const action = getBladeburnerActionObject("getActionRepGain", type, name); const action = getBladeburnerActionObject("getActionRepGain", type, name);
let rewardMultiplier; let rewardMultiplier;
@ -161,7 +161,7 @@ export function NetscriptBladeburner(
return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank; return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank;
}, },
getActionCountRemaining: function (type: any = "", name: any = ""): number { getActionCountRemaining: function (type: any = "", name: any = ""): number {
helper.updateDynamicRam("getActionCountRemaining", getRamCost("bladeburner", "getActionCountRemaining")); helper.updateDynamicRam("getActionCountRemaining", getRamCost(player, "bladeburner", "getActionCountRemaining"));
checkBladeburnerAccess("getActionCountRemaining"); checkBladeburnerAccess("getActionCountRemaining");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -172,31 +172,31 @@ export function NetscriptBladeburner(
} }
}, },
getActionMaxLevel: function (type: any = "", name: any = ""): number { getActionMaxLevel: function (type: any = "", name: any = ""): number {
helper.updateDynamicRam("getActionMaxLevel", getRamCost("bladeburner", "getActionMaxLevel")); helper.updateDynamicRam("getActionMaxLevel", getRamCost(player, "bladeburner", "getActionMaxLevel"));
checkBladeburnerAccess("getActionMaxLevel"); checkBladeburnerAccess("getActionMaxLevel");
const action = getBladeburnerActionObject("getActionMaxLevel", type, name); const action = getBladeburnerActionObject("getActionMaxLevel", type, name);
return action.maxLevel; return action.maxLevel;
}, },
getActionCurrentLevel: function (type: any = "", name: any = ""): number { getActionCurrentLevel: function (type: any = "", name: any = ""): number {
helper.updateDynamicRam("getActionCurrentLevel", getRamCost("bladeburner", "getActionCurrentLevel")); helper.updateDynamicRam("getActionCurrentLevel", getRamCost(player, "bladeburner", "getActionCurrentLevel"));
checkBladeburnerAccess("getActionCurrentLevel"); checkBladeburnerAccess("getActionCurrentLevel");
const action = getBladeburnerActionObject("getActionCurrentLevel", type, name); const action = getBladeburnerActionObject("getActionCurrentLevel", type, name);
return action.level; return action.level;
}, },
getActionAutolevel: function (type: any = "", name: any = ""): boolean { getActionAutolevel: function (type: any = "", name: any = ""): boolean {
helper.updateDynamicRam("getActionAutolevel", getRamCost("bladeburner", "getActionAutolevel")); helper.updateDynamicRam("getActionAutolevel", getRamCost(player, "bladeburner", "getActionAutolevel"));
checkBladeburnerAccess("getActionAutolevel"); checkBladeburnerAccess("getActionAutolevel");
const action = getBladeburnerActionObject("getActionCurrentLevel", type, name); const action = getBladeburnerActionObject("getActionCurrentLevel", type, name);
return action.autoLevel; return action.autoLevel;
}, },
setActionAutolevel: function (type: any = "", name: any = "", autoLevel: any = true): void { setActionAutolevel: function (type: any = "", name: any = "", autoLevel: any = true): void {
helper.updateDynamicRam("setActionAutolevel", getRamCost("bladeburner", "setActionAutolevel")); helper.updateDynamicRam("setActionAutolevel", getRamCost(player, "bladeburner", "setActionAutolevel"));
checkBladeburnerAccess("setActionAutolevel"); checkBladeburnerAccess("setActionAutolevel");
const action = getBladeburnerActionObject("setActionAutolevel", type, name); const action = getBladeburnerActionObject("setActionAutolevel", type, name);
action.autoLevel = autoLevel; action.autoLevel = autoLevel;
}, },
setActionLevel: function (type: any = "", name: any = "", level: any = 1): void { setActionLevel: function (type: any = "", name: any = "", level: any = 1): void {
helper.updateDynamicRam("setActionLevel", getRamCost("bladeburner", "setActionLevel")); helper.updateDynamicRam("setActionLevel", getRamCost(player, "bladeburner", "setActionLevel"));
checkBladeburnerAccess("setActionLevel"); checkBladeburnerAccess("setActionLevel");
const action = getBladeburnerActionObject("setActionLevel", type, name); const action = getBladeburnerActionObject("setActionLevel", type, name);
if (level < 1 || level > action.maxLevel) { if (level < 1 || level > action.maxLevel) {
@ -208,21 +208,21 @@ export function NetscriptBladeburner(
action.level = level; action.level = level;
}, },
getRank: function (): number { getRank: function (): number {
helper.updateDynamicRam("getRank", getRamCost("bladeburner", "getRank")); helper.updateDynamicRam("getRank", getRamCost(player, "bladeburner", "getRank"));
checkBladeburnerAccess("getRank"); checkBladeburnerAccess("getRank");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.rank; return bladeburner.rank;
}, },
getSkillPoints: function (): number { getSkillPoints: function (): number {
helper.updateDynamicRam("getSkillPoints", getRamCost("bladeburner", "getSkillPoints")); helper.updateDynamicRam("getSkillPoints", getRamCost(player, "bladeburner", "getSkillPoints"));
checkBladeburnerAccess("getSkillPoints"); checkBladeburnerAccess("getSkillPoints");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.skillPoints; return bladeburner.skillPoints;
}, },
getSkillLevel: function (skillName: any = ""): number { getSkillLevel: function (skillName: any = ""): number {
helper.updateDynamicRam("getSkillLevel", getRamCost("bladeburner", "getSkillLevel")); helper.updateDynamicRam("getSkillLevel", getRamCost(player, "bladeburner", "getSkillLevel"));
checkBladeburnerAccess("getSkillLevel"); checkBladeburnerAccess("getSkillLevel");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -233,7 +233,7 @@ export function NetscriptBladeburner(
} }
}, },
getSkillUpgradeCost: function (skillName: any = ""): number { getSkillUpgradeCost: function (skillName: any = ""): number {
helper.updateDynamicRam("getSkillUpgradeCost", getRamCost("bladeburner", "getSkillUpgradeCost")); helper.updateDynamicRam("getSkillUpgradeCost", getRamCost(player, "bladeburner", "getSkillUpgradeCost"));
checkBladeburnerAccess("getSkillUpgradeCost"); checkBladeburnerAccess("getSkillUpgradeCost");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -244,7 +244,7 @@ export function NetscriptBladeburner(
} }
}, },
upgradeSkill: function (skillName: any): boolean { upgradeSkill: function (skillName: any): boolean {
helper.updateDynamicRam("upgradeSkill", getRamCost("bladeburner", "upgradeSkill")); helper.updateDynamicRam("upgradeSkill", getRamCost(player, "bladeburner", "upgradeSkill"));
checkBladeburnerAccess("upgradeSkill"); checkBladeburnerAccess("upgradeSkill");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -255,7 +255,7 @@ export function NetscriptBladeburner(
} }
}, },
getTeamSize: function (type: any = "", name: any = ""): number { getTeamSize: function (type: any = "", name: any = ""): number {
helper.updateDynamicRam("getTeamSize", getRamCost("bladeburner", "getTeamSize")); helper.updateDynamicRam("getTeamSize", getRamCost(player, "bladeburner", "getTeamSize"));
checkBladeburnerAccess("getTeamSize"); checkBladeburnerAccess("getTeamSize");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -266,7 +266,7 @@ export function NetscriptBladeburner(
} }
}, },
setTeamSize: function (type: any = "", name: any = "", size: any): number { setTeamSize: function (type: any = "", name: any = "", size: any): number {
helper.updateDynamicRam("setTeamSize", getRamCost("bladeburner", "setTeamSize")); helper.updateDynamicRam("setTeamSize", getRamCost(player, "bladeburner", "setTeamSize"));
checkBladeburnerAccess("setTeamSize"); checkBladeburnerAccess("setTeamSize");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
@ -277,7 +277,10 @@ export function NetscriptBladeburner(
} }
}, },
getCityEstimatedPopulation: function (cityName: any): number { getCityEstimatedPopulation: function (cityName: any): number {
helper.updateDynamicRam("getCityEstimatedPopulation", getRamCost("bladeburner", "getCityEstimatedPopulation")); helper.updateDynamicRam(
"getCityEstimatedPopulation",
getRamCost(player, "bladeburner", "getCityEstimatedPopulation"),
);
checkBladeburnerAccess("getCityEstimatedPopulation"); checkBladeburnerAccess("getCityEstimatedPopulation");
checkBladeburnerCity("getCityEstimatedPopulation", cityName); checkBladeburnerCity("getCityEstimatedPopulation", cityName);
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
@ -285,7 +288,7 @@ export function NetscriptBladeburner(
return bladeburner.cities[cityName].popEst; return bladeburner.cities[cityName].popEst;
}, },
getCityCommunities: function (cityName: any): number { getCityCommunities: function (cityName: any): number {
helper.updateDynamicRam("getCityCommunities", getRamCost("bladeburner", "getCityCommunities")); helper.updateDynamicRam("getCityCommunities", getRamCost(player, "bladeburner", "getCityCommunities"));
checkBladeburnerAccess("getCityCommunities"); checkBladeburnerAccess("getCityCommunities");
checkBladeburnerCity("getCityCommunities", cityName); checkBladeburnerCity("getCityCommunities", cityName);
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
@ -293,7 +296,7 @@ export function NetscriptBladeburner(
return bladeburner.cities[cityName].comms; return bladeburner.cities[cityName].comms;
}, },
getCityChaos: function (cityName: any): number { getCityChaos: function (cityName: any): number {
helper.updateDynamicRam("getCityChaos", getRamCost("bladeburner", "getCityChaos")); helper.updateDynamicRam("getCityChaos", getRamCost(player, "bladeburner", "getCityChaos"));
checkBladeburnerAccess("getCityChaos"); checkBladeburnerAccess("getCityChaos");
checkBladeburnerCity("getCityChaos", cityName); checkBladeburnerCity("getCityChaos", cityName);
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
@ -301,14 +304,14 @@ export function NetscriptBladeburner(
return bladeburner.cities[cityName].chaos; return bladeburner.cities[cityName].chaos;
}, },
getCity: function (): string { getCity: function (): string {
helper.updateDynamicRam("getCity", getRamCost("bladeburner", "getCity")); helper.updateDynamicRam("getCity", getRamCost(player, "bladeburner", "getCity"));
checkBladeburnerAccess("getCityChaos"); checkBladeburnerAccess("getCityChaos");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.city; return bladeburner.city;
}, },
switchCity: function (cityName: any): boolean { switchCity: function (cityName: any): boolean {
helper.updateDynamicRam("switchCity", getRamCost("bladeburner", "switchCity")); helper.updateDynamicRam("switchCity", getRamCost(player, "bladeburner", "switchCity"));
checkBladeburnerAccess("switchCity"); checkBladeburnerAccess("switchCity");
checkBladeburnerCity("switchCity", cityName); checkBladeburnerCity("switchCity", cityName);
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
@ -316,21 +319,21 @@ export function NetscriptBladeburner(
return (bladeburner.city = cityName); return (bladeburner.city = cityName);
}, },
getStamina: function (): [number, number] { getStamina: function (): [number, number] {
helper.updateDynamicRam("getStamina", getRamCost("bladeburner", "getStamina")); helper.updateDynamicRam("getStamina", getRamCost(player, "bladeburner", "getStamina"));
checkBladeburnerAccess("getStamina"); checkBladeburnerAccess("getStamina");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return [bladeburner.stamina, bladeburner.maxStamina]; return [bladeburner.stamina, bladeburner.maxStamina];
}, },
joinBladeburnerFaction: function (): boolean { joinBladeburnerFaction: function (): boolean {
helper.updateDynamicRam("joinBladeburnerFaction", getRamCost("bladeburner", "joinBladeburnerFaction")); helper.updateDynamicRam("joinBladeburnerFaction", getRamCost(player, "bladeburner", "joinBladeburnerFaction"));
checkBladeburnerAccess("joinBladeburnerFaction", true); checkBladeburnerAccess("joinBladeburnerFaction", true);
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
return bladeburner.joinBladeburnerFactionNetscriptFn(workerScript); return bladeburner.joinBladeburnerFactionNetscriptFn(workerScript);
}, },
joinBladeburnerDivision: function (): boolean { joinBladeburnerDivision: function (): boolean {
helper.updateDynamicRam("joinBladeburnerDivision", getRamCost("bladeburner", "joinBladeburnerDivision")); helper.updateDynamicRam("joinBladeburnerDivision", getRamCost(player, "bladeburner", "joinBladeburnerDivision"));
if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) { if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) {
if (player.bitNodeN === 8) { if (player.bitNodeN === 8) {
return false; return false;
@ -358,7 +361,7 @@ export function NetscriptBladeburner(
return false; return false;
}, },
getBonusTime: function (): number { getBonusTime: function (): number {
helper.updateDynamicRam("getBonusTime", getRamCost("bladeburner", "getBonusTime")); helper.updateDynamicRam("getBonusTime", getRamCost(player, "bladeburner", "getBonusTime"));
checkBladeburnerAccess("getBonusTime"); checkBladeburnerAccess("getBonusTime");
const bladeburner = player.bladeburner; const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner"); if (bladeburner === null) throw new Error("Should not be called without Bladeburner");

@ -31,7 +31,7 @@ export function NetscriptCodingContract(
hostname: any = workerScript.hostname, hostname: any = workerScript.hostname,
{ returnReward }: any = {}, { returnReward }: any = {},
): boolean | string { ): boolean | string {
helper.updateDynamicRam("attempt", getRamCost("codingcontract", "attempt")); helper.updateDynamicRam("attempt", getRamCost(player, "codingcontract", "attempt"));
const contract = getCodingContract("attempt", hostname, filename); const contract = getCodingContract("attempt", hostname, filename);
// Convert answer to string. If the answer is a 2D array, then we have to // Convert answer to string. If the answer is a 2D array, then we have to
@ -78,12 +78,12 @@ export function NetscriptCodingContract(
} }
}, },
getContractType: function (filename: any, hostname: any = workerScript.hostname): string { getContractType: function (filename: any, hostname: any = workerScript.hostname): string {
helper.updateDynamicRam("getContractType", getRamCost("codingcontract", "getContractType")); helper.updateDynamicRam("getContractType", getRamCost(player, "codingcontract", "getContractType"));
const contract = getCodingContract("getContractType", hostname, filename); const contract = getCodingContract("getContractType", hostname, filename);
return contract.getType(); return contract.getType();
}, },
getData: function (filename: any, hostname: any = workerScript.hostname): any { getData: function (filename: any, hostname: any = workerScript.hostname): any {
helper.updateDynamicRam("getData", getRamCost("codingcontract", "getData")); helper.updateDynamicRam("getData", getRamCost(player, "codingcontract", "getData"));
const contract = getCodingContract("getData", hostname, filename); const contract = getCodingContract("getData", hostname, filename);
const data = contract.getData(); const data = contract.getData();
if (data.constructor === Array) { if (data.constructor === Array) {
@ -103,12 +103,12 @@ export function NetscriptCodingContract(
} }
}, },
getDescription: function (filename: any, hostname: any = workerScript.hostname): string { getDescription: function (filename: any, hostname: any = workerScript.hostname): string {
helper.updateDynamicRam("getDescription", getRamCost("codingcontract", "getDescription")); helper.updateDynamicRam("getDescription", getRamCost(player, "codingcontract", "getDescription"));
const contract = getCodingContract("getDescription", hostname, filename); const contract = getCodingContract("getDescription", hostname, filename);
return contract.getDescription(); return contract.getDescription();
}, },
getNumTriesRemaining: function (filename: any, hostname: any = workerScript.hostname): number { getNumTriesRemaining: function (filename: any, hostname: any = workerScript.hostname): number {
helper.updateDynamicRam("getNumTriesRemaining", getRamCost("codingcontract", "getNumTriesRemaining")); helper.updateDynamicRam("getNumTriesRemaining", getRamCost(player, "codingcontract", "getNumTriesRemaining"));
const contract = getCodingContract("getNumTriesRemaining", hostname, filename); const contract = getCodingContract("getNumTriesRemaining", hostname, filename);
return contract.getMaxNumTries() - contract.tries; return contract.getMaxNumTries() - contract.tries;
}, },

@ -47,7 +47,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return { return {
createGang: function (faction: string): boolean { createGang: function (faction: string): boolean {
helper.updateDynamicRam("createGang", getRamCost("gang", "createGang")); helper.updateDynamicRam("createGang", getRamCost(player, "gang", "createGang"));
// this list is copied from Faction/ui/Root.tsx // this list is copied from Faction/ui/Root.tsx
const GangNames = [ const GangNames = [
"Slum Snakes", "Slum Snakes",
@ -67,18 +67,18 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return true; return true;
}, },
inGang: function (): boolean { inGang: function (): boolean {
helper.updateDynamicRam("inGang", getRamCost("gang", "inGang")); helper.updateDynamicRam("inGang", getRamCost(player, "gang", "inGang"));
return player.inGang(); return player.inGang();
}, },
getMemberNames: function (): string[] { getMemberNames: function (): string[] {
helper.updateDynamicRam("getMemberNames", getRamCost("gang", "getMemberNames")); helper.updateDynamicRam("getMemberNames", getRamCost(player, "gang", "getMemberNames"));
checkGangApiAccess("getMemberNames"); checkGangApiAccess("getMemberNames");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
return gang.members.map((member) => member.name); return gang.members.map((member) => member.name);
}, },
getGangInformation: function (): GangGenInfo { getGangInformation: function (): GangGenInfo {
helper.updateDynamicRam("getGangInformation", getRamCost("gang", "getGangInformation")); helper.updateDynamicRam("getGangInformation", getRamCost(player, "gang", "getGangInformation"));
checkGangApiAccess("getGangInformation"); checkGangApiAccess("getGangInformation");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -98,7 +98,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
}; };
}, },
getOtherGangInformation: function (): GangOtherInfo { getOtherGangInformation: function (): GangOtherInfo {
helper.updateDynamicRam("getOtherGangInformation", getRamCost("gang", "getOtherGangInformation")); helper.updateDynamicRam("getOtherGangInformation", getRamCost(player, "gang", "getOtherGangInformation"));
checkGangApiAccess("getOtherGangInformation"); checkGangApiAccess("getOtherGangInformation");
const cpy: any = {}; const cpy: any = {};
for (const gang in AllGangs) { for (const gang in AllGangs) {
@ -108,7 +108,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return cpy; return cpy;
}, },
getMemberInformation: function (name: any): GangMemberInfo { getMemberInformation: function (name: any): GangMemberInfo {
helper.updateDynamicRam("getMemberInformation", getRamCost("gang", "getMemberInformation")); helper.updateDynamicRam("getMemberInformation", getRamCost(player, "gang", "getMemberInformation"));
checkGangApiAccess("getMemberInformation"); checkGangApiAccess("getMemberInformation");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -161,14 +161,14 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
}; };
}, },
canRecruitMember: function (): boolean { canRecruitMember: function (): boolean {
helper.updateDynamicRam("canRecruitMember", getRamCost("gang", "canRecruitMember")); helper.updateDynamicRam("canRecruitMember", getRamCost(player, "gang", "canRecruitMember"));
checkGangApiAccess("canRecruitMember"); checkGangApiAccess("canRecruitMember");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
return gang.canRecruitMember(); return gang.canRecruitMember();
}, },
recruitMember: function (name: any): boolean { recruitMember: function (name: any): boolean {
helper.updateDynamicRam("recruitMember", getRamCost("gang", "recruitMember")); helper.updateDynamicRam("recruitMember", getRamCost(player, "gang", "recruitMember"));
checkGangApiAccess("recruitMember"); checkGangApiAccess("recruitMember");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -182,7 +182,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return recruited; return recruited;
}, },
getTaskNames: function (): string[] { getTaskNames: function (): string[] {
helper.updateDynamicRam("getTaskNames", getRamCost("gang", "getTaskNames")); helper.updateDynamicRam("getTaskNames", getRamCost(player, "gang", "getTaskNames"));
checkGangApiAccess("getTaskNames"); checkGangApiAccess("getTaskNames");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -191,7 +191,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return tasks; return tasks;
}, },
setMemberTask: function (memberName: any, taskName: any): boolean { setMemberTask: function (memberName: any, taskName: any): boolean {
helper.updateDynamicRam("setMemberTask", getRamCost("gang", "setMemberTask")); helper.updateDynamicRam("setMemberTask", getRamCost(player, "gang", "setMemberTask"));
checkGangApiAccess("setMemberTask"); checkGangApiAccess("setMemberTask");
const member = getGangMember("setMemberTask", memberName); const member = getGangMember("setMemberTask", memberName);
const success = member.assignToTask(taskName); const success = member.assignToTask(taskName);
@ -210,7 +210,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return success; return success;
}, },
getTaskStats: function (taskName: any): GangTaskStats { getTaskStats: function (taskName: any): GangTaskStats {
helper.updateDynamicRam("getTaskStats", getRamCost("gang", "getTaskStats")); helper.updateDynamicRam("getTaskStats", getRamCost(player, "gang", "getTaskStats"));
checkGangApiAccess("getTaskStats"); checkGangApiAccess("getTaskStats");
const task = getGangTask("getTaskStats", taskName); const task = getGangTask("getTaskStats", taskName);
const copy = Object.assign({}, task); const copy = Object.assign({}, task);
@ -218,12 +218,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return copy; return copy;
}, },
getEquipmentNames: function (): string[] { getEquipmentNames: function (): string[] {
helper.updateDynamicRam("getEquipmentNames", getRamCost("gang", "getEquipmentNames")); helper.updateDynamicRam("getEquipmentNames", getRamCost(player, "gang", "getEquipmentNames"));
checkGangApiAccess("getEquipmentNames"); checkGangApiAccess("getEquipmentNames");
return Object.keys(GangMemberUpgrades); return Object.keys(GangMemberUpgrades);
}, },
getEquipmentCost: function (equipName: any): number { getEquipmentCost: function (equipName: any): number {
helper.updateDynamicRam("getEquipmentCost", getRamCost("gang", "getEquipmentCost")); helper.updateDynamicRam("getEquipmentCost", getRamCost(player, "gang", "getEquipmentCost"));
checkGangApiAccess("getEquipmentCost"); checkGangApiAccess("getEquipmentCost");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -232,14 +232,14 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return gang.getUpgradeCost(upg); return gang.getUpgradeCost(upg);
}, },
getEquipmentType: function (equipName: any): string { getEquipmentType: function (equipName: any): string {
helper.updateDynamicRam("getEquipmentType", getRamCost("gang", "getEquipmentType")); helper.updateDynamicRam("getEquipmentType", getRamCost(player, "gang", "getEquipmentType"));
checkGangApiAccess("getEquipmentType"); checkGangApiAccess("getEquipmentType");
const upg = GangMemberUpgrades[equipName]; const upg = GangMemberUpgrades[equipName];
if (upg == null) return ""; if (upg == null) return "";
return upg.getType(); return upg.getType();
}, },
getEquipmentStats: function (equipName: any): EquipmentStats { getEquipmentStats: function (equipName: any): EquipmentStats {
helper.updateDynamicRam("getEquipmentStats", getRamCost("gang", "getEquipmentStats")); helper.updateDynamicRam("getEquipmentStats", getRamCost(player, "gang", "getEquipmentStats"));
checkGangApiAccess("getEquipmentStats"); checkGangApiAccess("getEquipmentStats");
const equipment = GangMemberUpgrades[equipName]; const equipment = GangMemberUpgrades[equipName];
if (!equipment) { if (!equipment) {
@ -249,7 +249,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return Object.assign({}, typecheck) as any; return Object.assign({}, typecheck) as any;
}, },
purchaseEquipment: function (memberName: any, equipName: any): boolean { purchaseEquipment: function (memberName: any, equipName: any): boolean {
helper.updateDynamicRam("purchaseEquipment", getRamCost("gang", "purchaseEquipment")); helper.updateDynamicRam("purchaseEquipment", getRamCost(player, "gang", "purchaseEquipment"));
checkGangApiAccess("purchaseEquipment"); checkGangApiAccess("purchaseEquipment");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -269,7 +269,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return res; return res;
}, },
ascendMember: function (name: any): GangMemberAscension | undefined { ascendMember: function (name: any): GangMemberAscension | undefined {
helper.updateDynamicRam("ascendMember", getRamCost("gang", "ascendMember")); helper.updateDynamicRam("ascendMember", getRamCost(player, "gang", "ascendMember"));
checkGangApiAccess("ascendMember"); checkGangApiAccess("ascendMember");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -278,7 +278,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return gang.ascendMember(member, workerScript); return gang.ascendMember(member, workerScript);
}, },
getAscensionResult: function (name: any): GangMemberAscension | undefined { getAscensionResult: function (name: any): GangMemberAscension | undefined {
helper.updateDynamicRam("getAscensionResult", getRamCost("gang", "getAscensionResult")); helper.updateDynamicRam("getAscensionResult", getRamCost(player, "gang", "getAscensionResult"));
checkGangApiAccess("getAscensionResult"); checkGangApiAccess("getAscensionResult");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -290,7 +290,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
}; };
}, },
setTerritoryWarfare: function (engage: any): void { setTerritoryWarfare: function (engage: any): void {
helper.updateDynamicRam("setTerritoryWarfare", getRamCost("gang", "setTerritoryWarfare")); helper.updateDynamicRam("setTerritoryWarfare", getRamCost(player, "gang", "setTerritoryWarfare"));
checkGangApiAccess("setTerritoryWarfare"); checkGangApiAccess("setTerritoryWarfare");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -303,7 +303,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
} }
}, },
getChanceToWinClash: function (otherGang: any): number { getChanceToWinClash: function (otherGang: any): number {
helper.updateDynamicRam("getChanceToWinClash", getRamCost("gang", "getChanceToWinClash")); helper.updateDynamicRam("getChanceToWinClash", getRamCost(player, "gang", "getChanceToWinClash"));
checkGangApiAccess("getChanceToWinClash"); checkGangApiAccess("getChanceToWinClash");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");
@ -317,7 +317,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
return playerPower / (otherPower + playerPower); return playerPower / (otherPower + playerPower);
}, },
getBonusTime: function (): number { getBonusTime: function (): number {
helper.updateDynamicRam("getBonusTime", getRamCost("gang", "getBonusTime")); helper.updateDynamicRam("getBonusTime", getRamCost(player, "gang", "getBonusTime"));
checkGangApiAccess("getBonusTime"); checkGangApiAccess("getBonusTime");
const gang = player.gang; const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang"); if (gang === null) throw new Error("Should not be called without Gang");

@ -7,6 +7,6 @@ export interface INetscriptHelper {
number(funcName: string, argName: string, v: any): number; number(funcName: string, argName: string, v: any): number;
boolean(v: any): boolean; boolean(v: any): boolean;
getServer(ip: any, fn: any): BaseServer; getServer(ip: any, fn: any): BaseServer;
checkSingularityAccess(func: string, n: number): void; checkSingularityAccess(func: string): void;
hack(hostname: string, manual: boolean): Promise<number>; hack(hostname: string, manual: boolean): Promise<number>;
} }

@ -85,15 +85,15 @@ export function NetscriptSingularity(
} }
const runningScriptObj = new RunningScript(script, []); // No args const runningScriptObj = new RunningScript(script, []); // No args
runningScriptObj.threads = 1; // Only 1 thread runningScriptObj.threads = 1; // Only 1 thread
startWorkerScript(runningScriptObj, home); startWorkerScript(player, runningScriptObj, home);
} }
} }
} }
}; };
return { return {
getOwnedAugmentations: function (purchased: any = false): any { getOwnedAugmentations: function (purchased: any = false): any {
helper.updateDynamicRam("getOwnedAugmentations", getRamCost("getOwnedAugmentations")); helper.updateDynamicRam("getOwnedAugmentations", getRamCost(player, "getOwnedAugmentations"));
helper.checkSingularityAccess("getOwnedAugmentations", 3); helper.checkSingularityAccess("getOwnedAugmentations");
const res = []; const res = [];
for (let i = 0; i < player.augmentations.length; ++i) { for (let i = 0; i < player.augmentations.length; ++i) {
res.push(player.augmentations[i].name); res.push(player.augmentations[i].name);
@ -106,8 +106,8 @@ export function NetscriptSingularity(
return res; return res;
}, },
getAugmentationsFromFaction: function (facname: any): any { getAugmentationsFromFaction: function (facname: any): any {
helper.updateDynamicRam("getAugmentationsFromFaction", getRamCost("getAugmentationsFromFaction")); helper.updateDynamicRam("getAugmentationsFromFaction", getRamCost(player, "getAugmentationsFromFaction"));
helper.checkSingularityAccess("getAugmentationsFromFaction", 3); helper.checkSingularityAccess("getAugmentationsFromFaction");
const faction = getFaction("getAugmentationsFromFaction", facname); const faction = getFaction("getAugmentationsFromFaction", facname);
// If player has a gang with this faction, return all augmentations. // If player has a gang with this faction, return all augmentations.
@ -128,38 +128,38 @@ export function NetscriptSingularity(
return faction.augmentations.slice(); return faction.augmentations.slice();
}, },
getAugmentationCost: function (name: any): any { getAugmentationCost: function (name: any): any {
helper.updateDynamicRam("getAugmentationCost", getRamCost("getAugmentationCost")); helper.updateDynamicRam("getAugmentationCost", getRamCost(player, "getAugmentationCost"));
helper.checkSingularityAccess("getAugmentationCost", 3); helper.checkSingularityAccess("getAugmentationCost");
const aug = getAugmentation("getAugmentationCost", name); const aug = getAugmentation("getAugmentationCost", name);
return [aug.baseRepRequirement, aug.baseCost]; return [aug.baseRepRequirement, aug.baseCost];
}, },
getAugmentationPrereq: function (name: any): any { getAugmentationPrereq: function (name: any): any {
helper.updateDynamicRam("getAugmentationPrereq", getRamCost("getAugmentationPrereq")); helper.updateDynamicRam("getAugmentationPrereq", getRamCost(player, "getAugmentationPrereq"));
helper.checkSingularityAccess("getAugmentationPrereq", 3); helper.checkSingularityAccess("getAugmentationPrereq");
const aug = getAugmentation("getAugmentationPrereq", name); const aug = getAugmentation("getAugmentationPrereq", name);
return aug.prereqs.slice(); return aug.prereqs.slice();
}, },
getAugmentationPrice: function (name: any): any { getAugmentationPrice: function (name: any): any {
helper.updateDynamicRam("getAugmentationPrice", getRamCost("getAugmentationPrice")); helper.updateDynamicRam("getAugmentationPrice", getRamCost(player, "getAugmentationPrice"));
helper.checkSingularityAccess("getAugmentationPrice", 3); helper.checkSingularityAccess("getAugmentationPrice");
const aug = getAugmentation("getAugmentationPrice", name); const aug = getAugmentation("getAugmentationPrice", name);
return aug.baseCost; return aug.baseCost;
}, },
getAugmentationRepReq: function (name: any): any { getAugmentationRepReq: function (name: any): any {
helper.updateDynamicRam("getAugmentationRepReq", getRamCost("getAugmentationRepReq")); helper.updateDynamicRam("getAugmentationRepReq", getRamCost(player, "getAugmentationRepReq"));
helper.checkSingularityAccess("getAugmentationRepReq", 3); helper.checkSingularityAccess("getAugmentationRepReq");
const aug = getAugmentation("getAugmentationRepReq", name); const aug = getAugmentation("getAugmentationRepReq", name);
return aug.baseRepRequirement; return aug.baseRepRequirement;
}, },
getAugmentationStats: function (name: any): any { getAugmentationStats: function (name: any): any {
helper.updateDynamicRam("getAugmentationStats", getRamCost("getAugmentationStats")); helper.updateDynamicRam("getAugmentationStats", getRamCost(player, "getAugmentationStats"));
helper.checkSingularityAccess("getAugmentationStats", 3); helper.checkSingularityAccess("getAugmentationStats");
const aug = getAugmentation("getAugmentationStats", name); const aug = getAugmentation("getAugmentationStats", name);
return Object.assign({}, aug.mults); return Object.assign({}, aug.mults);
}, },
purchaseAugmentation: function (faction: any, name: any): any { purchaseAugmentation: function (faction: any, name: any): any {
helper.updateDynamicRam("purchaseAugmentation", getRamCost("purchaseAugmentation")); helper.updateDynamicRam("purchaseAugmentation", getRamCost(player, "purchaseAugmentation"));
helper.checkSingularityAccess("purchaseAugmentation", 3); helper.checkSingularityAccess("purchaseAugmentation");
const fac = getFaction("purchaseAugmentation", faction); const fac = getFaction("purchaseAugmentation", faction);
const aug = getAugmentation("purchaseAugmentation", name); const aug = getAugmentation("purchaseAugmentation", name);
@ -214,8 +214,8 @@ export function NetscriptSingularity(
} }
}, },
softReset: function (cbScript: any): any { softReset: function (cbScript: any): any {
helper.updateDynamicRam("softReset", getRamCost("softReset")); helper.updateDynamicRam("softReset", getRamCost(player, "softReset"));
helper.checkSingularityAccess("softReset", 3); helper.checkSingularityAccess("softReset");
workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed"); workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed");
setTimeout(() => { setTimeout(() => {
@ -228,8 +228,8 @@ export function NetscriptSingularity(
killWorkerScript(workerScript); killWorkerScript(workerScript);
}, },
installAugmentations: function (cbScript: any): any { installAugmentations: function (cbScript: any): any {
helper.updateDynamicRam("installAugmentations", getRamCost("installAugmentations")); helper.updateDynamicRam("installAugmentations", getRamCost(player, "installAugmentations"));
helper.checkSingularityAccess("installAugmentations", 3); helper.checkSingularityAccess("installAugmentations");
if (player.queuedAugmentations.length === 0) { if (player.queuedAugmentations.length === 0) {
workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed."); workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed.");
@ -250,8 +250,8 @@ export function NetscriptSingularity(
}, },
goToLocation: function (locationName: any): boolean { goToLocation: function (locationName: any): boolean {
helper.updateDynamicRam("goToLocation", getRamCost("goToLocation")); helper.updateDynamicRam("goToLocation", getRamCost(player, "goToLocation"));
helper.checkSingularityAccess("goToLocation", 1); helper.checkSingularityAccess("goToLocation");
const location = Object.values(Locations).find((l) => l.name === locationName); const location = Object.values(Locations).find((l) => l.name === locationName);
if (!location) { if (!location) {
workerScript.log("goToLocation", () => `No location named ${locationName}`); workerScript.log("goToLocation", () => `No location named ${locationName}`);
@ -266,8 +266,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
universityCourse: function (universityName: any, className: any): any { universityCourse: function (universityName: any, className: any): any {
helper.updateDynamicRam("universityCourse", getRamCost("universityCourse")); helper.updateDynamicRam("universityCourse", getRamCost(player, "universityCourse"));
helper.checkSingularityAccess("universityCourse", 1); helper.checkSingularityAccess("universityCourse");
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("universityCourse", () => txt); workerScript.log("universityCourse", () => txt);
@ -346,8 +346,8 @@ export function NetscriptSingularity(
}, },
gymWorkout: function (gymName: any, stat: any): any { gymWorkout: function (gymName: any, stat: any): any {
helper.updateDynamicRam("gymWorkout", getRamCost("gymWorkout")); helper.updateDynamicRam("gymWorkout", getRamCost(player, "gymWorkout"));
helper.checkSingularityAccess("gymWorkout", 1); helper.checkSingularityAccess("gymWorkout");
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
workerScript.log("gymWorkout", () => txt); workerScript.log("gymWorkout", () => txt);
@ -445,8 +445,8 @@ export function NetscriptSingularity(
}, },
travelToCity: function (cityname: any): any { travelToCity: function (cityname: any): any {
helper.updateDynamicRam("travelToCity", getRamCost("travelToCity")); helper.updateDynamicRam("travelToCity", getRamCost(player, "travelToCity"));
helper.checkSingularityAccess("travelToCity", 1); helper.checkSingularityAccess("travelToCity");
switch (cityname) { switch (cityname) {
case CityName.Aevum: case CityName.Aevum:
@ -470,8 +470,8 @@ export function NetscriptSingularity(
}, },
purchaseTor: function (): any { purchaseTor: function (): any {
helper.updateDynamicRam("purchaseTor", getRamCost("purchaseTor")); helper.updateDynamicRam("purchaseTor", getRamCost(player, "purchaseTor"));
helper.checkSingularityAccess("purchaseTor", 1); helper.checkSingularityAccess("purchaseTor");
if (player.hasTorRouter()) { if (player.hasTorRouter()) {
workerScript.log("purchaseTor", () => "You already have a TOR router!"); workerScript.log("purchaseTor", () => "You already have a TOR router!");
@ -502,8 +502,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
purchaseProgram: function (programName: any): any { purchaseProgram: function (programName: any): any {
helper.updateDynamicRam("purchaseProgram", getRamCost("purchaseProgram")); helper.updateDynamicRam("purchaseProgram", getRamCost(player, "purchaseProgram"));
helper.checkSingularityAccess("purchaseProgram", 1); helper.checkSingularityAccess("purchaseProgram");
if (!player.hasTorRouter()) { if (!player.hasTorRouter()) {
workerScript.log("purchaseProgram", () => "You do not have the TOR router."); workerScript.log("purchaseProgram", () => "You do not have the TOR router.");
@ -541,13 +541,13 @@ export function NetscriptSingularity(
return true; return true;
}, },
getCurrentServer: function (): any { getCurrentServer: function (): any {
helper.updateDynamicRam("getCurrentServer", getRamCost("getCurrentServer")); helper.updateDynamicRam("getCurrentServer", getRamCost(player, "getCurrentServer"));
helper.checkSingularityAccess("getCurrentServer", 1); helper.checkSingularityAccess("getCurrentServer");
return player.getCurrentServer().hostname; return player.getCurrentServer().hostname;
}, },
connect: function (hostname: any): any { connect: function (hostname: any): any {
helper.updateDynamicRam("connect", getRamCost("connect")); helper.updateDynamicRam("connect", getRamCost(player, "connect"));
helper.checkSingularityAccess("connect", 1); helper.checkSingularityAccess("connect");
if (!hostname) { if (!hostname) {
throw helper.makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`); throw helper.makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`);
} }
@ -581,14 +581,14 @@ export function NetscriptSingularity(
return false; return false;
}, },
manualHack: function (): any { manualHack: function (): any {
helper.updateDynamicRam("manualHack", getRamCost("manualHack")); helper.updateDynamicRam("manualHack", getRamCost(player, "manualHack"));
helper.checkSingularityAccess("manualHack", 1); helper.checkSingularityAccess("manualHack");
const server = player.getCurrentServer(); const server = player.getCurrentServer();
return helper.hack(server.hostname, true); return helper.hack(server.hostname, true);
}, },
installBackdoor: function (): any { installBackdoor: function (): any {
helper.updateDynamicRam("installBackdoor", getRamCost("installBackdoor")); helper.updateDynamicRam("installBackdoor", getRamCost(player, "installBackdoor"));
helper.checkSingularityAccess("installBackdoor", 1); helper.checkSingularityAccess("installBackdoor");
const baseserver = player.getCurrentServer(); const baseserver = player.getCurrentServer();
if (!(baseserver instanceof Server)) { if (!(baseserver instanceof Server)) {
workerScript.log("installBackdoor", () => "cannot backdoor this kind of server"); workerScript.log("installBackdoor", () => "cannot backdoor this kind of server");
@ -623,14 +623,14 @@ export function NetscriptSingularity(
}); });
}, },
isFocused: function (): boolean { isFocused: function (): boolean {
helper.updateDynamicRam("isFocused", getRamCost("isFocused")); helper.updateDynamicRam("isFocused", getRamCost(player, "isFocused"));
helper.checkSingularityAccess("isFocused", 2); helper.checkSingularityAccess("isFocused");
return player.focus; return player.focus;
}, },
setFocus: function (afocus: any): boolean { setFocus: function (afocus: any): boolean {
const focus = helper.boolean(afocus); const focus = helper.boolean(afocus);
helper.updateDynamicRam("setFocus", getRamCost("setFocus")); helper.updateDynamicRam("setFocus", getRamCost(player, "setFocus"));
helper.checkSingularityAccess("setFocus", 2); helper.checkSingularityAccess("setFocus");
if (!player.isWorking) { if (!player.isWorking) {
throw helper.makeRuntimeErrorMsg("setFocus", "Not currently working"); throw helper.makeRuntimeErrorMsg("setFocus", "Not currently working");
} }
@ -655,8 +655,8 @@ export function NetscriptSingularity(
return false; return false;
}, },
getStats: function (): any { getStats: function (): any {
helper.updateDynamicRam("getStats", getRamCost("getStats")); helper.updateDynamicRam("getStats", getRamCost(player, "getStats"));
helper.checkSingularityAccess("getStats", 1); helper.checkSingularityAccess("getStats");
workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`); workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`);
return { return {
@ -670,8 +670,8 @@ export function NetscriptSingularity(
}; };
}, },
getCharacterInformation: function (): any { getCharacterInformation: function (): any {
helper.updateDynamicRam("getCharacterInformation", getRamCost("getCharacterInformation")); helper.updateDynamicRam("getCharacterInformation", getRamCost(player, "getCharacterInformation"));
helper.checkSingularityAccess("getCharacterInformation", 1); helper.checkSingularityAccess("getCharacterInformation");
workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`); workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`);
return { return {
@ -718,8 +718,8 @@ export function NetscriptSingularity(
}; };
}, },
hospitalize: function (): any { hospitalize: function (): any {
helper.updateDynamicRam("hospitalize", getRamCost("hospitalize")); helper.updateDynamicRam("hospitalize", getRamCost(player, "hospitalize"));
helper.checkSingularityAccess("hospitalize", 1); helper.checkSingularityAccess("hospitalize");
if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) { if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy."); workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy.");
return; return;
@ -727,13 +727,13 @@ export function NetscriptSingularity(
return player.hospitalize(); return player.hospitalize();
}, },
isBusy: function (): any { isBusy: function (): any {
helper.updateDynamicRam("isBusy", getRamCost("isBusy")); helper.updateDynamicRam("isBusy", getRamCost(player, "isBusy"));
helper.checkSingularityAccess("isBusy", 1); helper.checkSingularityAccess("isBusy");
return player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse; return player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse;
}, },
stopAction: function (): any { stopAction: function (): any {
helper.updateDynamicRam("stopAction", getRamCost("stopAction")); helper.updateDynamicRam("stopAction", getRamCost(player, "stopAction"));
helper.checkSingularityAccess("stopAction", 1); helper.checkSingularityAccess("stopAction");
if (player.isWorking) { if (player.isWorking) {
if (player.focus) { if (player.focus) {
Router.toTerminal(); Router.toTerminal();
@ -745,8 +745,8 @@ export function NetscriptSingularity(
return false; return false;
}, },
upgradeHomeCores: function (): any { upgradeHomeCores: function (): any {
helper.updateDynamicRam("upgradeHomeCores", getRamCost("upgradeHomeCores")); helper.updateDynamicRam("upgradeHomeCores", getRamCost(player, "upgradeHomeCores"));
helper.checkSingularityAccess("upgradeHomeCores", 2); helper.checkSingularityAccess("upgradeHomeCores");
// Check if we're at max cores // Check if we're at max cores
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
@ -775,14 +775,14 @@ export function NetscriptSingularity(
return true; return true;
}, },
getUpgradeHomeCoresCost: function (): any { getUpgradeHomeCoresCost: function (): any {
helper.updateDynamicRam("getUpgradeHomeCoresCost", getRamCost("getUpgradeHomeCoresCost")); helper.updateDynamicRam("getUpgradeHomeCoresCost", getRamCost(player, "getUpgradeHomeCoresCost"));
helper.checkSingularityAccess("getUpgradeHomeCoresCost", 2); helper.checkSingularityAccess("getUpgradeHomeCoresCost");
return player.getUpgradeHomeCoresCost(); return player.getUpgradeHomeCoresCost();
}, },
upgradeHomeRam: function (): any { upgradeHomeRam: function (): any {
helper.updateDynamicRam("upgradeHomeRam", getRamCost("upgradeHomeRam")); helper.updateDynamicRam("upgradeHomeRam", getRamCost(player, "upgradeHomeRam"));
helper.checkSingularityAccess("upgradeHomeRam", 2); helper.checkSingularityAccess("upgradeHomeRam");
// Check if we're at max RAM // Check if we're at max RAM
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
@ -814,14 +814,14 @@ export function NetscriptSingularity(
return true; return true;
}, },
getUpgradeHomeRamCost: function (): any { getUpgradeHomeRamCost: function (): any {
helper.updateDynamicRam("getUpgradeHomeRamCost", getRamCost("getUpgradeHomeRamCost")); helper.updateDynamicRam("getUpgradeHomeRamCost", getRamCost(player, "getUpgradeHomeRamCost"));
helper.checkSingularityAccess("getUpgradeHomeRamCost", 2); helper.checkSingularityAccess("getUpgradeHomeRamCost");
return player.getUpgradeHomeRamCost(); return player.getUpgradeHomeRamCost();
}, },
workForCompany: function (companyName: any, focus = true): any { workForCompany: function (companyName: any, focus = true): any {
helper.updateDynamicRam("workForCompany", getRamCost("workForCompany")); helper.updateDynamicRam("workForCompany", getRamCost(player, "workForCompany"));
helper.checkSingularityAccess("workForCompany", 2); helper.checkSingularityAccess("workForCompany");
// Sanitize input // Sanitize input
if (companyName == null) { if (companyName == null) {
@ -863,8 +863,7 @@ export function NetscriptSingularity(
if (focus) { if (focus) {
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();
} } else if (wasFocused) {
else if (wasFocused) {
player.stopFocusing(); player.stopFocusing();
Router.toTerminal(); Router.toTerminal();
} }
@ -875,8 +874,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
applyToCompany: function (companyName: any, field: any): any { applyToCompany: function (companyName: any, field: any): any {
helper.updateDynamicRam("applyToCompany", getRamCost("applyToCompany")); helper.updateDynamicRam("applyToCompany", getRamCost(player, "applyToCompany"));
helper.checkSingularityAccess("applyToCompany", 2); helper.checkSingularityAccess("applyToCompany");
getCompany("applyToCompany", companyName); getCompany("applyToCompany", companyName);
player.location = companyName; player.location = companyName;
@ -945,32 +944,32 @@ export function NetscriptSingularity(
return res; return res;
}, },
getCompanyRep: function (companyName: any): any { getCompanyRep: function (companyName: any): any {
helper.updateDynamicRam("getCompanyRep", getRamCost("getCompanyRep")); helper.updateDynamicRam("getCompanyRep", getRamCost(player, "getCompanyRep"));
helper.checkSingularityAccess("getCompanyRep", 2); helper.checkSingularityAccess("getCompanyRep");
const company = getCompany("getCompanyRep", companyName); const company = getCompany("getCompanyRep", companyName);
return company.playerReputation; return company.playerReputation;
}, },
getCompanyFavor: function (companyName: any): any { getCompanyFavor: function (companyName: any): any {
helper.updateDynamicRam("getCompanyFavor", getRamCost("getCompanyFavor")); helper.updateDynamicRam("getCompanyFavor", getRamCost(player, "getCompanyFavor"));
helper.checkSingularityAccess("getCompanyFavor", 2); helper.checkSingularityAccess("getCompanyFavor");
const company = getCompany("getCompanyFavor", companyName); const company = getCompany("getCompanyFavor", companyName);
return company.favor; return company.favor;
}, },
getCompanyFavorGain: function (companyName: any): any { getCompanyFavorGain: function (companyName: any): any {
helper.updateDynamicRam("getCompanyFavorGain", getRamCost("getCompanyFavorGain")); helper.updateDynamicRam("getCompanyFavorGain", getRamCost(player, "getCompanyFavorGain"));
helper.checkSingularityAccess("getCompanyFavorGain", 2); helper.checkSingularityAccess("getCompanyFavorGain");
const company = getCompany("getCompanyFavorGain", companyName); const company = getCompany("getCompanyFavorGain", companyName);
return company.getFavorGain(); return company.getFavorGain();
}, },
checkFactionInvitations: function (): any { checkFactionInvitations: function (): any {
helper.updateDynamicRam("checkFactionInvitations", getRamCost("checkFactionInvitations")); helper.updateDynamicRam("checkFactionInvitations", getRamCost(player, "checkFactionInvitations"));
helper.checkSingularityAccess("checkFactionInvitations", 2); helper.checkSingularityAccess("checkFactionInvitations");
// Make a copy of player.factionInvitations // Make a copy of player.factionInvitations
return player.factionInvitations.slice(); return player.factionInvitations.slice();
}, },
joinFaction: function (name: any): any { joinFaction: function (name: any): any {
helper.updateDynamicRam("joinFaction", getRamCost("joinFaction")); helper.updateDynamicRam("joinFaction", getRamCost(player, "joinFaction"));
helper.checkSingularityAccess("joinFaction", 2); helper.checkSingularityAccess("joinFaction");
getFaction("joinFaction", name); getFaction("joinFaction", name);
if (!player.factionInvitations.includes(name)) { if (!player.factionInvitations.includes(name)) {
@ -992,8 +991,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
workForFaction: function (name: any, type: any, focus = true): any { workForFaction: function (name: any, type: any, focus = true): any {
helper.updateDynamicRam("workForFaction", getRamCost("workForFaction")); helper.updateDynamicRam("workForFaction", getRamCost(player, "workForFaction"));
helper.checkSingularityAccess("workForFaction", 2); helper.checkSingularityAccess("workForFaction");
getFaction("workForFaction", name); getFaction("workForFaction", name);
// if the player is in a gang and the target faction is any of the gang faction, fail // if the player is in a gang and the target faction is any of the gang faction, fail
@ -1106,8 +1105,7 @@ export function NetscriptSingularity(
return false; return false;
} }
player.startFactionHackWork(fac); player.startFactionHackWork(fac);
if (focus) if (focus) {
{
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();
} else if (wasFocusing) { } else if (wasFocusing) {
@ -1124,8 +1122,7 @@ export function NetscriptSingularity(
return false; return false;
} }
player.startFactionFieldWork(fac); player.startFactionFieldWork(fac);
if (focus) if (focus) {
{
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();
} else if (wasFocusing) { } else if (wasFocusing) {
@ -1142,8 +1139,7 @@ export function NetscriptSingularity(
return false; return false;
} }
player.startFactionSecurityWork(fac); player.startFactionSecurityWork(fac);
if (focus) if (focus) {
{
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();
} else if (wasFocusing) { } else if (wasFocusing) {
@ -1158,27 +1154,41 @@ export function NetscriptSingularity(
return true; return true;
}, },
getFactionRep: function (name: any): any { getFactionRep: function (name: any): any {
helper.updateDynamicRam("getFactionRep", getRamCost("getFactionRep")); helper.updateDynamicRam("getFactionRep", getRamCost(player, "getFactionRep"));
helper.checkSingularityAccess("getFactionRep", 2); helper.checkSingularityAccess("getFactionRep");
const faction = getFaction("getFactionRep", name); const faction = getFaction("getFactionRep", name);
return faction.playerReputation; return faction.playerReputation;
}, },
getFactionFavor: function (name: any): any { getFactionFavor: function (name: any): any {
helper.updateDynamicRam("getFactionFavor", getRamCost("getFactionFavor")); helper.updateDynamicRam("getFactionFavor", getRamCost(player, "getFactionFavor"));
helper.checkSingularityAccess("getFactionFavor", 2); helper.checkSingularityAccess("getFactionFavor");
const faction = getFaction("getFactionFavor", name); const faction = getFaction("getFactionFavor", name);
return faction.favor; return faction.favor;
}, },
getFactionFavorGain: function (name: any): any { getFactionFavorGain: function (name: any): any {
helper.updateDynamicRam("getFactionFavorGain", getRamCost("getFactionFavorGain")); helper.updateDynamicRam("getFactionFavorGain", getRamCost(player, "getFactionFavorGain"));
helper.checkSingularityAccess("getFactionFavorGain", 2); helper.checkSingularityAccess("getFactionFavorGain");
const faction = getFaction("getFactionFavorGain", name); const faction = getFaction("getFactionFavorGain", name);
return faction.getFavorGain(); return faction.getFavorGain();
}, },
donateToFaction: function (name: any, amt: any): any { donateToFaction: function (name: any, amt: any): any {
helper.updateDynamicRam("donateToFaction", getRamCost("donateToFaction")); helper.updateDynamicRam("donateToFaction", getRamCost(player, "donateToFaction"));
helper.checkSingularityAccess("donateToFaction", 3); helper.checkSingularityAccess("donateToFaction");
const faction = getFaction("donateToFaction", name); const faction = getFaction("donateToFaction", name);
if (!player.factions.includes(faction.name)) {
workerScript.log(
"donateToFaction",
() => `You can't donate to '${name}' because you aren't a member`,
);
return false;
}
if (player.inGang() && faction.name === player.getGangFaction().name) {
workerScript.log(
"donateToFaction",
() => `You can't donate to '${name}' because youre managing a gang for it`,
);
return false;
}
if (typeof amt !== "number" || amt <= 0 || isNaN(amt)) { if (typeof amt !== "number" || amt <= 0 || isNaN(amt)) {
workerScript.log("donateToFaction", () => `Invalid donation amount: '${amt}'.`); workerScript.log("donateToFaction", () => `Invalid donation amount: '${amt}'.`);
return false; return false;
@ -1212,8 +1222,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
createProgram: function (name: any): any { createProgram: function (name: any): any {
helper.updateDynamicRam("createProgram", getRamCost("createProgram")); helper.updateDynamicRam("createProgram", getRamCost(player, "createProgram"));
helper.checkSingularityAccess("createProgram", 3); helper.checkSingularityAccess("createProgram");
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
@ -1253,8 +1263,8 @@ export function NetscriptSingularity(
return true; return true;
}, },
commitCrime: function (crimeRoughName: any): any { commitCrime: function (crimeRoughName: any): any {
helper.updateDynamicRam("commitCrime", getRamCost("commitCrime")); helper.updateDynamicRam("commitCrime", getRamCost(player, "commitCrime"));
helper.checkSingularityAccess("commitCrime", 3); helper.checkSingularityAccess("commitCrime");
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
@ -1273,8 +1283,8 @@ export function NetscriptSingularity(
return crime.commit(Router, player, 1, workerScript); return crime.commit(Router, player, 1, workerScript);
}, },
getCrimeChance: function (crimeRoughName: any): any { getCrimeChance: function (crimeRoughName: any): any {
helper.updateDynamicRam("getCrimeChance", getRamCost("getCrimeChance")); helper.updateDynamicRam("getCrimeChance", getRamCost(player, "getCrimeChance"));
helper.checkSingularityAccess("getCrimeChance", 3); helper.checkSingularityAccess("getCrimeChance");
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if (crime == null) { if (crime == null) {
@ -1284,8 +1294,8 @@ export function NetscriptSingularity(
return crime.successRate(player); return crime.successRate(player);
}, },
getCrimeStats: function (crimeRoughName: any): any { getCrimeStats: function (crimeRoughName: any): any {
helper.updateDynamicRam("getCrimeStats", getRamCost("getCrimeStats")); helper.updateDynamicRam("getCrimeStats", getRamCost(player, "getCrimeStats"));
helper.checkSingularityAccess("getCrimeStats", 3); helper.checkSingularityAccess("getCrimeStats");
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if (crime == null) { if (crime == null) {

@ -32,20 +32,20 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
return { return {
getNumSleeves: function (): number { getNumSleeves: function (): number {
helper.updateDynamicRam("getNumSleeves", getRamCost("sleeve", "getNumSleeves")); helper.updateDynamicRam("getNumSleeves", getRamCost(player, "sleeve", "getNumSleeves"));
checkSleeveAPIAccess("getNumSleeves"); checkSleeveAPIAccess("getNumSleeves");
return player.sleeves.length; return player.sleeves.length;
}, },
setToShockRecovery: function (asleeveNumber: any = 0): boolean { setToShockRecovery: function (asleeveNumber: any = 0): boolean {
const sleeveNumber = helper.number("setToShockRecovery", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToShockRecovery", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("setToShockRecovery", getRamCost("sleeve", "setToShockRecovery")); helper.updateDynamicRam("setToShockRecovery", getRamCost(player, "sleeve", "setToShockRecovery"));
checkSleeveAPIAccess("setToShockRecovery"); checkSleeveAPIAccess("setToShockRecovery");
checkSleeveNumber("setToShockRecovery", sleeveNumber); checkSleeveNumber("setToShockRecovery", sleeveNumber);
return player.sleeves[sleeveNumber].shockRecovery(player); return player.sleeves[sleeveNumber].shockRecovery(player);
}, },
setToSynchronize: function (asleeveNumber: any = 0): boolean { setToSynchronize: function (asleeveNumber: any = 0): boolean {
const sleeveNumber = helper.number("setToSynchronize", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToSynchronize", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("setToSynchronize", getRamCost("sleeve", "setToSynchronize")); helper.updateDynamicRam("setToSynchronize", getRamCost(player, "sleeve", "setToSynchronize"));
checkSleeveAPIAccess("setToSynchronize"); checkSleeveAPIAccess("setToSynchronize");
checkSleeveNumber("setToSynchronize", sleeveNumber); checkSleeveNumber("setToSynchronize", sleeveNumber);
return player.sleeves[sleeveNumber].synchronize(player); return player.sleeves[sleeveNumber].synchronize(player);
@ -53,7 +53,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
setToCommitCrime: function (asleeveNumber: any = 0, aCrimeRoughName: any = ""): boolean { setToCommitCrime: function (asleeveNumber: any = 0, aCrimeRoughName: any = ""): boolean {
const sleeveNumber = helper.number("setToCommitCrime", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToCommitCrime", "sleeveNumber", asleeveNumber);
const crimeRoughName = helper.string("setToCommitCrime", "crimeName", aCrimeRoughName); const crimeRoughName = helper.string("setToCommitCrime", "crimeName", aCrimeRoughName);
helper.updateDynamicRam("setToCommitCrime", getRamCost("sleeve", "setToCommitCrime")); helper.updateDynamicRam("setToCommitCrime", getRamCost(player, "sleeve", "setToCommitCrime"));
checkSleeveAPIAccess("setToCommitCrime"); checkSleeveAPIAccess("setToCommitCrime");
checkSleeveNumber("setToCommitCrime", sleeveNumber); checkSleeveNumber("setToCommitCrime", sleeveNumber);
const crime = findCrime(crimeRoughName); const crime = findCrime(crimeRoughName);
@ -66,7 +66,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
const sleeveNumber = helper.number("setToUniversityCourse", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToUniversityCourse", "sleeveNumber", asleeveNumber);
const universityName = helper.string("setToUniversityCourse", "universityName", auniversityName); const universityName = helper.string("setToUniversityCourse", "universityName", auniversityName);
const className = helper.string("setToUniversityCourse", "className", aclassName); const className = helper.string("setToUniversityCourse", "className", aclassName);
helper.updateDynamicRam("setToUniversityCourse", getRamCost("sleeve", "setToUniversityCourse")); helper.updateDynamicRam("setToUniversityCourse", getRamCost(player, "sleeve", "setToUniversityCourse"));
checkSleeveAPIAccess("setToUniversityCourse"); checkSleeveAPIAccess("setToUniversityCourse");
checkSleeveNumber("setToUniversityCourse", sleeveNumber); checkSleeveNumber("setToUniversityCourse", sleeveNumber);
return player.sleeves[sleeveNumber].takeUniversityCourse(player, universityName, className); return player.sleeves[sleeveNumber].takeUniversityCourse(player, universityName, className);
@ -74,7 +74,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
travel: function (asleeveNumber: any = 0, acityName: any = ""): boolean { travel: function (asleeveNumber: any = 0, acityName: any = ""): boolean {
const sleeveNumber = helper.number("travel", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("travel", "sleeveNumber", asleeveNumber);
const cityName = helper.string("setToUniversityCourse", "cityName", acityName); const cityName = helper.string("setToUniversityCourse", "cityName", acityName);
helper.updateDynamicRam("travel", getRamCost("sleeve", "travel")); helper.updateDynamicRam("travel", getRamCost(player, "sleeve", "travel"));
checkSleeveAPIAccess("travel"); checkSleeveAPIAccess("travel");
checkSleeveNumber("travel", sleeveNumber); checkSleeveNumber("travel", sleeveNumber);
return player.sleeves[sleeveNumber].travel(player, cityName as CityName); return player.sleeves[sleeveNumber].travel(player, cityName as CityName);
@ -82,7 +82,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
setToCompanyWork: function (asleeveNumber: any = 0, acompanyName: any = ""): boolean { setToCompanyWork: function (asleeveNumber: any = 0, acompanyName: any = ""): boolean {
const sleeveNumber = helper.number("setToCompanyWork", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToCompanyWork", "sleeveNumber", asleeveNumber);
const companyName = helper.string("setToUniversityCourse", "companyName", acompanyName); const companyName = helper.string("setToUniversityCourse", "companyName", acompanyName);
helper.updateDynamicRam("setToCompanyWork", getRamCost("sleeve", "setToCompanyWork")); helper.updateDynamicRam("setToCompanyWork", getRamCost(player, "sleeve", "setToCompanyWork"));
checkSleeveAPIAccess("setToCompanyWork"); checkSleeveAPIAccess("setToCompanyWork");
checkSleeveNumber("setToCompanyWork", sleeveNumber); checkSleeveNumber("setToCompanyWork", sleeveNumber);
@ -106,7 +106,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
const sleeveNumber = helper.number("setToFactionWork", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToFactionWork", "sleeveNumber", asleeveNumber);
const factionName = helper.string("setToUniversityCourse", "factionName", afactionName); const factionName = helper.string("setToUniversityCourse", "factionName", afactionName);
const workType = helper.string("setToUniversityCourse", "workType", aworkType); const workType = helper.string("setToUniversityCourse", "workType", aworkType);
helper.updateDynamicRam("setToFactionWork", getRamCost("sleeve", "setToFactionWork")); helper.updateDynamicRam("setToFactionWork", getRamCost(player, "sleeve", "setToFactionWork"));
checkSleeveAPIAccess("setToFactionWork"); checkSleeveAPIAccess("setToFactionWork");
checkSleeveNumber("setToFactionWork", sleeveNumber); checkSleeveNumber("setToFactionWork", sleeveNumber);
@ -130,7 +130,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
const sleeveNumber = helper.number("setToGymWorkout", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("setToGymWorkout", "sleeveNumber", asleeveNumber);
const gymName = helper.string("setToUniversityCourse", "gymName", agymName); const gymName = helper.string("setToUniversityCourse", "gymName", agymName);
const stat = helper.string("setToUniversityCourse", "stat", astat); const stat = helper.string("setToUniversityCourse", "stat", astat);
helper.updateDynamicRam("setToGymWorkout", getRamCost("sleeve", "setToGymWorkout")); helper.updateDynamicRam("setToGymWorkout", getRamCost(player, "sleeve", "setToGymWorkout"));
checkSleeveAPIAccess("setToGymWorkout"); checkSleeveAPIAccess("setToGymWorkout");
checkSleeveNumber("setToGymWorkout", sleeveNumber); checkSleeveNumber("setToGymWorkout", sleeveNumber);
@ -147,7 +147,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
charisma: number; charisma: number;
} { } {
const sleeveNumber = helper.number("getSleeveStats", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("getSleeveStats", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("getSleeveStats", getRamCost("sleeve", "getSleeveStats")); helper.updateDynamicRam("getSleeveStats", getRamCost(player, "sleeve", "getSleeveStats"));
checkSleeveAPIAccess("getSleeveStats"); checkSleeveAPIAccess("getSleeveStats");
checkSleeveNumber("getSleeveStats", sleeveNumber); checkSleeveNumber("getSleeveStats", sleeveNumber);
@ -171,7 +171,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
factionWorkType: string; factionWorkType: string;
} { } {
const sleeveNumber = helper.number("getTask", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("getTask", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("getTask", getRamCost("sleeve", "getTask")); helper.updateDynamicRam("getTask", getRamCost(player, "sleeve", "getTask"));
checkSleeveAPIAccess("getTask"); checkSleeveAPIAccess("getTask");
checkSleeveNumber("getTask", sleeveNumber); checkSleeveNumber("getTask", sleeveNumber);
@ -186,7 +186,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
}, },
getInformation: function (asleeveNumber: any = 0): any { getInformation: function (asleeveNumber: any = 0): any {
const sleeveNumber = helper.number("getInformation", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("getInformation", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("getInformation", getRamCost("sleeve", "getInformation")); helper.updateDynamicRam("getInformation", getRamCost(player, "sleeve", "getInformation"));
checkSleeveAPIAccess("getInformation"); checkSleeveAPIAccess("getInformation");
checkSleeveNumber("getInformation", sleeveNumber); checkSleeveNumber("getInformation", sleeveNumber);
@ -251,7 +251,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
}, },
getSleeveAugmentations: function (asleeveNumber: any = 0): string[] { getSleeveAugmentations: function (asleeveNumber: any = 0): string[] {
const sleeveNumber = helper.number("getSleeveAugmentations", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("getSleeveAugmentations", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("getSleeveAugmentations", getRamCost("sleeve", "getSleeveAugmentations")); helper.updateDynamicRam("getSleeveAugmentations", getRamCost(player, "sleeve", "getSleeveAugmentations"));
checkSleeveAPIAccess("getSleeveAugmentations"); checkSleeveAPIAccess("getSleeveAugmentations");
checkSleeveNumber("getSleeveAugmentations", sleeveNumber); checkSleeveNumber("getSleeveAugmentations", sleeveNumber);
@ -266,7 +266,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
cost: number; cost: number;
}[] { }[] {
const sleeveNumber = helper.number("getSleevePurchasableAugs", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("getSleevePurchasableAugs", "sleeveNumber", asleeveNumber);
helper.updateDynamicRam("getSleevePurchasableAugs", getRamCost("sleeve", "getSleevePurchasableAugs")); helper.updateDynamicRam("getSleevePurchasableAugs", getRamCost(player, "sleeve", "getSleevePurchasableAugs"));
checkSleeveAPIAccess("getSleevePurchasableAugs"); checkSleeveAPIAccess("getSleevePurchasableAugs");
checkSleeveNumber("getSleevePurchasableAugs", sleeveNumber); checkSleeveNumber("getSleevePurchasableAugs", sleeveNumber);
@ -285,7 +285,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
purchaseSleeveAug: function (asleeveNumber: any = 0, aaugName: any = ""): boolean { purchaseSleeveAug: function (asleeveNumber: any = 0, aaugName: any = ""): boolean {
const sleeveNumber = helper.number("purchaseSleeveAug", "sleeveNumber", asleeveNumber); const sleeveNumber = helper.number("purchaseSleeveAug", "sleeveNumber", asleeveNumber);
const augName = helper.string("setToUniversityCourse", "augName", aaugName); const augName = helper.string("setToUniversityCourse", "augName", aaugName);
helper.updateDynamicRam("purchaseSleeveAug", getRamCost("sleeve", "purchaseSleeveAug")); helper.updateDynamicRam("purchaseSleeveAug", getRamCost(player, "sleeve", "purchaseSleeveAug"));
checkSleeveAPIAccess("purchaseSleeveAug"); checkSleeveAPIAccess("purchaseSleeveAug");
checkSleeveNumber("purchaseSleeveAug", sleeveNumber); checkSleeveNumber("purchaseSleeveAug", sleeveNumber);

@ -32,7 +32,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
const rootX = helper.number("stanek.charge", "rootX", arootX); const rootX = helper.number("stanek.charge", "rootX", arootX);
const rootY = helper.number("stanek.charge", "rootY", arootY); const rootY = helper.number("stanek.charge", "rootY", arootY);
helper.updateDynamicRam("charge", getRamCost("stanek", "charge")); helper.updateDynamicRam("charge", getRamCost(player, "stanek", "charge"));
checkStanekAPIAccess("charge"); checkStanekAPIAccess("charge");
const fragment = staneksGift.findFragment(rootX, rootY); const fragment = staneksGift.findFragment(rootX, rootY);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.charge", `No fragment with root (${rootX}, ${rootY}).`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.charge", `No fragment with root (${rootX}, ${rootY}).`);
@ -47,13 +47,13 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
}); });
}, },
fragmentDefinitions: function (): IFragment[] { fragmentDefinitions: function (): IFragment[] {
helper.updateDynamicRam("fragmentDefinitions", getRamCost("stanek", "fragmentDefinitions")); helper.updateDynamicRam("fragmentDefinitions", getRamCost(player, "stanek", "fragmentDefinitions"));
checkStanekAPIAccess("fragmentDefinitions"); checkStanekAPIAccess("fragmentDefinitions");
workerScript.log("stanek.fragmentDefinitions", () => `Returned ${Fragments.length} fragments`); workerScript.log("stanek.fragmentDefinitions", () => `Returned ${Fragments.length} fragments`);
return Fragments.map((f) => f.copy()); return Fragments.map((f) => f.copy());
}, },
activeFragments: function (): IActiveFragment[] { activeFragments: function (): IActiveFragment[] {
helper.updateDynamicRam("activeFragments", getRamCost("stanek", "activeFragments")); helper.updateDynamicRam("activeFragments", getRamCost(player, "stanek", "activeFragments"));
checkStanekAPIAccess("activeFragments"); checkStanekAPIAccess("activeFragments");
workerScript.log("stanek.activeFragments", () => `Returned ${staneksGift.fragments.length} fragments`); workerScript.log("stanek.activeFragments", () => `Returned ${staneksGift.fragments.length} fragments`);
return staneksGift.fragments.map((af) => { return staneksGift.fragments.map((af) => {
@ -61,7 +61,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
}); });
}, },
clear: function (): void { clear: function (): void {
helper.updateDynamicRam("clear", getRamCost("stanek", "clear")); helper.updateDynamicRam("clear", getRamCost(player, "stanek", "clear"));
checkStanekAPIAccess("clear"); checkStanekAPIAccess("clear");
workerScript.log("stanek.clear", () => `Cleared Stanek's Gift.`); workerScript.log("stanek.clear", () => `Cleared Stanek's Gift.`);
staneksGift.clear(); staneksGift.clear();
@ -71,7 +71,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
const rootY = helper.number("stanek.canPlace", "rootY", arootY); const rootY = helper.number("stanek.canPlace", "rootY", arootY);
const rotation = helper.number("stanek.canPlace", "rotation", arotation); const rotation = helper.number("stanek.canPlace", "rotation", arotation);
const fragmentId = helper.number("stanek.canPlace", "fragmentId", afragmentId); const fragmentId = helper.number("stanek.canPlace", "fragmentId", afragmentId);
helper.updateDynamicRam("canPlace", getRamCost("stanek", "canPlace")); helper.updateDynamicRam("canPlace", getRamCost(player, "stanek", "canPlace"));
checkStanekAPIAccess("canPlace"); checkStanekAPIAccess("canPlace");
const fragment = FragmentById(fragmentId); const fragment = FragmentById(fragmentId);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.canPlace", `Invalid fragment id: ${fragmentId}`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.canPlace", `Invalid fragment id: ${fragmentId}`);
@ -83,7 +83,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
const rootY = helper.number("stanek.place", "rootY", arootY); const rootY = helper.number("stanek.place", "rootY", arootY);
const rotation = helper.number("stanek.place", "rotation", arotation); const rotation = helper.number("stanek.place", "rotation", arotation);
const fragmentId = helper.number("stanek.place", "fragmentId", afragmentId); const fragmentId = helper.number("stanek.place", "fragmentId", afragmentId);
helper.updateDynamicRam("place", getRamCost("stanek", "place")); helper.updateDynamicRam("place", getRamCost(player, "stanek", "place"));
checkStanekAPIAccess("place"); checkStanekAPIAccess("place");
const fragment = FragmentById(fragmentId); const fragment = FragmentById(fragmentId);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`);
@ -92,7 +92,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
get: function (arootX: any, arootY: any): IActiveFragment | undefined { get: function (arootX: any, arootY: any): IActiveFragment | undefined {
const rootX = helper.number("stanek.get", "rootX", arootX); const rootX = helper.number("stanek.get", "rootX", arootX);
const rootY = helper.number("stanek.get", "rootY", arootY); const rootY = helper.number("stanek.get", "rootY", arootY);
helper.updateDynamicRam("get", getRamCost("stanek", "get")); helper.updateDynamicRam("get", getRamCost(player, "stanek", "get"));
checkStanekAPIAccess("get"); checkStanekAPIAccess("get");
const fragment = staneksGift.findFragment(rootX, rootY); const fragment = staneksGift.findFragment(rootX, rootY);
if (fragment !== undefined) return fragment.copy(); if (fragment !== undefined) return fragment.copy();
@ -101,7 +101,7 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
remove: function (arootX: any, arootY: any): boolean { remove: function (arootX: any, arootY: any): boolean {
const rootX = helper.number("stanek.remove", "rootX", arootX); const rootX = helper.number("stanek.remove", "rootX", arootX);
const rootY = helper.number("stanek.remove", "rootY", arootY); const rootY = helper.number("stanek.remove", "rootY", arootY);
helper.updateDynamicRam("remove", getRamCost("stanek", "remove")); helper.updateDynamicRam("remove", getRamCost(player, "stanek", "remove"));
checkStanekAPIAccess("remove"); checkStanekAPIAccess("remove");
return staneksGift.delete(rootX, rootY); return staneksGift.delete(rootX, rootY);
}, },

@ -35,33 +35,33 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
}; };
return { return {
getSymbols: function (): any { getSymbols: function (): any {
helper.updateDynamicRam("getSymbols", getRamCost("stock", "getSymbols")); helper.updateDynamicRam("getSymbols", getRamCost(player, "stock", "getSymbols"));
checkTixApiAccess("getSymbols"); checkTixApiAccess("getSymbols");
return Object.values(StockSymbols); return Object.values(StockSymbols);
}, },
getPrice: function (symbol: any): any { getPrice: function (symbol: any): any {
helper.updateDynamicRam("getPrice", getRamCost("stock", "getPrice")); helper.updateDynamicRam("getPrice", getRamCost(player, "stock", "getPrice"));
checkTixApiAccess("getPrice"); checkTixApiAccess("getPrice");
const stock = getStockFromSymbol(symbol, "getPrice"); const stock = getStockFromSymbol(symbol, "getPrice");
return stock.price; return stock.price;
}, },
getAskPrice: function (symbol: any): any { getAskPrice: function (symbol: any): any {
helper.updateDynamicRam("getAskPrice", getRamCost("stock", "getAskPrice")); helper.updateDynamicRam("getAskPrice", getRamCost(player, "stock", "getAskPrice"));
checkTixApiAccess("getAskPrice"); checkTixApiAccess("getAskPrice");
const stock = getStockFromSymbol(symbol, "getAskPrice"); const stock = getStockFromSymbol(symbol, "getAskPrice");
return stock.getAskPrice(); return stock.getAskPrice();
}, },
getBidPrice: function (symbol: any): any { getBidPrice: function (symbol: any): any {
helper.updateDynamicRam("getBidPrice", getRamCost("stock", "getBidPrice")); helper.updateDynamicRam("getBidPrice", getRamCost(player, "stock", "getBidPrice"));
checkTixApiAccess("getBidPrice"); checkTixApiAccess("getBidPrice");
const stock = getStockFromSymbol(symbol, "getBidPrice"); const stock = getStockFromSymbol(symbol, "getBidPrice");
return stock.getBidPrice(); return stock.getBidPrice();
}, },
getPosition: function (symbol: any): any { getPosition: function (symbol: any): any {
helper.updateDynamicRam("getPosition", getRamCost("stock", "getPosition")); helper.updateDynamicRam("getPosition", getRamCost(player, "stock", "getPosition"));
checkTixApiAccess("getPosition"); checkTixApiAccess("getPosition");
const stock = SymbolToStockMap[symbol]; const stock = SymbolToStockMap[symbol];
if (stock == null) { if (stock == null) {
@ -70,14 +70,14 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx]; return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
}, },
getMaxShares: function (symbol: any): any { getMaxShares: function (symbol: any): any {
helper.updateDynamicRam("getMaxShares", getRamCost("stock", "getMaxShares")); helper.updateDynamicRam("getMaxShares", getRamCost(player, "stock", "getMaxShares"));
checkTixApiAccess("getMaxShares"); checkTixApiAccess("getMaxShares");
const stock = getStockFromSymbol(symbol, "getMaxShares"); const stock = getStockFromSymbol(symbol, "getMaxShares");
return stock.maxShares; return stock.maxShares;
}, },
getPurchaseCost: function (symbol: any, shares: any, posType: any): any { getPurchaseCost: function (symbol: any, shares: any, posType: any): any {
helper.updateDynamicRam("getPurchaseCost", getRamCost("stock", "getPurchaseCost")); helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost"));
checkTixApiAccess("getPurchaseCost"); checkTixApiAccess("getPurchaseCost");
const stock = getStockFromSymbol(symbol, "getPurchaseCost"); const stock = getStockFromSymbol(symbol, "getPurchaseCost");
shares = Math.round(shares); shares = Math.round(shares);
@ -100,7 +100,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return res; return res;
}, },
getSaleGain: function (symbol: any, shares: any, posType: any): any { getSaleGain: function (symbol: any, shares: any, posType: any): any {
helper.updateDynamicRam("getSaleGain", getRamCost("stock", "getSaleGain")); helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain"));
checkTixApiAccess("getSaleGain"); checkTixApiAccess("getSaleGain");
const stock = getStockFromSymbol(symbol, "getSaleGain"); const stock = getStockFromSymbol(symbol, "getSaleGain");
shares = Math.round(shares); shares = Math.round(shares);
@ -123,14 +123,14 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return res; return res;
}, },
buy: function (symbol: any, shares: any): any { buy: function (symbol: any, shares: any): any {
helper.updateDynamicRam("buy", getRamCost("stock", "buy")); helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy"));
checkTixApiAccess("buy"); checkTixApiAccess("buy");
const stock = getStockFromSymbol(symbol, "buy"); const stock = getStockFromSymbol(symbol, "buy");
const res = buyStock(stock, shares, workerScript, {}); const res = buyStock(stock, shares, workerScript, {});
return res ? stock.getAskPrice() : 0; return res ? stock.getAskPrice() : 0;
}, },
sell: function (symbol: any, shares: any): any { sell: function (symbol: any, shares: any): any {
helper.updateDynamicRam("sell", getRamCost("stock", "sell")); helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell"));
checkTixApiAccess("sell"); checkTixApiAccess("sell");
const stock = getStockFromSymbol(symbol, "sell"); const stock = getStockFromSymbol(symbol, "sell");
const res = sellStock(stock, shares, workerScript, {}); const res = sellStock(stock, shares, workerScript, {});
@ -138,7 +138,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return res ? stock.getBidPrice() : 0; return res ? stock.getBidPrice() : 0;
}, },
short: function (symbol: any, shares: any): any { short: function (symbol: any, shares: any): any {
helper.updateDynamicRam("short", getRamCost("stock", "short")); helper.updateDynamicRam("short", getRamCost(player, "stock", "short"));
checkTixApiAccess("short"); checkTixApiAccess("short");
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 1) { if (player.sourceFileLvl(8) <= 1) {
@ -154,7 +154,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return res ? stock.getBidPrice() : 0; return res ? stock.getBidPrice() : 0;
}, },
sellShort: function (symbol: any, shares: any): any { sellShort: function (symbol: any, shares: any): any {
helper.updateDynamicRam("sellShort", getRamCost("stock", "sellShort")); helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort"));
checkTixApiAccess("sellShort"); checkTixApiAccess("sellShort");
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 1) { if (player.sourceFileLvl(8) <= 1) {
@ -170,7 +170,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return res ? stock.getAskPrice() : 0; return res ? stock.getAskPrice() : 0;
}, },
placeOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any { placeOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
helper.updateDynamicRam("placeOrder", getRamCost("stock", "placeOrder")); helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder"));
checkTixApiAccess("placeOrder"); checkTixApiAccess("placeOrder");
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 2) { if (player.sourceFileLvl(8) <= 2) {
@ -209,7 +209,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return placeOrder(stock, shares, price, orderType, orderPos, workerScript); return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
}, },
cancelOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any { cancelOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
helper.updateDynamicRam("cancelOrder", getRamCost("stock", "cancelOrder")); helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder"));
checkTixApiAccess("cancelOrder"); checkTixApiAccess("cancelOrder");
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 2) { if (player.sourceFileLvl(8) <= 2) {
@ -259,7 +259,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return cancelOrder(params, workerScript); return cancelOrder(params, workerScript);
}, },
getOrders: function (): any { getOrders: function (): any {
helper.updateDynamicRam("getOrders", getRamCost("stock", "getOrders")); helper.updateDynamicRam("getOrders", getRamCost(player, "stock", "getOrders"));
checkTixApiAccess("getOrders"); checkTixApiAccess("getOrders");
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 2) { if (player.sourceFileLvl(8) <= 2) {
@ -291,7 +291,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return orders; return orders;
}, },
getVolatility: function (symbol: any): any { getVolatility: function (symbol: any): any {
helper.updateDynamicRam("getVolatility", getRamCost("stock", "getVolatility")); helper.updateDynamicRam("getVolatility", getRamCost(player, "stock", "getVolatility"));
if (!player.has4SDataTixApi) { if (!player.has4SDataTixApi) {
throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!"); throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!");
} }
@ -300,7 +300,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return stock.mv / 100; // Convert from percentage to decimal return stock.mv / 100; // Convert from percentage to decimal
}, },
getForecast: function (symbol: any): any { getForecast: function (symbol: any): any {
helper.updateDynamicRam("getForecast", getRamCost("stock", "getForecast")); helper.updateDynamicRam("getForecast", getRamCost(player, "stock", "getForecast"));
if (!player.has4SDataTixApi) { if (!player.has4SDataTixApi) {
throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!"); throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!");
} }
@ -311,7 +311,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return forecast / 100; // Convert from percentage to decimal return forecast / 100; // Convert from percentage to decimal
}, },
purchase4SMarketData: function () { purchase4SMarketData: function () {
helper.updateDynamicRam("purchase4SMarketData", getRamCost("stock", "purchase4SMarketData")); helper.updateDynamicRam("purchase4SMarketData", getRamCost(player, "stock", "purchase4SMarketData"));
checkTixApiAccess("purchase4SMarketData"); checkTixApiAccess("purchase4SMarketData");
if (player.has4SData) { if (player.has4SData) {
@ -330,7 +330,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
return true; return true;
}, },
purchase4SMarketDataTixApi: function () { purchase4SMarketDataTixApi: function () {
helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost("stock", "purchase4SMarketDataTixApi")); helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost(player, "stock", "purchase4SMarketDataTixApi"));
checkTixApiAccess("purchase4SMarketDataTixApi"); checkTixApiAccess("purchase4SMarketDataTixApi");
if (player.has4SDataTixApi) { if (player.has4SDataTixApi) {

@ -12,9 +12,8 @@ export function NetscriptUserInterface(
): IUserInterface { ): IUserInterface {
return { return {
getTheme: function (): UserInterfaceTheme { getTheme: function (): UserInterfaceTheme {
helper.updateDynamicRam("getTheme", getRamCost("ui", "getTheme")); helper.updateDynamicRam("getTheme", getRamCost(player, "ui", "getTheme"));
return {...Settings.theme}; return { ...Settings.theme };
}, },
} };
} }

@ -6,13 +6,14 @@ import { computeHash } from "./utils/helpers/computeHash";
import { BlobCache } from "./utils/BlobCache"; import { BlobCache } from "./utils/BlobCache";
import { ImportCache } from "./utils/ImportCache"; import { ImportCache } from "./utils/ImportCache";
import { areImportsEquals } from "./Terminal/DirectoryHelpers"; import { areImportsEquals } from "./Terminal/DirectoryHelpers";
import { IPlayer } from "./PersonObjects/IPlayer";
// Makes a blob that contains the code of a given script. // Makes a blob that contains the code of a given script.
function makeScriptBlob(code: string): Blob { function makeScriptBlob(code: string): Blob {
return new Blob([code], { type: "text/javascript" }); return new Blob([code], { type: "text/javascript" });
} }
export async function compile(script: Script, scripts: Script[]): Promise<void> { export async function compile(player: IPlayer, script: Script, scripts: Script[]): Promise<void> {
if (!shouldCompile(script, scripts)) return; if (!shouldCompile(script, scripts)) return;
// The URL at the top is the one we want to import. It will // The URL at the top is the one we want to import. It will
// recursively import all the other modules in the urlStack. // recursively import all the other modules in the urlStack.
@ -21,7 +22,7 @@ export async function compile(script: Script, scripts: Script[]): Promise<void>
// but not really behaves like import. Particularly, it cannot // but not really behaves like import. Particularly, it cannot
// load fully dynamic content. So we hide the import from webpack // load fully dynamic content. So we hide the import from webpack
// by placing it inside an eval call. // by placing it inside an eval call.
await script.updateRamUsage(scripts); await script.updateRamUsage(player, scripts);
const uurls = _getScriptUrls(script, scripts, []); const uurls = _getScriptUrls(script, scripts, []);
const url = uurls[uurls.length - 1].url; const url = uurls[uurls.length - 1].url;
if (script.url && script.url !== url) { if (script.url && script.url !== url) {
@ -50,10 +51,14 @@ export async function compile(script: Script, scripts: Script[]): Promise<void>
// (i.e. hack, grow, etc.). // (i.e. hack, grow, etc.).
// When the promise returned by this resolves, we'll have finished // When the promise returned by this resolves, we'll have finished
// running the main function of the script. // running the main function of the script.
export async function executeJSScript(scripts: Script[] = [], workerScript: WorkerScript): Promise<void> { export async function executeJSScript(
player: IPlayer,
scripts: Script[] = [],
workerScript: WorkerScript,
): Promise<void> {
const script = workerScript.getScript(); const script = workerScript.getScript();
if (script === null) throw new Error("script is null"); if (script === null) throw new Error("script is null");
await compile(script, scripts); await compile(player, script, scripts);
workerScript.ramUsage = script.ramUsage; workerScript.ramUsage = script.ramUsage;
const loadedModule = await script.module; const loadedModule = await script.module;

@ -35,6 +35,7 @@ import { simple as walksimple } from "acorn-walk";
import { areFilesEqual } from "./Terminal/DirectoryHelpers"; import { areFilesEqual } from "./Terminal/DirectoryHelpers";
import { Player } from "./Player"; import { Player } from "./Player";
import { Terminal } from "./Terminal"; import { Terminal } from "./Terminal";
import { IPlayer } from "./PersonObjects/IPlayer";
// Netscript Ports are instantiated here // Netscript Ports are instantiated here
export const NetscriptPorts: IPort[] = []; export const NetscriptPorts: IPort[] = [];
@ -55,7 +56,7 @@ export function prestigeWorkerScripts(): void {
// JS script promises need a little massaging to have the same guarantees as netscript // JS script promises need a little massaging to have the same guarantees as netscript
// promises. This does said massaging and kicks the script off. It returns a promise // promises. This does said massaging and kicks the script off. It returns a promise
// that resolves or rejects when the corresponding worker script is done. // that resolves or rejects when the corresponding worker script is done.
function startNetscript2Script(workerScript: WorkerScript): Promise<WorkerScript> { function startNetscript2Script(player: IPlayer, workerScript: WorkerScript): Promise<WorkerScript> {
workerScript.running = true; workerScript.running = true;
// The name of the currently running netscript function, to prevent concurrent // The name of the currently running netscript function, to prevent concurrent
@ -121,7 +122,7 @@ function startNetscript2Script(workerScript: WorkerScript): Promise<WorkerScript
// Note: the environment that we pass to the JS script only needs to contain the functions visible // Note: the environment that we pass to the JS script only needs to contain the functions visible
// to that script, which env.vars does at this point. // to that script, which env.vars does at this point.
return new Promise<WorkerScript>((resolve, reject) => { return new Promise<WorkerScript>((resolve, reject) => {
executeJSScript(workerScript.getServer().scripts, workerScript) executeJSScript(player, workerScript.getServer().scripts, workerScript)
.then(() => { .then(() => {
resolve(workerScript); resolve(workerScript);
}) })
@ -457,8 +458,13 @@ function processNetscript1Imports(code: string, workerScript: WorkerScript): any
* @param {Server} server - Server on which the script is to be run * @param {Server} server - Server on which the script is to be run
* @returns {number} pid of started script * @returns {number} pid of started script
*/ */
export function startWorkerScript(runningScript: RunningScript, server: BaseServer, parent?: WorkerScript): number { export function startWorkerScript(
if (createAndAddWorkerScript(runningScript, server, parent)) { player: IPlayer,
runningScript: RunningScript,
server: BaseServer,
parent?: WorkerScript,
): number {
if (createAndAddWorkerScript(player, runningScript, server, parent)) {
// Push onto runningScripts. // Push onto runningScripts.
// This has to come after createAndAddWorkerScript() because that fn updates RAM usage // This has to come after createAndAddWorkerScript() because that fn updates RAM usage
server.runScript(runningScript); server.runScript(runningScript);
@ -478,7 +484,12 @@ export function startWorkerScript(runningScript: RunningScript, server: BaseServ
* @param {Server} server - Server on which the script is to be run * @param {Server} server - Server on which the script is to be run
* returns {boolean} indicating whether or not the workerScript was successfully added * returns {boolean} indicating whether or not the workerScript was successfully added
*/ */
function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseServer, parent?: WorkerScript): boolean { function createAndAddWorkerScript(
player: IPlayer,
runningScriptObj: RunningScript,
server: BaseServer,
parent?: WorkerScript,
): boolean {
// Update server's ram usage // Update server's ram usage
let threads = 1; let threads = 1;
if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) { if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) {
@ -522,7 +533,7 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
// Start the script's execution // Start the script's execution
let p: Promise<WorkerScript> | null = null; // Script's resulting promise let p: Promise<WorkerScript> | null = null; // Script's resulting promise
if (s.name.endsWith(".js") || s.name.endsWith(".ns")) { if (s.name.endsWith(".js") || s.name.endsWith(".ns")) {
p = startNetscript2Script(s); p = startNetscript2Script(player, s);
} else { } else {
p = startNetscript1Script(s); p = startNetscript1Script(s);
if (!(p instanceof Promise)) { if (!(p instanceof Promise)) {
@ -607,7 +618,7 @@ export function updateOnlineScriptTimes(numCycles = 1): void {
* Called when the game is loaded. Loads all running scripts (from all servers) * Called when the game is loaded. Loads all running scripts (from all servers)
* into worker scripts so that they will start running * into worker scripts so that they will start running
*/ */
export function loadAllRunningScripts(): void { export function loadAllRunningScripts(player: IPlayer): void {
const skipScriptLoad = window.location.href.toLowerCase().indexOf("?noscripts") !== -1; const skipScriptLoad = window.location.href.toLowerCase().indexOf("?noscripts") !== -1;
if (skipScriptLoad) { if (skipScriptLoad) {
Terminal.warn("Skipped loading player scripts during startup"); Terminal.warn("Skipped loading player scripts during startup");
@ -627,7 +638,7 @@ export function loadAllRunningScripts(): void {
server.runningScripts.length = 0; server.runningScripts.length = 0;
} else { } else {
for (let j = 0; j < server.runningScripts.length; ++j) { for (let j = 0; j < server.runningScripts.length; ++j) {
createAndAddWorkerScript(server.runningScripts[j], server); createAndAddWorkerScript(player, server.runningScripts[j], server);
// Offline production // Offline production
scriptCalculateOfflineProduction(server.runningScripts[j]); scriptCalculateOfflineProduction(server.runningScripts[j]);
@ -640,6 +651,7 @@ export function loadAllRunningScripts(): void {
* Run a script from inside another script (run(), exec(), spawn(), etc.) * Run a script from inside another script (run(), exec(), spawn(), etc.)
*/ */
export function runScriptFromScript( export function runScriptFromScript(
player: IPlayer,
caller: string, caller: string,
server: BaseServer, server: BaseServer,
scriptname: string, scriptname: string,
@ -714,7 +726,7 @@ export function runScriptFromScript(
runningScriptObj.threads = threads; runningScriptObj.threads = threads;
runningScriptObj.server = server.hostname; runningScriptObj.server = server.hostname;
return startWorkerScript(runningScriptObj, server, workerScript); return startWorkerScript(player, runningScriptObj, server, workerScript);
} }
break; break;
} }

@ -52,7 +52,7 @@ export function prestigeAugmentation(): void {
// Reset home computer (only the programs) and add to AllServers // Reset home computer (only the programs) and add to AllServers
AddToAllServers(homeComp); AddToAllServers(homeComp);
prestigeHomeComputer(homeComp); prestigeHomeComputer(Player, homeComp);
if (augmentationExists(AugmentationNames.Neurolink) && Augmentations[AugmentationNames.Neurolink].owned) { if (augmentationExists(AugmentationNames.Neurolink) && Augmentations[AugmentationNames.Neurolink].owned) {
homeComp.programs.push(Programs.FTPCrackProgram.name); homeComp.programs.push(Programs.FTPCrackProgram.name);
@ -180,7 +180,7 @@ export function prestigeSourceFile(flume: boolean): void {
// Reset home computer (only the programs) and add to AllServers // Reset home computer (only the programs) and add to AllServers
AddToAllServers(homeComp); AddToAllServers(homeComp);
prestigeHomeComputer(homeComp); prestigeHomeComputer(Player, homeComp);
// Re-create foreign servers // Re-create foreign servers
initForeignServers(Player.getHomeComputer()); initForeignServers(Player.getHomeComputer());

@ -14,6 +14,7 @@ import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
import { Script } from "../Script/Script"; import { Script } from "../Script/Script";
import { WorkerScript } from "../Netscript/WorkerScript"; import { WorkerScript } from "../Netscript/WorkerScript";
import { areImportsEquals } from "../Terminal/DirectoryHelpers"; import { areImportsEquals } from "../Terminal/DirectoryHelpers";
import { IPlayer } from "../PersonObjects/IPlayer";
// These special strings are used to reference the presence of a given logical // These special strings are used to reference the presence of a given logical
// construct within a user script. // construct within a user script.
@ -33,6 +34,7 @@ const memCheckGlobalKey = ".__GLOBAL__";
* keep track of what functions have/havent been accounted for * keep track of what functions have/havent been accounted for
*/ */
async function parseOnlyRamCalculate( async function parseOnlyRamCalculate(
player: IPlayer,
otherScripts: Script[], otherScripts: Script[],
code: string, code: string,
workerScript: WorkerScript, workerScript: WorkerScript,
@ -169,6 +171,8 @@ async function parseOnlyRamCalculate(
function applyFuncRam(cost: any): number { function applyFuncRam(cost: any): number {
if (typeof cost === "number") { if (typeof cost === "number") {
return cost; return cost;
} else if (typeof cost === "function") {
return cost(player);
} else { } else {
return 0; return 0;
} }
@ -375,6 +379,7 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): any {
* Used to account for imported scripts * Used to account for imported scripts
*/ */
export async function calculateRamUsage( export async function calculateRamUsage(
player: IPlayer,
codeCopy: string, codeCopy: string,
otherScripts: Script[], otherScripts: Script[],
): Promise<RamCalculationErrorCode | number> { ): Promise<RamCalculationErrorCode | number> {
@ -388,7 +393,7 @@ export async function calculateRamUsage(
} as WorkerScript; } as WorkerScript;
try { try {
return await parseOnlyRamCalculate(otherScripts, codeCopy, workerScript); return await parseOnlyRamCalculate(player, otherScripts, codeCopy, workerScript);
} catch (e) { } catch (e) {
console.error(`Failed to parse script for RAM calculations:`); console.error(`Failed to parse script for RAM calculations:`);
console.error(e); console.error(e);

@ -10,6 +10,7 @@ import { ScriptUrl } from "./ScriptUrl";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
import { roundToTwo } from "../utils/helpers/roundToTwo"; import { roundToTwo } from "../utils/helpers/roundToTwo";
import { computeHash } from "../utils/helpers/computeHash"; import { computeHash } from "../utils/helpers/computeHash";
import { IPlayer } from "../PersonObjects/IPlayer";
let globalModuleSequenceNumber = 0; let globalModuleSequenceNumber = 0;
@ -44,7 +45,7 @@ export class Script {
// sha256 hash of the code in the Script. Do not access directly. // sha256 hash of the code in the Script. Do not access directly.
_hash = ""; _hash = "";
constructor(fn = "", code = "", server = "", otherScripts: Script[] = []) { constructor(player: IPlayer | null = null, fn = "", code = "", server = "", otherScripts: Script[] = []) {
this.filename = fn; this.filename = fn;
this.code = code; this.code = code;
this.ramUsage = 0; this.ramUsage = 0;
@ -52,8 +53,8 @@ export class Script {
this.module = ""; this.module = "";
this.moduleSequenceNumber = ++globalModuleSequenceNumber; this.moduleSequenceNumber = ++globalModuleSequenceNumber;
this._hash = ""; this._hash = "";
if (this.code !== "") { if (this.code !== "" && player !== null) {
this.updateRamUsage(otherScripts); this.updateRamUsage(player, otherScripts);
this.rehash(); this.rehash();
} }
} }
@ -105,8 +106,7 @@ export class Script {
* @returns the computed hash of the script * @returns the computed hash of the script
*/ */
hash(): string { hash(): string {
if (!this._hash) if (!this._hash) this.rehash();
this.rehash();
return this._hash; return this._hash;
} }
@ -115,13 +115,13 @@ export class Script {
* @param {string} code - The new contents of the script * @param {string} code - The new contents of the script
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports * @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
*/ */
saveScript(filename: string, code: string, hostname: string, otherScripts: Script[]): void { saveScript(player: IPlayer, filename: string, code: string, hostname: string, otherScripts: Script[]): void {
// Update code and filename // Update code and filename
this.code = code.replace(/^\s+|\s+$/g, ""); this.code = code.replace(/^\s+|\s+$/g, "");
this.filename = filename; this.filename = filename;
this.server = hostname; this.server = hostname;
this.updateRamUsage(otherScripts); this.updateRamUsage(player, otherScripts);
this.markUpdated(); this.markUpdated();
} }
@ -129,8 +129,8 @@ export class Script {
* Calculates and updates the script's RAM usage based on its code * Calculates and updates the script's RAM usage based on its code
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports * @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
*/ */
async updateRamUsage(otherScripts: Script[]): Promise<void> { async updateRamUsage(player: IPlayer, otherScripts: Script[]): Promise<void> {
const res = await calculateRamUsage(this.code, otherScripts); const res = await calculateRamUsage(player, this.code, otherScripts);
if (res > 0) { if (res > 0) {
this.ramUsage = roundToTwo(res); this.ramUsage = roundToTwo(res);
} }

@ -226,7 +226,7 @@ export function Root(props: IProps): React.ReactElement {
} }
setUpdatingRam(true); setUpdatingRam(true);
const codeCopy = newCode + ""; const codeCopy = newCode + "";
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts); const ramUsage = await calculateRamUsage(props.player, codeCopy, props.player.getCurrentServer().scripts);
if (ramUsage > 0) { if (ramUsage > 0) {
debouncedSetRAM("RAM: " + numeralWrapper.formatRAM(ramUsage)); debouncedSetRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
return; return;
@ -431,6 +431,7 @@ export function Root(props: IProps): React.ReactElement {
for (let i = 0; i < server.scripts.length; i++) { for (let i = 0; i < server.scripts.length; i++) {
if (scriptToSave.fileName == server.scripts[i].filename) { if (scriptToSave.fileName == server.scripts[i].filename) {
server.scripts[i].saveScript( server.scripts[i].saveScript(
props.player,
scriptToSave.fileName, scriptToSave.fileName,
scriptToSave.code, scriptToSave.code,
props.player.currentServer, props.player.currentServer,
@ -444,7 +445,13 @@ export function Root(props: IProps): React.ReactElement {
//If the current script does NOT exist, create a new one //If the current script does NOT exist, create a new one
const script = new Script(); const script = new Script();
script.saveScript(scriptToSave.fileName, scriptToSave.code, props.player.currentServer, server.scripts); script.saveScript(
props.player,
scriptToSave.fileName,
scriptToSave.code,
props.player.currentServer,
server.scripts,
);
server.scripts.push(script); server.scripts.push(script);
} else if (scriptToSave.fileName.endsWith(".txt")) { } else if (scriptToSave.fileName.endsWith(".txt")) {
for (let i = 0; i < server.textFiles.length; ++i) { for (let i = 0; i < server.textFiles.length; ++i) {
@ -510,6 +517,7 @@ export function Root(props: IProps): React.ReactElement {
for (let i = 0; i < server.scripts.length; i++) { for (let i = 0; i < server.scripts.length; i++) {
if (currentScript.fileName == server.scripts[i].filename) { if (currentScript.fileName == server.scripts[i].filename) {
server.scripts[i].saveScript( server.scripts[i].saveScript(
props.player,
currentScript.fileName, currentScript.fileName,
currentScript.code, currentScript.code,
props.player.currentServer, props.player.currentServer,
@ -522,7 +530,13 @@ export function Root(props: IProps): React.ReactElement {
//If the current script does NOT exist, create a new one //If the current script does NOT exist, create a new one
const script = new Script(); const script = new Script();
script.saveScript(currentScript.fileName, currentScript.code, props.player.currentServer, server.scripts); script.saveScript(
props.player,
currentScript.fileName,
currentScript.code,
props.player.currentServer,
server.scripts,
);
server.scripts.push(script); server.scripts.push(script);
} else if (currentScript.fileName.endsWith(".txt")) { } else if (currentScript.fileName.endsWith(".txt")) {
for (let i = 0; i < server.textFiles.length; ++i) { for (let i = 0; i < server.textFiles.length; ++i) {

@ -255,7 +255,7 @@ export class BaseServer {
* Write to a script file * Write to a script file
* Overwrites existing files. Creates new files if the script does not eixst * Overwrites existing files. Creates new files if the script does not eixst
*/ */
writeToScriptFile(fn: string, code: string): writeResult { writeToScriptFile(player: IPlayer, fn: string, code: string): writeResult {
const ret = { success: false, overwritten: false }; const ret = { success: false, overwritten: false };
if (!isValidFilePath(fn) || !isScriptFilename(fn)) { if (!isValidFilePath(fn) || !isScriptFilename(fn)) {
return ret; return ret;
@ -266,7 +266,7 @@ export class BaseServer {
if (fn === this.scripts[i].filename) { if (fn === this.scripts[i].filename) {
const script = this.scripts[i]; const script = this.scripts[i];
script.code = code; script.code = code;
script.updateRamUsage(this.scripts); script.updateRamUsage(player, this.scripts);
script.markUpdated(); script.markUpdated();
ret.overwritten = true; ret.overwritten = true;
ret.success = true; ret.success = true;
@ -275,7 +275,7 @@ export class BaseServer {
} }
// Otherwise, create a new script // Otherwise, create a new script
const newScript = new Script(fn, code, this.hostname, this.scripts); const newScript = new Script(player, fn, code, this.hostname, this.scripts);
this.scripts.push(newScript); this.scripts.push(newScript);
ret.success = true; ret.success = true;
return ret; return ret;

@ -98,7 +98,7 @@ export function processSingleServerGrowth(server: Server, threads: number, p: IP
return server.moneyAvailable / oldMoneyAvailable; return server.moneyAvailable / oldMoneyAvailable;
} }
export function prestigeHomeComputer(homeComp: Server): void { export function prestigeHomeComputer(player: IPlayer, homeComp: Server): void {
const hasBitflume = homeComp.programs.includes(Programs.BitFlume.name); const hasBitflume = homeComp.programs.includes(Programs.BitFlume.name);
homeComp.programs.length = 0; //Remove programs homeComp.programs.length = 0; //Remove programs
@ -113,7 +113,7 @@ export function prestigeHomeComputer(homeComp: Server): void {
//Update RAM usage on all scripts //Update RAM usage on all scripts
homeComp.scripts.forEach(function (script) { homeComp.scripts.forEach(function (script) {
script.updateRamUsage(homeComp.scripts); script.updateRamUsage(player, homeComp.scripts);
}); });
homeComp.messages.length = 0; //Remove .lit and .msg files homeComp.messages.length = 0; //Remove .lit and .msg files

@ -56,7 +56,7 @@ SourceFiles["SourceFile4"] = new SourceFile(
( (
<> <>
This Source-File lets you access and use the Singularity Functions in every BitNode. Every level of this This Source-File lets you access and use the Singularity Functions in every BitNode. Every level of this
Source-File opens up more of the Singularity Functions you can use. Source-File reduces the RAM cost of Singularity functions.
</> </>
), ),
); );

@ -4,6 +4,9 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { getServerOnNetwork } from "../../Server/ServerHelpers"; import { getServerOnNetwork } from "../../Server/ServerHelpers";
import { GetServer } from "../../Server/AllServers"; import { GetServer } from "../../Server/AllServers";
import { Server } from "../../Server/Server";
import { Programs } from "src/Programs/Programs";
import { programsMetadata } from "src/Programs/data/ProgramsMetadata";
export function connect( export function connect(
terminal: ITerminal, terminal: ITerminal,
@ -29,7 +32,12 @@ export function connect(
} }
} }
if (GetServer(hostname) !== null) { const other = GetServer(hostname);
if (other !== null) {
if (other instanceof Server && other.backdoorInstalled) {
terminal.connectToServer(player, hostname);
return;
}
terminal.error(`Cannot directly connect to ${hostname}`); terminal.error(`Cannot directly connect to ${hostname}`);
} else { } else {
terminal.error("Host not found"); terminal.error("Host not found");

@ -89,7 +89,7 @@ export function cp(
return; return;
} }
const sRes = server.writeToScriptFile(dst, sourceScript.code); const sRes = server.writeToScriptFile(player, dst, sourceScript.code);
if (!sRes.success) { if (!sRes.success) {
terminal.error(`cp failed`); terminal.error(`cp failed`);
return; return;

@ -76,7 +76,7 @@ export function runScript(
const runningScript = new RunningScript(script, args); const runningScript = new RunningScript(script, args);
runningScript.threads = numThreads; runningScript.threads = numThreads;
const success = startWorkerScript(runningScript, server); const success = startWorkerScript(player, runningScript, server);
if (!success) { if (!success) {
terminal.error(`Failed to start script`); terminal.error(`Failed to start script`);
return; return;

@ -94,7 +94,7 @@ export function scp(
return; return;
} }
const sRes = destServer.writeToScriptFile(scriptname, sourceScript.code); const sRes = destServer.writeToScriptFile(player, scriptname, sourceScript.code);
if (!sRes.success) { if (!sRes.success) {
terminal.error(`scp failed`); terminal.error(`scp failed`);
return; return;

@ -26,7 +26,7 @@ export function wget(
function (data: any) { function (data: any) {
let res; let res;
if (isScriptFilename(target)) { if (isScriptFilename(target)) {
res = server.writeToScriptFile(target, data); res = server.writeToScriptFile(player, target, data);
} else { } else {
res = server.writeToTextFile(target, data); res = server.writeToTextFile(target, data);
} }

@ -296,7 +296,7 @@ export async function determineAllPossibilitiesForTabCompletion(
const script = currServ.scripts.find((script) => script.filename === filename); const script = currServ.scripts.find((script) => script.filename === filename);
if (!script) return; // Doesn't exist. if (!script) return; // Doesn't exist.
if (!script.module) { if (!script.module) {
await compile(script, currServ.scripts); await compile(p, script, currServ.scripts);
} }
const loadedModule = await script.module; const loadedModule = await script.module;
if (!loadedModule.autocomplete) return; // Doesn't have an autocomplete function. if (!loadedModule.autocomplete) return; // Doesn't have an autocomplete function.

@ -277,7 +277,7 @@ const Engine: {
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75; const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
Player.gainMoney(offlineHackingIncome, "hacking"); Player.gainMoney(offlineHackingIncome, "hacking");
// Process offline progress // Process offline progress
loadAllRunningScripts(); // This also takes care of offline production for those scripts loadAllRunningScripts(Player); // This also takes care of offline production for those scripts
if (Player.isWorking) { if (Player.isWorking) {
Player.focus = true; Player.focus = true;
if (Player.workType == CONSTANTS.WorkTypeFaction) { if (Player.workType == CONSTANTS.WorkTypeFaction) {

@ -16,6 +16,7 @@ import { startWorkerScript } from "../../NetscriptWorker";
import { GetServer } from "../../Server/AllServers"; import { GetServer } from "../../Server/AllServers";
import { Theme } from "@mui/material"; import { Theme } from "@mui/material";
import { findRunningScript } from "../../Script/ScriptHelpers"; import { findRunningScript } from "../../Script/ScriptHelpers";
import { Player } from "../../Player";
let layerCounter = 0; let layerCounter = 0;
@ -79,12 +80,12 @@ const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
title: { title: {
"&.is-minimized + *": { "&.is-minimized + *": {
border: "none", border: "none",
margin: 0, margin: 0,
"max-height": 0, "max-height": 0,
padding: 0, padding: 0,
"pointer-events": "none", "pointer-events": "none",
visibility: "hidden" visibility: "hidden",
}, },
}, },
logs: { logs: {
@ -137,7 +138,7 @@ function LogWindow(props: IProps): React.ReactElement {
if (server === null) return; if (server === null) return;
const s = findRunningScript(script.filename, script.args, server); const s = findRunningScript(script.filename, script.args, server);
if (s === null) { if (s === null) {
startWorkerScript(script, server); startWorkerScript(Player, script, server);
} else { } else {
setScript(s); setScript(s);
} }
@ -195,7 +196,7 @@ function LogWindow(props: IProps): React.ReactElement {
> >
<div onMouseDown={updateLayer}> <div onMouseDown={updateLayer}>
<Paper <Paper
className={classes.title + " " + (minimized ? 'is-minimized' : '')} className={classes.title + " " + (minimized ? "is-minimized" : "")}
style={{ style={{
cursor: "grab", cursor: "grab",
}} }}

@ -110,7 +110,7 @@ export function v1APIBreak(): void {
for (const script of server.scripts) { for (const script of server.scripts) {
if (!hasChanges(script.code)) continue; if (!hasChanges(script.code)) continue;
const prefix = script.filename.includes("/") ? "/BACKUP_" : "BACKUP_"; const prefix = script.filename.includes("/") ? "/BACKUP_" : "BACKUP_";
backups.push(new Script(prefix + script.filename, script.code, script.server)); backups.push(new Script(Player, prefix + script.filename, script.code, script.server));
script.code = convert(script.code); script.code = convert(script.code);
} }
server.scripts = server.scripts.concat(backups); server.scripts = server.scripts.concat(backups);

@ -1,6 +1,7 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals' import { jest, describe, expect, test } from "@jest/globals";
import { Player } from "../../src/Player";
import { NetscriptFunctions } from "../../src/NetscriptFunctions"; import { NetscriptFunctions } from "../../src/NetscriptFunctions";
import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator"; import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator";
import { Environment } from "../../src/Netscript/Environment"; import { Environment } from "../../src/Netscript/Environment";
@ -8,7 +9,7 @@ import { RunningScript } from "../../src/Script/RunningScript";
import { Script } from "../../src/Script/Script"; import { Script } from "../../src/Script/Script";
import { SourceFileFlags } from "../../src/SourceFile/SourceFileFlags"; import { SourceFileFlags } from "../../src/SourceFile/SourceFileFlags";
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => '', { jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
virtual: true, virtual: true,
}); });
@ -19,7 +20,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
async function createRunningScript(code) { async function createRunningScript(code) {
const script = new Script(); const script = new Script();
script.code = code; script.code = code;
await script.updateRamUsage([]); await script.updateRamUsage(Player, []);
const runningScript = new RunningScript(script); const runningScript = new RunningScript(script);
@ -52,7 +53,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
if (!Array.isArray(fnDesc)) { if (!Array.isArray(fnDesc)) {
throw new Error("Non-array passed to testNonzeroDynamicRamCost()"); throw new Error("Non-array passed to testNonzeroDynamicRamCost()");
} }
const expected = getRamCost(...fnDesc); const expected = getRamCost(Player, ...fnDesc);
expect(expected).toBeGreaterThan(0); expect(expected).toBeGreaterThan(0);
const code = `${fnDesc.join(".")}();`; const code = `${fnDesc.join(".")}();`;
@ -117,7 +118,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
if (!Array.isArray(fnDesc)) { if (!Array.isArray(fnDesc)) {
throw new Error("Non-array passed to testZeroDynamicRamCost()"); throw new Error("Non-array passed to testZeroDynamicRamCost()");
} }
const expected = getRamCost(...fnDesc); const expected = getRamCost(Player, ...fnDesc);
expect(expected).toEqual(0); expect(expected).toEqual(0);
if (skipRun) return; if (skipRun) return;
@ -293,7 +294,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
it("exec()", async function () { it("exec()", async function () {
const f = ["exec"]; const f = ["exec"];
jest.spyOn(console, 'log').mockImplementation(() => {}); // eslint-disable-line jest.spyOn(console, "log").mockImplementation(() => {}); // eslint-disable-line
await testNonzeroDynamicRamCost(f); await testNonzeroDynamicRamCost(f);
}); });
@ -434,7 +435,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
it("purchaseServer()", async function () { it("purchaseServer()", async function () {
const f = ["purchaseServer"]; const f = ["purchaseServer"];
await testNonzeroDynamicRamCost(f, "abc", '64'); await testNonzeroDynamicRamCost(f, "abc", "64");
}); });
it("deleteServer()", async function () { it("deleteServer()", async function () {

@ -1,9 +1,14 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals' import { jest, describe, expect } from "@jest/globals";
import { Player } from "../../src/Player";
import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator"; import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator";
import { calculateRamUsage } from "../../src/Script/RamCalculations"; import { calculateRamUsage } from "../../src/Script/RamCalculations";
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
virtual: true,
});
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost; const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
const HacknetNamespaceCost = RamCostConstants.ScriptHacknetNodesRamCost; const HacknetNamespaceCost = RamCostConstants.ScriptHacknetNodesRamCost;
@ -26,16 +31,16 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
if (!Array.isArray(fnDesc)) { if (!Array.isArray(fnDesc)) {
expect.fail("Non-array passed to expectNonZeroRamCost()"); expect.fail("Non-array passed to expectNonZeroRamCost()");
} }
const expected = getRamCost(...fnDesc); const expected = getRamCost(Player, ...fnDesc);
expect(expected).toBeGreaterThan(0); expect(expected).toBeGreaterThan(0);
const code = fnDesc.join(".") + "(); "; const code = fnDesc.join(".") + "(); ";
const calculated = await calculateRamUsage(code, []); const calculated = await calculateRamUsage(Player, code, []);
testEquality(calculated, expected + ScriptBaseCost); testEquality(calculated, expected + ScriptBaseCost);
const multipleCallsCode = code.repeat(3); const multipleCallsCode = code.repeat(3);
const multipleCallsCalculated = await calculateRamUsage(multipleCallsCode, []); const multipleCallsCalculated = await calculateRamUsage(Player, multipleCallsCode, []);
expect(multipleCallsCalculated).toEqual(calculated); expect(multipleCallsCalculated).toEqual(calculated);
} }
@ -51,15 +56,15 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
if (!Array.isArray(fnDesc)) { if (!Array.isArray(fnDesc)) {
expect.fail("Non-array passed to expectZeroRamCost()"); expect.fail("Non-array passed to expectZeroRamCost()");
} }
const expected = getRamCost(...fnDesc); const expected = getRamCost(Player, ...fnDesc);
expect(expected).toEqual(0); expect(expected).toEqual(0);
const code = fnDesc.join(".") + "(); "; const code = fnDesc.join(".") + "(); ";
const calculated = await calculateRamUsage(code, []); const calculated = await calculateRamUsage(Player, code, []);
testEquality(calculated, ScriptBaseCost); testEquality(calculated, ScriptBaseCost);
const multipleCallsCalculated = await calculateRamUsage(code, []); const multipleCallsCalculated = await calculateRamUsage(Player, code, []);
expect(multipleCallsCalculated).toEqual(ScriptBaseCost); expect(multipleCallsCalculated).toEqual(ScriptBaseCost);
} }
@ -495,7 +500,7 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
]; ];
it("should have zero RAM cost for all functions", function () { it("should have zero RAM cost for all functions", function () {
for (const fn of apiFunctions) { for (const fn of apiFunctions) {
expect(getRamCost("hacknet", fn)).toEqual(0); expect(getRamCost(Player, "hacknet", fn)).toEqual(0);
} }
}); });
@ -505,7 +510,7 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
code += "hacknet." + fn + "(); "; code += "hacknet." + fn + "(); ";
} }
const calculated = await calculateRamUsage(code, []); const calculated = await calculateRamUsage(Player, code, []);
testEquality(calculated, ScriptBaseCost + HacknetNamespaceCost); testEquality(calculated, ScriptBaseCost + HacknetNamespaceCost);
}); });
}); });

@ -1,6 +1,6 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals' import { jest, describe, expect, test } from "@jest/globals";
import { Player } from "../../src/Player"; import { Player } from "../../src/Player";
import { determineAllPossibilitiesForTabCompletion } from "../../src/Terminal/determineAllPossibilitiesForTabCompletion"; import { determineAllPossibilitiesForTabCompletion } from "../../src/Terminal/determineAllPossibilitiesForTabCompletion";
@ -9,7 +9,7 @@ import { AddToAllServers, prestigeAllServers } from "../../src/Server/AllServers
import { LocationName } from "../../src/Locations/data/LocationNames"; import { LocationName } from "../../src/Locations/data/LocationNames";
import { CodingContract } from "../../src/CodingContracts"; import { CodingContract } from "../../src/CodingContracts";
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => '', { jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
virtual: true, virtual: true,
}); });
@ -56,24 +56,26 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
it("completes the buy command", async () => { it("completes the buy command", async () => {
const options = await determineAllPossibilitiesForTabCompletion(Player, "buy ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "buy ", 0);
expect(options.sort()).toEqual([ expect(options.sort()).toEqual(
"BruteSSH.exe", [
"FTPCrack.exe", "BruteSSH.exe",
"relaySMTP.exe", "FTPCrack.exe",
"HTTPWorm.exe", "relaySMTP.exe",
"SQLInject.exe", "HTTPWorm.exe",
"DeepscanV1.exe", "SQLInject.exe",
"DeepscanV2.exe", "DeepscanV1.exe",
"AutoLink.exe", "DeepscanV2.exe",
"ServerProfiler.exe", "AutoLink.exe",
"Formulas.exe", "ServerProfiler.exe",
].sort()); "Formulas.exe",
].sort(),
);
}); });
it("completes the scp command", async () => { it("completes the scp command", async () => {
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark"); Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
Player.getHomeComputer().messages.push("af.lit"); Player.getHomeComputer().messages.push("af.lit");
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
const options1 = await determineAllPossibilitiesForTabCompletion(Player, "scp ", 0); const options1 = await determineAllPossibilitiesForTabCompletion(Player, "scp ", 0);
expect(options1).toEqual(["/www/script.js", "af.lit", "note.txt", "www/"]); expect(options1).toEqual(["/www/script.js", "af.lit", "note.txt", "www/"]);
@ -82,7 +84,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
}); });
it("completes the kill, tail, mem, and check commands", async () => { it("completes the kill, tail, mem, and check commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
for (const command of ["kill", "tail", "mem", "check"]) { for (const command of ["kill", "tail", "mem", "check"]) {
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0); const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual(["/www/script.js", "www/"]); expect(options).toEqual(["/www/script.js", "www/"]);
@ -90,43 +92,27 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
}); });
it("completes the nano commands", async () => { it("completes the nano commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark"); Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
const options = await determineAllPossibilitiesForTabCompletion(Player, "nano ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "nano ", 0);
expect(options).toEqual([ expect(options).toEqual(["/www/script.js", "note.txt", "www/"]);
"/www/script.js",
"note.txt",
"www/",
]);
}); });
it("completes the rm command", async () => { it("completes the rm command", async () => {
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark"); Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct")); Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
Player.getHomeComputer().messages.push("asl.msg"); Player.getHomeComputer().messages.push("asl.msg");
Player.getHomeComputer().messages.push("af.lit"); Player.getHomeComputer().messages.push("af.lit");
const options = await determineAllPossibilitiesForTabCompletion(Player, "rm ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "rm ", 0);
expect(options).toEqual([ expect(options).toEqual(["/www/script.js", "NUKE.exe", "af.lit", "note.txt", "linklist.cct", "www/"]);
"/www/script.js",
"NUKE.exe",
"af.lit",
"note.txt",
"linklist.cct",
"www/",
]);
}); });
it("completes the run command", async () => { it("completes the run command", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct")); Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "run ", 0);
expect(options).toEqual([ expect(options).toEqual(["/www/script.js", "NUKE.exe", "linklist.cct", "www/"]);
"/www/script.js",
"NUKE.exe",
"linklist.cct",
"www/",
]);
}); });
it("completes the cat command", async () => { it("completes the cat command", async () => {
@ -134,36 +120,26 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
Player.getHomeComputer().messages.push("asl.msg"); Player.getHomeComputer().messages.push("asl.msg");
Player.getHomeComputer().messages.push("af.lit"); Player.getHomeComputer().messages.push("af.lit");
const options = await determineAllPossibilitiesForTabCompletion(Player, "cat ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "cat ", 0);
expect(options).toEqual([ expect(options).toEqual(["asl.msg", "af.lit", "/www/note.txt", "www/"]);
"asl.msg",
"af.lit",
"/www/note.txt",
"www/",
]);
}); });
it("completes the download and mv commands", async () => { it("completes the download and mv commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark"); Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
for (const command of ["download", "mv"]) { for (const command of ["download", "mv"]) {
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0); const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual([ expect(options).toEqual(["/www/script.js", "note.txt", "www/"]);
"/www/script.js",
"note.txt",
"www/",
]);
} }
}); });
it("completes the cd command", async () => { it("completes the cd command", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
const options = await determineAllPossibilitiesForTabCompletion(Player, "cd ", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "cd ", 0);
expect(options).toEqual(["www/"]); expect(options).toEqual(["www/"]);
}); });
it("completes the ls and cd commands", async () => { it("completes the ls and cd commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
for (const command of ["ls", "cd"]) { for (const command of ["ls", "cd"]) {
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0); const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual(["www/"]); expect(options).toEqual(["www/"]);
@ -171,12 +147,8 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
}); });
it("completes commands starting with ./", async () => { it("completes commands starting with ./", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark"); Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ./", 0); const options = await determineAllPossibilitiesForTabCompletion(Player, "run ./", 0);
expect(options).toEqual([ expect(options).toEqual([".//www/script.js", "NUKE.exe", "./www/"]);
".//www/script.js",
"NUKE.exe",
"./www/",
]);
}); });
}); });