Compare commits
1 Commits
develop
...
laptop-bac
Author | SHA1 | Date | |
---|---|---|---|
ff4cc47e60 |
30
.github/issue_template/bug.md
vendored
30
.github/issue_template/bug.md
vendored
@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
name: "Bug report"
|
|
||||||
about: "Encountered an issue"
|
|
||||||
ref: "develop"
|
|
||||||
labels:
|
|
||||||
- Type/Bug
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Bug Report
|
|
||||||
<!-- Description of problem -->
|
|
||||||
I tried to ...
|
|
||||||
|
|
||||||
But instead ...
|
|
||||||
|
|
||||||
## Steps to Reproduce
|
|
||||||
<!-- How can developers replicate & test the problem? -->
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
## Logs
|
|
||||||
<!-- Any logs that accompenied the error -->
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
<!-- Screenshots (annoted if possible) of the problem -->
|
|
22
.github/issue_template/enhancement.md
vendored
22
.github/issue_template/enhancement.md
vendored
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
name: "Enhancement"
|
|
||||||
about: "Request a feature"
|
|
||||||
ref: "develop"
|
|
||||||
labels:
|
|
||||||
- Type/Enhancement
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Feature Request
|
|
||||||
<!-- Detailed description -->
|
|
||||||
...
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
<!-- Bullet list of requirments -->
|
|
||||||
1. ...
|
|
||||||
2. ...
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
<!-- Any additional considerations, solutions or design choices -->
|
|
||||||
...
|
|
14
.github/pull_request_template.md
vendored
14
.github/pull_request_template.md
vendored
@ -1,14 +0,0 @@
|
|||||||
## Description
|
|
||||||
<!-- Adition information & context -->
|
|
||||||
...
|
|
||||||
|
|
||||||
## Issues
|
|
||||||
<!-- Issues this PR will address -->
|
|
||||||
- closes #___
|
|
||||||
- owner/repo#___
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
<!-- Compelte after creating PR -->
|
|
||||||
- [ ] Linked issues
|
|
||||||
- [ ] Reviewed changes
|
|
||||||
- [ ] Updated comments/documentation
|
|
7
LICENSE
7
LICENSE
@ -1,7 +0,0 @@
|
|||||||
Copyright (c) 2023 Zakary Timson
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
916
README.md
916
README.md
@ -1,505 +1,411 @@
|
|||||||
<!-- Header -->
|
# BitBurner - Scripts
|
||||||
<div id="top" align="center">
|
A collection of scripts & information pertaining to the [open source](https://github.com/danielyxie/bitburner) game
|
||||||
<br />
|
[BitBurner](https://danielyxie.github.io/bitburner/).
|
||||||
|
|
||||||
<!-- Logo -->
|
## Table of Contents
|
||||||
<img src="https://git.zakscode.com/repo-avatars/9b25b57330ba3a1d9da80dad4051be68373e52c4bfffc6f6ba9e89f7392f5f7d" alt="Logo" width="200" height="200">
|
- [BitBurner - Scripts](#bitburner-scripts)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
<!-- Title -->
|
- [Quick Start](#quick-start)
|
||||||
### Bitburner
|
- [Guide](#guide)
|
||||||
|
- [BitNode 1](#bitnode-1)
|
||||||
<!-- Description -->
|
- [Scripts](#scripts)
|
||||||
Collection of Bitburner scipts
|
- [banner.js](#bannerjs)
|
||||||
|
- [botnet-manager.js (WIP)](#botnet-managerjs-wip)
|
||||||
<!-- Repo badges -->
|
- [connect.js](#connectjs)
|
||||||
[![Version](https://img.shields.io/badge/dynamic/json.svg?label=Version&style=for-the-badge&url=https://git.zakscode.com/api/v1/repos/ztimson/bitburner/tags&query=$[0].name)](https://git.zakscode.com/ztimson/bitburner/tags)
|
- [copy.js](#copyjs)
|
||||||
[![Pull Requests](https://img.shields.io/badge/dynamic/json.svg?label=Pull%20Requests&style=for-the-badge&url=https://git.zakscode.com/api/v1/repos/ztimson/bitburner&query=open_pr_counter)](https://git.zakscode.com/ztimson/bitburner/pulls)
|
- [crawler.js](#crawlerjs)
|
||||||
[![Issues](https://img.shields.io/badge/dynamic/json.svg?label=Issues&style=for-the-badge&url=https://git.zakscode.com/api/v1/repos/ztimson/bitburner&query=open_issues_count)](https://git.zakscode.com/ztimson/bitburner/issues)
|
- [find-target.js](#find-targetjs)
|
||||||
|
- [hacknet-manager.js](#hacknet-managerjs)
|
||||||
<!-- Links -->
|
- [miner.js](#minerjs)
|
||||||
|
- [network-graph.js](#network-graphjs)
|
||||||
---
|
- [rm.js](#rmjs)
|
||||||
<div>
|
- [rootkit.js](#rootkitjs)
|
||||||
<a href="https://git.zakscode.com/ztimson/bitburner/releases" target="_blank">Release Notes</a>
|
- [server-manager.js](#server-managerjs)
|
||||||
• <a href="https://git.zakscode.com/ztimson/bitburner/issues/new?template=.github%2fissue_template%2fbug.md" target="_blank">Report a Bug</a>
|
- [update.js](#updatejs)
|
||||||
• <a href="https://git.zakscode.com/ztimson/bitburner/issues/new?template=.github%2fissue_template%2fenhancement.md" target="_blank">Request a Feature</a>
|
|
||||||
</div>
|
## Quick Start
|
||||||
|
|
||||||
---
|
```bash
|
||||||
</div>
|
# Download the update script in-game & run it
|
||||||
|
wget https://gitlab.zakscode.com/ztimson/BitBurner/-/raw/develop/scripts/update.js scripts/update.js
|
||||||
## Table of Contents
|
run scripts/update.js # Repeat to pull the latest
|
||||||
- [Bitburner](#top)
|
|
||||||
- [About](#about)
|
# View the network
|
||||||
- [Built With](#built-with)
|
run scripts/network-graph.js --verbose
|
||||||
- [Quick Start](#qiuck-start)
|
run scripts/netowkr-graph.js -v --filter CSEC # Find path to a specific device
|
||||||
- [Scripts](#scripts)
|
|
||||||
- [banner.js](#banner)
|
# Start the node manager in auto-mode
|
||||||
- [botnet-manager.js (WIP)](#botnet)
|
run scripts/node-manager.js -a
|
||||||
- [connect.js](#connect)
|
|
||||||
- [copy.js](#copy)
|
# Chain the crawler & rootkit to root all devices on the network
|
||||||
- [crawler.js](#crawler)
|
run scripts/crawler.js --not-rooted /scripts/rootkit.js {{TARGET}}
|
||||||
- [find-target.js](#find-target)
|
|
||||||
- [hacknet-manager.js](#hacknet)
|
# Find the most profitable server & use the crawler to deploy miners on the network targeting it
|
||||||
- [miner.js](#miner)
|
run scripts/find-target.js # Output: n00dles
|
||||||
- [network-graph.js](#network-graph)
|
run scriipts/crawler.js --rooted --remote-exec /scripts/miner.js n00dles
|
||||||
- [rm.js](#rm)
|
|
||||||
- [rootkit.js](#rootkit)
|
# Install backdoor on CSEC
|
||||||
- [server-manager.js](#server-manager)
|
run scripts/rootkit.js CSEC
|
||||||
- [update.js](#update)
|
run scripts/connect.js CSEC
|
||||||
- [License](#license)
|
backdoor
|
||||||
|
```
|
||||||
## About
|
|
||||||
A collection of scripts & information pertaining to the [open source](https://github.com/danielyxie/bitburner) game [Bitburner](https://danielyxie.github.io/bitburner/)
|
Learn more about the [available scripts](#scripts) bellow or pass the `--help` flag to any of the included scripts in-game.
|
||||||
|
|
||||||
### Built with
|
## Guide
|
||||||
[![JavaScript](https://img.shields.io/badge/JavaScript-000000?style=for-the-badge&logo=javascript)](https://javascript.com/)
|
This guide documents how you can use this repository to progress through the game. You should complete the tutorial
|
||||||
|
first if you haven't already.
|
||||||
## Quick Start
|
|
||||||
|
### BitNode 1
|
||||||
```bash
|
1. First you need to download this repo into the game. Manually download `update.js` & run it:
|
||||||
# Download the update script in-game & run it
|
`wget https://gitlab.zakscode.com/ztimson/BitBurner/-/raw/develop/scripts/update.js scripts/update.js; run scripts/update.js`
|
||||||
wget https://gitlab.zakscode.com/ztimson/Bitburner/-/raw/develop/scripts/update.js scripts/update.js
|
2. Scan the network to figure out your bearings, take note of discovered server's required hack level:
|
||||||
run scripts/update.js # Repeat to pull the latest
|
`run scripts/network-graph.js -vd 3`
|
||||||
|
3. Root the lowest level server (probably n00dles) & make it hack itself for money. You should repeat this step when
|
||||||
# View the network
|
ever your hack level is high enough to hack another a new server. `run scripts/rootkit.js n00dles /scripts/miner.js`
|
||||||
run scripts/network-graph.js --verbose
|
4. Start `hacknet-manger.js`. You won't have enough *RAM* in the beginning to run the manager & hack servers. It's
|
||||||
run scripts/netowkr-graph.js -v --filter CSEC # Find path to a specific device
|
recommended you `tail` the manager, so you can easily start/stop it as needed. `run script/hacknet-manager.js -a`
|
||||||
|
5. Once you have enough money ($??,???.??), upgrade your home severs *RAM*:
|
||||||
# Start the node manager in auto-mode
|
`City > alpha ent. > Upgrade 'home' RAM (8.00GB -> 16.00GB)`
|
||||||
run scripts/node-manager.js -a
|
6. At this point you have enough *RAM* to use `crawler.js` to automatically discover servers & hack them. Continue to
|
||||||
|
run this periodically as your hack level increases & you unlock more exploits:
|
||||||
# Chain the crawler & rootkit to root all devices on the network
|
`run scripts/crawler.js -n /scripts/rootkit.js {{TARGET}} /scripts/miner.js`
|
||||||
run scripts/crawler.js --not-rooted /scripts/rootkit.js {{TARGET}}
|
|
||||||
|
## Scripts
|
||||||
# Find the most profitable server & use the crawler to deploy miners on the network targeting it
|
|
||||||
run scripts/find-target.js # Output: n00dles
|
### [banner.js](./scripts/banner.js)
|
||||||
run scriipts/crawler.js --rooted --remote-exec /scripts/miner.js n00dles
|
**RAM:** 1.60 GB
|
||||||
|
|
||||||
# Install backdoor on CSEC
|
Aesthetic & serves no real purpose. Prints a banner to the terminal & can repeat after game restarts.
|
||||||
run scripts/rootkit.js CSEC
|
```
|
||||||
run scripts/connect.js CSEC
|
[home ~/]> run scripts/banner.js --help
|
||||||
backdoor
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
```
|
/scripts/banner.js:
|
||||||
|
|
||||||
## Scripts
|
Display an ASCII banner.
|
||||||
|
|
||||||
<details>
|
Usage: run banner.js [OPTIONS]
|
||||||
<summary>
|
run banner.js --help
|
||||||
<h3 id="banner" style="display: inline">banner.js</h3>
|
|
||||||
</summary>
|
Options:
|
||||||
<br />
|
-r, --reboot Automatically display after game reboots
|
||||||
|
-h, --help Display this help message
|
||||||
**RAM:** 1.60 GB | [Code](./src/banner.js)
|
```
|
||||||
|
|
||||||
Aesthetic & serves no real purpose. Prints a banner to the terminal & can repeat after game restarts.
|
### [botnet-manager.js (WIP)](./scripts/botnet-manager.js)
|
||||||
```
|
**RAM:** 7.15 GB
|
||||||
[home ~/]> run scripts/banner.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
Late-game solution to hack servers. It orchestrates an unlimited number of servers to carry out distributed batched
|
||||||
/scripts/banner.js:
|
attacks against targets. It includes a bunch of utilities to quickly dispatch single commands to all workers. Manger
|
||||||
|
can be tailed for live updates.
|
||||||
Display an ASCII banner.
|
```
|
||||||
|
[home ~/]> run /scripts/botnet-manager.js --help
|
||||||
Usage: run banner.js [OPTIONS]
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
run banner.js --help
|
/scripts/botnet-manager.js:
|
||||||
|
|
||||||
Options:
|
Connect & manage a network of devices to launch distributed attacks.
|
||||||
-r, --reboot Automatically display after game reboots
|
|
||||||
-h, --help Display this help message
|
Usage: run botnet-manager.js [OPTIONS]
|
||||||
```
|
run botnet-manager.js [OPTIONS] COMMAND
|
||||||
</details>
|
run botnet-manager.js --help [COMMAND]
|
||||||
|
|
||||||
<details>
|
Options:
|
||||||
<summary>
|
-s, --silent Suppress program output
|
||||||
<h3 id="botnet" style="display: inline">botnet-manager.js (WIP)</h3>
|
-h, --help Display this help message
|
||||||
</summary>
|
|
||||||
<br />
|
Commands:
|
||||||
|
copy Copy file & dependencies to swarm nodes
|
||||||
**RAM:** 7.15 GB | [Code](./scripts/botnet-manager.js)
|
join Connect device as a worker node to the swarm
|
||||||
|
kill Kill any scripts running on worker nodes
|
||||||
Late-game solution to hack servers. It orchestrates an unlimited number of servers to carry out distributed batched
|
leave Disconnect worker node from swarm
|
||||||
attacks against targets. It includes a bunch of utilities to quickly dispatch single commands to all workers. Manger
|
run Copy & run script on all worker nodes
|
||||||
can be tailed for live updates.
|
start Start this device as the swarm manager
|
||||||
```
|
```
|
||||||
[home ~/]> run /scripts/botnet-manager.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
### [connect.js](./scripts/connect.js)
|
||||||
/scripts/botnet-manager.js:
|
**RAM:** 1.85 GB
|
||||||
|
|
||||||
Connect & manage a network of devices to launch distributed attacks.
|
The built in `connect` command only allows you to connect to devices in the immediate vicinity or servers that have
|
||||||
|
backdoors installed requiring you to make several jumps. This script will automatically find a path & connect you saving
|
||||||
Usage: run botnet-manager.js [OPTIONS]
|
you some time.
|
||||||
run botnet-manager.js [OPTIONS] COMMAND
|
```
|
||||||
run botnet-manager.js --help [COMMAND]
|
[home ~/]> run /scripts/connect.js --help
|
||||||
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
Options:
|
/scripts/connect.js:
|
||||||
-s, --silent Suppress program output
|
|
||||||
-h, --help Display this help message
|
Connect to a server anywhere in the network without a backdoor.
|
||||||
|
|
||||||
Commands:
|
Usage: run connect.js [OPTIONS] SERVER
|
||||||
copy Copy file & dependencies to swarm nodes
|
run connect.js --help
|
||||||
join Connect device as a worker node to the swarm
|
|
||||||
kill Kill any scripts running on worker nodes
|
SERVER Server to connect to
|
||||||
leave Disconnect worker node from swarm
|
|
||||||
run Copy & run script on all worker nodes
|
Options:
|
||||||
start Start this device as the swarm manager
|
-h, --help Display this help message
|
||||||
```
|
```
|
||||||
</details>
|
|
||||||
|
### [copy.js](./scripts/copy.js)
|
||||||
<details>
|
**RAM:** 4.20 GB
|
||||||
<summary>
|
|
||||||
<h3 id="connect" style="display: inline">connect.js</h3>
|
Scripts often import other scripts requiring multiple `scp` calls before it can be run on a remote machine. This script
|
||||||
</summary>
|
will automatically scan the file being copied for imports & recursively scan & copy the dependencies. Plus it has a
|
||||||
<br />
|
fancy animated loading bar.
|
||||||
|
```
|
||||||
**RAM:** 1.85 GB | [Code](./scripts/connect.js)
|
[home ~/]> run scripts/copy.js --help
|
||||||
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
The built in `connect` command only allows you to connect to devices in the immediate vicinity or servers that have
|
/scripts/copy.js:
|
||||||
backdoors installed requiring you to make several jumps. This script will automatically find a path & connect you saving
|
|
||||||
you some time.
|
Copy a file & it's dependencies to a server.
|
||||||
```
|
|
||||||
[home ~/]> run /scripts/connect.js --help
|
Usage: run copy.js [OPTIONS] FILE SERVER [ARGS]...
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
run copy.js --help
|
||||||
/scripts/connect.js:
|
|
||||||
|
FILE File to copy
|
||||||
Connect to a server anywhere in the network without a backdoor.
|
SERVER Server to copy file(s) to
|
||||||
|
ARGS Arguments to start file/script with
|
||||||
Usage: run connect.js [OPTIONS] SERVER
|
|
||||||
run connect.js --help
|
Options:
|
||||||
|
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
||||||
SERVER Server to connect to
|
-e, --execute Start script after copying
|
||||||
|
-n, --no-deps Skip copying dependencies
|
||||||
Options:
|
-q, --quite Suppress program output
|
||||||
-h, --help Display this help message
|
-h, --help Display this help message
|
||||||
```
|
```
|
||||||
</details>
|
|
||||||
|
### [crawler.js](./scripts/crawler.js)
|
||||||
<details>
|
**RAM:** 5.80 GB
|
||||||
<summary>
|
|
||||||
<h3 id="copy" style="display: inline">copy.js</h3>
|
Mid-game solution to distribute & run scripts across the network.
|
||||||
</summary>
|
```
|
||||||
<br />
|
[home ~/]> run scripts/crawler.js --help
|
||||||
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
**RAM:** 4.20 GB | [Code](./scripts/copy.js)
|
/scripts/crawler.js:
|
||||||
|
|
||||||
Scripts often import other scripts requiring multiple `scp` calls before it can be run on a remote machine. This script
|
Search the network for servers to execute a script against.
|
||||||
will automatically scan the file being copied for imports & recursively scan & copy the dependencies. Plus it has a
|
|
||||||
fancy animated loading bar.
|
Usage: run crawler.js [OPTIONS] SCRIPT [ARGS]...
|
||||||
```
|
run crawler.js --help
|
||||||
[home ~/]> run scripts/copy.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
SCRIPT Script to copy & execute
|
||||||
/scripts/copy.js:
|
ARGS Arguments for script. Forward the discovered server with: {{SERVER}}
|
||||||
|
|
||||||
Copy a file & it's dependencies to a server.
|
Options:
|
||||||
|
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
||||||
Usage: run copy.js [OPTIONS] FILE SERVER [ARGS]...
|
-d, --depth Depth to scan to, defaults to 3
|
||||||
run copy.js --help
|
-k, --kill Kill all running scripts on the server
|
||||||
|
--level Skip servers with higher hack level, defaults to current hack level
|
||||||
FILE File to copy
|
-e, --remote-exec Execute script on remote server
|
||||||
SERVER Server to copy file(s) to
|
-r, --rooted Only servers that have been rooted
|
||||||
ARGS Arguments to start file/script with
|
-n, --not-rooted Only servers that have not been rooted
|
||||||
|
-p, --ports Skip servers with too many closed ports
|
||||||
Options:
|
-q, --quite Suppress program output
|
||||||
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
-v, --verbose Display the server names in the final report
|
||||||
-e, --execute Start script after copying
|
-h, --help Display this help message
|
||||||
-n, --no-deps Skip copying dependencies
|
```
|
||||||
-q, --quite Suppress program output
|
|
||||||
-h, --help Display this help message
|
### [find-target.js](./scripts/find-target.js)
|
||||||
```
|
**RAM:** 4.05 GB
|
||||||
</details>
|
|
||||||
|
A utility to help figure out which server is worth hacking the most. It does this by estimating the financial yield per
|
||||||
<details>
|
minute for each server & returns the servers in a sorted list.
|
||||||
<summary>
|
```
|
||||||
<h3 id="crawler" style="display: inline">crawler.js</h3>
|
[home ~/]> run scripts/find-target.js --help
|
||||||
</summary>
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
<br />
|
/scripts/find-target.js:
|
||||||
|
|
||||||
**RAM:** 5.80 GB | [Code](./scripts/crawler.js)
|
Scan the network for the best servers(s) to hack.
|
||||||
|
|
||||||
Mid-game solution to distribute & run scripts across the network.
|
Usage: run find-target.js [OPTIONS]
|
||||||
```
|
run find-target.js --help
|
||||||
[home ~/]> run scripts/crawler.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
Options:
|
||||||
/scripts/crawler.js:
|
-c, --count Number of servers to return
|
||||||
|
-r, --rooted Only servers that have been rooted
|
||||||
Search the network for servers to execute a script against.
|
-n, --not-rooted Only servers that have not been rooted
|
||||||
|
-v, --verbose Display the estimated income per minute per core
|
||||||
Usage: run crawler.js [OPTIONS] SCRIPT [ARGS]...
|
-h, --help Display this help message
|
||||||
run crawler.js --help
|
```
|
||||||
|
|
||||||
SCRIPT Script to copy & execute
|
### [hacknet-manager.js](./scripts/hacknet-manager.js)
|
||||||
ARGS Arguments for script. Forward the discovered server with: {{SERVER}}
|
**RAM:** 5.70 GB
|
||||||
|
|
||||||
Options:
|
An early game solution to automate the hacknet & get easy money.
|
||||||
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
```
|
||||||
-d, --depth Depth to scan to, defaults to 3
|
[home ~/]> run scripts/hacknet-manager.js --help
|
||||||
-k, --kill Kill all running scripts on the server
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
--level Skip servers with higher hack level, defaults to current hack level
|
/scripts/hacknet-manager.js:
|
||||||
-e, --remote-exec Execute script on remote server
|
|
||||||
-r, --rooted Only servers that have been rooted
|
Buy, upgrade & manage Hacknet nodes automatically. Tail for live updates.
|
||||||
-n, --not-rooted Only servers that have not been rooted
|
|
||||||
-p, --ports Skip servers with too many closed ports
|
Usage: run hacknet-manager.js [OPTIONS] [LIMIT]
|
||||||
-q, --quite Suppress program output
|
run hacknet-manager.js --help
|
||||||
-v, --verbose Display the server names in the final report
|
|
||||||
-h, --help Display this help message
|
LIMIT Limit the number of nodes the manager will buy, defaults to 8 or the current number of nodes
|
||||||
```
|
|
||||||
</details>
|
Options:
|
||||||
|
-a, --auto-limit Automatically increase the node limit when there is nothing to do
|
||||||
<details>
|
-b, --balance Prevent spending bellow point
|
||||||
<summary>
|
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
||||||
<h3 id="find-target" style="display: inline">find-target.js</h3>
|
-h, --help Display this help message
|
||||||
</summary>
|
```
|
||||||
<br />
|
|
||||||
|
### [miner.js](./scripts/miner.js)
|
||||||
**RAM:** 4.05 GB | [Code](./scripts/find-target.js)
|
**RAM:** 2.45 GB
|
||||||
|
|
||||||
A utility to help figure out which server is worth hacking the most. It does this by estimating the financial yield per
|
An early-game HGW script to steal money from servers. You can deploy this on each server and have them hack themselves,
|
||||||
minute for each server & returns the servers in a sorted list.
|
or they can all target the server with the most money which is more efficient (see [find-target.js](#find-targetjs)).
|
||||||
```
|
```
|
||||||
[home ~/]> run scripts/find-target.js --help
|
[home ~/]> run scripts/miner.js --help
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
/scripts/find-target.js:
|
/scripts/miner.js:
|
||||||
|
|
||||||
Scan the network for the best servers(s) to hack.
|
Buy, upgrade & manage Hacknet nodes automatically. Tail for live updates.
|
||||||
|
|
||||||
Usage: run find-target.js [OPTIONS]
|
Usage: run hacknet-manager.js [OPTIONS] [LIMIT]
|
||||||
run find-target.js --help
|
run hacknet-manager.js --help
|
||||||
|
|
||||||
Options:
|
LIMIT Limit the number of nodes the manager will buy, defaults to 8 or the current number of nodes
|
||||||
-c, --count Number of servers to return
|
|
||||||
-r, --rooted Only servers that have been rooted
|
Options:
|
||||||
-n, --not-rooted Only servers that have not been rooted
|
-a, --auto-limit Automatically increase the node limit when there is nothing to do
|
||||||
-v, --verbose Display the estimated income per minute per core
|
-b, --balance Prevent spending bellow point
|
||||||
-h, --help Display this help message
|
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
||||||
```
|
-h, --help Display this help message
|
||||||
</details>
|
```
|
||||||
|
|
||||||
<details>
|
### [network-graph.js](./scripts/network-graph.js)
|
||||||
<summary>
|
**RAM:** 3.85 GB
|
||||||
<h3 id="hacknet" style="display: inline">hacknet-manager.js</h3>
|
|
||||||
</summary>
|
A utility to scan the network & build a visual tree of all the devices. It comes with lots of flags to narrow down the
|
||||||
<br />
|
results. It's useful for figuring out where you are, manually finding targets & discovering the path to a server &
|
||||||
|
connecting to it.
|
||||||
**RAM:** 5.70 GB | [Code](./scripts/hacknet-manager.js)
|
```
|
||||||
|
[home ~/]> run /scripts/network-graph.js --help
|
||||||
An early game solution to automate the hacknet & get easy money.
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
```
|
/scripts/network-graph.js:
|
||||||
[home ~/]> run scripts/hacknet-manager.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
Scan the network for servers and display as an ASCII tree. Servers with root access are highlighted & bold. Click to
|
||||||
/scripts/hacknet-manager.js:
|
automatically connect.
|
||||||
|
|
||||||
Buy, upgrade & manage Hacknet nodes automatically. Tail for live updates.
|
Usage: run network-graph.js [OPTIONS] [SERVER]
|
||||||
|
run network-graph.js --help
|
||||||
Usage: run hacknet-manager.js [OPTIONS] [LIMIT]
|
|
||||||
run hacknet-manager.js --help
|
SERVER Point to start scan from, defaults to local server
|
||||||
|
|
||||||
LIMIT Limit the number of nodes the manager will buy, defaults to 8 or the current number of nodes
|
Options:
|
||||||
|
-d, --depth Depth to scan to
|
||||||
Options:
|
-f, --filter Filter to servers matching name
|
||||||
-a, --auto-limit Automatically increase the node limit when there is nothing to do
|
-e, --regex Filter to servers matching pattern
|
||||||
-b, --balance Prevent spending bellow point
|
-l, --level Display the required hack level & number of ports to root: [level|port]
|
||||||
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
-n, --not-rooted Filter to servers that have not been rooted
|
||||||
-h, --help Display this help message
|
-r, --rooted Filter to servers that have been rooted
|
||||||
```
|
-s, --specs Display the server specifications: {CPU|RAM}
|
||||||
</details>
|
-u, --usage Display the server utilization: (USG%)
|
||||||
|
-v, --verbose Display level, specs & usage in that order: [HL|P] {CPU|RAM} (USG%)
|
||||||
<details>
|
-h, --help Display this help message
|
||||||
<summary>
|
```
|
||||||
<h3 id="miner" style="display: inline">miner.js</h3>
|
|
||||||
</summary>
|
### [rm.js](./scripts/rm.js)
|
||||||
<br />
|
**RAM:** 2.85 GB
|
||||||
|
|
||||||
**RAM:** 2.45 GB | [Code](./scripts/miner.js)
|
[BitBurner-Connector](https://plugins.jetbrains.com/plugin/18338-bitburner-connector) would occasionally push my IDE
|
||||||
|
files to the game, so I created this simple script to recursively search & delete files from a directory to save me
|
||||||
An early-game HGW script to steal money from servers. You can deploy this on each server and have them hack themselves,
|
from having to delete files one-by-one.
|
||||||
or they can all target the server with the most money which is more efficient (see [find-target.js](#find-target)).
|
```
|
||||||
```
|
[home ~/scripts]> run /scripts/rm.js --help
|
||||||
[home ~/]> run scripts/miner.js --help
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
/scripts/rm.js:
|
||||||
/scripts/miner.js:
|
|
||||||
|
Recursively delete files inside a directory
|
||||||
Buy, upgrade & manage Hacknet nodes automatically. Tail for live updates.
|
|
||||||
|
Usage: run rm.js [OPTIONS] PATH [SERVER]
|
||||||
Usage: run hacknet-manager.js [OPTIONS] [LIMIT]
|
run rm.js --help
|
||||||
run hacknet-manager.js --help
|
|
||||||
|
PATH Path to recursively search
|
||||||
LIMIT Limit the number of nodes the manager will buy, defaults to 8 or the current number of nodes
|
SERVER Run on remote server
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-a, --auto-limit Automatically increase the node limit when there is nothing to do
|
-f, --force Remove game files (.exe, .lit, .msg)
|
||||||
-b, --balance Prevent spending bellow point
|
-r, --recursive Delete everything inside directory
|
||||||
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
-h, --help Display this help message
|
||||||
-h, --help Display this help message
|
```
|
||||||
```
|
|
||||||
</details>
|
### [rootkit.js](./scripts/rootkit.js)
|
||||||
|
**RAM:** 4.65 GB
|
||||||
<details>
|
|
||||||
<summary>
|
Automatically gains root on the local or remote server. A script can be passed as an additional argument; it will be
|
||||||
<h3 id="network-graph" style="display: inline">network-graph.js</h3>
|
copied and automatically executed with the maximum number of threads after being rooted.
|
||||||
</summary>
|
```
|
||||||
<br />
|
[home ~/]> run scripts/rootkit.js --help
|
||||||
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
**RAM:** 3.85 GB | [Code](./scripts/network-graph.js)
|
/scripts/rootkit.js:
|
||||||
|
|
||||||
A utility to scan the network & build a visual tree of all the devices. It comes with lots of flags to narrow down the
|
Scan the network for servers and display as an ASCII tree. Servers with root access are highlighted & bold.
|
||||||
results. It's useful for figuring out where you are, manually finding targets & discovering the path to a server &
|
|
||||||
connecting to it.
|
Usage: run network-graph.js [OPTIONS] [SERVER]
|
||||||
```
|
run network-graph.js --help
|
||||||
[home ~/]> run /scripts/network-graph.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
SERVER Point to start scan from, defaults to local server
|
||||||
/scripts/network-graph.js:
|
|
||||||
|
Options:
|
||||||
Scan the network for servers and display as an ASCII tree. Servers with root access are highlighted & bold. Click to
|
-d, --depth Depth to scan to
|
||||||
automatically connect.
|
-f, --filter Filter to servers matching name
|
||||||
|
-e, --regex Filter to servers matching pattern
|
||||||
Usage: run network-graph.js [OPTIONS] [SERVER]
|
-l, --level Display the required hack level & number of ports to root: [level|port]
|
||||||
run network-graph.js --help
|
-n, --not-rooted Filter to servers that have not been rooted
|
||||||
|
-r, --rooted Filter to servers that have been rooted
|
||||||
SERVER Point to start scan from, defaults to local server
|
-s, --specs Display the server specifications: {CPU|RAM}
|
||||||
|
-u, --usage Display the server utilization: (USG%)
|
||||||
Options:
|
-v, --verbose Display level, specs & usage in that order: [HL|P] {CPU|RAM} (USG%)
|
||||||
-d, --depth Depth to scan to
|
-h, --help Display this help message
|
||||||
-f, --filter Filter to servers matching name
|
```
|
||||||
-e, --regex Filter to servers matching pattern
|
|
||||||
-l, --level Display the required hack level & number of ports to root: [level|port]
|
### [server-manager.js](./scripts/server-manager.js)
|
||||||
-n, --not-rooted Filter to servers that have not been rooted
|
**RAM:** 11.35 GB
|
||||||
-r, --rooted Filter to servers that have been rooted
|
|
||||||
-s, --specs Display the server specifications: {CPU|RAM}
|
Mid-game script to handle purchasing and upgrading servers for more computer power. You can also set a script to run
|
||||||
-u, --usage Display the server utilization: (USG%)
|
automatically after purchase. Useful to chain with `miner.js` or `botnet.js`.
|
||||||
-v, --verbose Display level, specs & usage in that order: [HL|P] {CPU|RAM} (USG%)
|
```
|
||||||
-h, --help Display this help message
|
[home ~/]> run /scripts/server-manager.js --help
|
||||||
```
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
</details>
|
/scripts/server-manager.js:
|
||||||
|
|
||||||
<details>
|
Automate the buying & upgrading of servers. Automatically starts script after purchase. Tail for live updates.
|
||||||
<summary>
|
|
||||||
<h3 id="rm" style="display: inline">rm.js</h3>
|
Usage: run server-manager.js [OPTIONS] [SCRIPT] [ARGS]...
|
||||||
</summary>
|
run server-manager.js --help
|
||||||
<br />
|
|
||||||
|
SCRIPT Script to copy & execute
|
||||||
**RAM:** 2.85 GB | [Code](./scripts/rm.js)
|
ARGS Arguments for script. Forward the discovered server with: {{SERVER}}
|
||||||
|
|
||||||
[bitburner-connector](https://plugins.jetbrains.com/plugin/18338-bitburner-connector) would occasionally push my IDE
|
Options:
|
||||||
files to the game, so I created this simple script to recursively search & delete files from a directory to save me
|
-b, --balance Prevent spending bellow point
|
||||||
from having to delete files one-by-one.
|
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
||||||
```
|
-l, --limit Limit the number of servers that can be purchased, defaults to 25
|
||||||
[home ~/scripts]> run /scripts/rm.js --help
|
-r, --ram Amount of RAM to purchase new servers with, defaults to 8 GB
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
||||||
/scripts/rm.js:
|
-h, --help Display this help message
|
||||||
|
```
|
||||||
Recursively delete files inside a directory
|
|
||||||
|
### [update.js](./scripts/update.js)
|
||||||
Usage: run rm.js [OPTIONS] PATH [SERVER]
|
**RAM:** 2.65 GB
|
||||||
run rm.js --help
|
|
||||||
|
Uses the in-game `wget` to download all the scripts in this repository. Can target remote servers to quickly copy the
|
||||||
PATH Path to recursively search
|
entire toolkit to the target.
|
||||||
SERVER Run on remote server
|
```
|
||||||
|
[home ~/]> run scripts/update.js --help
|
||||||
Options:
|
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||||
-f, --force Remove game files (.exe, .lit, .msg)
|
/scripts/update.js:
|
||||||
-r, --recursive Delete everything inside directory
|
|
||||||
-h, --help Display this help message
|
Download the latest script updates from the repository using wget.
|
||||||
```
|
|
||||||
</details>
|
Usage: run update.js [OPTIONS] [DEVICE]
|
||||||
|
run update.js --help
|
||||||
<details>
|
|
||||||
<summary>
|
DEVICE Device to update, defaults to current machine
|
||||||
<h3 id="rootkit" style="display: inline">rootkit.js</h3>
|
|
||||||
</summary>
|
Options:
|
||||||
<br />
|
--skip-self Skip updating self (for debugging & used internally)
|
||||||
|
--no-banner Hide the banner (Used internally)
|
||||||
**RAM:** 4.65 GB | [Code](./scripts/rootkit.js)
|
-h, --help Display this help message
|
||||||
|
```
|
||||||
Automatically gains root on the local or remote server. A script can be passed as an additional argument; it will be
|
|
||||||
copied and automatically executed with the maximum number of threads after being rooted.
|
|
||||||
```
|
|
||||||
[home ~/]> run scripts/rootkit.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
|
||||||
/scripts/rootkit.js:
|
|
||||||
|
|
||||||
Scan the network for servers and display as an ASCII tree. Servers with root access are highlighted & bold.
|
|
||||||
|
|
||||||
Usage: run network-graph.js [OPTIONS] [SERVER]
|
|
||||||
run network-graph.js --help
|
|
||||||
|
|
||||||
SERVER Point to start scan from, defaults to local server
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-d, --depth Depth to scan to
|
|
||||||
-f, --filter Filter to servers matching name
|
|
||||||
-e, --regex Filter to servers matching pattern
|
|
||||||
-l, --level Display the required hack level & number of ports to root: [level|port]
|
|
||||||
-n, --not-rooted Filter to servers that have not been rooted
|
|
||||||
-r, --rooted Filter to servers that have been rooted
|
|
||||||
-s, --specs Display the server specifications: {CPU|RAM}
|
|
||||||
-u, --usage Display the server utilization: (USG%)
|
|
||||||
-v, --verbose Display level, specs & usage in that order: [HL|P] {CPU|RAM} (USG%)
|
|
||||||
-h, --help Display this help message
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>
|
|
||||||
<h3 id="server-miner" style="display: inline">server-miner.js</h3>
|
|
||||||
</summary>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
**RAM:** 11.35 GB | [Code](./scripts/server-manager.js)
|
|
||||||
|
|
||||||
Mid-game script to handle purchasing and upgrading servers for more computer power. You can also set a script to run
|
|
||||||
automatically after purchase. Useful to chain with `miner.js` or `botnet.js`.
|
|
||||||
```
|
|
||||||
[home ~/]> run /scripts/server-manager.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
|
||||||
/scripts/server-manager.js:
|
|
||||||
|
|
||||||
Automate the buying & upgrading of servers. Automatically starts script after purchase. Tail for live updates.
|
|
||||||
|
|
||||||
Usage: run server-manager.js [OPTIONS] [SCRIPT] [ARGS]...
|
|
||||||
run server-manager.js --help
|
|
||||||
|
|
||||||
SCRIPT Script to copy & execute
|
|
||||||
ARGS Arguments for script. Forward the discovered server with: {{SERVER}}
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-b, --balance Prevent spending bellow point
|
|
||||||
-c, --cpu Number of CPU threads to start script with, will use maximum if not specified
|
|
||||||
-l, --limit Limit the number of servers that can be purchased, defaults to 25
|
|
||||||
-r, --ram Amount of RAM to purchase new servers with, defaults to 8 GB
|
|
||||||
-s, --sleep Amount of time to wait between purchases, defaults to 1 (second)
|
|
||||||
-h, --help Display this help message
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>
|
|
||||||
<h3 id="update" style="display: inline">update.js</h3>
|
|
||||||
</summary>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
**RAM:** 2.65 GB | [Code](./scripts/update.js)
|
|
||||||
|
|
||||||
Uses the in-game `wget` to download all the scripts in this repository. Can target remote servers to quickly copy the
|
|
||||||
entire toolkit to the target.
|
|
||||||
```
|
|
||||||
[home ~/]> run scripts/update.js --help
|
|
||||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
|
||||||
/scripts/update.js:
|
|
||||||
|
|
||||||
Download the latest script updates from the repository using wget.
|
|
||||||
|
|
||||||
Usage: run update.js [OPTIONS] [DEVICE]
|
|
||||||
run update.js --help
|
|
||||||
|
|
||||||
DEVICE Device to update, defaults to current machine
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--skip-self Skip updating self (for debugging & used internally)
|
|
||||||
--no-banner Hide the banner (Used internally)
|
|
||||||
-h, --help Display this help message
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## License
|
|
||||||
Copyright © 2023 Zakary Timson | Available under MIT Licensing
|
|
||||||
|
|
||||||
See the [license](./LICENSE) for more information.
|
|
||||||
|
@ -1,49 +1,49 @@
|
|||||||
import {ArgParser} from "/scripts/lib/arg-parser";
|
import {ArgParser} from "/scripts/lib/arg-parser";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display an ASCII banner, optionally automatically after reboots.
|
* Display an ASCII banner, optionally automatically after reboots.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
*/
|
*/
|
||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
const argParser = new ArgParser('banner.js', 'Display an ASCII banner.', [
|
const argParser = new ArgParser('banner.js', 'Display an ASCII banner.', [
|
||||||
{name: 'reboot', desc: 'Automatically display after game reboots', flags: ['-r', '--reboot'], default: false}
|
{name: 'reboot', desc: 'Automatically display after game reboots', flags: ['-r', '--reboot'], default: false}
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args);
|
const args = argParser.parse(ns.args);
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
if(args['help'] || args['_error'].length)
|
if(args['help'] || args['_error'].length)
|
||||||
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
||||||
|
|
||||||
ns.tprint(`
|
ns.tprint(`
|
||||||
|
|
||||||
&&&&&&&& O &&&&&&&&
|
&&&&&&&& O &&&&&&&&
|
||||||
&&& & && CDDDD &&&&&&&&&&
|
&&& & && CDDDD &&&&&&&&&&
|
||||||
&&&& &&& && &&& &&&&&&&&&&&&&
|
&&&& &&& && &&& &&&&&&&&&&&&&
|
||||||
&&&&& && && & .&&&. &&&&&&&&&&&&&&
|
&&&&& && && & .&&&. &&&&&&&&&&&&&&
|
||||||
&&&&&&&&&& && && &&&&& &&&&&&&&&&&&&&&
|
&&&&&&&&&& && && &&&&& &&&&&&&&&&&&&&&
|
||||||
&&&&&&&& && & &&&&& &&&&&&&&&&&&&&&&
|
&&&&&&&& && & &&&&& &&&&&&&&&&&&&&&&
|
||||||
&&&&&&&&&& &&& &&&&& &&&&&&&&&&&&&&&&
|
&&&&&&&&&& &&& &&&&& &&&&&&&&&&&&&&&&
|
||||||
&&&&&&&&&&&&&&&& *&&&* *&&&&&&&&&&&&&&&
|
&&&&&&&&&&&&&&&& *&&&* *&&&&&&&&&&&&&&&
|
||||||
&&&&&&&&&&&&& &&&&&&&&& *&&&&&&* .&&
|
&&&&&&&&&&&&& &&&&&&&&& *&&&&&&* .&&
|
||||||
&&&&&&&&&&& &&& & & &&& &&* .&&&
|
&&&&&&&&&&& &&& & & &&& &&* .&&&
|
||||||
&&&&&&&&&& & & ,,,,,* .&&&&
|
&&&&&&&&&& & & ,,,,,* .&&&&
|
||||||
&&&&& & & &&&&&&&&&&&&&&&&
|
&&&&& & & &&&&&&&&&&&&&&&&
|
||||||
&& &&&& & & & &&&&&&&&&&&&&&
|
&& &&&& & & & &&&&&&&&&&&&&&
|
||||||
&& &&&&&&& & & & &&&&&* &&&&&
|
&& &&&&&&& & & & &&&&&* &&&&&
|
||||||
&& &&&&&&&& & & &&&&&&&* &&&*
|
&& &&&&&&&& & & &&&&&&&* &&&*
|
||||||
&& &&&&&&&&&&& & & &&&& &*
|
&& &&&&&&&&&&& & & &&&& &*
|
||||||
&& &&&&&&&&& & & && &&
|
&& &&&&&&&&& & & && &&
|
||||||
&&& &&&&&& & & && &&
|
&&& &&&&&& & & && &&
|
||||||
&&& &&&& & & && &&
|
&&& &&&& & & && &&
|
||||||
&&&& &&& & & && &&
|
&&&& &&& & & && &&
|
||||||
&&&&&&& \\&/ && &&
|
&&&&&&& \\&/ && &&
|
||||||
&&&&&& V &* &*
|
&&&&&& V &* &*
|
||||||
|
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// Prevent from exiting so the banner will automatically display on startup.
|
// Prevent from exiting so the banner will automatically display on startup.
|
||||||
if(args['reboot']) while(true) { await ns.sleep(1000 * 60); }
|
if(args['reboot']) while(true) { await ns.sleep(1000 * 60); }
|
||||||
}
|
}
|
||||||
|
34
scripts/bitburner.js
Normal file
34
scripts/bitburner.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Automatically complete the current BitNode.
|
||||||
|
*
|
||||||
|
* @param {NS} ns - BitBurner API
|
||||||
|
*/
|
||||||
|
export function main(ns) {
|
||||||
|
let modules = [
|
||||||
|
'auto-root',
|
||||||
|
'auto-hack',
|
||||||
|
'botnet-manager',
|
||||||
|
'hacknet-manager',
|
||||||
|
'server-manager'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Banner
|
||||||
|
ns.run('/scripts/banner.js', 1, '-r');
|
||||||
|
ns.tprint(`Starting BitBurner with ${modules.length} enabled: `);
|
||||||
|
ns.tprint(modules.join(', '));
|
||||||
|
|
||||||
|
// botnet-manager
|
||||||
|
|
||||||
|
// hacknet-manager
|
||||||
|
ns.run('/scripts/hacknet-manager', 1, '-a');
|
||||||
|
|
||||||
|
// server-manager
|
||||||
|
ns.run('/scripts/server-manager', 1, '');
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
// auto-hack
|
||||||
|
|
||||||
|
|
||||||
|
ns.sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,20 @@
|
|||||||
import {ArgParser} from '/scripts/lib/arg-parser';
|
import {ArgParser} from '/scripts/lib/arg-parser';
|
||||||
|
import {Config} from '/scripts/lib/data-file';
|
||||||
import {Logger} from '/scripts/lib/logger';
|
import {Logger} from '/scripts/lib/logger';
|
||||||
import {copyWithDependencies} from '/scripts/copy';
|
import {copyWithDependencies} from '/scripts/copy';
|
||||||
|
|
||||||
|
const configPath = '/etc/botnet.txt';
|
||||||
|
const port = 1;
|
||||||
|
|
||||||
class Manager {
|
class Manager {
|
||||||
running;
|
running;
|
||||||
workers = [];
|
workers = [];
|
||||||
|
|
||||||
constructor(ns, device, port, config = '/conf/botnet.txt') {
|
async constructor(ns, hostname) {
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
this.ns = ns;
|
this.ns = ns;
|
||||||
this.config = config;
|
this.config = new Config(configPath);
|
||||||
this.device = device;
|
this.hostname = hostname;
|
||||||
this.logger = new Logger(this.ns, [
|
this.logger = new Logger(this.ns, [
|
||||||
() => `Botnet: ${device}`,
|
() => `Botnet: ${device}`,
|
||||||
() => `Workers: ${this.workers.length}\tCores: ${this.workers.reduce((acc, w) => acc + w.cpuCores, 0)}\tRAM: ${this.workers.reduce((acc, w) => acc + w.maxRam, 0)} GB`
|
() => `Workers: ${this.workers.length}\tCores: ${this.workers.reduce((acc, w) => acc + w.cpuCores, 0)}\tRAM: ${this.workers.reduce((acc, w) => acc + w.maxRam, 0)} GB`
|
||||||
@ -124,7 +128,8 @@ class Manager {
|
|||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
const hostname = ns.getHostname(), portNum = 1;
|
const config = await new Config(ns, configPath).load();
|
||||||
|
const hostname = ns.getHostname();
|
||||||
const argParser = new ArgParser('botnet-manager.js', 'Connect & manage a network of servers to launch distributed attacks.', [
|
const argParser = new ArgParser('botnet-manager.js', 'Connect & manage a network of servers to launch distributed attacks.', [
|
||||||
new ArgParser('copy', 'Copy file & dependencies to botnet', [
|
new ArgParser('copy', 'Copy file & dependencies to botnet', [
|
||||||
{name: 'file', desc: 'File to copy', default: false},
|
{name: 'file', desc: 'File to copy', default: false},
|
||||||
@ -139,6 +144,7 @@ export async function main(ns) {
|
|||||||
new ArgParser('leave', 'Disconnect worker node from swarm', [
|
new ArgParser('leave', 'Disconnect worker node from swarm', [
|
||||||
{name: 'device', desc: 'Device to disconnect, defaults to the current machine', optional: true, default: hostname}
|
{name: 'device', desc: 'Device to disconnect, defaults to the current machine', optional: true, default: hostname}
|
||||||
]),
|
]),
|
||||||
|
new ArgParser('list', 'List connected worker nodes'),
|
||||||
new ArgParser('run', 'Copy & run script on the botnet', [
|
new ArgParser('run', 'Copy & run script on the botnet', [
|
||||||
{name: 'script', desc: 'Script to copy & execute', type: 'string'},
|
{name: 'script', desc: 'Script to copy & execute', type: 'string'},
|
||||||
{name: 'args', desc: 'Arguments for script. Forward the current target with: {{TARGET}}', optional: true, extras: true},
|
{name: 'args', desc: 'Arguments for script. Forward the current target with: {{TARGET}}', optional: true, extras: true},
|
||||||
@ -154,9 +160,9 @@ export async function main(ns) {
|
|||||||
|
|
||||||
// Run command
|
// Run command
|
||||||
if(args['_command'] == 'start') { // Start botnet manager
|
if(args['_command'] == 'start') { // Start botnet manager
|
||||||
ns.tprint(`Starting ${hostname} as botnet manager`);
|
ns.tprint(`Starting botnet controller on: ${hostname}`);
|
||||||
ns.tprint(`Connect more nodes with: run botnet-manager.js join [SERVER]`);
|
ns.tprint(`Connect workers to botnet with: run botnet-manager.js join [SERVER]`);
|
||||||
await new Manager(ns, hostname, portNum).start();
|
await new Manager(ns, hostname).start();
|
||||||
} else if(args['_command'] == 'copy') { // Issue copy command
|
} else if(args['_command'] == 'copy') { // Issue copy command
|
||||||
await ns.writePort(portNum, JSON.stringify({
|
await ns.writePort(portNum, JSON.stringify({
|
||||||
command: 'copy',
|
command: 'copy',
|
||||||
@ -176,6 +182,9 @@ export async function main(ns) {
|
|||||||
command: 'leave',
|
command: 'leave',
|
||||||
value: args['device']
|
value: args['device']
|
||||||
}));
|
}));
|
||||||
|
} else if(args['_command'] == 'list') {
|
||||||
|
ns.tprint('Botnet workers:');
|
||||||
|
ns.tprint(config['workers'].map(worker => worker.hostname).join(', '));
|
||||||
} else if(args['_command'] == 'run') { // Issue run command
|
} else if(args['_command'] == 'run') { // Issue run command
|
||||||
await ns.writePort(portNum, JSON.stringify({
|
await ns.writePort(portNum, JSON.stringify({
|
||||||
command: 'run',
|
command: 'run',
|
||||||
|
214
scripts/copy.js
214
scripts/copy.js
@ -1,107 +1,107 @@
|
|||||||
import {ArgParser} from '/scripts/lib/arg-parser';
|
import {ArgParser} from '/scripts/lib/arg-parser';
|
||||||
import {maxThreads, progressBar} from '/scripts/lib/utils';
|
import {maxThreads, progressBar} from '/scripts/lib/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a file & it's dependencies to a server.
|
* Copy a file & it's dependencies to a server.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
* @param {string} src - File to scan & copy
|
* @param {string} src - File to scan & copy
|
||||||
* @param {string} server - Device to copy files to
|
* @param {string} server - Device to copy files to
|
||||||
* @returns {Promise<string[]>} - Array of copied files
|
* @returns {Promise<string[]>} - Array of copied files
|
||||||
*/
|
*/
|
||||||
export async function copyWithDependencies(ns, src, server) {
|
export async function copyWithDependencies(ns, src, server) {
|
||||||
const queue = [src], found = [src];
|
const queue = [src], found = [src];
|
||||||
while(queue.length) {
|
while(queue.length) {
|
||||||
const file = queue.splice(0, 1)[0];
|
const file = queue.splice(0, 1)[0];
|
||||||
const imports = new RegExp(/from ["']\.?(\/.+)["']/g);
|
const imports = new RegExp(/from ["']\.?(\/.+)["']/g);
|
||||||
const script = await ns.read(file);
|
const script = await ns.read(file);
|
||||||
let match;
|
let match;
|
||||||
while((match = imports.exec(script)) != null) {
|
while((match = imports.exec(script)) != null) {
|
||||||
const path = `${match[1]}.js`;
|
const path = `${match[1]}.js`;
|
||||||
if(!found.includes(path)) found.push(path);
|
if(!found.includes(path)) found.push(path);
|
||||||
queue.push(path);
|
queue.push(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ns.scp(found, server);
|
await ns.scp(found, server);
|
||||||
return found.reverse();
|
return found.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a file & it's dependencies to a server.
|
* Copy a file & it's dependencies to a server.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
*/
|
*/
|
||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
const argParser = new ArgParser('copy.js', 'Copy a file & it\'s dependencies to a server.', [
|
const argParser = new ArgParser('copy.js', 'Copy a file & it\'s dependencies to a server.', [
|
||||||
{name: 'file', desc: 'File to copy'},
|
{name: 'file', desc: 'File to copy'},
|
||||||
{name: 'server', desc: 'Server to copy file(s) to'},
|
{name: 'server', desc: 'Server to copy file(s) to'},
|
||||||
{name: 'args', desc: 'Arguments to start file/script with', optional: true, extras: true},
|
{name: 'args', desc: 'Arguments to start file/script with', optional: true, extras: true},
|
||||||
{name: 'cpu', desc: 'Number of CPU threads to start script with, will use maximum if not specified', flags: ['-c', '--cpu']},
|
{name: 'cpu', desc: 'Number of CPU threads to start script with, will use maximum if not specified', flags: ['-c', '--cpu']},
|
||||||
{name: 'execute', desc: 'Start script after copying', flags: ['-e', '--execute'], default: false},
|
{name: 'execute', desc: 'Start script after copying', flags: ['-e', '--execute'], default: false},
|
||||||
{name: 'noDeps', desc: 'Skip copying dependencies', flags: ['-n', '--no-deps'], default: false},
|
{name: 'noDeps', desc: 'Skip copying dependencies', flags: ['-n', '--no-deps'], default: false},
|
||||||
{name: 'quite', desc: 'Suppress program output', flags: ['-q', '--quite'], default: false},
|
{name: 'quite', desc: 'Suppress program output', flags: ['-q', '--quite'], default: false},
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args);
|
const args = argParser.parse(ns.args);
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
if(args['help'] || args['_error'].length)
|
if(args['help'] || args['_error'].length)
|
||||||
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
||||||
|
|
||||||
// Banner
|
// Banner
|
||||||
if(!args['quite']) {
|
if(!args['quite']) {
|
||||||
ns.tprint('===================================================');
|
ns.tprint('===================================================');
|
||||||
ns.tprint(`Copying: ${args['server']}`);
|
ns.tprint(`Copying: ${args['server']}`);
|
||||||
ns.tprint('===================================================');
|
ns.tprint('===================================================');
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
ns.tprint('Copying Files:');
|
ns.tprint('Copying Files:');
|
||||||
await ns.sleep(500);
|
await ns.sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy files & create download bar
|
// Copy files & create download bar
|
||||||
if(args['noDeps']) {
|
if(args['noDeps']) {
|
||||||
await ns.scp(args['file'], args['server']);
|
await ns.scp(args['file'], args['server']);
|
||||||
if(!args['quite']) await progressBar(ns, args['file']);
|
if(!args['quite']) await progressBar(ns, args['file']);
|
||||||
} else {
|
} else {
|
||||||
const files = await copyWithDependencies(ns, args['file'], args['server']);
|
const files = await copyWithDependencies(ns, args['file'], args['server']);
|
||||||
if(!args['quite']) {
|
if(!args['quite']) {
|
||||||
for(let file of files) {
|
for(let file of files) {
|
||||||
await progressBar(ns, file);
|
await progressBar(ns, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the script if requested
|
// Run the script if requested
|
||||||
if(args['execute']) {
|
if(args['execute']) {
|
||||||
const threads = args['cpu'] || maxThreads(ns, args['file'], args['server']) || 1;
|
const threads = args['cpu'] || maxThreads(ns, args['file'], args['server']) || 1;
|
||||||
if(!args['quite']) {
|
if(!args['quite']) {
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
ns.tprint(`Executing with ${threads} thread${threads > 1 ? 's' : ''}...`);
|
ns.tprint(`Executing with ${threads} thread${threads > 1 ? 's' : ''}...`);
|
||||||
await ns.sleep(500);
|
await ns.sleep(500);
|
||||||
}
|
}
|
||||||
ns.killall(args['server']);
|
ns.killall(args['server']);
|
||||||
const pid = ns.exec(args['file'], args['server'], threads, ...args['args']);
|
const pid = ns.exec(args['file'], args['server'], threads, ...args['args']);
|
||||||
if(!args['quite']) {
|
if(!args['quite']) {
|
||||||
ns.tprint(!!pid ? 'Done!' : 'Failed to start');
|
ns.tprint(!!pid ? 'Done!' : 'Failed to start');
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done message
|
// Done message
|
||||||
if(!args['quite']) {
|
if(!args['quite']) {
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
ns.tprint('Done!');
|
ns.tprint('Done!');
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BitBurner autocomplete.
|
* BitBurner autocomplete.
|
||||||
*
|
*
|
||||||
* @param {{servers: string[], txts: string[], scripts: string[], flags: string[]}} data - Contextual information
|
* @param {{servers: string[], txts: string[], scripts: string[], flags: string[]}} data - Contextual information
|
||||||
* @returns {string[]} - Pool of autocomplete options
|
* @returns {string[]} - Pool of autocomplete options
|
||||||
*/
|
*/
|
||||||
export function autocomplete(data) {
|
export function autocomplete(data) {
|
||||||
return [...data.servers, ...data.scripts];
|
return [...data.servers, ...data.scripts];
|
||||||
}
|
}
|
||||||
|
@ -1,68 +1,68 @@
|
|||||||
import {ArgParser} from '/scripts/lib/arg-parser';
|
import {ArgParser} from '/scripts/lib/arg-parser';
|
||||||
import {toCurrency} from '/scripts/lib/utils';
|
import {toCurrency} from '/scripts/lib/utils';
|
||||||
import {scanNetwork} from '/scripts/crawler';
|
import {scanNetwork} from '/scripts/crawler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort array of servers based on the potential return/yield.
|
* Sort array of servers based on the potential return/yield.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
* @param {string[]} servers - List of servers to sort based on yield
|
* @param {string[]} servers - List of servers to sort based on yield
|
||||||
* @returns {[string, number][]} - Sorted list of servers & their potential yield per minute
|
* @returns {[string, number][]} - Sorted list of servers & their potential yield per minute
|
||||||
*/
|
*/
|
||||||
export function bestTarget(ns, servers) {
|
export function bestTarget(ns, servers) {
|
||||||
return servers.map(s => [s, serverYield(ns, s)]).sort((a, b) => {
|
return servers.map(s => [s, serverYield(ns, s)]).sort((a, b) => {
|
||||||
if(a[1] < b[1]) return 1;
|
if(a[1] < b[1]) return 1;
|
||||||
if(a[1] > b[1]) return -1;
|
if(a[1] > b[1]) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the average return per minute when hacking a server.
|
* Calculate the average return per minute when hacking a server.
|
||||||
*
|
*
|
||||||
* **Disclaimer:** Does not take into account security or weaken time.
|
* **Disclaimer:** Does not take into account security or weaken time.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
* @param {string} server - Server to calculate yield for
|
* @param {string} server - Server to calculate yield for
|
||||||
* @returns {number} - $/minute
|
* @returns {number} - $/minute
|
||||||
*/
|
*/
|
||||||
export function serverYield(ns, server) {
|
export function serverYield(ns, server) {
|
||||||
return (ns.hackAnalyze(server) * ns.getServerMaxMoney(server))
|
return (ns.hackAnalyze(server) * ns.getServerMaxMoney(server))
|
||||||
* ((60 / (ns.getHackTime(server) / 1000)) * ns.hackAnalyzeChance(server));
|
* ((60 / (ns.getHackTime(server) / 1000)) * ns.hackAnalyzeChance(server));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan the network for the best server(s) to hack.
|
* Scan the network for the best server(s) to hack.
|
||||||
*
|
*
|
||||||
* @param ns {NS} - BitBurner API
|
* @param ns {NS} - BitBurner API
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function main(ns) {
|
export function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
const argParser = new ArgParser('find-target.js', 'Scan the network for the best servers(s) to hack.',[
|
const argParser = new ArgParser('find-target.js', 'Scan the network for the best servers(s) to hack.',[
|
||||||
{name: 'count', desc: 'Number of servers to return', flags: ['-c', '--count'], default: Infinity},
|
{name: 'count', desc: 'Number of servers to return', flags: ['-c', '--count'], default: Infinity},
|
||||||
{name: 'rooted', desc: 'Only servers that have been rooted', flags: ['-r', '--rooted'], default: false},
|
{name: 'rooted', desc: 'Only servers that have been rooted', flags: ['-r', '--rooted'], default: false},
|
||||||
{name: 'notRooted', desc: 'Only servers that have not been rooted', flags: ['-n', '--not-rooted'], default: false},
|
{name: 'notRooted', desc: 'Only servers that have not been rooted', flags: ['-n', '--not-rooted'], default: false},
|
||||||
{name: 'verbose', desc: 'Display the estimated income per minute per core', flags: ['-v', '--verbose'], default: false},
|
{name: 'verbose', desc: 'Display the estimated income per minute per core', flags: ['-v', '--verbose'], default: false},
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args);
|
const args = argParser.parse(ns.args);
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
if(args['help'] || args['_error'].length)
|
if(args['help'] || args['_error'].length)
|
||||||
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
||||||
|
|
||||||
// Banner
|
// Banner
|
||||||
ns.tprint('===================================================');
|
ns.tprint('===================================================');
|
||||||
ns.tprint(`Finding Targets:`);
|
ns.tprint(`Finding Targets:`);
|
||||||
ns.tprint('===================================================');
|
ns.tprint('===================================================');
|
||||||
|
|
||||||
// Search & display results
|
// Search & display results
|
||||||
const [servers, ignore] = scanNetwork(ns);
|
const [servers, ignore] = scanNetwork(ns);
|
||||||
bestTarget(ns, servers).map(s => [...s, ns.hasRootAccess(s[0])])
|
bestTarget(ns, servers).map(s => [...s, ns.hasRootAccess(s[0])])
|
||||||
.filter(s => (!args['rooted'] || s[2]) || (!args['notRooted'] || !s[2]))
|
.filter(s => (!args['rooted'] || s[2]) || (!args['notRooted'] || !s[2]))
|
||||||
.filter((s, i) => i < args['count'])
|
.filter((s, i) => i < args['count'])
|
||||||
.map(s => `${s[0]}${args['verbose'] ? ` (~${toCurrency(s[1])}/min)` : ''}`)
|
.map(s => `${s[0]}${args['verbose'] ? ` (~${toCurrency(s[1])}/min)` : ''}`)
|
||||||
.forEach((s, i) => ns.tprint(`${i + 1}) ${s}`));
|
.forEach((s, i) => ns.tprint(`${i + 1}) ${s}`));
|
||||||
ns.tprint('');
|
ns.tprint('');
|
||||||
}
|
}
|
||||||
|
31
scripts/lib/data-file.js
Normal file
31
scripts/lib/data-file.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export class DataFile {
|
||||||
|
/**
|
||||||
|
* Read & write data to a JSON file.
|
||||||
|
*
|
||||||
|
* @param {NS} ns - Bitburner API
|
||||||
|
* @param path - Path to config file
|
||||||
|
*/
|
||||||
|
constructor(ns, path) {
|
||||||
|
this.ns = ns;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data file
|
||||||
|
*
|
||||||
|
* @returns {Promise<any>} - Saved data
|
||||||
|
*/
|
||||||
|
async load() {
|
||||||
|
return JSON.parse(await this.ns.read(this.path) || 'null');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save data to file
|
||||||
|
*
|
||||||
|
* @param values - Data to save
|
||||||
|
* @returns {Promise<void>} - Save complete
|
||||||
|
*/
|
||||||
|
async save(values) {
|
||||||
|
await this.ns.write(this.path, JSON.stringify(values), 'w');
|
||||||
|
}
|
||||||
|
}
|
42
scripts/lib/port-helper.js
Normal file
42
scripts/lib/port-helper.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
export class PortHelper {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ns
|
||||||
|
* @param port
|
||||||
|
* @param host
|
||||||
|
*/
|
||||||
|
constructor(ns, port, host) {
|
||||||
|
this.ns = ns;
|
||||||
|
this.host = host;
|
||||||
|
this.portNum = port;
|
||||||
|
this.port = ns.getPortHandle(port);
|
||||||
|
this.callbacks = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
const pending = [];
|
||||||
|
while(!this.port.empty()) pending.push(this.port.read());
|
||||||
|
pending.filter(p => {
|
||||||
|
try {
|
||||||
|
const payload = JSON.parse(p);
|
||||||
|
if(this.callbacks[payload.subject]) return !this.callbacks[payload.subject](payload.value);
|
||||||
|
if(this.callbacks['*']) return !this.callbacks['*'](payload.value);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}).forEach(p => this.port.write(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(subject, callback) { if(typeof callback == 'function') this.callbacks[subject] = callback; }
|
||||||
|
|
||||||
|
send(subject, value) {
|
||||||
|
this.ns.writePort(this.portNum, JSON.stringify({
|
||||||
|
from: this.host,
|
||||||
|
subject,
|
||||||
|
value
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe(subject) { delete this.callbacks[subject]; }
|
||||||
|
}
|
@ -1,39 +1,39 @@
|
|||||||
import {ArgParser} from '/scripts/lib/arg-parser';
|
import {ArgParser} from '/scripts/lib/arg-parser';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively delete files inside a path. Equivalent to the Unix "rm -r".
|
* Recursively delete files inside a path. Equivalent to the Unix "rm -r".
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
*/
|
*/
|
||||||
export function main(ns) {
|
export function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
const argParser = new ArgParser('rm.js', 'Recursively delete files inside a directory', [
|
const argParser = new ArgParser('rm.js', 'Recursively delete files inside a directory', [
|
||||||
{name: 'path', desc: 'Path to recursively search'},
|
{name: 'path', desc: 'Path to recursively search'},
|
||||||
{name: 'server', desc: 'Run on remote server', optional: true, default: ns.getHostname()},
|
{name: 'server', desc: 'Run on remote server', optional: true, default: ns.getHostname()},
|
||||||
{name: 'force', desc: 'Remove game files (.exe, .lit, .msg)', flags: ['-f', '--force'], default: false},
|
{name: 'force', desc: 'Remove game files (.exe, .lit, .msg)', flags: ['-f', '--force'], default: false},
|
||||||
{name: 'recursive', desc: 'Delete everything inside directory', flags: ['-r', '--recursive'], default: true}
|
{name: 'recursive', desc: 'Delete everything inside directory', flags: ['-r', '--recursive'], default: true}
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args);
|
const args = argParser.parse(ns.args);
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
if(args['help'] || args['_error'].length)
|
if(args['help'] || args['_error'].length)
|
||||||
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
ns.ls(args['server'], args['path'])
|
ns.ls(args['server'], args['path'])
|
||||||
.filter(f => new RegExp(/\.(exe|lit|msg)$/g).test(f) ? args['force'] : true)
|
.filter(f => new RegExp(/\.(exe|lit|msg)$/g).test(f) ? args['force'] : true)
|
||||||
.forEach(f => ns.rm(f, args['server']));
|
.forEach(f => ns.rm(f, args['server']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BitBurner autocomplete.
|
* BitBurner autocomplete.
|
||||||
*
|
*
|
||||||
* @param {{servers: string[], txts: string[], scripts: string[], flags: string[]}} data - Contextual information
|
* @param {{servers: string[], txts: string[], scripts: string[], flags: string[]}} data - Contextual information
|
||||||
* @returns {string[]} - Pool of autocomplete options
|
* @returns {string[]} - Pool of autocomplete options
|
||||||
*/
|
*/
|
||||||
export function autocomplete(data) {
|
export function autocomplete(data) {
|
||||||
return [...data.txts, ...data.scripts]
|
return [...data.txts, ...data.scripts]
|
||||||
.map(file => file.split('/').slice(0, -1).join('/'))
|
.map(file => file.split('/').slice(0, -1).join('/'))
|
||||||
.filter((path, i, arr) => arr.indexOf(path) == i)
|
.filter((path, i, arr) => arr.indexOf(path) == i)
|
||||||
.concat(data.txts, data.scripts);
|
.concat(data.txts, data.scripts);
|
||||||
}
|
}
|
||||||
|
@ -1,87 +1,87 @@
|
|||||||
import {ArgParser} from '/scripts/lib/arg-parser';
|
import {ArgParser} from '/scripts/lib/arg-parser';
|
||||||
import {Logger} from '/scripts/lib/logger';
|
import {Logger} from '/scripts/lib/logger';
|
||||||
import {maxThreads, toCurrency} from '/scripts/lib/utils';
|
import {maxThreads, toCurrency} from '/scripts/lib/utils';
|
||||||
import {copyWithDependencies} from "/scripts/copy";
|
import {copyWithDependencies} from "/scripts/copy";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automate the buying & upgrading of servers.
|
* Automate the buying & upgrading of servers.
|
||||||
*
|
*
|
||||||
* @param {NS} ns - BitBurner API
|
* @param {NS} ns - BitBurner API
|
||||||
*/
|
*/
|
||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
// Setup
|
// Setup
|
||||||
ns.disableLog('ALL');
|
ns.disableLog('ALL');
|
||||||
let servers = ns.getPurchasedServers();
|
let servers = ns.getPurchasedServers();
|
||||||
const logger = new Logger(ns, [
|
const logger = new Logger(ns, [
|
||||||
() => `Server Manager: ${servers.length}`
|
() => `Server Manager: ${servers.length}`
|
||||||
]);
|
]);
|
||||||
const argParser = new ArgParser('server-manager.js', 'Automate the buying & upgrading of servers. Automatically starts script after purchase. Tail for live updates.', [
|
const argParser = new ArgParser('server-manager.js', 'Automate the buying & upgrading of servers. Automatically starts script after purchase. Tail for live updates.', [
|
||||||
{name: 'script', desc: 'Script to copy & execute', optional: true},
|
{name: 'script', desc: 'Script to copy & execute', optional: true},
|
||||||
{name: 'args', desc: 'Arguments for script. Forward the discovered server with: {{SERVER}}', optional: true, extras: true},
|
{name: 'args', desc: 'Arguments for script. Forward the discovered server with: {{SERVER}}', optional: true, extras: true},
|
||||||
{name: 'balance', desc: 'Prevent spending bellow point', flags: ['-b', '--balance'], default: 0},
|
{name: 'balance', desc: 'Prevent spending bellow point', flags: ['-b', '--balance'], default: 0},
|
||||||
{name: 'cpu', desc: 'Number of CPU threads to start script with, will use maximum if not specified', flags: ['-c', '--cpu'], default: false},
|
{name: 'cpu', desc: 'Number of CPU threads to start script with, will use maximum if not specified', flags: ['-c', '--cpu'], default: false},
|
||||||
{name: 'limit', desc: 'Limit the number of servers that can be purchased, defaults to 25', flags: ['-l', '--limit'], default: 25},
|
{name: 'limit', desc: 'Limit the number of servers that can be purchased, defaults to 25', flags: ['-l', '--limit'], default: 25},
|
||||||
{name: 'ram', desc: 'Amount of RAM to purchase new servers with, defaults to 8 GB', flags: ['-r', '--ram'], default: 8},
|
{name: 'ram', desc: 'Amount of RAM to purchase new servers with, defaults to 8 GB', flags: ['-r', '--ram'], default: 8},
|
||||||
{name: 'sleep', desc: 'Amount of time to wait between purchases, defaults to 1 (second)', flags: ['-s', '--sleep'], default: 1}
|
{name: 'sleep', desc: 'Amount of time to wait between purchases, defaults to 1 (second)', flags: ['-s', '--sleep'], default: 1}
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args);
|
const args = argParser.parse(ns.args);
|
||||||
const serverPrefix = 'botnet_'
|
const serverPrefix = 'botnet_'
|
||||||
const maxRam = ns.getPurchasedServerMaxRam();
|
const maxRam = ns.getPurchasedServerMaxRam();
|
||||||
const minRamCost = ns.getPurchasedServerCost(args['ram']);
|
const minRamCost = ns.getPurchasedServerCost(args['ram']);
|
||||||
|
|
||||||
async function startScript(server) {
|
async function startScript(server) {
|
||||||
await copyWithDependencies(ns, args['script'], server);
|
await copyWithDependencies(ns, args['script'], server);
|
||||||
const threads = args['cpu'] || maxThreads(ns, args['script'], server) || 1;
|
const threads = args['cpu'] || maxThreads(ns, args['script'], server) || 1;
|
||||||
const pid = ns.exec(args['script'], server, threads, ...args['args']);
|
const pid = ns.exec(args['script'], server, threads, ...args['args']);
|
||||||
logger.log(`Starting "${args['script']}" with ${threads} thread${threads > 1 ? 's' : ''}`);
|
logger.log(`Starting "${args['script']}" with ${threads} thread${threads > 1 ? 's' : ''}`);
|
||||||
logger[pid == -1 ? 'warn' : 'log'](pid == -1 ? 'Done!' : 'Failed to start');
|
logger[pid == -1 ? 'warn' : 'log'](pid == -1 ? 'Done!' : 'Failed to start');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Help
|
// Help
|
||||||
if(args['help'] || args['_error'].length)
|
if(args['help'] || args['_error'].length)
|
||||||
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
return ns.tprint(argParser.help(args['help'] ? null : args['_error'][0], args['_command']));
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
// noinspection InfiniteLoopJS
|
// noinspection InfiniteLoopJS
|
||||||
while(true) {
|
while(true) {
|
||||||
servers = ns.getPurchasedServers();
|
servers = ns.getPurchasedServers();
|
||||||
const balance = ns.getServerMoneyAvailable('home');
|
const balance = ns.getServerMoneyAvailable('home');
|
||||||
// Purchase new server if we can afford it
|
// Purchase new server if we can afford it
|
||||||
if(servers.length < args['limit'] && balance - minRamCost > args['balance']) {
|
if(servers.length < args['limit'] && balance - minRamCost > args['balance']) {
|
||||||
logger.log(`Buying server (${args['ram']} GB): ${toCurrency(minRamCost)}`);
|
logger.log(`Buying server (${args['ram']} GB): ${toCurrency(minRamCost)}`);
|
||||||
ns.purchaseServer(`${serverPrefix}${servers.length}`, args['ram']);
|
ns.purchaseServer(`${serverPrefix}${servers.length}`, args['ram']);
|
||||||
|
|
||||||
// Run the script if requested
|
// Run the script if requested
|
||||||
if(args['script']) await startScript(`${serverPrefix}${servers.length}`);
|
if(args['script']) await startScript(`${serverPrefix}${servers.length}`);
|
||||||
} else { // Check for upgrades
|
} else { // Check for upgrades
|
||||||
let upgrades = servers.map(server => {
|
let upgrades = servers.map(server => {
|
||||||
// Calculate next RAM upgrades (must be a power of two: 2, 4, 8, 16, 32...)
|
// Calculate next RAM upgrades (must be a power of two: 2, 4, 8, 16, 32...)
|
||||||
let ram = Math.pow(2, Math.log2(ns.getServerMaxRam(server)) + 1);
|
let ram = Math.pow(2, Math.log2(ns.getServerMaxRam(server)) + 1);
|
||||||
if(ram > maxRam) ram = null;
|
if(ram > maxRam) ram = null;
|
||||||
return {
|
return {
|
||||||
server,
|
server,
|
||||||
ram,
|
ram,
|
||||||
cost: ram ? ns.getPurchasedServerCost(ram) : null
|
cost: ram ? ns.getPurchasedServerCost(ram) : null
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
upgrades = upgrades.sort((a, b) => { // Sort by price
|
upgrades = upgrades.sort((a, b) => { // Sort by price
|
||||||
if(a.cost < b.cost) return 1;
|
if(a.cost < b.cost) return 1;
|
||||||
if(a.cost < b.cost) return -1;
|
if(a.cost < b.cost) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Do the cheapest upgrade if we can afford it
|
// Do the cheapest upgrade if we can afford it
|
||||||
const upgrade = upgrades[0];
|
const upgrade = upgrades[0];
|
||||||
if(upgrade && !!upgrade.ram && balance - upgrade.cost > args['balance']) {
|
if(upgrade && !!upgrade.ram && balance - upgrade.cost > args['balance']) {
|
||||||
logger.log(`Upgrading ${upgrade.server}: ${upgrade.ram} GB / ${toCurrency(upgrade.cost)}`);
|
logger.log(`Upgrading ${upgrade.server}: ${upgrade.ram} GB / ${toCurrency(upgrade.cost)}`);
|
||||||
ns.killall(upgrade.server);
|
ns.killall(upgrade.server);
|
||||||
ns.deleteServer(upgrade.server);
|
ns.deleteServer(upgrade.server);
|
||||||
ns.purchaseServer(upgrade.server, upgrade.ram);
|
ns.purchaseServer(upgrade.server, upgrade.ram);
|
||||||
|
|
||||||
// Run the script if requested
|
// Run the script if requested
|
||||||
if(args['script']) await startScript(upgrade.server);
|
if(args['script']) await startScript(upgrade.server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ns.sleep(args['sleep'] * 1000);
|
await ns.sleep(args['sleep'] * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ export async function main(ns) {
|
|||||||
{name: 'no-banner', desc: 'Hide the banner (Used internally)', flags: ['--no-banner'], default: false}
|
{name: 'no-banner', desc: 'Hide the banner (Used internally)', flags: ['--no-banner'], default: false}
|
||||||
]);
|
]);
|
||||||
const args = argParser.parse(ns.args || []);
|
const args = argParser.parse(ns.args || []);
|
||||||
const src = 'https://raw.githubusercontent.com/PointyTrident/Bitburner/develop/scripts/';
|
const src = 'https://gitlab.zakscode.com/ztimson/BitBurner/-/raw/develop/scripts/';
|
||||||
const dest = '/scripts/';
|
const dest = '/scripts/';
|
||||||
const fileList = [
|
const fileList = [
|
||||||
'lib/arg-parser.js',
|
'lib/arg-parser.js',
|
||||||
|
Loading…
Reference in New Issue
Block a user