Compare commits

...

259 Commits

Author SHA1 Message Date
catloversg
c21d1f44b2 UI: Add button to open Faction page from Gang UI (#2655) 2026-04-14 15:53:40 -07:00
catloversg
956e00f789 BUGFIX: Intelligence data is incorrectly migrated when Intelligence is not unlocked (#2660) 2026-04-14 15:20:01 -07:00
catloversg
c5536d252b MISC: Update "Last updated" date in changelog (#2658) 2026-04-13 13:10:59 +07:00
catloversg
a99ca64455 MISC: Update changelog (#2657) 2026-04-13 11:32:39 +07:00
catloversg
cb14655325 MISC: Update description of "cat" command (#2654) 2026-04-12 17:06:27 -07:00
catloversg
9ab3e0bcb4 DOCUMENTATION: Update tutorial script for buying cloud servers (#2653) 2026-04-12 17:05:56 -07:00
catloversg
cc9144c01b UI: Use exponential notation when formatting very small HP or thread values (#2656) 2026-04-12 16:49:30 -07:00
Lee Stutzman
fb3fa00b3d API: Add weakenEffect to formulas.hacking namespace (#2626) 2026-04-10 16:36:45 -07:00
Lee Stutzman
8cbd6ff9e1 BUGFIX: Fix tab completion for multi-word quoted autocomplete options (#2612) 2026-04-10 16:36:11 -07:00
Michael Ficocelli
00a1bc2f6e DNET: Remove bonus time effect on authentication and heartbleed speed; fix ram rounding (#2627) 2026-04-10 16:04:05 -07:00
Lee Stutzman
be6fcd206f API: Rename ns.gang.getOtherGangInformation to getAllGangInformation (#2635) 2026-04-10 15:59:39 -07:00
catloversg
a6a112198e WORKFLOW: Allow specifying commit hash id when building artifacts (#2652) 2026-04-10 15:56:51 -07:00
catloversg
732aadb2d6 UI: Add hooks to sidebar for players to attach custom content (#2651) 2026-04-10 15:54:54 -07:00
catloversg
85c9ac0181 TOOL: Remove redundant "$" from JS/TS regex in webpack config (#2649) 2026-04-10 15:50:52 -07:00
catloversg
e232f37550 BLADEBURNER: Add tooltips explaining why skill upgrades are disabled (#2648) 2026-04-10 15:50:07 -07:00
catloversg
6074721c59 MISC: Update description of "BN9: Challenge" achievement (#2647) 2026-04-10 15:46:47 -07:00
catloversg
09e46d757b CLI: Add "hidden" mkdir command (#2646) 2026-04-10 15:45:51 -07:00
catloversg
5cb0d559df UI: Consistently calculate BitNode "level" (#2645) 2026-04-10 15:45:18 -07:00
catloversg
54287e5f7f DOCUMENTATION: Update RAM cost of hacknet APIs and remove unnecessary RAM cost docs (#2639) 2026-04-09 17:27:17 -07:00
catloversg
d25b1676ab MISC: Apply SF override to charisma calculations (#2642) 2026-04-09 17:25:51 -07:00
Lee Stutzman
d6299becd6 DOCUMENTATION: Clarify scp and exec darknet permissions in API docs (#2634) 2026-04-09 17:24:37 -07:00
catloversg
19b137e2fb UI: Remove unnecessary max-width of tab list in in-game editor (#2643) 2026-04-09 17:22:53 -07:00
catloversg
ee2949418f API: Expose charged effects of active fragments (#2638) 2026-04-08 14:45:17 -07:00
Lee Stutzman
fbd7930ab2 BUGFIX: Fix recursive alias detection causing infinite recursion (#2610) 2026-04-04 17:01:21 -07:00
catloversg
8b3c7c13c5 CODEBASE: Use type-only imports in ArrayHelpers.ts (#2630) 2026-04-04 16:39:24 -07:00
catloversg
996bb01075 UI: Ensure prompts shown by ns.prompt do not lose focus in the terminal tab (#2631) 2026-04-04 16:39:06 -07:00
catloversg
eb4e193fac DEVMENU: Initialize dark net data when setting SF15 level (#2632) 2026-04-04 16:37:26 -07:00
catloversg
0c39fc3720 MISC: Update changelog and version number (#2628) 2026-04-04 12:39:38 +07:00
catloversg
44741a7795 DOCUMENTATION: Document coding contract's generation and rewards (#2624) 2026-04-03 21:50:19 -07:00
Lee Stutzman
2818969c8a UI: Fix non-explicit GameRoot effect dependency (#2617) 2026-04-03 21:49:17 -07:00
Lee Stutzman
de9311f820 UI: Add dependency array to TerminalInput keydown useEffect (#2620) 2026-04-03 15:39:05 -07:00
Lee Stutzman
15d463d583 BUGFIX: "Do something else simultaneously" navigates to gym/university instead of City (#2613) 2026-04-03 15:37:34 -07:00
catloversg
2819947378 CODEBASE: Refactor and fix issues in db.ts (#2623) 2026-04-03 15:28:48 -07:00
catloversg
48fad72b6a UI: Follow-up to #2615 (#2622) 2026-04-03 15:15:04 -07:00
Lee Stutzman
63aa4d2a45 BUGFIX: Fix prompt text input losing focus to terminal (#2615) 2026-04-03 00:10:48 -07:00
catloversg
abdf3082ca ELECTRON: Fix issues in edge cases of using --export-save (#2590) 2026-04-02 23:57:25 -07:00
catloversg
8dcccdc5bb MISC: Make implicit string conversion consistent across all coding contracts (#2608) 2026-04-02 23:53:16 -07:00
Lee Stutzman
d1b6acc57a CODEBASE: Replace ipExists() linear scan with O(1) Map.has() (#2621) 2026-04-02 19:13:35 -07:00
catloversg
dc4ea8452c CODEBASE: Update comments to reflect changes in #2603 (#2606) 2026-04-02 19:13:21 -07:00
Lee Stutzman
5fc54809de BUGFIX: Fix skillMaxUpgradeCount returning 1 at extreme skill levels (#2611) 2026-04-02 19:06:44 -07:00
catloversg
7425d8a8fd UI: Show hints of Sleeves mechanic in pre-endgame (#2605) 2026-03-31 13:29:49 -07:00
Michael Ficocelli
3e44f08a0f CCT: Generate more frequent and lower-reward coding contracts (#2603) 2026-03-31 13:28:39 -07:00
catloversg
e3ae5478d5 DOCUMENTATION: Fix newline issues in IPvGO docs and add missing RAM cost (#2602) 2026-03-27 10:26:45 -07:00
catloversg
3d5079a4e6 REFACTOR: Remove duplicate random alphanumeric string functions (#2601) 2026-03-26 21:49:20 -07:00
Michael Ficocelli
fdd6d65c25 DNET: Tweaks from player feedback (#2593) 2026-03-26 18:38:45 -07:00
catloversg
38d5f3b364 REFACTOR: Split Settings.ts to reduce number of imports (#2600) 2026-03-26 18:33:11 -07:00
Michael Ficocelli
5c02f81dc7 DNET: Remove packet capture (#2594)
* DNET: Remove packet capture as an API tool; add the mechanic as part of the logs in the Open Web Access Point puzzle

* DNET: Make harder version of the packet capture puzzle just have alphanumeric noise instead of lore data and stuff

* DNET: Make harder version of the packet capture puzzle just have alphanumeric noise instead of lore data and stuff

* PR feedback
2026-03-26 18:27:30 -07:00
catloversg
92a8e619b8 ELECTRON: Import correct cloud file when multiple exist (#2599) 2026-03-26 18:23:09 -07:00
catloversg
eacdc081df ELECTRON: Mitigate issue of forcefullyCrashRenderer (#2597) 2026-03-25 13:29:50 -07:00
catloversg
a2de3c1a35 DEPS: Update Electron (#2591) 2026-03-24 14:07:10 -07:00
catloversg
aced392f53 BLADEBURNER: Always show Black Operations list (#2592) 2026-03-24 14:05:51 -07:00
catloversg
2834684170 ELECTRON: Add UI menus and CLI flags to change log levels (#2596) 2026-03-24 13:56:28 -07:00
catloversg
ed557e9e46 BUGFIX: Import save comparison popup shows wrong BN level (#2595) 2026-03-24 13:49:44 -07:00
catloversg
77cc7874ab MISC: Support importing Steam Cloud save file manually (#2583) 2026-03-21 22:23:43 -07:00
catloversg
a9bb3f6d2f ELECTRON: Allow opening dev tools via CLI arguments (#2589) 2026-03-21 05:41:29 -07:00
catloversg
2e7d591583 TOOL: Add script to generate webpack bundle report (#2587) 2026-03-20 10:44:22 -07:00
catloversg
08604e1e76 DEPS: Update Babel core, presets and module loader for webpack (#2585) 2026-03-20 01:20:24 -07:00
Michael Ficocelli
1b6b07faae DNET: Player feedback (#2545) 2026-03-19 21:07:43 -07:00
catloversg
73b7921ef0 API: Reduce RAM cost of inGang and inBladeburner APIs (#2582) 2026-03-19 20:15:41 -07:00
catloversg
9de9fbaf27 CODEBASE: Fix React warning in IPvGO scoring explanation popup (#2581) 2026-03-19 20:14:16 -07:00
catloversg
0bc05772f6 CODEBASE: Remove barrel imports in Bladeburner code (#2580) 2026-03-19 20:13:19 -07:00
catloversg
3813d03fb6 MISC: Rework intelligence override (#2575) 2026-03-19 20:09:37 -07:00
catloversg
6a9abd9544 DOCUMENTATION: Update mention of outdated getStockForecast API (#2578) 2026-03-16 12:46:43 -07:00
catloversg
c00da0cd87 BUGFIX: hacknetNodeCost formula API throws when using documented optional parameter (#2577) 2026-03-16 12:46:06 -07:00
catloversg
06e6479408 DEPS: Update dependencies (#2576) 2026-03-16 12:44:29 -07:00
catloversg
17a7b2efac UI: Prevent ending BNs through reuse of Bladeburner UI event handler (#2574) 2026-03-16 11:55:05 -07:00
catloversg
3b372e9cad UI: Prevent joining banned factions via UI (#2573) 2026-03-16 11:52:21 -07:00
catloversg
f916daf252 MISC: Rework faction rumor (#2569) 2026-03-16 11:49:46 -07:00
catloversg
ade79c0f65 UI: Add option to autosave scripts on focus change (#2565) 2026-03-13 19:37:17 -07:00
catloversg
9f6e2ce2d1 MISC: Improve help text of expr command (#2561) 2026-03-13 19:34:40 -07:00
catloversg
50442472b5 BLADEBURNER: Add APIs to get rank gain and rank loss of an action (#2572) 2026-03-13 19:34:13 -07:00
catloversg
bc3e8ff3d5 DOCUMENTATION: Add missing newline after RAM cost (#2570) 2026-03-13 19:23:29 -07:00
catloversg
8bdcaf5f83 API: Improve error messages for invalid sleeve numbers (#2567) 2026-03-12 17:36:16 -07:00
catloversg
b737bb63e6 CODEBASE: Create monaco editor instance with null model (#2563) 2026-03-12 17:19:14 -07:00
catloversg
9eb2863e48 API: Add API to minimize and expand tail windows (#2556) 2026-03-08 14:00:06 -07:00
catloversg
342dea77fa API: Make ns.cloud.purchaseServer() and ns.cloud.deleteServer() use hostname as provided (#2560) 2026-03-08 13:57:13 -07:00
catloversg
e329082a48 API: Cancel sleeve's current task when calling ns.sleeve.travel() (#2559) 2026-03-07 12:10:20 -08:00
catloversg
39a7a31276 API: Add minimum width/height constraints to ns.ui.resizeTail (#2558) 2026-03-07 12:07:56 -08:00
catloversg
e06fb3dd9d API: Print error message when calling ns.ui.closeTail with nonexistent pid or pid of stopped scripts (#2557) 2026-03-07 12:05:21 -08:00
catloversg
f8bb1ed997 UI: Show "undefined" instead of -1 as pid in error popup when catching promise errors (#2555) 2026-03-07 11:34:04 -08:00
David Walker
b6a29681f4 BUGFIX: Fix webstorm by using a mutationLock (#2542) 2026-03-06 11:11:06 -08:00
catloversg
90f6db6d24 MISC: Allow parsing unknown options with data.flags in autocomplete (#2539) 2026-03-04 12:27:12 -08:00
David Walker
dc5c43db2e REFACTOR: Make getPlayer 10x faster (#2548) 2026-03-03 14:21:34 -08:00
catloversg
5e71612fd7 UI: Update toolbar of in-game editor (#2551) 2026-03-03 14:07:08 -08:00
catloversg
45366a1a42 DOCUMENTATION: Update guides (#2550) 2026-03-03 14:05:14 -08:00
David N
17f8c354e0 UI: Add inline script RAM usage text to each active script (#2546) 2026-03-03 13:38:59 -08:00
catloversg
cf1f5224fd BLADEBURNER: Rebalance charisma exp gain of Recruitment action (#2549) 2026-03-03 13:36:11 -08:00
catloversg
c14b4955f6 DOCUMENTATION: Clarify how share power affects reputation gain rate of non-hacking work (#2544) 2026-02-28 11:50:53 -08:00
Michael Ficocelli
3d41c348bc DNET: Rebalance / player feedback (#2533) 2026-02-28 11:48:03 -08:00
Joshua
15e1ab9af7 BLADEBURNER: Adjusted team bonus computation to make one member help (#2541) 2026-02-27 17:19:27 -08:00
catloversg
cfb536cd01 BUGFIX: Fix issues with RFA auto-reconnecting feature (#2535) 2026-02-26 13:34:28 -08:00
catloversg
47d8db8b91 DOCUMENTATION: Follow-up of #2523 (#2529) 2026-02-24 13:30:43 -08:00
catloversg
144fd50774 UI: Add indicator of RFA connection status to overview panel (#2497) 2026-02-24 12:11:20 -08:00
Misha279-UA
c85d9cbe8c CCT: Add "Find Largest Rectangle in a Matrix" coding contract (#2519) 2026-02-24 12:10:42 -08:00
catloversg
6626f0d5d1 DOCUMENTATION: Document quirky behavior of ns.flags when default value is nullish (#2528) 2026-02-24 12:03:10 -08:00
catloversg
d677b4ad18 CODEBASE: Update comment of LoadingScreen of ComplexPage enum (#2527) 2026-02-24 11:59:18 -08:00
catloversg
dbc58f1f58 DOCUMENTATION: Update BitNode recommendation short guide (#2523) 2026-02-23 12:09:21 -08:00
David Walker
8f4313b180 Revert "PIPE: Add pipe support for passing data into and out of terminal commands (#2395)" (#2524)
This reverts commit 92b8b58588.

Accidental merge on my part - the code is in decent shape, but isn't meant to go in for 3.0.
2026-02-22 11:28:10 -08:00
Michael Ficocelli
92b8b58588 PIPE: Add pipe support for passing data into and out of terminal commands (#2395) 2026-02-22 11:18:23 -08:00
catloversg
4a22e16058 WORKFLOW: Fix wrong instruction of generating docs (#2522) 2026-02-21 11:58:50 -08:00
catloversg
0c118ede38 DOCUMENTATION: Use relative links instead of absolute links (#2521) 2026-02-21 11:58:15 -08:00
catloversg
67fd763c30 JEST: Show coding contract names when their tests failed (#2520) 2026-02-21 10:20:31 -08:00
David Walker
42acdc6d84 UI: Tweak CSS/Position of Darknet Docs link (#2517)
Per Discord discussion, the lower left seems to be more visible.
2026-02-21 10:17:15 -08:00
catloversg
00b9034980 UI: Show errors if using nano/vim with patterns that do not match any files (#2515) 2026-02-19 09:53:01 -08:00
David Walker
2b542257a9 MISC: Update changelog (#2514)
Latest commit: 9279b16
2026-02-18 13:52:02 -08:00
Michael Ficocelli
9279b16729 DNET: Adjust balance from player feedback (#2512) 2026-02-18 13:41:48 -08:00
catloversg
8f77dc2df0 UI: Show hints of BitNode documentation and allow opening it in BitVerse (#2513) 2026-02-18 10:08:53 -08:00
catloversg
f7483243fd UI: Use font family setting when rendering MUI Link component (#2511) 2026-02-18 09:59:28 -08:00
catloversg
7c3473e98d MISC: Update changelog and version number (#2509) 2026-02-17 01:27:21 +07:00
David Walker
42bdbbc2c8 MISC: Update blood donations (#2508)
Per Hydroflame's request
2026-02-16 10:12:52 -08:00
catloversg
9a6e80129f UI: Improve navigation system of in-game documentation viewer (#2499)
* UI: Improve navigation system of in-game documentation viewer

* Update based on feedback

* Update based on feedback
2026-02-16 09:00:58 -08:00
catloversg
dd78a2cb44 API: Remove RAM cost of hacknet namespace and set RAM cost of each hacknet API (#2502)
* API: Remove RAM cost of hacknet namespace and set RAM cost of each hacknet API

* Fix Jest tests

* Update based on feedback
2026-02-16 09:00:02 -08:00
catloversg
775a1b1e4b CODEBASE: Refactor ImportSave component (#2505) 2026-02-15 10:57:40 -08:00
catloversg
77d83a2fdc UI: Add option to disable minimap in script editor (#2504) 2026-02-15 10:56:01 -08:00
catloversg
dc0c3b6fa3 JEST: Add tests for checking getAnswer and solver of coding contracts (#2503) 2026-02-15 10:53:58 -08:00
David Walker
b51ed8fd59 BUG: Fix missed cases in offline server handling (#2495)
There were two large holes in the existing offline server handling:

1. It didn't include IPs, so scripts that used IPs instead of hostnames
   would get exceptions thrown for "server not found."
2. Coverage was very low for non-Darknet APIs. Maybe most of them don't
   need to be covered, but many obvious ones like "ps", "killall" and
   "hasRootAccess" were missing. IMO the only reliable answer is one
   that enforces *all* are covered via the type system.

To accomplish the second part, helpers.getServer() was changed to return
null when a server is offline. This intentionally breaks a lot of its
utility, which was to return a server unconditionally. To compensate,
its utility was increased - it now also does unknown argument
processing, allowing it to subsume a common line that all callers were
repeating.

Some callers switched to ctx.workerScript.getServer(), because they
didn't actually need to be using helpers.getServer(). Similarly, a few
callsites switched to GetServerOrThrow(), for the cases where it should
be guaranteed that the server is valid. The rest are returning a
default/failure response when the server is offline. (Except for
contracts, which threw on failure already anyway.)
2026-02-15 10:29:47 -08:00
catloversg
b5ab495837 BUGFIX: Hacknet server UI shows NaN hash rate when 100% RAM is being used (#2500) 2026-02-15 10:27:21 -08:00
David Walker
a0bbdfd871 DARKNET: Refactor/adjust getPixelPosition (#2501)
This simplifies the logic. It also adjusts the position of special
servers slightly; in particular, they are horizontally centered
(appearing in-between the adjacent row, and not merely staggered).

The split into two functions is in preparation for perf improvements
that require calculating this without access to the server.
2026-02-13 20:19:17 -08:00
Michael Ficocelli
26db9f2955 DNET: More fixes and feedback (#2489)
* Add some re-rendering improvements to avoid the canvas and visual servers getting desynched

* removed underlevelled nerf to low-level servers; improved charisma level docs

* Remove offscreen dynamic culling

* PR feedback; add cache file names to tooltip

* Ensure stasis link servers get loaded properly; ensure darkweb has neighbors to prevent unit tests from failing; remove extra optional chaining accessors
2026-02-13 17:23:24 -08:00
catloversg
68700ff01f API: Expose ProgramName enum (#2492) 2026-02-13 11:51:42 -08:00
catloversg
be66b766a2 DOCUMENTATION: Fix invalid links in ns.sleep and ns.asleep (#2496) 2026-02-11 10:46:04 -08:00
David Walker
26b5c28df6 REFACTOR: Speed up by-ip lookups by introducing a new map entry (#2488)
Thankfully, the existing AllServers map is not exported, so we can
ensure that all the changes are only local to this file.

This also fixes a bug if renameServer was called with the same
name. (Probably calling code checked that case already.)
2026-02-11 10:43:52 -08:00
catloversg
826fd42296 DOCUMENTATION: Improve help text of scp and run (#2493) 2026-02-11 10:42:10 -08:00
catloversg
ac34d6508d BLADEBURNER: Stop randomizing action difficulty (#2491) 2026-02-11 10:36:10 -08:00
catloversg
638c791047 MISC: Change how coding contract rewards are randomized (#2490) 2026-02-11 10:34:59 -08:00
David Walker
62f7501b43 REFACTOR: Change getFailureResult to checkDarknetServer (#2494) 2026-02-11 08:42:27 -08:00
catloversg
97987fe35b BUGFIX: Global states are not reset properly between each Jest test (#2487) 2026-02-10 10:13:00 -08:00
catloversg
95b739f703 BUGFIX: Darknet state is not reset properly on prestige (#2486) 2026-02-10 09:39:31 -08:00
David Walker
ed727d6e74 DARKNET: Buff packet sniffing slightly (#2485)
Refactor the sniff code so that successful sniffs for the current server
are tagged server_name:password, not just those for adjacent servers.
2026-02-10 08:10:33 -08:00
Michael Ficocelli
bab6280735 DNET: Add JS object properties as server names; refactor save/load/server storage to support this (#2482) 2026-02-10 00:13:47 -08:00
Groot-0909
b99e522d1c UI: Update incorrect ps command shown in help (#2484) 2026-02-08 09:37:04 -08:00
catloversg
8633e94899 UI: Update icon of DARKNET_BACKDOOR and DARKNET_DEPTHS achievements (#2480) 2026-02-08 08:40:35 -08:00
David Walker
b5da311133 REFACTOR: Consolidate checks under getFailureResult() (#2476)
There was duplicated code, and more importantly, were were handling
certain things subtly differently in exec() and scp() as a result. This
notably causes a behavior change in exec() and scp() where failure to
authenticate now returns failure instead of throwing, which I believe is
the proper response.

This also makes it easier to see in the code exactly which functions
require what (auth, session, etc.)
2026-02-08 08:39:42 -08:00
Michael Ficocelli
425bff8217 DNET: Update documentation (#2483) 2026-02-07 19:25:56 -08:00
Michael Ficocelli
e649adfef4 DARKNET: Add improved challenge achievement for BN15 (#2479)
* DARKNET: Add improved challenge achievement for BN15

* DARKNET: Adjust heartbleed check location for achievement

* Fix wrong achievement data and update svg

* DARKNET: Fix styling of documentation link

* lint

---------

Co-authored-by: CatLover <152669316+catloversg@users.noreply.github.com>
2026-02-07 18:28:55 -08:00
gmcew
95d08d7722 Change fallback reward priorities (#2481) 2026-02-07 08:50:40 -08:00
Michael Ficocelli
60a8996707 DARKNET: Add extra hint to sorted echo puzzle at high levels (#2465) 2026-02-06 04:58:01 -08:00
Michael Ficocelli
451aed153f DARKNET: Add glossary of terms to the documentation page (#2469) 2026-02-06 04:57:30 -08:00
catloversg
4c7e3d0833 UI: Show karma in Stats page and explain what it is in documentation (#2475) 2026-02-05 10:07:51 -08:00
Michael Ficocelli
6ca7c677a9 DARKNET: Prevent blocked ram on the "darkweb" server (#2468) 2026-02-05 07:32:58 -08:00
catloversg
a29f2945c5 BUGFIX: Monaco shows wrong TSDoc of APIs that have "export" word (#2473) 2026-02-05 07:31:13 -08:00
Michael Ficocelli
0eae02adcf DARKNET: Improve documentation; remove requirement that getBlockedRam and getDepth be called on a darknet server (#2472) 2026-02-05 07:28:06 -08:00
David Walker
a16706a33b DOCS: Add a note to CONTRIBUTING.md about the npm peer dep issue (#2474) 2026-02-05 07:24:24 -08:00
catloversg
796bef81b3 BUGFIX: Sleeves can earn exp and purchase augmentations when enabling disableSleeveExpAndAugmentation (#2467) 2026-02-05 04:47:24 -08:00
Michael Ficocelli
77cc582bf9 DARKNET: make threads' bonus apply to timing attack puzzle's extra time per char (#2466) 2026-02-05 04:43:13 -08:00
Snarling
2d69387227 GITHUB: Update format created by "build artifacts" workflows (#2470)
* Change filenames and structure of build artifacts, for compatibility with steam version updating
Co-authored-by: CatLover <152669316+catloversg@users.noreply.github.com>
2026-02-04 22:59:40 -05:00
catloversg
79b3b9cb74 MISC: Update version number (#2462) 2026-02-03 04:56:05 -08:00
Michael Ficocelli
b9068ab328 DOCS: Fix some IPvGO docs that do not reflect winstreak rep converted to favor (#2463) 2026-02-03 04:55:38 -08:00
Michael Ficocelli
ba1c6f3818 IPVGO: Fix scoring of very large open areas (#2464) 2026-02-03 04:52:40 -08:00
catloversg
00339a206c DOCUMENTATION: Move current changelog to changelog-v2.md (#2461) 2026-02-03 04:14:17 -08:00
Michael Ficocelli
6073964768 DARKNET: Darkweb Expansion Project & Bitnode (#2139)
This is BN15. It is a really big change; see the PR for all the details.
2026-02-03 03:40:36 -08:00
catloversg
a674633f6c MISC: Update changelog (#2460) 2026-02-02 03:43:30 -08:00
catloversg
5a2bdfc9f1 CODEBASE: Update NodeJS to v24 (#2456) 2026-01-28 22:10:55 -08:00
catloversg
8b07879ad9 CODEBASE: Update SaveData type to be compatible with TS 5.9 and upgrade TS (#2457) 2026-01-28 12:26:06 -08:00
kaoticengineering
afddd284fc UI: Add settings to change currency symbol and whether to show it after money value (#2453) 2026-01-28 12:16:28 -08:00
catloversg
366c44d5c2 API: Add warning when installing backdoor on backdoored server with Singularity API (#2458) 2026-01-28 12:10:13 -08:00
catloversg
d7c1c7be72 UI: Remove BitNode's difficulty in BitNode selection popup (#2454)
* UI: Remove BitNode's difficulty in BitNode selection popup

* Run prettier
2026-01-25 20:34:54 -08:00
catloversg
5f519991a6 API: Allow ns.read to read .msg and .lit files (#2455) 2026-01-25 20:32:44 -08:00
catloversg
2edad3ed37 DOCUMENTATION: Update math notations in corporation docs (#2452) 2026-01-20 13:04:38 -08:00
TheAimMan
210c338f86 SLEEVES: Add sleeve commands to purchase sleeves and memory via the API (#2443) 2026-01-20 12:55:51 -08:00
Michael Ficocelli
19064a1b12 MISC: Improve script args validation message (#2451) 2026-01-18 11:34:49 -08:00
catloversg
c55577929c BLADEBURNER: Make some editorial changes in Black Operations' description (#2449) 2026-01-17 14:43:07 -08:00
catloversg
c8e3eb2050 CODEBASE: Generate display data for math notation at built time and remove runtime mathjax dependency (#2447) 2026-01-17 14:41:24 -08:00
catloversg
be16b2a375 BLADEBURNER: Reduce threshold of showing warning of low population (#2450) 2026-01-17 14:35:53 -08:00
David Walker
3d7d2d7734 REFACTOR: Move Result to the public API (#2398)
* REFACTOR: Move Result to the public API

This refactors Result<T> to be part of the public NetscriptDefinitions.
It is not used by anything in this PR, but it is planned to be used in
the autoinfil APIs, or lacking that, future APIs, so this should not be
exposing anything prematurely.

* Add @public as api-extractor suggested and generate docs

* Use import type

---------

Co-authored-by: CatLover <152669316+catloversg@users.noreply.github.com>
2026-01-17 14:30:49 +07:00
EntenBu
95528ebb09 Add a question and a grammatical fix in faq.md (#2446)
"Made with beginners in mind" might be a bit of an overstatement, but I'm not gonna quibble on the wording. (IMO we are less "let me hold your hand while you learn how to cast your fishing rod" and more "I shoved you into the pond, grab some fish or smth idk")
2026-01-12 15:58:55 -08:00
catloversg
d0474a7adf DEPS: Update dependencies to fix vulnerability warnings (#2445) 2026-01-11 13:31:21 -08:00
Jonathon Chase
d7ee3cc3bb Update README.md to correct Frequently Asked Questions link. (#2444) 2026-01-08 13:25:24 -08:00
Adam Weeden
7af9dca6bc CONTRACTS: Display contract answers on completely failed contracts (#2440) 2026-01-08 13:21:52 -08:00
Nicholas Colclasure
edf3d11b72 LORE: Add literature expanding the augment prestige lore (#2433) 2026-01-03 13:49:42 -08:00
EntenBu
fc2931bc15 DOC: Change wording in Singularity.installAugmentation (#2439)
This commit changes a minor wording in the API commit. "uninstalled" implies "removed" hence the change
2026-01-03 13:45:40 -08:00
gmcew
df6c507369 MISC: Fix typos and duplicating ms per cycle constant (#2436) 2025-12-28 16:09:35 -08:00
Cica
3663b4507f MISC: Update error message when backdooring without admin rights (#2435) 2025-12-27 09:48:55 -08:00
Michael Ficocelli
4218b01dfb IPVGO: Do not update captures on passed analysis boards (#2415) 2025-12-21 13:44:24 -08:00
catloversg
49e231fd41 DEPS: Update dependencies related to monaco (#2432) 2025-12-21 13:42:20 -08:00
gmcew
3e90217cdb UI: Add Script Editor toggle for Sticky Scroll (#2431) 2025-12-21 13:40:14 -08:00
catloversg
d92b5520ec UI: Do not show error popup related to Stanek's Gift data when loading save files from pre-v1.1.0 (#2429) 2025-12-19 12:32:20 -08:00
catloversg
b76ceb725f DOCUMENTATION: Clean up "doc" folder (#2427) 2025-12-19 12:28:09 -08:00
catloversg
903b885ea2 UI: Change notice for breaking changes in v2 (#2426) 2025-12-18 14:59:17 -08:00
catloversg
bd2af9392f UI: Show useful error messages when loading unsupported save data from newer versions (#2425) 2025-12-18 14:51:48 -08:00
catloversg
be7bb0ad7c UI: Add links to documentation pages in tutorial's last step (#2424) 2025-12-18 14:43:44 -08:00
catloversg
a47867c406 CODEBASE: Refactor code related to in-game documentation link (#2422)
Nice!
2025-12-17 13:39:44 -08:00
EntenBu
6f9447e27e DOC: Add FAQ and another JIT batcher illustration to documentation (#2400) 2025-12-17 13:30:58 -08:00
Paul Setzer
968c0c2a8c CONTRACTS: Generate test contracts on executing host by default. Add support for optional parameter to specify the server. (#2417) 2025-12-16 16:23:59 -08:00
CTN
e7768824ba UI: Add option to set fractional digits (#2419) 2025-12-15 11:51:34 -08:00
catloversg
c3eb4f9ad6 DOCUMENTATION: Add instructions to troubleshoot common issues for contributors to CONTRIBUTING.md (#2420) 2025-12-15 11:46:58 -08:00
catloversg
2167a92af1 CODEBASE: Allow specifying migrator when migrating player's scripts (#2418) 2025-12-14 15:58:27 -08:00
sg673
a20053cde8 DOCUMENTATION: Clarify behavior of NS.getScriptLogs() for running scripts (#2408) 2025-12-02 12:39:35 -08:00
maglinvinn
d664d2b41a DOCUMENTATION: Remove references to defunct wiki from Hack/Weaken/Grow (#2404) 2025-11-30 13:31:43 -08:00
Michael Taylor
47b7a6f656 CODEBASE: Update packages-lock.json to not use vulnerable versions (#2405) 2025-11-28 01:19:44 -08:00
gmcew
cf32ea553f Clarification of Singularity costs inside BN4 (#2403)
- change BN description to highlight SF levels impact other BN use of singularity functions
 - add detail to singularity API description to highlight the same
2025-11-27 11:15:02 -08:00
imcute_aaaa
77fe36db89 BUGFIX: Coding contracts may have duplicate names (#2399) 2025-11-26 23:59:11 -08:00
catloversg
329fdc50fb CODEBASE: Follow-up of infil refactor #2316 (#2393) 2025-11-22 23:08:15 -08:00
David Walker
f3e9e3ddc8 BUGFIX: Avoid re-entrency issues with EventEmitter (#2397)
Subscribing or unsubscribing from within an event handler (possibly
transitively) could cause issues or even infinite loops.

This was initially fixed in #2257, which exhibited such problems.
Currently no code is known to have this issue, but it could easily come
up again in the future.
2025-11-22 18:13:44 -08:00
David Walker
50b0cc2808 MISC: Refactor implementation of ports (#2396)
This moves the implementation entirely into the PortHandle class, which
makes the code a bit more streamlined and will allow for other port
implementations in the future.
2025-11-22 17:52:25 -08:00
catloversg
67119e6c9c UI: Improve instructions in recovery mode (#2394) 2025-11-22 09:28:02 -08:00
catloversg
ce8852f3a2 BUGFIX: Company's job list shows wrong starting jobs (#2391) 2025-11-21 20:06:31 -08:00
catloversg
5c271eddf1 BUGFIX: Bladeburner console prints main body's HP instead of sleeve's HP (#2390) 2025-11-21 06:52:19 -08:00
imcute_aaaa
bb50272e54 MISC: Avoid reinventing core bonus calculation and fix formatting issue (#2387) 2025-11-19 14:18:54 -08:00
David Walker
4d230c3121 REFACTOR: Rewrite infiltration to pull state out of React (#2316)
* REFACTOR: Rewrite infiltration to pull state out of React

Upcoming projects (auto-infil, the possibility of making infil a work
task, etc.) require infiltration state to transition with predictable
timing and be under our control, instead of inside React. This refactor
accomplishes this by pulling the state out into accompanying model
classes.

After this, infiltration can theoretically run headless (without UI),
although it doesn't actually, and you would quickly be
hospitalized due to failing all the minigames.

There should be no user-visible changes, aside from the progress-bars
scrolling much more smoothly.

* Fix console warning in InfiltrationRoot

It turns out true isn't actually a safe value to use in JSX, only false works.

* Fix up some comments
2025-11-16 22:55:06 -08:00
Shy
57ca5ffeaf UI: Prevent showing redundant error toasts on failed RFA auto connect attempts (#2381) 2025-11-08 12:26:41 -08:00
gmcew
7c0286222c API: Move and rename purchased server functions to cloud API (#2367)
* Convert purchased server functions to cloud API

- Create `ns.cloud`
- Change `bitnode multipliers` and `server constants` wording for consistency
- change `server`, `ram` and `getting started` docs for consistency
- Added changes to 3.0.0 API Break and `setRemovedFunctions` in NetscriptFunctions.js

Tested by
- running tutorial `purchase-server-8gb.js`, and a more typical player one
- buying manually using vendor (Alpha Ent in Sector 12)
- deleting them all using script, and checked all deleted functions gave correct error
- Imported completed save to ensure auto-transfer of function work

* Revision in line with comments

- changed more `purchased` to `cloud` references
- Added BN mults auto-conversion

* Update getting_started.md

 - Corrected function names for new `cloud API`

* Don't show `cloud API` warning

v3.0.0 API break auto-replaces `cloud` functions, not warning suggested.

* API Break correction

- `cloud` affected API break replacement changed to be more descriptive and functional

* Fix typo and add empty lines

* Update many things (check commit's description)

- Comments
- Terminal message
- UI Text
- TSDoc
- md docs
- Improve error messages in src\NetscriptFunctions\Cloud.ts
2025-11-07 12:10:33 -08:00
Nick Shelley
d1a4ec8337 DOCUMENTATION: Improve wording around host argument of getScriptRam (#2374) 2025-11-07 11:57:33 -08:00
Shy
4ad9a96788 MISC: Support css file type (#2378) 2025-11-05 14:05:31 -08:00
Shy
9cd3ffd308 UI: Expose theme as css custom props (#2380) 2025-11-03 16:58:09 -08:00
EntenBu
e599988af7 MISC: Fix typo in README.md (#2375) 2025-10-30 10:28:59 -07:00
catloversg
174e160348 API: Make ActiveFragment extend Fragment (#2373)
* DOCUMENTATION: Fix wrong return type of ns.stanek.activeFragments

* Make ActiveFragment extend Fragment
2025-10-30 10:27:58 -07:00
catloversg
a69ee132f9 CODEBASE: Prepare for save data migration of next beta version (#2369) 2025-10-30 10:25:34 -07:00
catloversg
a5cb2a97bd UI: Reword tutorial steps to distinguish between instruction and example (#2370)
* UI: Reword tutorial steps to distinguish between instruction and example

* Minor change
2025-10-29 11:47:58 -07:00
Chaddeus
0c5256b83c UI: Correct phrasing in SmartSonar description (#2368) 2025-10-29 11:38:42 -07:00
catloversg
c6e40476bb DOCUMENTATION: Fix missing/wrong TSDoc of APIs having optional host parameter (#2371) 2025-10-29 11:15:10 -07:00
catloversg
3e75577ded BUGFIX: Electron app does not show achievement icons (#2362) 2025-10-23 12:39:11 -04:00
catloversg
1d3b96326e DEPS: Update Electron version (#2360) 2025-10-23 12:31:23 -04:00
catloversg
a703e8753b JEST: Refactor tests that add home server manually (#2358) 2025-10-21 20:57:14 -04:00
Michael Taylor
c6684431b5 UI: Format the shared RAM multipler on the factions (#2355) 2025-10-20 01:53:35 -07:00
catloversg
6837f334fd CODEBASE: Remove redundant check in getServer utility function and serverExists API (#2357) 2025-10-19 11:45:30 -07:00
Petal Ladenson
b495deb458 CLI: Let ServerProfiler.exe autocomplete servers (#2356) 2025-10-19 11:36:47 -07:00
catloversg
222e42000c CLI: Add --temporary flag to run command (#2354) 2025-10-18 12:04:39 -07:00
Michael Taylor
d785f20921 CODEBASE: Minor React related packages update (#2353)
* CODEBASE: Update @types/react & react-dom packages

Update @types/react and @types/react-dom to
17.0.26 (ts3.8) and 17.0.89 (ts3.8) from
17.0.21 (2021) and 17.0.67.

To major changes, no apparent breaking changes,
mostly packaging fixes.

* CODEBASE: Update react-syntax-higher package

Update from 15.5.0 (2022) to 15.6.6 (August 2025) which
fixes a bug with wrapLines (15.6.0, 15.6.1), fixes some
small bugs in 15.6.3 (line count, spelling), and
primarily updates dependencies, in particular prismjs to 1.30.0.

* CODEBASE: Update react-draggable package

Updates from 4.4.6 to
[4.5.0](https://github.com/react-grid-layout/react-draggable/commits/master/),
some small fixes, updated dependencies. Nothing critical, but
nothing breaking or radical as far as I can tell.

* CODEBASE: Update tss-react package

Patch level update of [tss-react](https://www.tss-react.dev/) package,
from 4.9.10 (Apr 2024) to 4.9.19 (Jul 2025). Appears to be primarily
for React 19 and Material UI 7 support. Low-priority, but should be
low-risk.

* CODEBASE: Update react-refresh package

[react-refresh](https://www.npmjs.com/package/react-refresh)
From 0.17.0 to 0.18.0.
2025-10-18 09:15:52 -07:00
catloversg
cb5b80a6d5 DOCUMENTATION: Use alternative fix for newline issue in IPvGO docs (#2350) 2025-10-15 11:58:11 -07:00
catloversg
30a572cfe6 API: Rename "TIX" interface to "Stock" (#2351) 2025-10-14 11:51:54 -07:00
catloversg
7ca364f49f DOCUMENTATION: Fix wrong commands in getting_started.md (#2349) 2025-10-13 08:59:53 -07:00
Adam Weeden
0335d8bc70 STANEK: Add FragmentType to NS Enums (#2341) 2025-10-13 08:57:19 -07:00
catloversg
2dfc2126df CODEBASE: Follow-up of #2344 (#2345) 2025-10-12 13:26:03 -07:00
catloversg
030be41df9 CODEBASE: Refactor Stanek's Gift UI code and change internal FragmentType enum (#2346) 2025-10-12 13:23:45 -07:00
catloversg
950c21d734 API: Update type of Player.factions, GangGenInfo.faction and CorpMaterialConstantData.name (#2347) 2025-10-12 13:00:21 -07:00
catloversg
d421d4fcf9 MISC: Make TIX access independent from WSE account (#2342) 2025-10-11 17:28:45 -07:00
catloversg
bd4e34fae0 CLI: Do not round down amount of hacked money in "hack" CLI (#2344) 2025-10-10 10:38:50 -07:00
catloversg
5c0f24f5d0 UI: Show server's money in exponential form if it's too small (#2343) 2025-10-10 10:37:35 -07:00
catloversg
2a2b38f4ad UI: Warn player if they run no-arg programs with arguments (#2338) 2025-10-08 14:14:01 -07:00
Michael Taylor
f12fc380cc MUI: Update minor version of material UI and Emotion packages (#2339) 2025-10-08 14:11:24 -07:00
Thaccus
625fe46bc3 DOCUMENTATION: Clarify cross-host characteristic of PID and port (#2336) 2025-10-07 13:40:05 -07:00
catloversg
1883af6c38 TOOLS: Enable linting in test folder (#2337) 2025-10-06 23:48:18 -07:00
Michael Ficocelli
0d1f5f3eeb IPVGO: Consistently return error() calls to make sure it is obvious the function halts at that point (#2335) 2025-10-06 14:26:31 -07:00
Michael Taylor
370424af2d JEST: Quiet Jest tests output on expected failures (#2332) 2025-10-05 12:31:15 -07:00
Femboy Fireball
8a2f8bb746 UI: Clarify why you can't buy 4S when disabled (#2311) 2025-10-04 14:45:42 -07:00
catloversg
4b8af02026 WORKFLOW: Add new job to check generated docs (#2329) 2025-10-04 14:41:02 -07:00
catloversg
020b185377 JEST: Enable restoreMocks option and fix lint errors (#2333)
* JEST: Enable restoreMocks option and fix lint errors

* Fix test\jest\Save.test.ts
2025-10-04 14:38:50 -07:00
Femboy Fireball
18b062663d ELECTRON: Allow automatically hiding the top menu in Electron (#2325) 2025-10-03 12:45:18 -07:00
catloversg
7225a2b22e BUGFIX: Color picker appears behind theme editor (#2321)
* BUGFIX: Color picker appears behind theme editor

* Remove unnecessary newline
2025-10-02 16:24:04 -07:00
catloversg
66a5c9568b TOOLS: Update doc.sh (#2331)
* TOOLS: Update doc.sh

* Update as suggested
2025-10-01 12:37:04 -07:00
Ante
f9a6cc841e CORPORATION: Expose production limit of material and product (#2330) 2025-10-01 01:04:39 -07:00
catloversg
060e929b68 UI: Print error detail to terminal if script cannot be compiled or there is runtime error while autocompleting (#2328)
* UI: Print error detail to terminal if script cannot be compiled while autocompleting

* Print error if there is runtime error
2025-09-28 22:45:58 -07:00
catloversg
9c2a5c25cb CODEBASE: Add more debug info for troubleshooting corporation issues (#2327) 2025-09-28 14:34:35 -07:00
catloversg
bb8552fa81 UI: Prevent text from overflowing when script's args are too long in Active Scripts page (#2324) 2025-09-27 23:25:52 -07:00
David Walker
e1352e67b1 UI: Better status bar animations (#2317)
* UI: Better status bar animations

This is an alternate implementation of #2286. It does the same
wrap-around behaviour for when the progressbar crosses into the next
level, but it skips animation entirely if the effective skill level goes
down, or if more than one level is gained at a time.

The implementation uses the animate() DOM api instead of manipulating
styles, which completely avoids the issues of having CSS style buildup.
This API is designed for exactly what we're trying to do.

I also pushed rerender handling down from CharacterOverview to
StatsProgressBar, which simplifies things and is helpful for doing the
animation implementation.
2025-09-27 23:05:21 -07:00
David Walker
5f51f355c6 UI: Improve dev menu for augmentations (#2315)
* UI: Improve dev menu for augmentations

The button layout was confusing, there was no quick way to install augs,
and uninstalled augs didn't properly lose their stat effects.
2025-09-27 23:04:59 -07:00
catloversg
4c3c56623d BUGFIX: Stat levels are not recalculated after grafting augs or accepting Stanek's Gift (#2322) 2025-09-27 23:04:18 -07:00
Michael Taylor
dcd2f33f7c CODEBASE: Update api-documentor and api-extractor (#2320)
* Update api-documentor and api-extractor. #1566 follow-up.

I have verified that the HTML/markdown table generation bug in
[#4878](https://github.com/microsoft/rushstack/issues/4878) in rushstack
for api-documentor has been fixed as per rushstack#5256. The testcase
[repro](https://github.com/catloversg/api-documenter-bug-pr-4578) now
produces the correct expected output.

I have confirmed that the generated output in bitburner from
`npm run doc` now generated HTML tables, and correctly inserts
a blank line between the </table> and the follow line (e.g. Returns).

Stylisticly it could use some whitespace, but it is correctly rendered.

This commit is only the updated packages, not the updated generated
documentation. I assume that is automatically generated by the GitHub
workflow.

* Follow up to 5f732a6f35, include `npm run doc` changed docs.

* Add missing license info

* Fix React warning

---------

Co-authored-by: CatLover <152669316+catloversg@users.noreply.github.com>
2025-09-26 14:52:39 -07:00
Michael Taylor
09ecd915c2 DEVENV: Update NodeJS to v22 (#2318)
* move to minimum nodejs 22 (from 18)
2025-09-23 11:46:26 -07:00
catloversg
b1bdfc4a9e WORKFLOW: Update NodeJs version in workflows (#2319) 2025-09-23 17:55:26 +07:00
catloversg
2637baffc7 CD: Split build-artifacts.yml into 2 workflows (#2309) 2025-09-06 11:41:39 -07:00
catloversg
9d5342732c JEST: Add Jest test to test migration from v2 to v3 (#2305) 2025-09-05 23:40:02 -07:00
Snarling
0c64c3620d ELECTRON: Build universal macOS binary (#2306) 2025-09-05 23:35:29 -07:00
Michael Ficocelli
cad38f015c IPVGO: Prevent tiny islands surrounded by offline nodes during initial board generation (#2310) 2025-09-05 23:26:57 -07:00
catloversg
21ddb99fd5 MISC: Export save data before migrating to v3 (#2304) 2025-09-02 22:55:44 -07:00
catloversg
f8329813e5 BUGFIX: Active Scripts page may mix up UI after prestige (#2303) 2025-08-29 12:19:44 -07:00
catloversg
8bd1c4af24 MISC: Update version number (#2300) 2025-08-27 17:33:18 -07:00
catloversg
bde1d95d88 MISC: Update changelog (#2299) 2025-08-27 17:32:24 -07:00
1187 changed files with 74768 additions and 14129 deletions

View File

@@ -6,8 +6,5 @@ indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
[src/ScriptEditor/NetscriptDefinitions.d.ts]
trim_trailing_whitespace = false
[*.md]
trim_trailing_whitespace = false

View File

@@ -55,5 +55,15 @@ module.exports = {
"@typescript-eslint/prefer-literal-enum-member": ["off"],
},
},
/**
* TypeScript requires the "var" keyword within "declare global" to correctly merge variables into the global
* namespace.
*/
{
files: ["**/*.d.ts"],
rules: {
"no-var": "off",
},
},
],
};

View File

@@ -1,8 +1,18 @@
name: Build artifacts
on:
release:
types: [published]
workflow_dispatch:
inputs:
git-sha:
description: "Commit SHA-1 to checkout"
required: false
default: ""
workflow_call:
inputs:
git-sha:
type: string
required: false
default: ""
env:
GH_TOKEN: ${{ github.token }}
@@ -13,10 +23,12 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
with:
ref: ${{ github.event.inputs.git-sha || inputs.git-sha || github.sha }}
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -26,15 +38,19 @@ jobs:
- name: Build the Electron app
shell: bash
run: npm run electron-win
- name: Zip
shell: bash
run: cd .build; for i in bitburner-*; do 7z a "$i.zip" "$i"; done; cd ../;
- name: Upload artifact
- name: Upload x64 artifact
uses: actions/upload-artifact@v4
with:
name: build-artifacts-win
name: bitburner-win32-x64
include-hidden-files: true
path: .build/*.zip
path: .build/bitburner-win32-x64/*
if-no-files-found: error
- name: Upload arm64 artifact
uses: actions/upload-artifact@v4
with:
name: bitburner-win32-arm64
include-hidden-files: true
path: .build/bitburner-win32-arm64/*
if-no-files-found: error
build-linux:
@@ -42,10 +58,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
with:
ref: ${{ github.event.inputs.git-sha || inputs.git-sha || github.sha }}
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -53,14 +71,19 @@ jobs:
run: npm run build
- name: Build the Electron app
run: npm run electron-linux
- name: Zip
run: cd .build; for i in bitburner-*; do zip -r "$i.zip" "$i"; done; cd ../;
- name: Upload artifact
- name: Upload x64 artifact
uses: actions/upload-artifact@v4
with:
name: build-artifacts-linux
name: bitburner-linux-x64
include-hidden-files: true
path: .build/*.zip
path: .build/bitburner-linux-x64/*
if-no-files-found: error
- name: Upload arm64 artifact
uses: actions/upload-artifact@v4
with:
name: bitburner-linux-arm64
include-hidden-files: true
path: .build/bitburner-linux-arm64/*
if-no-files-found: error
build-mac:
@@ -68,10 +91,12 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
with:
ref: ${{ github.event.inputs.git-sha || inputs.git-sha || github.sha }}
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -79,37 +104,10 @@ jobs:
run: npm run build
- name: Build the Electron app
run: npm run electron-mac
- name: Zip
run: cd .build; for i in bitburner-*; do zip -r "$i.zip" "$i"; done; cd ../;
- name: Upload artifact
- name: Upload darwin-universal artifact
uses: actions/upload-artifact@v4
with:
name: build-artifacts-mac
name: bitburner-darwin-universal
include-hidden-files: true
path: .build/*.zip
path: .build/bitburner-darwin-universal/*
if-no-files-found: error
upload:
name: Upload
runs-on: ubuntu-latest
needs: [build-windows, build-linux, build-mac]
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: .build
pattern: build-artifacts-*
merge-multiple: true
- name: List files
run: ls -la .build
- name: Upload to release
env:
GH_REF_NAME: ${{ github.ref_name }}
run: |
for i in .build/*.zip; do gh release upload "$GH_REF_NAME" "$i" --clobber; done;

View File

@@ -0,0 +1,40 @@
name: Build and upload artifacts
on:
release:
types: [published]
env:
GH_TOKEN: ${{ github.token }}
jobs:
build:
name: Build artifacts
uses: ./.github/workflows/build-artifacts.yml
upload:
name: Upload
runs-on: ubuntu-latest
permissions:
contents: write
needs: [build]
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v7
with:
path: .build
pattern: bitburner-*
merge-multiple: false
- name: List files
run: ls -la .build
- name: Zip
run: cd .build; for i in bitburner-*; do cd "$i"; zip -r "../$i.zip" *; cd ../; done; cd ../;
- name: List files
run: |
ls -la .build
- name: Upload to release
env:
GH_REF_NAME: ${{ github.ref_name }}
run: |
for i in .build/*.zip; do gh release upload "$GH_REF_NAME" "$i" --clobber; done;

View File

@@ -42,10 +42,10 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js 20
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install NPM dependencies for version updater
working-directory: ./tools/bump-version

View File

@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -30,10 +30,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -44,10 +44,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
@@ -58,12 +58,29 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
- name: Run tests
run: npm run test
check-docs:
name: Check docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 24
uses: actions/setup-node@v4
with:
node-version: 24
cache: "npm"
- name: Install npm dependencies
run: npm ci
- name: Generate docs
run: npm run doc
- name: Check generated docs
run: |
test -z "$(git status --porcelain)" || (echo "::error title=Documentation is outdated::You need to run 'npm run doc'";exit 1;)

View File

@@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
- run: npm ci
- env:
ENABLE_DEV_MODE: ${{ github.event.inputs.enable_dev_mode }}

View File

@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node 20
- name: Use Node 22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
cache: "npm"
- name: Install NPM dependencies
working-directory: ./tools/fetch-changelog

View File

@@ -19,7 +19,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24
- name: Build and deploy
run: |

View File

@@ -19,5 +19,7 @@ tsdoc-metadata.json
.git_blame_ignore_revs
# This file is generated by tools/bundle-doc/index.js
src/Documentation/pages.ts
# This file is generated by tools/bundle-doc/index.mjs
src/Documentation/pages.ts
# This file is generated by tools/bundle-doc/generate-math-notation-output.mjs
src/Documentation/data/MathNotationOutput.json

View File

@@ -48,8 +48,8 @@ already been reported as an [Issue](https://github.com/bitburner-official/bitbur
## As a Developer
Anyone is welcome to contribute to Bitburner code. However, please read
the [license](https://github.com/bitburner-official/bitburner-src/blob/dev/license.txt)
and the [readme](https://github.com/bitburner-official/bitburner-src/blob/dev/README.md)
the [license](./license.txt)
and the [readme](./README.md)
before doing so.
To contribute to Bitburner code, you will need to have
@@ -151,17 +151,11 @@ upstream/master
- Keep code-changes on a branch as small as possible. This makes it easier for code review. Each branch should be its own independent feature.
- Regularly rebase your branch against `dev` to make sure you have the latest updates pulled.
### Special Exceptions
- In `src/ScriptEditor/NetscriptDefinitions.d.ts`, there are two specially-formatted go boards with two trailing whitespaces.
Make sure your editor does not automatically format those examples.
You can look for changes to that part using `git diff` to make sure the whitespaces are still present.
## Running locally
Install
- `npm` (maybe via `nvm`)
- NodeJS (maybe via `nvm`). When installing NodeJS, you also get a tool called `npm`. You can update `npm` to the latest version by running `npm install -g npm@latest`.
- Github Desktop (Windows only)
- Visual Studio Code (optional)
@@ -175,7 +169,7 @@ Saving a file will reload the game automatically.
### How to build the electron app
Tested on Node v20.11.1 (LTS) on Windows.
Tested on Node 24.13.0 (LTS) on Windows.
These steps only work in a Bash-like environment, like MinGW for Windows.
```sh
@@ -221,6 +215,22 @@ the following rules:
and relate to the kind of change being implemented. Possible examples
are UI, BUGFIX, SERVERS, NETSCRIPT... You get the idea.
## Troubleshooting common issues
### Unrelated changes in `package-lock.json`
After running `npm install`, if you do not change anything in `package.json` and `package-lock.json` is still changed, you need to update `npm` to the latest version. After that, discard the changes in `package-lock.json`, delete the `node_modules` folder, and run `npm install` again.
### Lots of `peer: true` lines added in `package-lock.json`
npm version 11.6.2 has a bug that causes this. Unfortunately, this is the current LTS (stable) release as of this writing. Use a newer or older npm version, and re-run `npm install`.
See https://github.com/npm/cli/pull/8671 and https://github.com/npm/cli/issues/8690 for details.
### Unrelated failed Jest tests
Some Jest tests fail to run in Node versions older than v24. On those versions, these tests show a small difference between the expected value ("Snapshot") and the actual value ("Received"). You need to use Node v24+ to run these tests.
## As a Documenter
To contribute to and view your changes to the BitBurner documentation in-game, you will
@@ -250,3 +260,17 @@ Update the following:
- `doc/source/changelog.rst`
- post to Discord
- post to reddit.com/r/Bitburner
## Adding a BN guidelines
Promote:
- New mechanic.
- Coding problems based on NP problems. This makes solutions that are easy to implement inefficient and solutions that are hard to implement efficient. (e.g., Stanek)
- Inter-mechanic synergy.
- Simplicity (e.g., Stanek, Hashnet. Bad example: Corp)
Avoid:
- Failure conditions. It's very frustrating to lose several days' worth of progress.
- Making existing mechanics harder. This makes it hard to port the content to other BNs.

View File

@@ -14,5 +14,24 @@ export default class FixJSDOMEnvironment extends JSDOMEnvironment {
// Wrap the construction of the function in eval, so that transpilers
// don't touch the import() call.
this.global.importActual = eval("url => import(url)");
/**
* By default, Jest only passes a limited number of global objects to the test environment. We need these global
* objects when testing code that loads save data.
*/
this.global.Uint8Array = Uint8Array;
this.global.Blob = Blob;
this.global.CompressionStream = CompressionStream;
this.global.DecompressionStream = DecompressionStream;
this.global.TextDecoderStream = TextDecoderStream;
this.global.URL = URL;
this.global.Response = Response;
/**
* https://github.com/jsdom/jsdom/issues/3766
* https://github.com/jsdom/jsdom/issues/3444
*/
this.global.document.adoptedStyleSheets = [];
this.global.CSSStyleSheet.prototype.replaceSync = () => {};
}
}

View File

@@ -9,14 +9,14 @@ that revolves around hacking and cyberpunk themes.
The game can be played at https://bitburner-official.github.io/ (release build), https://bitburner-official.github.io/bitburner-src/ (development build), or installed through [Steam](https://store.steampowered.com/app/1812820/Bitburner/).
The location of the release build may change in the near future.
See the [frequently asked questions](./doc/FAQ.md) for more information . To discuss the game or get help, join the [official Discord server](https://discord.gg/TFc3hKD).
See the [frequently asked questions](/src/Documentation/doc/en/help/faq.md) for more information. To discuss the game or get help, join the [official Discord server](https://discord.gg/TFc3hKD).
# Documentation
There are 2 types of documentation:
- In-game documentation: It can be found in the Documentation tab. This is the best place to get up-to-date information. You can also read the web version at https://github.com/bitburner-official/bitburner-src/blob/stable/src/Documentation/doc/index.md.
- NS API documentation: It's generated from the [TypeScript definitions](./src/ScriptEditor/NetscriptDefinitions.d.ts). You can read it at https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.md.
- In-game documentation: It can be found in the Documentation tab. This is the best place to get up-to-date information. You can also read the web version at [Documentation](./src/Documentation/doc/en/index.md).
- NS API documentation: It's generated from the [TypeScript definitions](./src/ScriptEditor/NetscriptDefinitions.d.ts). You can read it at [API Documentation](./markdown/bitburner.md).
Anyone is welcome to contribute to the documentation by editing the [source
files](/src/Documentation/doc/en) and then making a pull request with your contributions.

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="BN15+.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill:#000000;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;fill:#55d400;stroke-width:0.264583"
x="33.591061"
y="40.205647"
id="text1"><tspan
sodipodi:role="line"
id="tspan1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#00ff00;fill-opacity:1;stroke-width:0.264583"
x="33.591061"
y="40.205647">BN15+</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="SF15.1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill:#000000;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;fill:#55d400;stroke-width:0.264583"
x="34.982018"
y="40.175503"
id="text1"><tspan
sodipodi:role="line"
id="tspan1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#00ff00;fill-opacity:1;stroke-width:0.264583"
x="34.982018"
y="40.175503">SF15.1</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="darknet-backdoor.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="svg5"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill:#000000;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<path
style="font-weight:bold;font-size:38.8056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#00ff00;stroke-width:0.264583"
d="m 48.845096,31.384471 q 0.606337,0.170533 1.098986,0.568442 0.511598,0.397909 0.87161,0.928454 0.360013,0.511597 0.549494,1.117935 0.208428,0.606337 0.208428,1.231623 v 16.333216 q 0,0.852662 -0.322116,1.591636 -0.322117,0.738973 -0.890559,1.288467 -0.549493,0.568441 -1.288467,0.890558 -0.738974,0.322117 -1.591636,0.322117 H 20.252493 q -0.852662,0 -1.591635,-0.322117 -0.738974,-0.322117 -1.307416,-0.890558 -0.549493,-0.549494 -0.87161,-1.288467 -0.322117,-0.738974 -0.322117,-1.591636 V 35.230925 q 0,-0.644234 0.189481,-1.250571 0.18948,-0.606338 0.549493,-1.098987 0.360013,-0.492649 0.852662,-0.87161 0.511598,-0.397909 1.117935,-0.625286 v -4.320154 q 0,-2.065338 0.530545,-3.97909 0.549494,-1.913753 1.515844,-3.581181 0.985299,-1.667428 2.349558,-3.031687 1.383207,-1.36426 3.031687,-2.33061 1.667428,-0.985299 3.581181,-1.515844 1.913753,-0.549493 3.97909,-0.549493 2.065337,0 3.97909,0.549493 1.913752,0.530545 3.58118,1.515844 1.667429,0.96635 3.031688,2.33061 1.364259,1.364259 2.33061,3.031687 0.985298,1.667428 1.515843,3.581181 0.549494,1.913752 0.549494,3.97909 z m 0,20.17967 V 35.230925 q 0,-0.549494 -0.416857,-0.947403 -0.397909,-0.416857 -0.947403,-0.416857 H 20.252493 q -0.568441,0 -0.96635,0.397909 -0.397909,0.397909 -0.397909,0.966351 v 16.333216 q 0,0.568441 0.397909,0.96635 0.397909,0.397909 0.96635,0.397909 h 27.36098 q 0.435805,0 0.644233,-0.227377 0.227377,-0.227376 0.435805,-0.549493 l 0.07579,-0.113688 q 0.07579,-0.246325 0.07579,-0.473701 z M 21.597805,27.064317 h 2.728518 q 0,-1.970597 0.738974,-3.69487 0.757922,-1.74322 2.046389,-3.031687 1.288467,-1.307415 3.031688,-2.046389 1.74322,-0.757922 3.713817,-0.757922 1.970597,0 3.694869,0.757922 1.74322,0.738974 3.031687,2.046389 1.307416,1.288467 2.046389,3.031687 0.757922,1.724273 0.757922,3.69487 v 5.438089 h 2.728519 v -5.438089 q 0,-1.686377 -0.435805,-3.259064 -0.435805,-1.572688 -1.231623,-2.936948 -0.795818,-1.364259 -1.913753,-2.482194 -1.117935,-1.117934 -2.482194,-1.913752 -1.364259,-0.795818 -2.936947,-1.231623 -1.572688,-0.435806 -3.259064,-0.435806 -1.686376,0 -3.259064,0.435806 -1.572688,0.435805 -2.936947,1.250571 -1.345312,0.795818 -2.463246,1.913752 -1.117935,1.117935 -1.932701,2.482194 -0.795818,1.345312 -1.231623,2.918 -0.435805,1.572687 -0.435805,3.259064 z"
id="text1"
aria-label="🔓" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="darknet-depths.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="svg5"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill:#000000;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0.27560617,7.2846654)">
<path
style="font-weight:bold;font-size:38.8056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#00ff00;stroke-width:0.264583"
d="M 55.381314,14.095238 44.258811,25.217742 h 5.665466 v 2.728518 q 0,1.781117 -0.416857,3.486441 -0.397909,1.705324 -1.193727,3.29696 l 2.747467,2.747467 q 0.890558,0 1.667428,0.341065 0.795818,0.341064 1.383207,0.928454 0.587389,0.587389 0.928454,1.364259 0.341065,0.77687 0.341065,1.686376 0,0.871611 -0.341065,1.64848 -0.322117,0.795818 -0.928454,1.402156 l -2.254818,2.254817 q -0.606337,0.606338 -1.402155,0.928455 -0.77687,0.341065 -1.64848,0.341065 -0.890558,0 -1.686376,-0.341065 -0.77687,-0.341065 -1.36426,-0.928455 -0.587389,-0.587389 -0.928454,-1.383207 -0.341065,-0.77687 -0.341065,-1.667428 l -2.747466,-2.747467 q -1.212675,0.606338 -2.292714,0.928454 -1.080039,0.341065 -2.160077,0.49265 -1.080039,0.151584 -2.197974,0.170532 -1.117934,0.0379 -2.406402,0.0379 h -0.454753 q -1.781116,0 -3.48644,-0.416857 -1.705324,-0.416857 -3.29696,-1.212675 L 22.695934,44.0521 q 0,0.909506 -0.341065,1.686376 -0.341065,0.77687 -0.928454,1.345311 -0.568442,0.58739 -1.36426,0.909507 -0.776869,0.341064 -1.686376,0.341064 -0.852662,0 -1.64848,-0.322116 -0.795818,-0.303169 -1.402155,-0.909507 -0.568442,-0.549493 -1.136883,-1.117934 -0.549493,-0.568442 -1.117935,-1.136883 -0.606337,-0.606338 -0.947402,-1.402156 -0.322117,-0.776869 -0.322117,-1.64848 0,-0.890558 0.341065,-1.667428 0.341065,-0.795818 0.928454,-1.383207 0.58739,-0.58739 1.36426,-0.928454 0.795818,-0.341065 1.686376,-0.341065 l 2.747467,-2.747467 q -0.606338,-1.212675 -0.947403,-2.292714 -0.322117,-1.080038 -0.473701,-2.160077 -0.151584,-1.080038 -0.18948,-2.197973 -0.01895,-1.117935 -0.01895,-2.406402 V 25.217742 H 22.92331 L 11.800807,14.095238 V 4.7917476 h 9.303491 L 33.591061,17.27851 46.077823,4.7917476 h 9.303491 z M 52.652795,7.5202663 h -5.438089 q -5.419141,5.4191417 -10.857231,10.8193347 -5.438089,5.400193 -10.819334,10.857231 0.18948,1.023194 0.68213,1.9327 0.492649,0.909506 1.193726,1.629532 0.720026,0.701078 1.629532,1.193727 0.909507,0.492649 1.932701,0.68213 5.43809,-5.400193 10.838283,-10.819335 5.419141,-5.438089 10.838282,-10.85723 z M 27.186621,25.615651 32.62471,20.177561 19.967415,7.5202663 h -5.438089 v 5.4380897 z m 20.028085,2.330609 h -4.092778 q 0,1.686377 -0.644234,3.183272 -0.625285,1.477948 -1.74322,2.595883 -1.098987,1.098986 -2.595882,1.74322 -1.477948,0.644233 -3.183272,0.644233 v 4.092779 q 2.539038,0 4.774908,-0.947403 2.235869,-0.96635 3.884349,-2.633778 1.667428,-1.667428 2.633779,-3.903298 0.96635,-2.235869 0.96635,-4.774908 z m -27.247291,0 q 0,1.686377 0.435805,3.259064 0.435805,1.572688 1.231623,2.936948 0.814766,1.345311 1.932701,2.463246 1.117935,1.117934 2.463246,1.9327 1.364259,0.795818 2.936947,1.231623 1.572688,0.435806 3.259064,0.435806 v -4.092779 q -1.686376,0 -3.183272,-0.644233 -1.477947,-0.644234 -2.595882,-1.74322 -1.098987,-1.117935 -1.74322,-2.595883 -0.644234,-1.496895 -0.644234,-3.183272 z m 20.028085,-0.397909 -5.438089,5.43809 1.64848,1.64848 q 1.023195,-0.189481 1.932701,-0.68213 0.909506,-0.492649 1.610584,-1.193727 0.720026,-0.720026 1.212675,-1.629532 0.492649,-0.909506 0.682129,-1.9327 z M 47.214706,44.0521 q 0,0.663182 0.454753,1.117935 0.454753,0.473701 1.117935,0.473701 0.68213,0 1.136883,-0.454753 0.568441,-0.549494 1.136883,-1.117935 0.587389,-0.568441 1.136882,-1.136883 0.454753,-0.492649 0.454753,-1.136883 0,-0.682129 -0.473701,-1.136882 -0.454753,-0.454753 -1.117934,-0.454753 -0.227377,0 -0.454754,0.05684 -0.227376,0.05684 -0.416857,0.18948 -0.07579,0.05684 -0.303168,0.246325 -0.208429,0.208428 -0.511598,0.492649 -0.28422,0.284221 -0.606337,0.606337 -0.322117,0.322117 -0.606338,0.606338 -0.265272,0.284221 -0.473701,0.492649 -0.18948,0.227377 -0.227376,0.284221 -0.132637,0.18948 -0.189481,0.416857 -0.05684,0.227376 -0.05684,0.454753 z M 16.13991,40.205647 q -0.663182,0 -1.136883,0.454753 -0.473701,0.473701 -0.473701,1.136882 0,0.265273 0.09474,0.549494 0.09474,0.303169 0.303169,0.511597 l 2.311662,2.33061 q 0.454753,0.454753 1.136882,0.454753 0.322117,0 0.606338,-0.132636 0.303169,-0.113689 0.511597,-0.322117 0.227377,-0.208429 0.341065,-0.492649 0.132636,-0.284221 0.132636,-0.625286 0,-0.625286 -0.435805,-1.098987 Q 19.34213,42.763633 19.001065,42.40362 18.66,42.043607 18.281039,41.645698 17.902078,41.266737 17.542065,40.925672 17.201,40.603555 16.992572,40.451971 q -0.170533,-0.132636 -0.416857,-0.18948 -0.227377,-0.05684 -0.435805,-0.05684 z m 29.710537,-4.092779 q -1.174779,1.572688 -2.728519,2.728519 l 3.372752,3.372752 q 0.113689,-0.170532 0.49265,-0.568441 0.37896,-0.397909 0.814766,-0.833714 0.454753,-0.435805 0.852662,-0.814766 0.397909,-0.397909 0.568441,-0.511597 z m -21.790254,2.728519 q -1.572688,-1.155831 -2.728518,-2.728519 l -3.372753,3.372753 q 0.170533,0.113688 0.568442,0.511597 0.397909,0.378961 0.833714,0.814766 0.435805,0.435805 0.814766,0.833714 0.397909,0.397909 0.511597,0.568441 z"
id="text1"
aria-label="⚔️" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

69
dist/icons/achievements/BN15+.svg vendored Normal file
View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="BN15+.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill-opacity: 0%;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;fill:#55d400;stroke-width:0.264583"
x="33.591061"
y="40.205647"
id="text1"><tspan
sodipodi:role="line"
id="tspan1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
x="33.591061"
y="40.205647">BN15+</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

69
dist/icons/achievements/SF15.1.svg vendored Normal file
View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="SF15.1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill-opacity: 0%;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;fill:#55d400;stroke-width:0.264583"
x="34.982018"
y="40.175503"
id="text1"><tspan
sodipodi:role="line"
id="tspan1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.6389px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
x="34.982018"
y="40.175503">SF15.1</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="darknet-backdoor.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="svg5"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill-opacity: 0%;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1">
<path
style="font-weight:bold;font-size:38.8056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
d="m 48.845096,31.384471 q 0.606337,0.170533 1.098986,0.568442 0.511598,0.397909 0.87161,0.928454 0.360013,0.511597 0.549494,1.117935 0.208428,0.606337 0.208428,1.231623 v 16.333216 q 0,0.852662 -0.322116,1.591636 -0.322117,0.738973 -0.890559,1.288467 -0.549493,0.568441 -1.288467,0.890558 -0.738974,0.322117 -1.591636,0.322117 H 20.252493 q -0.852662,0 -1.591635,-0.322117 -0.738974,-0.322117 -1.307416,-0.890558 -0.549493,-0.549494 -0.87161,-1.288467 -0.322117,-0.738974 -0.322117,-1.591636 V 35.230925 q 0,-0.644234 0.189481,-1.250571 0.18948,-0.606338 0.549493,-1.098987 0.360013,-0.492649 0.852662,-0.87161 0.511598,-0.397909 1.117935,-0.625286 v -4.320154 q 0,-2.065338 0.530545,-3.97909 0.549494,-1.913753 1.515844,-3.581181 0.985299,-1.667428 2.349558,-3.031687 1.383207,-1.36426 3.031687,-2.33061 1.667428,-0.985299 3.581181,-1.515844 1.913753,-0.549493 3.97909,-0.549493 2.065337,0 3.97909,0.549493 1.913752,0.530545 3.58118,1.515844 1.667429,0.96635 3.031688,2.33061 1.364259,1.364259 2.33061,3.031687 0.985298,1.667428 1.515843,3.581181 0.549494,1.913752 0.549494,3.97909 z m 0,20.17967 V 35.230925 q 0,-0.549494 -0.416857,-0.947403 -0.397909,-0.416857 -0.947403,-0.416857 H 20.252493 q -0.568441,0 -0.96635,0.397909 -0.397909,0.397909 -0.397909,0.966351 v 16.333216 q 0,0.568441 0.397909,0.96635 0.397909,0.397909 0.96635,0.397909 h 27.36098 q 0.435805,0 0.644233,-0.227377 0.227377,-0.227376 0.435805,-0.549493 l 0.07579,-0.113688 q 0.07579,-0.246325 0.07579,-0.473701 z M 21.597805,27.064317 h 2.728518 q 0,-1.970597 0.738974,-3.69487 0.757922,-1.74322 2.046389,-3.031687 1.288467,-1.307415 3.031688,-2.046389 1.74322,-0.757922 3.713817,-0.757922 1.970597,0 3.694869,0.757922 1.74322,0.738974 3.031687,2.046389 1.307416,1.288467 2.046389,3.031687 0.757922,1.724273 0.757922,3.69487 v 5.438089 h 2.728519 v -5.438089 q 0,-1.686377 -0.435805,-3.259064 -0.435805,-1.572688 -1.231623,-2.936948 -0.795818,-1.364259 -1.913753,-2.482194 -1.117935,-1.117934 -2.482194,-1.913752 -1.364259,-0.795818 -2.936947,-1.231623 -1.572688,-0.435806 -3.259064,-0.435806 -1.686376,0 -3.259064,0.435806 -1.572688,0.435805 -2.936947,1.250571 -1.345312,0.795818 -2.463246,1.913752 -1.117935,1.117935 -1.932701,2.482194 -0.795818,1.345312 -1.231623,2.918 -0.435805,1.572687 -0.435805,3.259064 z"
id="text1"
aria-label="🔓" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733325 67.733325"
version="1.1"
id="svg5"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="darknet-depths.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="true"
units="px"
inkscape:current-layer="svg5"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1"
originx="0"
originy="0"
spacingy="1"
spacingx="1"
units="px" />
</sodipodi:namedview>
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background">
<rect
style="fill-opacity: 0%;stroke:none;stroke-width:7.02745"
id="rect1"
width="67.73333"
height="67.73333"
x="0"
y="0" />
</g>
<g
inkscape:label="main"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0.27560617,7.2846654)">
<path
style="font-weight:bold;font-size:38.8056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
d="M 55.381314,14.095238 44.258811,25.217742 h 5.665466 v 2.728518 q 0,1.781117 -0.416857,3.486441 -0.397909,1.705324 -1.193727,3.29696 l 2.747467,2.747467 q 0.890558,0 1.667428,0.341065 0.795818,0.341064 1.383207,0.928454 0.587389,0.587389 0.928454,1.364259 0.341065,0.77687 0.341065,1.686376 0,0.871611 -0.341065,1.64848 -0.322117,0.795818 -0.928454,1.402156 l -2.254818,2.254817 q -0.606337,0.606338 -1.402155,0.928455 -0.77687,0.341065 -1.64848,0.341065 -0.890558,0 -1.686376,-0.341065 -0.77687,-0.341065 -1.36426,-0.928455 -0.587389,-0.587389 -0.928454,-1.383207 -0.341065,-0.77687 -0.341065,-1.667428 l -2.747466,-2.747467 q -1.212675,0.606338 -2.292714,0.928454 -1.080039,0.341065 -2.160077,0.49265 -1.080039,0.151584 -2.197974,0.170532 -1.117934,0.0379 -2.406402,0.0379 h -0.454753 q -1.781116,0 -3.48644,-0.416857 -1.705324,-0.416857 -3.29696,-1.212675 L 22.695934,44.0521 q 0,0.909506 -0.341065,1.686376 -0.341065,0.77687 -0.928454,1.345311 -0.568442,0.58739 -1.36426,0.909507 -0.776869,0.341064 -1.686376,0.341064 -0.852662,0 -1.64848,-0.322116 -0.795818,-0.303169 -1.402155,-0.909507 -0.568442,-0.549493 -1.136883,-1.117934 -0.549493,-0.568442 -1.117935,-1.136883 -0.606337,-0.606338 -0.947402,-1.402156 -0.322117,-0.776869 -0.322117,-1.64848 0,-0.890558 0.341065,-1.667428 0.341065,-0.795818 0.928454,-1.383207 0.58739,-0.58739 1.36426,-0.928454 0.795818,-0.341065 1.686376,-0.341065 l 2.747467,-2.747467 q -0.606338,-1.212675 -0.947403,-2.292714 -0.322117,-1.080038 -0.473701,-2.160077 -0.151584,-1.080038 -0.18948,-2.197973 -0.01895,-1.117935 -0.01895,-2.406402 V 25.217742 H 22.92331 L 11.800807,14.095238 V 4.7917476 h 9.303491 L 33.591061,17.27851 46.077823,4.7917476 h 9.303491 z M 52.652795,7.5202663 h -5.438089 q -5.419141,5.4191417 -10.857231,10.8193347 -5.438089,5.400193 -10.819334,10.857231 0.18948,1.023194 0.68213,1.9327 0.492649,0.909506 1.193726,1.629532 0.720026,0.701078 1.629532,1.193727 0.909507,0.492649 1.932701,0.68213 5.43809,-5.400193 10.838283,-10.819335 5.419141,-5.438089 10.838282,-10.85723 z M 27.186621,25.615651 32.62471,20.177561 19.967415,7.5202663 h -5.438089 v 5.4380897 z m 20.028085,2.330609 h -4.092778 q 0,1.686377 -0.644234,3.183272 -0.625285,1.477948 -1.74322,2.595883 -1.098987,1.098986 -2.595882,1.74322 -1.477948,0.644233 -3.183272,0.644233 v 4.092779 q 2.539038,0 4.774908,-0.947403 2.235869,-0.96635 3.884349,-2.633778 1.667428,-1.667428 2.633779,-3.903298 0.96635,-2.235869 0.96635,-4.774908 z m -27.247291,0 q 0,1.686377 0.435805,3.259064 0.435805,1.572688 1.231623,2.936948 0.814766,1.345311 1.932701,2.463246 1.117935,1.117934 2.463246,1.9327 1.364259,0.795818 2.936947,1.231623 1.572688,0.435806 3.259064,0.435806 v -4.092779 q -1.686376,0 -3.183272,-0.644233 -1.477947,-0.644234 -2.595882,-1.74322 -1.098987,-1.117935 -1.74322,-2.595883 -0.644234,-1.496895 -0.644234,-3.183272 z m 20.028085,-0.397909 -5.438089,5.43809 1.64848,1.64848 q 1.023195,-0.189481 1.932701,-0.68213 0.909506,-0.492649 1.610584,-1.193727 0.720026,-0.720026 1.212675,-1.629532 0.492649,-0.909506 0.682129,-1.9327 z M 47.214706,44.0521 q 0,0.663182 0.454753,1.117935 0.454753,0.473701 1.117935,0.473701 0.68213,0 1.136883,-0.454753 0.568441,-0.549494 1.136883,-1.117935 0.587389,-0.568441 1.136882,-1.136883 0.454753,-0.492649 0.454753,-1.136883 0,-0.682129 -0.473701,-1.136882 -0.454753,-0.454753 -1.117934,-0.454753 -0.227377,0 -0.454754,0.05684 -0.227376,0.05684 -0.416857,0.18948 -0.07579,0.05684 -0.303168,0.246325 -0.208429,0.208428 -0.511598,0.492649 -0.28422,0.284221 -0.606337,0.606337 -0.322117,0.322117 -0.606338,0.606338 -0.265272,0.284221 -0.473701,0.492649 -0.18948,0.227377 -0.227376,0.284221 -0.132637,0.18948 -0.189481,0.416857 -0.05684,0.227376 -0.05684,0.454753 z M 16.13991,40.205647 q -0.663182,0 -1.136883,0.454753 -0.473701,0.473701 -0.473701,1.136882 0,0.265273 0.09474,0.549494 0.09474,0.303169 0.303169,0.511597 l 2.311662,2.33061 q 0.454753,0.454753 1.136882,0.454753 0.322117,0 0.606338,-0.132636 0.303169,-0.113689 0.511597,-0.322117 0.227377,-0.208429 0.341065,-0.492649 0.132636,-0.284221 0.132636,-0.625286 0,-0.625286 -0.435805,-1.098987 Q 19.34213,42.763633 19.001065,42.40362 18.66,42.043607 18.281039,41.645698 17.902078,41.266737 17.542065,40.925672 17.201,40.603555 16.992572,40.451971 q -0.170533,-0.132636 -0.416857,-0.18948 -0.227377,-0.05684 -0.435805,-0.05684 z m 29.710537,-4.092779 q -1.174779,1.572688 -2.728519,2.728519 l 3.372752,3.372752 q 0.113689,-0.170532 0.49265,-0.568441 0.37896,-0.397909 0.814766,-0.833714 0.454753,-0.435805 0.852662,-0.814766 0.397909,-0.397909 0.568441,-0.511597 z m -21.790254,2.728519 q -1.572688,-1.155831 -2.728518,-2.728519 l -3.372753,3.372753 q 0.170533,0.113688 0.568442,0.511597 0.397909,0.378961 0.833714,0.814766 0.435805,0.435805 0.814766,0.833714 0.397909,0.397909 0.511597,0.568441 z"
id="text1"
aria-label="⚔️" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,90 +0,0 @@
# Frequently Asked Questions
## Can I donate to the project?
No, the project does not take donations.
If you still want to donate, go donate blood to your local blood bank or donate to the [Electronic Frontier Foundation](https://www.eff.org/) or [Médecins Sans Frontières](https://www.msf.org/)
---
## I need help / Where can I learn?
The best way to get help is to join the [official discord server](https://discord.gg/TFc3hKD). People of all skill levels will be able to give you hints and tips.
---
## Can I play the same save on browser & steam?
Yes, just export the save file from the options menu & import it in the other platform.
---
## Game is stuck after running scripts!
You may have created an infinite loop with no sleep. You'll have to restart the game by killing all scripts.
- On Browser: Stick `?noScript` at the end of the URL
- On Steam:
- In the menu, "Reloads" -> "Reload & Kill All Scripts".
- If this does not work, when launching the game, use the kill all scripts option.
---
## Steam: Where is the save game located?
To maintain compatibility with the web browser version, the save game is not stored as a file on your filesystem. It lives inside the localStorage of the WebKit instance. Export the save (and back it up!) in the option menu.
---
## Steam: Game won't stop / Game is shown as "Running"
Due to a limitation with the way Steam tracks the game, if you launch an external link (such as documentation), Steam may keep tracking the game as "Running" even after it is closed. Simply close the web browser to fix this.
---
## Steam: How do I get to the game files? <a name="game-files"></a>
Right-click the game in your Steam library, then go into "Manage" -> "Browse Local Files". The game can be launched directly from that location if you're having issues with Steam.
---
## Steam: Game won't launch
### **On Windows**
If the game is installed on a network drive, it will fail to start due to a [limitation in Chromium](https://github.com/electron/electron/issues/27356).
If you cannot move the game to another drive, you'll have to add `--no-sandbox` to the launch options. In your Steam Library, right click the game and hit "Properties". You'll see the "launch options" section in the "General" window.
### **On Linux**
The game is built natively. Do not use Proton unless native does not work.
When launching the game, you will be prompted with three options. If the standard launch does not work, you may attempt the `--disable-seccomp-filter-sandbox` or `--no-sandbox` launch options. If this still does not work, the game should be able to start by launching it directly or through the terminal. See [How do I get to the game files?](#game-files).
---
## Steam: File locations
### Logs (using [electron-log](https://github.com/megahertz/electron-log#readme))
You may want to access the logs to get information about crashes and such.
- on Linux: `~/.config/bitburner/logs/main.log`
- on macOS: `~/Library/Logs/bitburner/main.log`
- on Windows: `%USERPROFILE%\AppData\Roaming\bitburner\logs\main.log`
### Config (using [electron-store](https://github.com/sindresorhus/electron-store#readme))
Configuration files can be found in the application's data directory.
- on Linux: `~/.config/bitburner/config.json`
- on macOS: `~/Library/Application\ Support/bitburner/config.json`
- on Windows: `%USERPROFILE%\AppData\Roaming\bitburner\config.json`
---
## Steam: What is the API Server?
The API Server allows the official [Visual Studio Code Extension](https://github.com/bitburner-official/bitburner-vscode) to push script files from VSCode to your in-game home.

View File

@@ -1,11 +0,0 @@
Promote:
- New mechanic
- Coding problems based on NP problems. This makes solution that are easy to implement inefficient and solutions that are hard to implement efficent. (eg. Stanek)
- inter-mechanic synergy
- Simplicity (eg. Stanek, Hashnet. bad example: Corp)
Avoid:
- Failure conditions, it's very frustrating to revert several days worth of progress.
- Making existing mechanic harder. This makes it hard to port the content to other BNs.

View File

@@ -1,33 +0,0 @@
If you played Exponential Idle start with the idea that BN14 will be very similar to the Lemmas from that game.
BN14 will consist of a series of mathematical equation that needs optimizing. BN14 can only be completed by obtaining enough currency from the equations. It also has no levels as the reward is based on how fast you can complete it.
Each equation contains several variable that can be upgraded by spending currency specific to BN14
Let's imagine a very simple equation
`delta p = c1/|e-c2/c3|`
(c1 div absolute value of the natural constant e minus c2/c3)
`delta p` is the amount of currency you earn every tick
`c1`, `c2`, `c3` are all variables that the player can upgrade in exchange for the `p` currency
`c2` and `c3` increase by `1` every level and the cost to upgrade is exponential
`c1` increases exponentially and the cost to upgrade is also exponential
So the goal here is to generate as much currency as possible. For this particular equation the goal is to increase `c1` as much as possible but also to make `c2/c3` as close to `e` as possible.
An equation like this represents one part of the BN. Players will be presented with MANY different equations.
Every equation contributes to completing the BN faster.
I need equations that test many different aspect of "math culture", it can be chaos theory, quantum mechanic, weird polynomials, etc.
All variable purchasing will be scriptable.
All equation must have:
- several variables that can be upgraded, at least 1 variable must be strategic in it's upgrading (upgrading too much can cause drop in performance)
- Some sort of math twist that requires some thinking, like (-2)^c1 alters between positive and negative.
Equations must be of a wide variety of difficulty the more of a math nerd you are the better your time in the BN should be but math "noobs" shouldn't be unable to complete it.

View File

@@ -1,78 +0,0 @@
## Enter the Enderverse
This bitnode will have your sleeves and yourself move on a 2d grid to fight the Enders.
Players can access the Enderverse by accessing the glitch in Ishima.
Upon doing so they will have access to a new tab in which they can view the enderverse map.
The goal of this bitnode is to eliminate all the Enders in this Enderverse.
### Map layout
The enderverse is 10 x 10 cells big. A cell is 10 x 10 tile big. (about 4mb)
Each tile has a id representing the type of terrain on it. Some terrain can be traverse/occupied by entities, others can't.
e.g. dirt can be occupied by a sleeve but is slower than an asphalt tile.
Entities also have a cell+tile coordinate but some of them can move.
e.g. Sleeves are an entity that can be controlled by scripts.
### Stats
All stats but charisma are useful in the Enderverse. Althought the Enders special technology make them much less potent (like log2)
Strength determines the power of your attacks
Agility determines movement speed
Dexterity determines accuracy of attacks
Defense determine health points.
Hacking determine the ability to interact with special objects in the world.
### The base
Players start in their main cell. Which contains their base. This base is where your units respawn if they die. The base can also store energy to be used later.
### Moving
Moving, like almost all actions, can only be done via scripts, one tile at a time. The time it takes to move to the next tile depends on the agility of the entity and the type of tile they are trying to enter. Dirt takes longer than asphalt.
### Attacking
An entity can chose to attack any unit within its range. At first your entities will only have a range of 1, meaning they can only attack entities directly next to them. But this can be upgraded. The damage taken is determined with the entity strength and the time is determined by agility.
### Vision
It's not possible to know what is on a tile unless you have a unit within range of it. Your starting units all have 3 vision, which can be upgraded.
### Energy
Some tiles contain minable energy. Energy can be stored in sleeves or in the base. It can be spend to upgrade your units or to build helpful tools and entities such as roads or defense systems.
### Building
Building can be done by any main unit to a surrounding tile. Building anything costs energy which must be carried by your unit.
### Upgrades
Your starting units can be upgrade with energy and rewards found in the Enderverse.
Examples of upgradable stats:
- vision range
- attack range
- str/agi/dex/def bonus
- Energy capacity
### Chests
Chest can be found containing various improvements. From new buildings to stat upgrades for your units.
### Dying
When unit dies it comes back to life and gains a bonus based on it's exp. This bonus is only based on the max, it is not cummulative like gang members ascension.
### Waves
Every now and then the game will spawn waves of ennemies to attack the home base. If the players core is destroyed the player suffers heavy penalty. Those wave do get stronger over time but also nerfed in the event of a wipeout in order to prevent deadlock.
### Non-starting cells
The cells other than the starting one is where you can find better rewards but also stronger and stronger enemies. Those enemies only attack what's inside their cell and will not follow players back home. But their health is restored if none of your units are in that cell.

View File

@@ -1,3 +0,0 @@
A game of risk from the point of view of a politician.
You allocate resources on a world map, trying to win elections.

View File

@@ -1,45 +0,0 @@
Collection of Quotes
The past is relevant only as data.
Pull on the new flesh like borrowed gloves and burn your fingers once again.
A weapon is a tool. A tool for killing and destroying. And there will be times
when you must kill and destroy. Then you will choose and equip yourself with the tools
that you need. But remember the weakness of weapons. They are an extension --
you are the killer and destroyer. You are whole, with or without them.
For all that we have done, as a civilization, as individuals, the universe is
not stable, and nor is any single thing within it. Stars consume themselves,
the universe itself rushes apart, and we ourselves are composed of matter in
constant flux. Colonies of cells in temporary alliance, replicating and
decaying and housed within, an incandescent cloud of electrical impulse and
precariously stacked carbon code memory. This is reality, this is self knowledge,
and the perception of it will, of course, make you dizzy.
You are still young and stupid. Human life has no value. Haven't you learned
that yet, Takeshi, with all you've seen? It has no value, intrinsic to itself.
Machines cost money to build. Raw materials cost money to extract. But people?"
She made a tiny spitting sound. "You can always get some more people. they
reproduce like cancer cells, whether you want them or not. They are abundant,
Takeshi. Why should they be valuable? Do you know that it costs us less to
recruit and use up a real snuff whore than it does to set up and run the virtual
equivalent format. Real human flesh is cheaper than a machine. It's the axiomatic
truth of our times.
Peace is an illusion, no matter how tranquil the world seems, peace doesn't last long.
Peace is a struggle against our very nature. A skin we sketch over the bone, muscle,
and sinew of our own innate savagery.
The human eye is a wonderful device. With a little effort, it can fail to see even
the most glaring injustice.
Humanity has spread to the stars. We set out like ancient seafarers to explore
the limitless ocean of space. But no matter how far we venture into the unknown,
the worst monsters are those we bring with us.
What we believe shapes who we are. Belief can bring us salvation or destruction.
But when you believe a lie for too long, the truth doesn't set you free. It tears
you apart.
We aren't meant to live forever. It corrupts even the best of us.

View File

@@ -1,34 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
# -- Project information -----------------------------------------------------
project = 'Bitburner'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['*']
exclude_patterns = ['doc/index.rst']
# -- Options for HTML output -------------------------------------------------

View File

@@ -1,5 +0,0 @@
.. meta::
:http-equiv=Refresh: 0; url='https://github.com/bitburner-official/bitburner-src/blob/stable/src/Documentation/doc/en/index.md'
This link is outdated as documentation for Bitburner has been migrated to an in-game menu, this page should have redirected you to the new location.
You can also click `here to go to the game's documentation <https://github.com/bitburner-official/bitburner-src/blob/stable/src/Documentation/doc/en/index.md/>`_.

View File

@@ -25,5 +25,77 @@
<div>
<h1>Close me when operation is completed.</h1>
</div>
<!-- Use esm for top-level await -->
<script type="module">
const databaseName = "bitburnerSave";
// Check src/db.ts to see why the current max version is 2. If the database version is greater than this value, it
// means that the code in this file is outdated.
const maxDatabaseVersion = 2;
const databases = await window.indexedDB.databases();
const database = databases.find((info) => info.name === databaseName);
if (!database) {
alert("There is no save data");
// This is the simplest way to stop execution in top-level code without using a labeled block or IIFE.
throw new Error("There is no save data");
}
if (database.version === undefined || database.version > maxDatabaseVersion) {
alert(`Invalid database version: ${database.version}`);
throw new Error(`Invalid database version: ${database.version}`);
}
// Do NOT specify the version. We must open the database at the current version; otherwise, we will trigger
// onupgradeneeded.
const dbRequest = window.indexedDB.open(databaseName);
dbRequest.onerror = (event) => {
console.error(event.target.error);
alert(event.target.error);
};
dbRequest.onsuccess = () => {
const db = dbRequest.result;
try {
if (!db.objectStoreNames.contains("savestring")) {
alert("There is no save data");
return;
}
const transaction = db.transaction(["savestring"], "readonly");
const objectStore = transaction.objectStore("savestring");
const request = objectStore.get("save");
request.onsuccess = () => {
if (request.result == null) {
alert("There is no save data");
return;
}
let isBinaryFormat;
if (request.result instanceof Uint8Array) {
// All modules in the Electron folder are CommonJS, so importing them here would be really difficult. The
// isBinaryFormat function is very small, so let's inline it here.
isBinaryFormat = true;
const magicBytesOfDeflateGzip = [0x1f, 0x8b, 0x08];
for (let i = 0; i < magicBytesOfDeflateGzip.length; ++i) {
if (magicBytesOfDeflateGzip[i] !== request.result[i]) {
isBinaryFormat = false;
break;
}
}
} else {
isBinaryFormat = false;
}
const extension = isBinaryFormat ? "json.gz" : "json";
const filename = `bitburnerSave_${Date.now()}.${extension}`;
const blob = new Blob([request.result]);
const anchorElement = document.createElement("a");
const url = URL.createObjectURL(blob);
anchorElement.href = url;
anchorElement.download = filename;
anchorElement.click();
setTimeout(function () {
URL.revokeObjectURL(url);
}, 0);
};
} catch (error) {
console.error(error);
alert(error);
}
};
</script>
</body>
</html>

View File

@@ -5,8 +5,9 @@ const achievements = require("./achievements");
const menu = require("./menu");
const path = require("path");
const { windowTracker } = require("./windowTracker");
const storage = require("./storage");
const debug = process.argv.includes("--debug");
const openDevtools = process.argv.includes("--dev");
async function createWindow(killall) {
const setStopProcessHandler = global.app_handlers.stopProcess;
@@ -18,12 +19,14 @@ async function createWindow(killall) {
}
const tracker = windowTracker("main");
const window = new BrowserWindow({
icon,
show: false,
backgroundThrottling: false,
backgroundColor: "#000000",
title: "Bitburner",
autoHideMenuBar: storage.isMenuHideEnabled(),
x: tracker.state.x,
y: tracker.state.y,
width: tracker.state.width,
@@ -40,13 +43,13 @@ async function createWindow(killall) {
if (tracker.state.isMaximized) window.maximize();
window.removeMenu();
noScripts = killall ? { query: { noScripts: killall } } : {};
const noScripts = killall ? { query: { noScripts: killall } } : {};
window.loadFile("index.html", noScripts);
window.once("ready-to-show", () => {
utils.setZoomFactor(window, utils.getZoomFactor());
});
window.show();
if (debug) window.webContents.openDevTools();
if (openDevtools) window.webContents.openDevTools();
window.webContents.setWindowOpenHandler(({ url }) => {
// File protocol is allowed because it will use the file protocol intercept from main.js

23
electron/global.d.ts vendored Normal file
View File

@@ -0,0 +1,23 @@
import type { BrowserWindow } from "electron";
declare global {
var steamworksError: Error | undefined;
var app_handlers: {
stopProcess: (window: BrowserWindow) => void;
};
namespace Electron {
interface BrowserWindow {
gameInfo?: {
player?: {
identifier: string;
playtime: number;
lastSave: number;
};
game?: {
version: string;
hash: string;
};
};
}
}
}

View File

@@ -27,11 +27,14 @@ const debounce = require("lodash/debounce");
const Store = require("electron-store");
const store = new Store();
const path = require("path");
const { realpathSync, readFileSync } = require("fs");
const { fileURLToPath } = require("url");
const { realpathSync } = require("fs");
const { fileURLToPath, format } = require("url");
log.transports.file.level = store.get("file-log-level", "info");
log.transports.console.level = store.get("console-log-level", "debug");
utils.initializeLogLevelConfig();
// Apply config of log levels.
log.transports.file.level = store.get("file-log-level");
log.transports.console.level = store.get("console-log-level");
log.info(`Started app: ${JSON.stringify(process.argv)}`);
@@ -219,11 +222,25 @@ app.on("ready", async () => {
relativePath = path.relative(__dirname, realPath);
// Only allow access to files in "dist" folder or html files in the same directory
if (method === "GET" && (relativePath.startsWith("dist") || relativePath.match(/^[a-zA-Z-_]*\.html/))) {
const customHeaders = {};
if (relativePath.endsWith(".wasm")) {
customHeaders["Content-Type"] = "application/wasm";
}
return new Response(readFileSync(realPath), { headers: new Headers(customHeaders) });
return net
.fetch(
/**
* On Windows, passing realPath (e.g., "C:\path") directly to net.fetch is okay, but on Linux, passing
* realPath (e.g., /path) like that throws an error (TypeError: Failed to parse URL from /path). We have to
* convert it to a file:// URL.
*/
format({ pathname: realPath, protocol: "file" }),
{
/**
* By default, requests made by net.fetch go through custom protocol handlers, so we have to explicitly tell it
* to bypass those handlers; otherwise, it creates an infinite loop.
*
* Ref: https://github.com/electron/electron/issues/39402
*/
bypassCustomProtocolHandlers: true,
},
)
.catch((error) => log.error(error));
}
} catch (error) {
log.error(error);
@@ -241,7 +258,6 @@ app.on("ready", async () => {
await window.loadFile("export.html");
window.show();
setStopProcessHandler(window);
await utils.exportSave(window);
} else {
window = await startWindow(process.argv.includes("--no-scripts"));
if (global.steamworksError) {

View File

@@ -7,6 +7,30 @@ const storage = require("./storage");
const store = new Store();
const { steamworksClient } = require("./steamworksUtils");
/** @import {LogLevel} from "electron-log" */
/**
* @param {*} window
* @param {"file-log-level" | "console-log-level"} configKey
* @param {LogLevel} logLevel
* @returns {*}
*/
function createLogLevelMenuItem(window, configKey, logLevel) {
return {
label: logLevel,
type: "checkbox",
checked: store.get(configKey) === logLevel,
click: () => {
if (configKey === "file-log-level") {
log.transports.file.level = logLevel;
} else {
log.transports.console.level = logLevel;
}
store.set(configKey, logLevel);
refreshMenu(window);
},
};
}
function getMenu(window) {
const canZoomIn = utils.getZoomFactor() <= 2;
const zoomIn = () => {
@@ -204,24 +228,10 @@ function getMenu(window) {
],
},
{
label: "Reloads",
label: "View",
submenu: [
{
label: "Reload",
accelerator: "f5",
click: () => window.loadFile("index.html"),
},
{
label: "Reload && Kill All Scripts",
click: () => utils.reloadAndKill(window, true),
},
],
},
{
label: "Fullscreen",
submenu: [
{
label: "Toggle",
label: "Fullscreen",
accelerator: "f9",
click: (() => {
let full = false;
@@ -231,11 +241,9 @@ function getMenu(window) {
};
})(),
},
],
},
{
label: "Zoom",
submenu: [
{
type: "separator",
},
{
label: "Zoom In",
enabled: canZoomIn,
@@ -278,11 +286,68 @@ function getMenu(window) {
acceleratorWorksWhenHidden: true,
click: resetZoom,
},
{
type: "separator",
},
{
label: "Autohide top menu",
type: "checkbox",
checked: storage.isMenuHideEnabled(),
click: (menuItem) => {
storage.setMenuHideConfig(menuItem.checked);
window.setAutoHideMenuBar(menuItem.checked);
if (menuItem.checked) {
window.setMenuBarVisibility(false);
} else {
window.setMenuBarVisibility(true);
}
refreshMenu(window);
},
},
],
},
{
label: "Reloads",
submenu: [
{
label: "Reload",
accelerator: "f5",
click: () => window.loadFile("index.html"),
},
{
label: "Reload && Kill All Scripts",
click: () => utils.reloadAndKill(window, true),
},
],
},
{
label: "Debug",
submenu: [
{
label: "File Log Level",
submenu: [
createLogLevelMenuItem(window, "file-log-level", "error"),
createLogLevelMenuItem(window, "file-log-level", "warn"),
createLogLevelMenuItem(window, "file-log-level", "info"),
createLogLevelMenuItem(window, "file-log-level", "verbose"),
createLogLevelMenuItem(window, "file-log-level", "debug"),
createLogLevelMenuItem(window, "file-log-level", "silly"),
],
},
{
label: "Console Log Level",
submenu: [
createLogLevelMenuItem(window, "console-log-level", "error"),
createLogLevelMenuItem(window, "console-log-level", "warn"),
createLogLevelMenuItem(window, "console-log-level", "info"),
createLogLevelMenuItem(window, "console-log-level", "verbose"),
createLogLevelMenuItem(window, "console-log-level", "debug"),
createLogLevelMenuItem(window, "console-log-level", "silly"),
],
},
{
type: "separator",
},
{
label: "Activate",
accelerator: "f12",
@@ -292,13 +357,12 @@ function getMenu(window) {
label: "Delete Steam Cloud Data",
enabled: steamworksClient !== undefined,
click: () => {
if (steamworksClient.cloud.listFiles().length === 0) {
if (steamworksClient === undefined || steamworksClient.cloud.listFiles().length === 0) {
log.info("There is no Steam cloud file");
return;
}
try {
if (!storage.deleteCloudFile()) {
log.warn("Cannot delete Steam Cloud data");
}
storage.deleteCloudFiles();
} catch (error) {
log.error(error);
}

View File

@@ -8,16 +8,17 @@
"name": "bitburner",
"version": "3.0.0",
"dependencies": {
"@catloversg/steamworks.js": "0.0.2",
"@catloversg/steamworks.js": "0.0.3",
"arg": "^5.0.2",
"electron-log": "^4.4.8",
"electron-store": "^8.1.0",
"lodash": "^4.17.21"
}
},
"node_modules/@catloversg/steamworks.js": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@catloversg/steamworks.js/-/steamworks.js-0.0.2.tgz",
"integrity": "sha512-EPB7vQFZa0zGw+Ft4SHiHIDZ7UcuM/XUiyzPo5a9Pf+g5XmcvjIEjo8wKwk7Ox0DOjmSJ+s8GmOD/TDDQW5jgg==",
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@catloversg/steamworks.js/-/steamworks.js-0.0.3.tgz",
"integrity": "sha512-fQhWQ0FNuFgO7zC1t009+jiPUTBL0VeH6pxYDMbEaauRw64o6wy4lGG9gJ9Rq+Rp/wXKs/BqNMFPLpdxRXprRQ==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
@@ -66,6 +67,12 @@
}
}
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
"license": "MIT"
},
"node_modules/atomically": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz",

View File

@@ -24,7 +24,8 @@
"buildResources": "public"
},
"dependencies": {
"@catloversg/steamworks.js": "0.0.2",
"@catloversg/steamworks.js": "0.0.3",
"arg": "^5.0.2",
"electron-log": "^4.4.8",
"electron-store": "^8.1.0",
"lodash": "^4.17.21"

View File

@@ -1 +1,4 @@
export declare const isBinaryFormat: (saveData: string | Uint8Array) => boolean;
export declare const encodeBytesToBase64String: (bytes: Uint8Array<ArrayBufferLike>) => string;
export declare const decodeBase64BytesToBytes: (bytes: Uint8Array<ArrayBufferLike>) => Uint8Array<ArrayBuffer>;
export declare const isBinaryFormat: (saveData: string | Uint8Array<ArrayBufferLike>) => boolean;
export declare const isSteamCloudFormat: (saveData: string | Uint8Array<ArrayBufferLike>) => boolean;

View File

@@ -1,13 +1,68 @@
// The 2 magic bytes of the gzip header plus the mandatory compression type of DEFLATE
const magicBytes = [0x1f, 0x8b, 0x08];
const magicBytesOfDeflateGzip = new Uint8Array([0x1f, 0x8b, 0x08]);
// Base64-encoded string of magicBytesOfDeflateGzip
const base64EncodingOfMagicBytes = encodeBytesToBase64String(magicBytesOfDeflateGzip);
// Convert the base64-encoded string to a byte array
const byteArrayOfBase64EncodingOfMagicBytes = Uint8Array.from(base64EncodingOfMagicBytes, (c) => c.charCodeAt(0));
/**
* @param {Uint8Array} bytes
* @returns {string}
*/
function encodeBytesToBase64String(bytes) {
let binaryString = "";
for (let i = 0; i < bytes.length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
return btoa(binaryString);
}
/**
* @param {Uint8Array} bytes
* @returns {Uint8Array}
*/
function decodeBase64BytesToBytes(bytes) {
let base64String = "";
for (let i = 0; i < bytes.length; i++) {
base64String += String.fromCharCode(bytes[i]);
}
const decodedBinaryString = atob(base64String);
const result = new Uint8Array(decodedBinaryString.length);
for (let i = 0; i < decodedBinaryString.length; i++) {
result[i] = decodedBinaryString.charCodeAt(i);
}
return result;
}
/**
* @param {string | Uint8Array} rawData
* @returns {boolean}
*/
function isBinaryFormat(rawData) {
for (let i = 0; i < magicBytes.length; ++i) {
if (magicBytes[i] !== rawData[i]) {
for (let i = 0; i < magicBytesOfDeflateGzip.length; ++i) {
if (magicBytesOfDeflateGzip[i] !== rawData[i]) {
return false;
}
}
return true;
}
module.exports = { isBinaryFormat };
/**
* The Steam Cloud save file is a base64-encoded gz file.
*
* @param {string | Uint8Array} rawData
* @returns {boolean}
*/
function isSteamCloudFormat(rawData) {
if (typeof rawData === "string") {
return rawData.startsWith(base64EncodingOfMagicBytes);
}
for (let i = 0; i < byteArrayOfBase64EncodingOfMagicBytes.length; ++i) {
if (byteArrayOfBase64EncodingOfMagicBytes[i] !== rawData[i]) {
return false;
}
}
return true;
}
module.exports = { encodeBytesToBase64String, decodeBase64BytesToBytes, isBinaryFormat, isSteamCloudFormat };

View File

@@ -2,17 +2,21 @@
const steamworks = require("@catloversg/steamworks.js");
const log = require("electron-log");
let steamworksClient;
/** @type {ReturnType<typeof import("@catloversg/steamworks.js").init> | undefined} */
let steamworksClient = undefined;
try {
// 1812820 is our Steam App ID.
steamworksClient = steamworks.init(1812820);
} catch (error) {
if (error.message?.includes("Steam is probably not running")) {
if (error instanceof Error) {
log.warn(error.message);
global.steamworksError = error;
} else {
log.warn(error);
// This should never happen.
log.error("steamworks.js threw an error that is not an instance of Error");
log.error(error);
global.steamworksError = new Error(typeof error === "string" ? error : String(error), { cause: error });
}
global.steamworksError = error;
}
module.exports = {

View File

@@ -1,3 +1,5 @@
/** @import { BrowserWindow } from "electron" */
/** @typedef {string | Uint8Array} SaveData */
/* eslint-disable @typescript-eslint/no-var-requires */
const { app, ipcMain } = require("electron");
const path = require("path");
@@ -6,10 +8,11 @@ const fs = require("fs/promises");
const log = require("electron-log");
const flatten = require("lodash/flatten");
const Store = require("electron-store");
const { isBinaryFormat } = require("./saveDataBinaryFormat");
const { decodeBase64BytesToBytes, isBinaryFormat, isSteamCloudFormat } = require("./saveDataBinaryFormat");
const store = new Store();
const { steamworksClient } = require("./steamworksUtils");
/** @param {string} directory */
// https://stackoverflow.com/a/69418940
const dirSize = async (directory) => {
const files = await fs.readdir(directory);
@@ -17,6 +20,7 @@ const dirSize = async (directory) => {
return (await Promise.all(stats)).reduce((accumulator, { size }) => accumulator + size, 0);
};
/** @param {string} directory */
const getDirFileStats = async (directory) => {
const files = await fs.readdir(directory);
const stats = files.map((f) => {
@@ -27,11 +31,13 @@ const getDirFileStats = async (directory) => {
return data;
};
/** @param {string} directory */
const getNewestFile = async (directory) => {
const data = await getDirFileStats(directory);
return data.sort((a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime())[0];
};
/** @param {BrowserWindow} window */
const getAllSaves = async (window) => {
const rootDirectory = getSaveFolder(window, true);
const data = await fs.readdir(rootDirectory, { withFileTypes: true });
@@ -44,6 +50,7 @@ const getAllSaves = async (window) => {
return flat;
};
/** @param {BrowserWindow} window */
async function prepareSaveFolders(window) {
const rootFolder = getSaveFolder(window, true);
const currentFolder = getSaveFolder(window);
@@ -51,12 +58,15 @@ async function prepareSaveFolders(window) {
await prepareFolders(rootFolder, currentFolder, backupsFolder);
}
/** @param {...string} folders */
async function prepareFolders(...folders) {
for (const folder of folders) {
try {
// Making sure the folder exists
await fs.stat(folder);
} catch (error) {
// @ts-expect-error - Node.js guarantees that errors thrown by its APIs are instances of the standard Error class
// and include an error.code property.
if (error.code === "ENOENT") {
log.warn(`'${folder}' not found, creating it...`);
await fs.mkdir(folder);
@@ -67,6 +77,9 @@ async function prepareFolders(...folders) {
}
}
// TODO: Check callers of this function. They currently don't properly handle the case where this function returns
// undefined due to errors when reading folder stats.
/** @param {string} saveFolder */
async function getFolderSizeInBytes(saveFolder) {
try {
return await dirSize(saveFolder);
@@ -75,6 +88,7 @@ async function getFolderSizeInBytes(saveFolder) {
}
}
/** @param {boolean} value */
function setAutosaveConfig(value) {
store.set("autosave-enabled", value);
}
@@ -83,14 +97,29 @@ function isAutosaveEnabled() {
return store.get("autosave-enabled", true);
}
/** @param {boolean} value */
function setCloudEnabledConfig(value) {
store.set("cloud-enabled", value);
}
function isMenuHideEnabled() {
return store.get("autoHideMenuBar", false);
}
/** @param {boolean} value */
function setMenuHideConfig(value) {
return store.set("autoHideMenuBar", value);
}
/**
* @param {BrowserWindow} window
* @param {boolean} [root]
*/
function getSaveFolder(window, root = false) {
if (root) {
return path.join(app.getPath("userData"), "/saves");
}
// TODO: check undefined gameInfo case
const identifier = window.gameInfo?.player?.identifier ?? "";
return path.join(app.getPath("userData"), "/saves", `/${identifier}`);
}
@@ -118,30 +147,93 @@ function isCloudEnabled() {
return true;
}
/**
* @param {string} name
* @param {string} content
*/
function saveCloudFile(name, content) {
steamworksClient.cloud.writeFile(name, content);
if (!steamworksClient) {
return;
}
const result = steamworksClient.cloud.writeFile(name, content);
if (!result) {
log.warn(`Cannot write Steam Cloud save file: ${name}`);
}
}
function getFilenameOfFirstCloudFile() {
/** @param {import("@catloversg/steamworks.js/client").cloud.FileInfo[]} files */
function logCloudFiles(files) {
for (const file of files) {
log.debug(
`Name: ${file.name}. Size: ${file.size}. ` +
`isFilePersisted: ${steamworksClient?.cloud.isFilePersisted(file.name)}. ` +
`timestamp: ${steamworksClient?.cloud.fileTimestamp(file.name)}`,
);
}
}
function getFilenameOfMostRecentlyPersistedCloudFile() {
if (!steamworksClient) {
return null;
}
const files = steamworksClient.cloud.listFiles();
if (files.length === 0) {
throw new Error("No files in cloud");
return null;
}
const file = files[0];
log.silly(`Found ${files.length} files.`);
log.silly(`First File: ${file.name} (${file.size} bytes)`);
const filteredFiles = files
// @ts-expect-error - https://github.com/microsoft/TypeScript/issues/9998
.filter((file) => steamworksClient.cloud.isFilePersisted(file.name))
.map((file) => ({
file,
// @ts-expect-error - https://github.com/microsoft/TypeScript/issues/9998
timestamp: steamworksClient.cloud.fileTimestamp(file.name),
}))
.sort((a, b) => b.timestamp - a.timestamp)
.map((item) => item.file);
if (filteredFiles.length === 0) {
log.warn("Found cloud file(s) but none are persisted");
logCloudFiles(files);
return null;
}
if (filteredFiles.length > 1) {
log.warn("Found more than 1 persisted cloud file");
logCloudFiles(files);
}
const file = filteredFiles[0];
log.debug(`Found ${filteredFiles.length} files.`);
log.debug(`First File: ${file.name} (${file.size} bytes)`);
return file.name;
}
function getCloudFile() {
return steamworksClient.cloud.readFile(getFilenameOfFirstCloudFile());
if (!steamworksClient) {
return null;
}
const filename = getFilenameOfMostRecentlyPersistedCloudFile();
if (filename === null) {
return null;
}
return steamworksClient.cloud.readFile(filename);
}
function deleteCloudFile() {
return steamworksClient.cloud.deleteFile(getFilenameOfFirstCloudFile());
function deleteCloudFiles() {
if (!steamworksClient) {
return;
}
for (const file of steamworksClient.cloud.listFiles()) {
if (steamworksClient.cloud.deleteFile(file.name)) {
log.info(`Deleted Steam cloud file: ${file.name}`);
} else {
log.warn(`Cannot delete Steam cloud file: ${file.name}`);
}
}
}
/** @param {string} currentPlayerId */
async function backupSteamDataToDisk(currentPlayerId) {
if (!steamworksClient) {
return;
}
const files = steamworksClient.cloud.listFiles();
if (files.length === 0) {
return;
@@ -161,16 +253,24 @@ async function backupSteamDataToDisk(currentPlayerId) {
* The name of save file is `${currentPlayerId}.json.gz`. The content of save file is weird: it's a base64 string of the
* binary data of compressed json save string. It's weird because the extension is .json.gz while the content is a
* base64 string. Check the comments in the implementation to see why it is like that.
*
* @param {SaveData} saveData
* @param {string} currentPlayerId
* @returns
*/
async function pushSaveDataToSteamCloud(saveData, currentPlayerId) {
// TODO: Check whether we really need to throw an error here or if we can log and return.
if (!isCloudEnabled()) {
return Promise.reject("Steam Cloud is not Enabled");
throw new Error("Steam Cloud is not enabled");
}
// TODO: Refactor this function and backupSteamDataToDisk. backupSteamDataToDisk is not really useful (it tries to
// back up the first cloud file). In the case of having multiple cloud files, calling backupSteamDataToDisk and
// saveCloudFile like this is useless.
try {
await backupSteamDataToDisk(currentPlayerId);
} catch (error) {
log.error(error);
log.error("Cannot back up Steam data to disk", error);
}
const steamSaveName = `${currentPlayerId}.json.gz`;
@@ -194,7 +294,7 @@ async function pushSaveDataToSteamCloud(saveData, currentPlayerId) {
try {
saveCloudFile(steamSaveName, content);
} catch (error) {
log.error(error);
log.error("Cannot save cloud file", error);
}
}
@@ -203,20 +303,29 @@ async function pushSaveDataToSteamCloud(saveData, currentPlayerId) {
*/
async function getSteamCloudSaveData() {
if (!isCloudEnabled()) {
return Promise.reject("Steam Cloud is not Enabled");
throw new Error("Steam Cloud is not enabled");
}
log.debug(`Fetching Save in Steam Cloud`);
log.debug("Fetching Save in Steam Cloud");
const cloudString = getCloudFile();
// TODO: Refactor this function and its callers. Not having a cloud file is a valid case.
if (cloudString === null) {
throw new Error("Cannot get cloud file");
}
// Decode cloudString to get save data back.
const saveData = Buffer.from(cloudString, "base64");
log.debug(`SaveData: ${saveData.length} bytes`);
return saveData;
}
/**
* @param {BrowserWindow} window
* @param {{save: SaveData, fileName: string}} electronGameData
* @returns
*/
async function saveGameToDisk(window, electronGameData) {
const currentFolder = getSaveFolder(window);
let saveFolderSizeBytes = await getFolderSizeInBytes(currentFolder);
const maxFolderSizeBytes = store.get("autosave-quota", 1e8); // 100Mb per playerIndentifier
const maxFolderSizeBytes = store.get("autosave-quota", 1e8); // 100Mb
const remainingSpaceBytes = maxFolderSizeBytes - saveFolderSizeBytes;
log.debug(`Folder Usage: ${saveFolderSizeBytes} bytes`);
log.debug(`Folder Capacity: ${maxFolderSizeBytes} bytes`);
@@ -261,6 +370,7 @@ async function saveGameToDisk(window, electronGameData) {
return file;
}
/** @param {BrowserWindow} window */
async function loadLastFromDisk(window) {
const folder = getSaveFolder(window);
const last = await getNewestFile(folder);
@@ -268,12 +378,16 @@ async function loadLastFromDisk(window) {
return loadFileFromDisk(last.file);
}
/** @param {string} path */
async function loadFileFromDisk(path) {
const buffer = await fs.readFile(path);
let content;
if (isBinaryFormat(buffer)) {
// Save file is in the binary format.
content = buffer;
} else if (isSteamCloudFormat(buffer)) {
// Save file is in the Steam Cloud format.
content = decodeBase64BytesToBytes(buffer);
} else {
// Save file is in the base64 format.
content = buffer.toString("utf8");
@@ -282,47 +396,60 @@ async function loadFileFromDisk(path) {
return content;
}
/**
* @param {BrowserWindow} window
* @param {SaveData} save
*/
function getSaveInformation(window, save) {
return new Promise((resolve) => {
ipcMain.once("get-save-info-response", (event, data) => {
ipcMain.once("get-save-info-response", (__event, data) => {
resolve(data);
});
window.webContents.send("get-save-info-request", save);
});
}
/** @param {BrowserWindow} window */
function getCurrentSave(window) {
return new Promise((resolve) => {
ipcMain.once("get-save-data-response", (event, data) => {
ipcMain.once("get-save-data-response", (__event, data) => {
resolve(data);
});
window.webContents.send("get-save-data-request");
});
}
/**
* @param {BrowserWindow} window
* @param {SaveData} save
* @param {boolean} automatic
*/
function pushSaveGameForImport(window, save, automatic) {
ipcMain.once("push-import-result", (event, arg) => {
ipcMain.once("push-import-result", (__event, arg) => {
log.debug(`Was save imported? ${arg.wasImported ? "Yes" : "No"}`);
});
window.webContents.send("push-save-request", { save, automatic });
}
/** @param {BrowserWindow} window */
async function restoreIfNewerExists(window) {
const currentSave = await getCurrentSave(window);
const currentData = await getSaveInformation(window, currentSave.save);
const steam = {};
const disk = {};
try {
steam.save = await getSteamCloudSaveData();
steam.data = await getSaveInformation(window, steam.save);
} catch (error) {
log.error("Could not retrieve steam file");
log.debug(error);
if (isCloudEnabled()) {
// TODO: Check if we can refactor to avoid using a try-catch block.
try {
steam.save = await getSteamCloudSaveData();
steam.data = await getSaveInformation(window, steam.save);
} catch (error) {
log.error("Could not retrieve Steam cloud file", error);
}
}
try {
const saves = (await getAllSaves()).sort((a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime());
const saves = (await getAllSaves(window)).sort((a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime());
if (saves.length > 0) {
disk.save = await loadFileFromDisk(saves[0].file);
disk.data = await getSaveInformation(window, disk.save);
@@ -377,7 +504,7 @@ module.exports = {
pushSaveGameForImport,
pushSaveDataToSteamCloud,
getSteamCloudSaveData,
deleteCloudFile,
deleteCloudFiles,
saveGameToDisk,
loadLastFromDisk,
loadFileFromDisk,
@@ -388,4 +515,6 @@ module.exports = {
setCloudEnabledConfig,
isAutosaveEnabled,
setAutosaveConfig,
isMenuHideEnabled,
setMenuHideConfig,
};

View File

@@ -1,18 +1,55 @@
/** @import { BrowserWindow } from "electron" */
/* eslint-disable @typescript-eslint/no-var-requires */
const { dialog } = require("electron");
const { app, dialog } = require("electron");
const log = require("electron-log");
const Store = require("electron-store");
const store = new Store();
const arg = require("arg");
/** @param {BrowserWindow} window */
function getRendererProcessUniqueId(window) {
const rendererProcesses = app
.getAppMetrics()
.filter((processMetric) => processMetric.pid === window.webContents.getOSProcessId());
if (rendererProcesses.length === 0) {
return null;
}
// This should never happen.
if (rendererProcesses.length > 1) {
log.error("Found more than 1 renderer process");
log.info(rendererProcesses);
}
const rendererProcess = rendererProcesses[0];
// Pid may be reused, so we need to use both pid and creationTime to uniquely identify the process.
return `${rendererProcess.pid}-${rendererProcess.creationTime}`;
}
/**
* @param {BrowserWindow} window
* @param {boolean} killScripts
*/
function reloadAndKill(window, killScripts) {
log.info("Reloading & Killing all scripts...");
const zoomFactor = getZoomFactor();
const currentRendererProcessUniqueId = getRendererProcessUniqueId(window);
log.debug(`Current renderer process unique id: ${currentRendererProcessUniqueId}`);
window.webContents.forcefullyCrashRenderer();
window.loadFile("index.html", killScripts ? { query: { noScripts: true } } : {});
window.once("ready-to-show", () => {
setZoomFactor(window, zoomFactor);
});
// Keep checking whether a new renderer process has been spawned. If not, call loadFile. We need to do this to
// mitigate the issue of forcefullyCrashRenderer.
// Check https://github.com/electron/electron/issues/48661 for more information.
const intervalId = setInterval(() => {
const rendererProcessUniqueId = getRendererProcessUniqueId(window);
log.debug(`Renderer process unique id: ${rendererProcessUniqueId}`);
if (rendererProcessUniqueId !== null && rendererProcessUniqueId !== currentRendererProcessUniqueId) {
clearInterval(intervalId);
return;
}
window.loadFile("index.html", killScripts ? { query: { noScripts: true } } : {});
}, 0);
}
function promptForReload(window) {
@@ -53,36 +90,6 @@ function showErrorBox(title, error) {
dialog.showErrorBox(title, `${error.name}\n\n${error.message}`);
}
function exportSaveFromIndexedDb() {
return new Promise((resolve) => {
const dbRequest = indexedDB.open("bitburnerSave");
dbRequest.onsuccess = () => {
const db = dbRequest.result;
const transaction = db.transaction(["savestring"], "readonly");
const store = transaction.objectStore("savestring");
const request = store.get("save");
request.onsuccess = () => {
const file = new Blob([request.result], { type: "text/plain" });
const a = document.createElement("a");
const url = URL.createObjectURL(file);
a.href = url;
a.download = "save.json";
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
resolve();
}, 0);
};
};
});
}
async function exportSave(window) {
await window.webContents.executeJavaScript(`${exportSaveFromIndexedDb.toString()}; exportSaveFromIndexedDb();`, true);
}
async function writeTerminal(window, message, type = null) {
await window.webContents.executeJavaScript(`window.appNotifier.terminal("${message}", "${type}");`, true);
}
@@ -105,14 +112,55 @@ function setZoomFactor(window, zoom = null) {
window.webContents.setZoomFactor(zoom);
}
function initializeLogLevelConfig() {
/**
* @type {{
* ["--file-log-level"]?: string,
* ["--console-log-level"]?: string,
* }}
*/
let args = {};
try {
args = arg(
{
"--file-log-level": String,
"--console-log-level": String,
},
{ permissive: true, argv: process.argv.slice(1) },
);
} catch (error) {
log.error("Cannot parse arguments", process.argv, error);
}
// Set default log levels if no stored config exists.
if (store.get("file-log-level") === undefined) {
store.set("file-log-level", "info");
}
if (store.get("console-log-level") === undefined) {
store.set("console-log-level", "debug");
}
const validLogLevels = ["error", "warn", "info", "verbose", "debug", "silly"];
// Override log levels if relevant arguments are provided.
const parsedFileLogLevel = args["--file-log-level"];
if (parsedFileLogLevel !== undefined && validLogLevels.includes(parsedFileLogLevel)) {
store.set("file-log-level", parsedFileLogLevel);
}
const parsedConsoleLogLevel = args["--console-log-level"];
if (parsedConsoleLogLevel !== undefined && validLogLevels.includes(parsedConsoleLogLevel)) {
store.set("console-log-level", parsedConsoleLogLevel);
}
}
module.exports = {
reloadAndKill,
showErrorBox,
exportSave,
attachUnresponsiveAppHandler,
detachUnresponsiveAppHandler,
writeTerminal,
writeToast,
getZoomFactor,
setZoomFactor,
initializeLogLevelConfig,
};

View File

@@ -21,4 +21,5 @@ module.exports = {
"/utils/Protections$": "<rootDir>/test/__mocks__/NullMock.js",
"@swc/wasm-web": "@swc/core",
},
restoreMocks: true,
};

View File

@@ -8,5 +8,5 @@
**Signature:**
```typescript
type _ValueOf<T> = T[keyof T];
export type _ValueOf<T> = T[keyof T];
```

View File

@@ -0,0 +1,19 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [ActiveFragment](./bitburner.activefragment.md) &gt; [chargedEffect](./bitburner.activefragment.chargedeffect.md)
## ActiveFragment.chargedEffect property
This is the raw value of the modifier used to calculate the effect on your multipliers. It may not be a multiplier.
With fragments that increase a multiplier, this value is a multiplier. For example, with "+x% hacknet production" fragment, a value of 1.25 will multiply the "hacknet\_node\_money" multiplier by 1.25. The UI will show "+25% hacknet production".
With fragments that decrease a multiplier, you need to invert this value. For example, with "-x% cheaper hacknet costs" fragment, a value of 1.25 means the "hacknet\_node\_purchase\_cost" (and other relevant cost multipliers) will be multiplied by 0.8 (1 / 1.25). The UI will show "20% cheaper hacknet costs".
With booster fragments, this value is always 1. Booster fragments only boost non-booster fragments. They don't directly boost your multipliers.
**Signature:**
```typescript
chargedEffect: number;
```

View File

@@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [ActiveFragment](./bitburner.activefragment.md) &gt; [id](./bitburner.activefragment.id.md)
## ActiveFragment.id property
**Signature:**
```typescript
id: number;
```

View File

@@ -8,17 +8,142 @@
**Signature:**
```typescript
interface ActiveFragment
interface ActiveFragment extends Fragment
```
**Extends:** [Fragment](./bitburner.fragment.md)
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [highestCharge](./bitburner.activefragment.highestcharge.md) | | number | |
| [id](./bitburner.activefragment.id.md) | | number | |
| [numCharge](./bitburner.activefragment.numcharge.md) | | number | |
| [rotation](./bitburner.activefragment.rotation.md) | | number | |
| [x](./bitburner.activefragment.x.md) | | number | |
| [y](./bitburner.activefragment.y.md) | | number | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[chargedEffect](./bitburner.activefragment.chargedeffect.md)
</td><td>
</td><td>
number
</td><td>
This is the raw value of the modifier used to calculate the effect on your multipliers. It may not be a multiplier.
With fragments that increase a multiplier, this value is a multiplier. For example, with "+x% hacknet production" fragment, a value of 1.25 will multiply the "hacknet\_node\_money" multiplier by 1.25. The UI will show "+25% hacknet production".
With fragments that decrease a multiplier, you need to invert this value. For example, with "-x% cheaper hacknet costs" fragment, a value of 1.25 means the "hacknet\_node\_purchase\_cost" (and other relevant cost multipliers) will be multiplied by 0.8 (1 / 1.25). The UI will show "20% cheaper hacknet costs".
With booster fragments, this value is always 1. Booster fragments only boost non-booster fragments. They don't directly boost your multipliers.
</td></tr>
<tr><td>
[highestCharge](./bitburner.activefragment.highestcharge.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[numCharge](./bitburner.activefragment.numcharge.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[rotation](./bitburner.activefragment.rotation.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[x](./bitburner.activefragment.x.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[y](./bitburner.activefragment.y.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
</tbody></table>

View File

@@ -14,8 +14,64 @@ interface AugmentPair
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [cost](./bitburner.augmentpair.cost.md) | | number | augmentation cost |
| [name](./bitburner.augmentpair.name.md) | | string | augmentation name |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[cost](./bitburner.augmentpair.cost.md)
</td><td>
</td><td>
number
</td><td>
augmentation cost
</td></tr>
<tr><td>
[name](./bitburner.augmentpair.name.md)
</td><td>
</td><td>
string
</td><td>
augmentation name
</td></tr>
</tbody></table>

View File

@@ -14,9 +14,37 @@ flags(schema: [string, string | number | boolean | string[]][]): { [key: string]
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| schema | \[string, string \| number \| boolean \| string\[\]\]\[\] | |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
schema
</td><td>
\[string, string \| number \| boolean \| string\[\]\]\[\]
</td><td>
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,20 +14,208 @@ interface AutocompleteData
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [command](./bitburner.autocompletedata.command.md) | | string | <p>The raw command string that you have typed until you press \[Tab\] to use the autocomplete feature.</p><p>For example, if you type <code>[Space]run test.js[Space][Space][Space][Press tab to use autocomplete]</code>, "command" will contain all space characters (1 space character before "run" and 3 space characters after ".js").</p> |
| [enums](./bitburner.autocompletedata.enums.md) | | [NSEnums](./bitburner.nsenums.md) | Netscript Enums |
| [filename](./bitburner.autocompletedata.filename.md) | | string | The filename of the script about to be run |
| [hostname](./bitburner.autocompletedata.hostname.md) | | string | The hostname of the server the script would be running on |
| [processes](./bitburner.autocompletedata.processes.md) | | [ProcessInfo](./bitburner.processinfo.md)<!-- -->\[\] | The processes running on the host |
| [scripts](./bitburner.autocompletedata.scripts.md) | | string\[\] | All scripts on the current server |
| [servers](./bitburner.autocompletedata.servers.md) | | string\[\] | <p>All server hostnames.</p><p>Some servers are hidden until you satisfy their requirements. This array does not contain those servers if you do not satisfy their requirements.</p> |
| [txts](./bitburner.autocompletedata.txts.md) | | string\[\] | All text files on the current server |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[command](./bitburner.autocompletedata.command.md)
</td><td>
</td><td>
string
</td><td>
The raw command string that you have typed until you press \[Tab\] to use the autocomplete feature.
For example, if you type `[Space]run test.js[Space][Space][Space][Press tab to use autocomplete]`<!-- -->, "command" will contain all space characters (1 space character before "run" and 3 space characters after ".js").
</td></tr>
<tr><td>
[enums](./bitburner.autocompletedata.enums.md)
</td><td>
</td><td>
[NSEnums](./bitburner.nsenums.md)
</td><td>
Netscript Enums
</td></tr>
<tr><td>
[filename](./bitburner.autocompletedata.filename.md)
</td><td>
</td><td>
string
</td><td>
The filename of the script about to be run
</td></tr>
<tr><td>
[hostname](./bitburner.autocompletedata.hostname.md)
</td><td>
</td><td>
string
</td><td>
The hostname of the server the script would be running on
</td></tr>
<tr><td>
[processes](./bitburner.autocompletedata.processes.md)
</td><td>
</td><td>
[ProcessInfo](./bitburner.processinfo.md)<!-- -->\[\]
</td><td>
The processes running on the host
</td></tr>
<tr><td>
[scripts](./bitburner.autocompletedata.scripts.md)
</td><td>
</td><td>
string\[\]
</td><td>
All scripts on the current server
</td></tr>
<tr><td>
[servers](./bitburner.autocompletedata.servers.md)
</td><td>
</td><td>
string\[\]
</td><td>
All server hostnames.
Some servers are hidden until you satisfy their requirements. This array does not contain those servers if you do not satisfy their requirements.
</td></tr>
<tr><td>
[txts](./bitburner.autocompletedata.txts.md)
</td><td>
</td><td>
string\[\]
</td><td>
All text files on the current server
</td></tr>
</tbody></table>
## Methods
| Method | Description |
| --- | --- |
| [flags(schema)](./bitburner.autocompletedata.flags.md) | Parses the flags schema on the already inputted flags |
<table><thead><tr><th>
Method
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[flags(schema)](./bitburner.autocompletedata.flags.md)
</td><td>
Parses the flags schema on the already inputted flags
</td></tr>
</tbody></table>

View File

@@ -14,8 +14,60 @@ interface BackdoorRequirement
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [server](./bitburner.backdoorrequirement.server.md) | | string | |
| [type](./bitburner.backdoorrequirement.type.md) | | "backdoorInstalled" | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[server](./bitburner.backdoorrequirement.server.md)
</td><td>
</td><td>
string
</td><td>
</td></tr>
<tr><td>
[type](./bitburner.backdoorrequirement.type.md)
</td><td>
</td><td>
"backdoorInstalled"
</td><td>
</td></tr>
</tbody></table>

View File

@@ -14,7 +14,45 @@ export interface BaseTask
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [cyclesWorked](./bitburner.basetask.cyclesworked.md) | | number | The number of game engine cycles has passed since this task started. 1 engine cycle = 200ms. |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[cyclesWorked](./bitburner.basetask.cyclesworked.md)
</td><td>
</td><td>
number
</td><td>
The number of game engine cycles has passed since this task started. 1 engine cycle = 200ms.
</td></tr>
</tbody></table>

View File

@@ -14,9 +14,83 @@ interface BasicHGWOptions
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [additionalMsec?](./bitburner.basichgwoptions.additionalmsec.md) | | number | _(Optional)_ Number of additional milliseconds that will be spent waiting between the start of the function and when it completes. |
| [stock?](./bitburner.basichgwoptions.stock.md) | | boolean | _(Optional)_ Set to true this action will affect the stock market. |
| [threads?](./bitburner.basichgwoptions.threads.md) | | number | _(Optional)_ Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. Accepts positive non integer values. |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[additionalMsec?](./bitburner.basichgwoptions.additionalmsec.md)
</td><td>
</td><td>
number
</td><td>
_(Optional)_ Number of additional milliseconds that will be spent waiting between the start of the function and when it completes.
</td></tr>
<tr><td>
[stock?](./bitburner.basichgwoptions.stock.md)
</td><td>
</td><td>
boolean
</td><td>
_(Optional)_ Set to true this action will affect the stock market.
</td></tr>
<tr><td>
[threads?](./bitburner.basichgwoptions.threads.md)
</td><td>
</td><td>
number
</td><td>
_(Optional)_ Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. Accepts positive non integer values.
</td></tr>
</tbody></table>

View File

@@ -18,13 +18,145 @@ export interface BitNodeBooleanOptions
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [disable4SData](./bitburner.bitnodebooleanoptions.disable4sdata.md) | | boolean | |
| [disableBladeburner](./bitburner.bitnodebooleanoptions.disablebladeburner.md) | | boolean | |
| [disableCorporation](./bitburner.bitnodebooleanoptions.disablecorporation.md) | | boolean | |
| [disableGang](./bitburner.bitnodebooleanoptions.disablegang.md) | | boolean | |
| [disableHacknetServer](./bitburner.bitnodebooleanoptions.disablehacknetserver.md) | | boolean | |
| [disableSleeveExpAndAugmentation](./bitburner.bitnodebooleanoptions.disablesleeveexpandaugmentation.md) | | boolean | |
| [restrictHomePCUpgrade](./bitburner.bitnodebooleanoptions.restricthomepcupgrade.md) | | boolean | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[disable4SData](./bitburner.bitnodebooleanoptions.disable4sdata.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[disableBladeburner](./bitburner.bitnodebooleanoptions.disablebladeburner.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[disableCorporation](./bitburner.bitnodebooleanoptions.disablecorporation.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[disableGang](./bitburner.bitnodebooleanoptions.disablegang.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[disableHacknetServer](./bitburner.bitnodebooleanoptions.disablehacknetserver.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[disableSleeveExpAndAugmentation](./bitburner.bitnodebooleanoptions.disablesleeveexpandaugmentation.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
<tr><td>
[restrictHomePCUpgrade](./bitburner.bitnodebooleanoptions.restricthomepcupgrade.md)
</td><td>
</td><td>
boolean
</td><td>
</td></tr>
</tbody></table>

View File

@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [CloudServerCost](./bitburner.bitnodemultipliers.cloudservercost.md)
## BitNodeMultipliers.CloudServerCost property
Influence how much it costs to purchase a cloud server
**Signature:**
```typescript
CloudServerCost: number;
```

View File

@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [CloudServerLimit](./bitburner.bitnodemultipliers.cloudserverlimit.md)
## BitNodeMultipliers.CloudServerLimit property
Influences the maximum number of cloud servers you can have
**Signature:**
```typescript
CloudServerLimit: number;
```

View File

@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [CloudServerMaxRam](./bitburner.bitnodemultipliers.cloudservermaxram.md)
## BitNodeMultipliers.CloudServerMaxRam property
Influences the maximum allowed RAM for a cloud server
**Signature:**
```typescript
CloudServerMaxRam: number;
```

View File

@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [CloudServerSoftcap](./bitburner.bitnodemultipliers.cloudserversoftcap.md)
## BitNodeMultipliers.CloudServerSoftcap property
Influence how much it costs to purchase a cloud server
**Signature:**
```typescript
CloudServerSoftcap: number;
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [PurchasedServerCost](./bitburner.bitnodemultipliers.purchasedservercost.md)
## BitNodeMultipliers.PurchasedServerCost property
Influence how much it costs to purchase a server
**Signature:**
```typescript
PurchasedServerCost: number;
```

View File

@@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [PurchasedServerLimit](./bitburner.bitnodemultipliers.purchasedserverlimit.md)
## BitNodeMultipliers.PurchasedServerLimit property
Influences the maximum number of purchased servers you can have
**Signature:**
```typescript
PurchasedServerLimit: number;
```

View File

@@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [PurchasedServerMaxRam](./bitburner.bitnodemultipliers.purchasedservermaxram.md)
## BitNodeMultipliers.PurchasedServerMaxRam property
Influences the maximum allowed RAM for a purchased server
**Signature:**
```typescript
PurchasedServerMaxRam: number;
```

View File

@@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [BitNodeMultipliers](./bitburner.bitnodemultipliers.md) &gt; [PurchasedServerSoftcap](./bitburner.bitnodemultipliers.purchasedserversoftcap.md)
## BitNodeMultipliers.PurchasedServerSoftcap property
Influence how much it costs to purchase a server
**Signature:**
```typescript
PurchasedServerSoftcap: number;
```

View File

@@ -23,8 +23,60 @@ export interface BitNodeOptions extends BitNodeBooleanOptions
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [intelligenceOverride](./bitburner.bitnodeoptions.intelligenceoverride.md) | | number \| undefined | |
| [sourceFileOverrides](./bitburner.bitnodeoptions.sourcefileoverrides.md) | | Map&lt;number, number&gt; | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[intelligenceOverride](./bitburner.bitnodeoptions.intelligenceoverride.md)
</td><td>
</td><td>
number \| undefined
</td><td>
</td></tr>
<tr><td>
[sourceFileOverrides](./bitburner.bitnodeoptions.sourcefileoverrides.md)
</td><td>
</td><td>
Map&lt;number, number&gt;
</td><td>
</td></tr>
</tbody></table>

View File

@@ -14,8 +14,60 @@ interface BitNodeRequirement
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [bitNodeN](./bitburner.bitnoderequirement.bitnoden.md) | | number | |
| [type](./bitburner.bitnoderequirement.type.md) | | "bitNodeN" | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[bitNodeN](./bitburner.bitnoderequirement.bitnoden.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[type](./bitburner.bitnoderequirement.type.md)
</td><td>
</td><td>
"bitNodeN"
</td><td>
</td></tr>
</tbody></table>

View File

@@ -14,10 +14,55 @@ getActionAutolevel(type: BladeburnerActionType, name: BladeburnerActionName): bo
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ getActionCountRemaining(type: BladeburnerActionType, name: BladeburnerActionName
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ getActionCurrentLevel(type: BladeburnerActionType, name: BladeburnerActionName):
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -18,11 +18,71 @@ getActionEstimatedSuccessChance(
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
| sleeveNumber | number | _(Optional)_ Optional. Index of the sleeve to retrieve information. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
sleeveNumber
</td><td>
number
</td><td>
_(Optional)_ Optional. Index of the sleeve to retrieve information.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ getActionMaxLevel(type: BladeburnerActionType, name: BladeburnerActionName): num
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -0,0 +1,94 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Bladeburner](./bitburner.bladeburner.md) &gt; [getActionRankGain](./bitburner.bladeburner.getactionrankgain.md)
## Bladeburner.getActionRankGain() method
Get the rank gain of an action.
**Signature:**
```typescript
getActionRankGain(type: BladeburnerActionType, name: BladeburnerActionName, level?: number): number;
```
## Parameters
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
level
</td><td>
number
</td><td>
_(Optional)_ Optional. Action level at which to calculate the gain. Defaults to the action's current level if not specified.
</td></tr>
</tbody></table>
**Returns:**
number
Average rank gain for successfully completing the specified action.
## Remarks
RAM cost: 4 GB
Returns the average rank gain for successfully completing the specified action. Note that this value is an "average" and the actual rank gain may vary slightly from this value.

View File

@@ -0,0 +1,94 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Bladeburner](./bitburner.bladeburner.md) &gt; [getActionRankLoss](./bitburner.bladeburner.getactionrankloss.md)
## Bladeburner.getActionRankLoss() method
Get the rank loss of an action.
**Signature:**
```typescript
getActionRankLoss(type: BladeburnerActionType, name: BladeburnerActionName, level?: number): number;
```
## Parameters
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
level
</td><td>
number
</td><td>
_(Optional)_ Optional. Action level at which to calculate the loss. Defaults to the action's current level if not specified.
</td></tr>
</tbody></table>
**Returns:**
number
Average rank loss for failing to complete the specified action.
## Remarks
RAM cost: 4 GB
Returns the average rank loss for failing to complete the specified action. Note that this value is an "average" and the actual rank loss may vary slightly from this value.

View File

@@ -14,21 +14,81 @@ getActionRepGain(type: BladeburnerActionType, name: BladeburnerActionName, level
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
| level | number | _(Optional)_ Optional number. Action level at which to calculate the gain. Will be the action's current level if not given. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
level
</td><td>
number
</td><td>
_(Optional)_ Optional. Action level at which to calculate the gain. Defaults to the action's current level if not specified.
</td></tr>
</tbody></table>
**Returns:**
number
Average Bladeburner reputation gain for successfully completing the specified action.
Average reputation gain for successfully completing the specified action.
## Remarks
RAM cost: 4 GB
Returns the average Bladeburner reputation gain for successfully completing the specified action. Note that this value is an average and the real reputation gain may vary slightly from this value.
Returns the average reputation gain for successfully completing the specified action. Note that this value is an "average" and the actual reputation gain may vary slightly from this value.

View File

@@ -14,10 +14,55 @@ getActionSuccesses(type: BladeburnerActionType, name: BladeburnerActionName): nu
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ getActionTime(type: BladeburnerActionType, name: BladeburnerActionName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ getBlackOpRank(name: BladeburnerBlackOpName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| name | [BladeburnerBlackOpName](./bitburner.bladeburnerblackopname.md) | Name of BlackOp. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
name
</td><td>
[BladeburnerBlackOpName](./bitburner.bladeburnerblackopname.md)
</td><td>
Name of BlackOp. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ getCityChaos(city: CityName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| city | [CityName](./bitburner.cityname.md) | Name of city. Case-sensitive |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
city
</td><td>
[CityName](./bitburner.cityname.md)
</td><td>
Name of city. Case-sensitive
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ getCityCommunities(city: CityName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| city | [CityName](./bitburner.cityname.md) | Name of city. Case-sensitive |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
city
</td><td>
[CityName](./bitburner.cityname.md)
</td><td>
Name of city. Case-sensitive
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ getCityEstimatedPopulation(city: CityName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| city | [CityName](./bitburner.cityname.md) | Name of city. Case-sensitive |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
city
</td><td>
[CityName](./bitburner.cityname.md)
</td><td>
Name of city. Case-sensitive
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ getSkillLevel(skillName: BladeburnerSkillName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| skillName | [BladeburnerSkillName](./bitburner.bladeburnerskillname.md) | Name of skill. Case-sensitive and must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
skillName
</td><td>
[BladeburnerSkillName](./bitburner.bladeburnerskillname.md)
</td><td>
Name of skill. Case-sensitive and must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ getSkillUpgradeCost(skillName: BladeburnerSkillName, count?: number): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| skillName | [BladeburnerSkillName](./bitburner.bladeburnerskillname.md) | Name of skill. Case-sensitive and must be an exact match. |
| count | number | _(Optional)_ Number of times to upgrade the skill. Defaults to 1 if not specified. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
skillName
</td><td>
[BladeburnerSkillName](./bitburner.bladeburnerskillname.md)
</td><td>
Name of skill. Case-sensitive and must be an exact match.
</td></tr>
<tr><td>
count
</td><td>
number
</td><td>
_(Optional)_ Number of times to upgrade the skill. Defaults to 1 if not specified.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -19,7 +19,9 @@ Array containing current stamina and max stamina.
## Remarks
RAM cost: 4 GB Returns an array with two elements: \* \[Current stamina, Max stamina\]
RAM cost: 4 GB
Returns an array with two elements: \[Current stamina, Max stamina\]
## Example

View File

@@ -14,10 +14,55 @@ getTeamSize(type?: BladeburnerActionType, name?: BladeburnerActionName): number;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | _(Optional)_ Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | _(Optional)_ Name of action. Must be an exact match. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
_(Optional)_ Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
_(Optional)_ Name of action. Must be an exact match.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -19,5 +19,5 @@ whether player is a member of Bladeburner division.
## Remarks
RAM cost: 1 GB
RAM cost: 0 GB

View File

@@ -19,7 +19,9 @@ True if you successfully join the Bladeburner faction, or if you are already a m
## Remarks
RAM cost: 4 GB Attempts to join the Bladeburner faction.
RAM cost: 4 GB
Attempts to join the Bladeburner faction.
Returns true if you successfully join the Bladeburner faction, or if you are already a member.

View File

@@ -18,45 +18,467 @@ You have to be employed in the Bladeburner division and be in BitNode 6/7 or hav
## Methods
| Method | Description |
| --- | --- |
| [getActionAutolevel(type, name)](./bitburner.bladeburner.getactionautolevel.md) | Get whether an action is set to autolevel. |
| [getActionCountRemaining(type, name)](./bitburner.bladeburner.getactioncountremaining.md) | Get action count remaining. |
| [getActionCurrentLevel(type, name)](./bitburner.bladeburner.getactioncurrentlevel.md) | Get the current level of an action. |
| [getActionCurrentTime()](./bitburner.bladeburner.getactioncurrenttime.md) | Get the time elapsed on current action. |
| [getActionEstimatedSuccessChance(type, name, sleeveNumber)](./bitburner.bladeburner.getactionestimatedsuccesschance.md) | Get estimate success chance of an action. |
| [getActionMaxLevel(type, name)](./bitburner.bladeburner.getactionmaxlevel.md) | Get the maximum level of an action. |
| [getActionRepGain(type, name, level)](./bitburner.bladeburner.getactionrepgain.md) | Get the reputation gain of an action. |
| [getActionSuccesses(type, name)](./bitburner.bladeburner.getactionsuccesses.md) | Get action successes. |
| [getActionTime(type, name)](./bitburner.bladeburner.getactiontime.md) | Get the time to complete an action. |
| [getBlackOpNames()](./bitburner.bladeburner.getblackopnames.md) | List all black ops. |
| [getBlackOpRank(name)](./bitburner.bladeburner.getblackoprank.md) | Get black op required rank. |
| [getBonusTime()](./bitburner.bladeburner.getbonustime.md) | Get Bladeburner bonus time. |
| [getCity()](./bitburner.bladeburner.getcity.md) | Get current city. |
| [getCityChaos(city)](./bitburner.bladeburner.getcitychaos.md) | Get chaos of a city. |
| [getCityCommunities(city)](./bitburner.bladeburner.getcitycommunities.md) | Get number of communities in a city. |
| [getCityEstimatedPopulation(city)](./bitburner.bladeburner.getcityestimatedpopulation.md) | Get estimated population in city. |
| [getContractNames()](./bitburner.bladeburner.getcontractnames.md) | List all contracts. |
| [getCurrentAction()](./bitburner.bladeburner.getcurrentaction.md) | Get current action. |
| [getGeneralActionNames()](./bitburner.bladeburner.getgeneralactionnames.md) | List all general actions. |
| [getNextBlackOp()](./bitburner.bladeburner.getnextblackop.md) | Get an object with the name and rank requirement of the next BlackOp that can be completed. |
| [getOperationNames()](./bitburner.bladeburner.getoperationnames.md) | List all operations. |
| [getRank()](./bitburner.bladeburner.getrank.md) | Get player bladeburner rank. |
| [getSkillLevel(skillName)](./bitburner.bladeburner.getskilllevel.md) | Get skill level. |
| [getSkillNames()](./bitburner.bladeburner.getskillnames.md) | List all skills. |
| [getSkillPoints()](./bitburner.bladeburner.getskillpoints.md) | Get bladeburner skill points. |
| [getSkillUpgradeCost(skillName, count)](./bitburner.bladeburner.getskillupgradecost.md) | Get cost to upgrade skill. |
| [getStamina()](./bitburner.bladeburner.getstamina.md) | Get Bladeburner stamina. |
| [getTeamSize(type, name)](./bitburner.bladeburner.getteamsize.md) | Get team size. |
| [inBladeburner()](./bitburner.bladeburner.inbladeburner.md) | Returns whether player is a member of Bladeburner division. Does not require API access. |
| [joinBladeburnerDivision()](./bitburner.bladeburner.joinbladeburnerdivision.md) | Join the Bladeburner division. |
| [joinBladeburnerFaction()](./bitburner.bladeburner.joinbladeburnerfaction.md) | Join the Bladeburner faction. |
| [nextUpdate()](./bitburner.bladeburner.nextupdate.md) | Sleep until the next Bladeburner update has happened. |
| [setActionAutolevel(type, name, autoLevel)](./bitburner.bladeburner.setactionautolevel.md) | Set an action autolevel. |
| [setActionLevel(type, name, level)](./bitburner.bladeburner.setactionlevel.md) | Set the level of an action. |
| [setTeamSize(type, name, size)](./bitburner.bladeburner.setteamsize.md) | Set team size. |
| [startAction(type, name)](./bitburner.bladeburner.startaction.md) | Start an action. |
| [stopBladeburnerAction()](./bitburner.bladeburner.stopbladeburneraction.md) | Stop current action. |
| [switchCity(city)](./bitburner.bladeburner.switchcity.md) | Travel to another city in Bladeburner. |
| [upgradeSkill(skillName, count)](./bitburner.bladeburner.upgradeskill.md) | Upgrade skill. |
<table><thead><tr><th>
Method
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[getActionAutolevel(type, name)](./bitburner.bladeburner.getactionautolevel.md)
</td><td>
Get whether an action is set to autolevel.
</td></tr>
<tr><td>
[getActionCountRemaining(type, name)](./bitburner.bladeburner.getactioncountremaining.md)
</td><td>
Get action count remaining.
</td></tr>
<tr><td>
[getActionCurrentLevel(type, name)](./bitburner.bladeburner.getactioncurrentlevel.md)
</td><td>
Get the current level of an action.
</td></tr>
<tr><td>
[getActionCurrentTime()](./bitburner.bladeburner.getactioncurrenttime.md)
</td><td>
Get the time elapsed on current action.
</td></tr>
<tr><td>
[getActionEstimatedSuccessChance(type, name, sleeveNumber)](./bitburner.bladeburner.getactionestimatedsuccesschance.md)
</td><td>
Get estimate success chance of an action.
</td></tr>
<tr><td>
[getActionMaxLevel(type, name)](./bitburner.bladeburner.getactionmaxlevel.md)
</td><td>
Get the maximum level of an action.
</td></tr>
<tr><td>
[getActionRankGain(type, name, level)](./bitburner.bladeburner.getactionrankgain.md)
</td><td>
Get the rank gain of an action.
</td></tr>
<tr><td>
[getActionRankLoss(type, name, level)](./bitburner.bladeburner.getactionrankloss.md)
</td><td>
Get the rank loss of an action.
</td></tr>
<tr><td>
[getActionRepGain(type, name, level)](./bitburner.bladeburner.getactionrepgain.md)
</td><td>
Get the reputation gain of an action.
</td></tr>
<tr><td>
[getActionSuccesses(type, name)](./bitburner.bladeburner.getactionsuccesses.md)
</td><td>
Get action successes.
</td></tr>
<tr><td>
[getActionTime(type, name)](./bitburner.bladeburner.getactiontime.md)
</td><td>
Get the time to complete an action.
</td></tr>
<tr><td>
[getBlackOpNames()](./bitburner.bladeburner.getblackopnames.md)
</td><td>
List all black ops.
</td></tr>
<tr><td>
[getBlackOpRank(name)](./bitburner.bladeburner.getblackoprank.md)
</td><td>
Get black op required rank.
</td></tr>
<tr><td>
[getBonusTime()](./bitburner.bladeburner.getbonustime.md)
</td><td>
Get Bladeburner bonus time.
</td></tr>
<tr><td>
[getCity()](./bitburner.bladeburner.getcity.md)
</td><td>
Get current city.
</td></tr>
<tr><td>
[getCityChaos(city)](./bitburner.bladeburner.getcitychaos.md)
</td><td>
Get chaos of a city.
</td></tr>
<tr><td>
[getCityCommunities(city)](./bitburner.bladeburner.getcitycommunities.md)
</td><td>
Get number of communities in a city.
</td></tr>
<tr><td>
[getCityEstimatedPopulation(city)](./bitburner.bladeburner.getcityestimatedpopulation.md)
</td><td>
Get estimated population in city.
</td></tr>
<tr><td>
[getContractNames()](./bitburner.bladeburner.getcontractnames.md)
</td><td>
List all contracts.
</td></tr>
<tr><td>
[getCurrentAction()](./bitburner.bladeburner.getcurrentaction.md)
</td><td>
Get current action.
</td></tr>
<tr><td>
[getGeneralActionNames()](./bitburner.bladeburner.getgeneralactionnames.md)
</td><td>
List all general actions.
</td></tr>
<tr><td>
[getNextBlackOp()](./bitburner.bladeburner.getnextblackop.md)
</td><td>
Get an object with the name and rank requirement of the next BlackOp that can be completed.
</td></tr>
<tr><td>
[getOperationNames()](./bitburner.bladeburner.getoperationnames.md)
</td><td>
List all operations.
</td></tr>
<tr><td>
[getRank()](./bitburner.bladeburner.getrank.md)
</td><td>
Get player bladeburner rank.
</td></tr>
<tr><td>
[getSkillLevel(skillName)](./bitburner.bladeburner.getskilllevel.md)
</td><td>
Get skill level.
</td></tr>
<tr><td>
[getSkillNames()](./bitburner.bladeburner.getskillnames.md)
</td><td>
List all skills.
</td></tr>
<tr><td>
[getSkillPoints()](./bitburner.bladeburner.getskillpoints.md)
</td><td>
Get bladeburner skill points.
</td></tr>
<tr><td>
[getSkillUpgradeCost(skillName, count)](./bitburner.bladeburner.getskillupgradecost.md)
</td><td>
Get cost to upgrade skill.
</td></tr>
<tr><td>
[getStamina()](./bitburner.bladeburner.getstamina.md)
</td><td>
Get Bladeburner stamina.
</td></tr>
<tr><td>
[getTeamSize(type, name)](./bitburner.bladeburner.getteamsize.md)
</td><td>
Get team size.
</td></tr>
<tr><td>
[inBladeburner()](./bitburner.bladeburner.inbladeburner.md)
</td><td>
Returns whether player is a member of Bladeburner division. Does not require API access.
</td></tr>
<tr><td>
[joinBladeburnerDivision()](./bitburner.bladeburner.joinbladeburnerdivision.md)
</td><td>
Join the Bladeburner division.
</td></tr>
<tr><td>
[joinBladeburnerFaction()](./bitburner.bladeburner.joinbladeburnerfaction.md)
</td><td>
Join the Bladeburner faction.
</td></tr>
<tr><td>
[nextUpdate()](./bitburner.bladeburner.nextupdate.md)
</td><td>
Sleep until the next Bladeburner update has happened.
</td></tr>
<tr><td>
[setActionAutolevel(type, name, autoLevel)](./bitburner.bladeburner.setactionautolevel.md)
</td><td>
Set an action autolevel.
</td></tr>
<tr><td>
[setActionLevel(type, name, level)](./bitburner.bladeburner.setactionlevel.md)
</td><td>
Set the level of an action.
</td></tr>
<tr><td>
[setTeamSize(type, name, size)](./bitburner.bladeburner.setteamsize.md)
</td><td>
Set team size.
</td></tr>
<tr><td>
[startAction(type, name)](./bitburner.bladeburner.startaction.md)
</td><td>
Start an action.
</td></tr>
<tr><td>
[stopBladeburnerAction()](./bitburner.bladeburner.stopbladeburneraction.md)
</td><td>
Stop current action.
</td></tr>
<tr><td>
[switchCity(city)](./bitburner.bladeburner.switchcity.md)
</td><td>
Travel to another city in Bladeburner.
</td></tr>
<tr><td>
[upgradeSkill(skillName, count)](./bitburner.bladeburner.upgradeskill.md)
</td><td>
Upgrade skill.
</td></tr>
</tbody></table>

View File

@@ -14,11 +14,71 @@ setActionAutolevel(type: BladeburnerActionType, name: BladeburnerActionName, aut
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
| autoLevel | boolean | Whether or not to autolevel this action |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
autoLevel
</td><td>
boolean
</td><td>
Whether or not to autolevel this action
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,11 +14,71 @@ setActionLevel(type: BladeburnerActionType, name: BladeburnerActionName, level:
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
| level | number | Level to set this action to. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
level
</td><td>
number
</td><td>
Level to set this action to.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,11 +14,71 @@ setTeamSize(type: BladeburnerActionType, name: BladeburnerActionName, size: numb
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match. |
| size | number | Number of team members to set. Must be a non-negative integer. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match.
</td></tr>
<tr><td>
size
</td><td>
number
</td><td>
Number of team members to set. Must be a non-negative integer.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,10 +14,55 @@ startAction(type: BladeburnerActionType, name: BladeburnerActionName): boolean;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| type | [BladeburnerActionType](./bitburner.bladeburneractiontype.md) | Type of action. |
| name | [BladeburnerActionName](./bitburner.bladeburneractionname.md) | Name of action. Must be an exact match |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
type
</td><td>
[BladeburnerActionType](./bitburner.bladeburneractiontype.md)
</td><td>
Type of action.
</td></tr>
<tr><td>
name
</td><td>
[BladeburnerActionName](./bitburner.bladeburneractionname.md)
</td><td>
Name of action. Must be an exact match
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,9 +14,39 @@ switchCity(city: CityName): boolean;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| city | [CityName](./bitburner.cityname.md) | Name of city. Case-sensitive |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
city
</td><td>
[CityName](./bitburner.cityname.md)
</td><td>
Name of city. Case-sensitive
</td></tr>
</tbody></table>
**Returns:**
@@ -26,7 +56,9 @@ true if successful, and false otherwise
## Remarks
RAM cost: 4 GB Attempts to switch to the specified city (for Bladeburner only).
RAM cost: 4 GB
Attempts to switch to the specified city (for Bladeburner only).
Returns true if successful, and false otherwise

View File

@@ -14,10 +14,55 @@ upgradeSkill(skillName: BladeburnerSkillName, count?: number): boolean;
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| skillName | [BladeburnerSkillName](./bitburner.bladeburnerskillname.md) | Name of skill to be upgraded. Case-sensitive and must be an exact match. |
| count | number | _(Optional)_ Number of times to upgrade the skill. Defaults to 1 if not specified. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
skillName
</td><td>
[BladeburnerSkillName](./bitburner.bladeburnerskillname.md)
</td><td>
Name of skill to be upgraded. Case-sensitive and must be an exact match.
</td></tr>
<tr><td>
count
</td><td>
number
</td><td>
_(Optional)_ Number of times to upgrade the skill. Defaults to 1 if not specified.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,8 +14,64 @@ interface BladeburnerCurAction
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [name](./bitburner.bladeburnercuraction.name.md) | | string | Name of Action |
| [type](./bitburner.bladeburnercuraction.type.md) | | string | Type of Action |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[name](./bitburner.bladeburnercuraction.name.md)
</td><td>
</td><td>
string
</td><td>
Name of Action
</td></tr>
<tr><td>
[type](./bitburner.bladeburnercuraction.type.md)
</td><td>
</td><td>
string
</td><td>
Type of Action
</td></tr>
</tbody></table>

View File

@@ -14,7 +14,27 @@ interface BladeburnerFormulas
## Methods
| Method | Description |
| --- | --- |
| [skillMaxUpgradeCount(name, level, skillPoints)](./bitburner.bladeburnerformulas.skillmaxupgradecount.md) | Calculate the number of times that you can upgrade a skill. |
<table><thead><tr><th>
Method
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[skillMaxUpgradeCount(name, level, skillPoints)](./bitburner.bladeburnerformulas.skillmaxupgradecount.md)
</td><td>
Calculate the number of times that you can upgrade a skill.
</td></tr>
</tbody></table>

View File

@@ -14,11 +14,71 @@ skillMaxUpgradeCount(name: BladeburnerSkillName, level: number, skillPoints: num
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| name | [BladeburnerSkillName](./bitburner.bladeburnerskillname.md) | Skill name. It's case-sensitive and must be an exact match. |
| level | number | Skill level. It must be a non-negative number. |
| skillPoints | number | Number of skill points to upgrade the skill. It must be a non-negative number. |
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
name
</td><td>
[BladeburnerSkillName](./bitburner.bladeburnerskillname.md)
</td><td>
Skill name. It's case-sensitive and must be an exact match.
</td></tr>
<tr><td>
level
</td><td>
number
</td><td>
Skill level. It must be a non-negative number.
</td></tr>
<tr><td>
skillPoints
</td><td>
number
</td><td>
Number of skill points to upgrade the skill. It must be a non-negative number.
</td></tr>
</tbody></table>
**Returns:**

View File

@@ -14,8 +14,60 @@ interface BladeburnerRankRequirement
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [bladeburnerRank](./bitburner.bladeburnerrankrequirement.bladeburnerrank.md) | | number | |
| [type](./bitburner.bladeburnerrankrequirement.type.md) | | "bladeburnerRank" | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[bladeburnerRank](./bitburner.bladeburnerrankrequirement.bladeburnerrank.md)
</td><td>
</td><td>
number
</td><td>
</td></tr>
<tr><td>
[type](./bitburner.bladeburnerrankrequirement.type.md)
</td><td>
</td><td>
"bladeburnerRank"
</td><td>
</td></tr>
</tbody></table>

View File

@@ -0,0 +1,16 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [CacheResult](./bitburner.cacheresult.md)
## CacheResult type
**Signature:**
```typescript
export type CacheResult = {
success: boolean;
message: string;
karmaLoss: number;
};
```

View File

@@ -14,8 +14,60 @@ interface CityRequirement
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [city](./bitburner.cityrequirement.city.md) | | [CityName](./bitburner.cityname.md) | |
| [type](./bitburner.cityrequirement.type.md) | | "city" | |
<table><thead><tr><th>
Property
</th><th>
Modifiers
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
[city](./bitburner.cityrequirement.city.md)
</td><td>
</td><td>
[CityName](./bitburner.cityname.md)
</td><td>
</td></tr>
<tr><td>
[type](./bitburner.cityrequirement.type.md)
</td><td>
</td><td>
"city"
</td><td>
</td></tr>
</tbody></table>

View File

@@ -0,0 +1,64 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Cloud](./bitburner.cloud.md) &gt; [deleteServer](./bitburner.cloud.deleteserver.md)
## Cloud.deleteServer() method
Delete a cloud server.
**Signature:**
```typescript
deleteServer(host: string): boolean;
```
## Parameters
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
host
</td><td>
string
</td><td>
Hostname/IP of the cloud server to delete.
</td></tr>
</tbody></table>
**Returns:**
boolean
True if successful, and false otherwise.
## Remarks
RAM cost: 2.25 GB
Deletes one of your cloud servers, which is specified by its hostname/ip.
The host argument can be any data type, but it will be converted to a string. Whitespace is automatically removed from the string. This function will not delete a cloud server that still has scripts running on it.

View File

@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Cloud](./bitburner.cloud.md) &gt; [getRamLimit](./bitburner.cloud.getramlimit.md)
## Cloud.getRamLimit() method
Returns the maximum RAM that a cloud server can have.
**Signature:**
```typescript
getRamLimit(): number;
```
**Returns:**
number
Returns the maximum RAM (in GB) that a cloud server can have.
## Remarks
RAM cost: 0.05 GB

View File

@@ -0,0 +1,71 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Cloud](./bitburner.cloud.md) &gt; [getServerCost](./bitburner.cloud.getservercost.md)
## Cloud.getServerCost() method
Get cost of purchasing a cloud server.
**Signature:**
```typescript
getServerCost(ram: number): number;
```
## Parameters
<table><thead><tr><th>
Parameter
</th><th>
Type
</th><th>
Description
</th></tr></thead>
<tbody><tr><td>
ram
</td><td>
number
</td><td>
Amount of RAM of a potential cloud server, in GB. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20).
</td></tr>
</tbody></table>
**Returns:**
number
The cost to purchase a cloud server with the specified amount of ram, or returns Infinity if ram is not a valid amount.
## Remarks
RAM cost: 0.25 GB
Returns the cost to purchase a cloud server with the specified amount of ram.
## Example
```js
const ram = 2 ** 20;
const cost = ns.cloud.getServerCost(ram);
ns.tprint(`A cloud server with ${ns.format.ram(ram)} costs $${ns.format.number(cost)}`);
```

Some files were not shown because too many files have changed in this diff Show More