wip
This commit is contained in:
parent
1a0f8e6b16
commit
35fcc721fa
32
README.md
32
README.md
@ -13,7 +13,6 @@ These scripts are for playing the [open source](https://github.com/danielyxie/bi
|
||||
- [network-graph.js](#network-graphjs)
|
||||
- [rootkit.js](#rootkitjs)
|
||||
- [update.js](#updatejs)
|
||||
- [vanguard.js](#vanguardjs)
|
||||
|
||||
## Quick Start
|
||||
|
||||
@ -151,10 +150,12 @@ Usage: run network-graph.js [OPTIONS] [DEVICE]
|
||||
DEVICE Point to start scan from, defaults to current machine
|
||||
|
||||
Options:
|
||||
-d --depth Depth to scan to, defaults to 3
|
||||
-f --filter Display devices matching name
|
||||
-r --regex Display devices matching pattern
|
||||
-v --verbose Displays the required hack level & ports needed to root: (level|port)
|
||||
-d --depth Depth to scan to, defaults is 3
|
||||
-f --filter Filter to device matching name
|
||||
-e --regex Filter to devices matching pattern
|
||||
-r --rooted Filter to devices that have been rooted
|
||||
-n --not-rooted Filter to devices that have not been rooted
|
||||
-v --verbose Display the required hack level & number of ports to root: (level|port)
|
||||
-h --help Display this help message
|
||||
```
|
||||
|
||||
@ -204,24 +205,3 @@ Options:
|
||||
--no-banner Hide the banner (Used internally)
|
||||
-h --help Display this help message
|
||||
```
|
||||
|
||||
### [vanguard.js](./scripts/vanguard.js)
|
||||
**RAM:** 1.90 GB
|
||||
|
||||
Weaken a device indefinitely.
|
||||
```
|
||||
[home ~/scripts]> run /scripts/vanguard.js --help
|
||||
Running script with 1 thread(s), pid 1 and args: ["--help"].
|
||||
/scripts/vanguard.js:
|
||||
|
||||
Weaken a device indefinitely.
|
||||
|
||||
Usage: run vanguard.js [OPTIONS] [DEVICE]
|
||||
run vanguard.js --help
|
||||
|
||||
DEVICE Device to weaken, defaults to the current machine
|
||||
|
||||
Options:
|
||||
-l --limit Limit the number of times to run
|
||||
-h --help Display this help message
|
||||
```
|
||||
|
@ -1,48 +1,38 @@
|
||||
import {ArgError, ArgParser} from './scripts/lib/arg-parser';
|
||||
import {terminal} from './scripts/lib/utils';
|
||||
import {ArgError, ArgParser} from '/scripts/lib/arg-parser';
|
||||
import {pruneTree, scanNetwork, terminal} from '/scripts/lib/utils';
|
||||
|
||||
/**
|
||||
* Connect to a device on a different network.
|
||||
* BitBurner autocomplete
|
||||
* @param data {server: string[], txts: string[], scripts: string[], flags: string[]} - Contextual information
|
||||
* @returns {string[]} - Pool of autocomplete options
|
||||
*/
|
||||
export function autocomplete(data) {
|
||||
return [...data.servers];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the network for a device and connect to it.
|
||||
* @param ns {NS} - BitBurner API
|
||||
*/
|
||||
export function main(ns) {
|
||||
// Setup
|
||||
ns.disableLog('ALL');
|
||||
let args;
|
||||
const argParser = new ArgParser('connect.js', 'Connect to a device on a different network.', null, [
|
||||
const argParser = new ArgParser('connect.js', 'Search the network for a device and connect to it.', null, [
|
||||
{name: 'device', desc: 'Device to connect to', default: ns.getHostname(), type: 'string'}
|
||||
]);
|
||||
|
||||
try {
|
||||
args = argParser.parse(ns.args);
|
||||
// Run
|
||||
const args = argParser.parse(ns.args);
|
||||
const [devices, network] = scanNetwork(ns);
|
||||
pruneTree(network, d => d == args['device']);
|
||||
let current = network, name;
|
||||
while(name = Object.keys(current)[0]) {
|
||||
terminal(`connect ${name}`);
|
||||
current = current[name];
|
||||
}
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find path to a device recursively
|
||||
* @param device {string} - Device to locate
|
||||
* @param current {string} - Current device to scan
|
||||
* @param path {string[]} - Path the the current device
|
||||
* @param all {Set} - Stop devices from being scanned
|
||||
* @returns {string[]} - Path to the located device
|
||||
*/
|
||||
function find(device, current = 'home', path = [current], blacklist = new Set()) {
|
||||
blacklist.add(current);
|
||||
const newDevices = ns.scan(current).filter(d => !blacklist.has(d));
|
||||
if(newDevices.length == 0) return [];
|
||||
if(newDevices.find(d => d == device)) return [...path, device];
|
||||
return newDevices.map(d => find(device, d, [...path, d], blacklist)).find(p => p && p.length);
|
||||
}
|
||||
|
||||
// Run
|
||||
const path = find(args['device']);
|
||||
path.splice(0, 1); // Delete 'home' from from the path
|
||||
for(let d of path) {
|
||||
terminal(`connect ${d}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function autocomplete(data) {
|
||||
return [...data.servers];
|
||||
}
|
||||
|
@ -1,4 +1,14 @@
|
||||
import {ArgError, ArgParser} from './scripts/lib/arg-parser';
|
||||
import {ArgError, ArgParser} from '/scripts/lib/arg-parser';
|
||||
import {scanNetwork} from '/scripts/lib/utils';
|
||||
|
||||
/**
|
||||
* BitBurner autocomplete
|
||||
* @param data {server: string[], txts: string[], scripts: string[], flags: string[]} - Contextual information
|
||||
* @returns {string[]} - Pool of autocomplete options
|
||||
*/
|
||||
export function autocomplete(data) {
|
||||
return [...data.scripts, '{{TARGET}}'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the network for targets to execute a script against.
|
||||
@ -13,45 +23,24 @@ export async function main(ns) {
|
||||
{name: 'cpu', desc: 'Number of CPU threads to use with script', flags: ['-c', '--cpu'], default: 1, type: 'num'},
|
||||
{name: 'depth', desc: 'Depth to scan to, defaults to 3', flags: ['-d', '--depth'], default: Infinity, type: 'num'},
|
||||
{name: 'level', desc: 'Exclude targets with higher hack level, defaults to current hack level', flags: ['-l', '--level'], default: ns.getHackingLevel(), type: 'num'},
|
||||
{name: 'ports', desc: 'Exclute targets with too many closed ports', flags: ['-p', '--ports'], optional: true, default: Infinity, type: 'num'},
|
||||
{name: 'ports', desc: 'Exclute targets with too many closed ports', flags: ['-p', '--ports'], default: Infinity, type: 'num'},
|
||||
{name: 'silent', desc: 'Surpress program output', flags: ['-s', '--silent'], type: 'bool'}
|
||||
], true);
|
||||
let args;
|
||||
|
||||
try {
|
||||
args = argParser.parse(ns.args);
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively search network & build a tree
|
||||
* @param host {string} - Point to scan from
|
||||
* @param depth {number} - Current scanning depth
|
||||
* @param blacklist {String[]} - Devices already discovered
|
||||
* @returns Dicionary of discovered devices
|
||||
*/
|
||||
function scan(target = 'home', depth = 1, found = new Set()) {
|
||||
if(found.size == 0) found.add(target);
|
||||
ns.scan(target).filter(t => !found.has(t)).forEach(t => {
|
||||
found.add(t);
|
||||
scan(t, depth + 1, found);
|
||||
});
|
||||
found.delete('home');
|
||||
return Array.from(found);
|
||||
}
|
||||
|
||||
// Run
|
||||
const targets = scan();
|
||||
const args = argParser.parse(ns.args);
|
||||
const [devices, network] = scanNetwork(ns);
|
||||
let complete = 0, failed = 0, skipped = 0;
|
||||
for(let target of targets) {
|
||||
if(target == 'home') continue;
|
||||
|
||||
if(args['level'] < ns.getServerRequiredHackingLevel(target) || args['ports'] < ns.getServerNumPortsRequired(target)) {
|
||||
for(let device of devices) {
|
||||
// Skip invalid devices
|
||||
if(device == 'home' || args['level'] < ns.getServerRequiredHackingLevel(device) || args['ports'] < ns.getServerNumPortsRequired(device)) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const scriptArgs = args['args'].map(arg => arg == '{{TARGET}}' ? target : arg);
|
||||
// Start script
|
||||
const scriptArgs = args['args'].map(arg => arg.toUpperCase() == '{{TARGET}}' ? device : arg);
|
||||
const pid = ns.run(args['script'], args['cpu'], ...scriptArgs);
|
||||
if(pid == 0) {
|
||||
failed++;
|
||||
@ -59,14 +48,21 @@ export async function main(ns) {
|
||||
}
|
||||
|
||||
// Wait for script to finish
|
||||
do { await ns.sleep(1000); }
|
||||
while(ns.scriptRunning(args['script'], 'home'));
|
||||
while(ns.scriptRunning(args['script'], 'home'))
|
||||
await ns.sleep(1000);
|
||||
complete++;
|
||||
}
|
||||
|
||||
// Output report
|
||||
if(!args['silent']) {
|
||||
ns.tprint('===================================================');
|
||||
ns.tprint(`Crawler Report: ${targets.length} Device${targets.length > 1 ? 's' : ''}`);
|
||||
ns.tprint(`Crawler Report: ${devices.length} Device${devices.length > 1 ? 's' : ''}`);
|
||||
ns.tprint('===================================================');
|
||||
ns.tprint(`Complete: ${complete}\tFailed: ${failed}\tSkipped: ${skipped}`);
|
||||
ns.tprint('');
|
||||
}
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
@ -7,37 +7,17 @@ import {ArgError, ArgParser} from './scripts/lib/arg-parser';
|
||||
export async function main(ns) {
|
||||
// Setup
|
||||
ns.disableLog('ALL');
|
||||
const historyLength = 17;
|
||||
const messageHistory = Array(historyLength).fill('');
|
||||
let args, nodeCount = ns.hacknet.numNodes();
|
||||
const argParser = new ArgParser('hacknet-manager.js', 'Buy, upgrade & manage Hacknet nodes automatically. Tail for live updates.', null, [
|
||||
{name: 'limit', desc: 'Limit the number of nodes the manager will buy, defaults to 8', optional: true, default: 8, type: 'num'},
|
||||
{name: 'balance', desc: 'Prevent spending bellow point', flags: ['-b', '--balance'], type: 'num'}
|
||||
{name: 'balance', desc: 'Prevent spending bellow point', flags: ['-b', '--balance'], type: 'num'},
|
||||
{name: 'sleep', desc: 'Amount of time to wait between purchases, defaults to 1 (second)', flags: ['-s', '--sleep'], default: 1, type: 'num'}
|
||||
]);
|
||||
|
||||
try {
|
||||
args = argParser.parse(ns.args);
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print header with logs
|
||||
* @param message - message to append to logs
|
||||
*/
|
||||
function log(message) {
|
||||
ns.clearLog();
|
||||
ns.print('===================================================');
|
||||
ns.print(`Hacknet Manager: ${nodeCount}/${args['limit']} Nodes`);
|
||||
ns.print('===================================================');
|
||||
if(message != null) messageHistory.push(message);
|
||||
messageHistory.splice(0, messageHistory.length - historyLength);
|
||||
messageHistory.forEach(m => ns.print(m));
|
||||
}
|
||||
|
||||
// Run
|
||||
log();
|
||||
const args = argParser.parse(ns.args);
|
||||
let nodeCount = ns.hacknet.numNodes();
|
||||
const logger = new Logger(ns, () => [() => `Hacknet Manager: ${nodeCount}/${args['limit']}`]);
|
||||
while(true) {
|
||||
const balance = ns.getServerMoneyAvailable('home');
|
||||
|
||||
@ -45,7 +25,7 @@ export async function main(ns) {
|
||||
if(nodeCount < args['limit'] && balance - ns.hacknet.getPurchaseNodeCost() >= args['balance']) {
|
||||
nodeCount++;
|
||||
ns.hacknet.purchaseNode();
|
||||
log(`Buying Node ${nodeCount}`);
|
||||
logger.log(`Buying Node ${nodeCount}`);
|
||||
} else {
|
||||
// Create an ordered list of nodes by their cheapest upgrade
|
||||
const nodes = Array(nodeCount).fill(null)
|
||||
@ -92,12 +72,16 @@ export async function main(ns) {
|
||||
// Apply the cheapest upgrade
|
||||
if(nodes.length && balance - nodes[0].bestUpgrade.cost >= args['balance']) {
|
||||
const cost = Math.round(nodes[0].bestUpgrade.cost * 100) / 100;
|
||||
log(`Node ${nodes[0].index} - ${nodes[0].bestUpgrade.name} ${nodes[0][nodes[0].bestUpgrade.name] + 1} - $${cost}`);
|
||||
logger.log(`Node ${nodes[0].index} - ${nodes[0].bestUpgrade.name} ${nodes[0][nodes[0].bestUpgrade.name] + 1} - $${cost}`);
|
||||
nodes[0].bestUpgrade.purchase();
|
||||
}
|
||||
}
|
||||
|
||||
// Check again in 1s
|
||||
await ns.sleep(1000);
|
||||
await ns.sleep(args['sleep'] * 1000);
|
||||
}
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ export class Logger {
|
||||
this.fns = lineFns;
|
||||
this.historyLen -= fns.length * 2;
|
||||
this.history = Array(this.historyLen).fill('');
|
||||
this.log();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,31 @@
|
||||
/**
|
||||
* Copy a file & scan it for dependencies copying them as well.
|
||||
* @param ns {NS} - BitBurner API
|
||||
* @param src {string} - File to scan & copy
|
||||
* @param device {string} - Device to copy files to
|
||||
* @returns {string[]} - Array of coppied files
|
||||
*/
|
||||
export async function copyWithDependencies(ns, src, device) {
|
||||
const queue = [src], found = [src];
|
||||
while(queue.length) {
|
||||
const file = queue.splice(0, 1)[0];
|
||||
const imports = new RegExp(/from ["']\.?(\/.+)["']/g);
|
||||
const script = await ns.read(file);
|
||||
let match;
|
||||
while((match = imports.exec(script)) != null) {
|
||||
const path = `${match[1]}.js`;
|
||||
queue.push(path);
|
||||
found.push(path);
|
||||
}
|
||||
}
|
||||
await ns.scp(found, device);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a download bar to the terminal.
|
||||
* @params ns {NS} - Bitburner API
|
||||
* @params file - Filename to display with progress bar
|
||||
* @param ns {NS} - BitBurner API
|
||||
* @param file - Filename to display with progress bar
|
||||
*/
|
||||
export async function downloadPrint(ns, file) {
|
||||
const speed = ~~(Math.random() * 100) / 10;
|
||||
@ -9,12 +33,50 @@ export async function downloadPrint(ns, file) {
|
||||
await slowPrint(ns, `${file}${spacing}[==================>] 100%\t(${speed} MB/s)`);
|
||||
}
|
||||
|
||||
export function flatten(object) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* **Impure:** Prune tree down to keys which pass function
|
||||
* @param tree {object} - Tree to search
|
||||
* @param fn {(key: string) => boolean} - Function to test each key with
|
||||
* @returns {boolean} - True if a match was found
|
||||
*/
|
||||
export function pruneTree(tree, fn) {
|
||||
return !!Object.keys(tree).map(k => {
|
||||
let matches = fn(k), children = Object.keys(k), childrenMatch = false;
|
||||
if(children.length) childrenMatch = pruneTree(tree[k], fn);
|
||||
if(!childrenMatch && !matches) delete tree[k];
|
||||
return childrenMatch || matches;
|
||||
}).find(el => el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the network of a given device.
|
||||
* @param ns {NS} - BitBurner API
|
||||
* @param device {string} - Device network that will be scanned
|
||||
* @param maxDepth - Depth to scan to
|
||||
* @returns {[string[], Object]} - A tuple including an array of discovered devices & a tree of the network
|
||||
*/
|
||||
export function scanNetwork(ns, device = ns.getHostname(), maxDepth = Infinity) {
|
||||
let discovered = [device];
|
||||
function scan (device, depth = 1) {
|
||||
if(depth > maxDepth) return {};
|
||||
const localTargets = ns.scan(device).filter(newDevice => !discovered.includes(newDevice));
|
||||
discovered = [...discovered, ...localTargets];
|
||||
return localTargets.reduce((acc, device) => ({...acc, [device]: scan(device, depth + 1)}), {});
|
||||
}
|
||||
const network = scan(device);
|
||||
return [discovered.slice(1), network];
|
||||
}
|
||||
|
||||
/**
|
||||
* Print text to the terminal & then delay for a random amount of time to emulate execution time.
|
||||
* @params ns {NS} - Bitburner API
|
||||
* @params message {string} - Text to display
|
||||
* @params min {number} - minimum amount of time to wait after printing text
|
||||
* @params max {number} - maximum amount of time to wait after printing text
|
||||
* @param ns {NS} - BitBurner API
|
||||
* @param message {string} - Text to display
|
||||
* @param min {number} - minimum amount of time to wait after printing text
|
||||
* @param max {number} - maximum amount of time to wait after printing text
|
||||
*/
|
||||
export async function slowPrint(ns, message, min = 0.5, max = 1.5) {
|
||||
const time = ~~(Math.random() * (max * 1000 - min * 1000)) + min * 1000;
|
||||
@ -24,7 +86,7 @@ export async function slowPrint(ns, message, min = 0.5, max = 1.5) {
|
||||
|
||||
/**
|
||||
* Write a command to the terminal.
|
||||
* @params command {string} - Command that will be run
|
||||
* @param command {string} - Command that will be run
|
||||
* @returns {string} - Response
|
||||
*/
|
||||
export async function terminal(command) {
|
||||
|
@ -10,7 +10,7 @@ export async function main(ns) {
|
||||
const historyLength = 15;
|
||||
const messageHistory = Array(historyLength).fill('');
|
||||
let maxBalance, balance, minSecurity, security;
|
||||
const argParser = new ArgParser('miner.js', 'Weaken, Grow, Hack loop to "mine" machine for money.', null, [
|
||||
const argParser = new ArgParser('miner.js', 'Weaken, Grow, Hack loop to "mine" machine for money. Tail for live updates', null, [
|
||||
{name: 'device', desc: 'Device to mine, defaults to current machine', optional: true, default: ns.getHostname(), type: 'string'}
|
||||
]);
|
||||
let args;
|
||||
|
@ -1,14 +1,30 @@
|
||||
import {ArgError, ArgParser} from './scripts/lib/arg-parser';
|
||||
import {ArgError, ArgParser} from '/scripts/lib/arg-parser';
|
||||
import {pruneTree, scanNetwork} from '/scripts/lib/utils';
|
||||
|
||||
/**
|
||||
* BitBurner autocomplete
|
||||
* @param data {server: string[], txts: string[], scripts: string[], flags: string[]} - Contextual information
|
||||
* @returns {string[]} - Pool of autocomplete options
|
||||
*/
|
||||
export function autocomplete(data) {
|
||||
return [...data.servers];
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the network for devices and display as an ASCII tree.
|
||||
* @param ns {NS} - BitBurner API
|
||||
*/
|
||||
export async function main(ns) {
|
||||
// Setup
|
||||
ns.disableLog('ALL');
|
||||
const argParser = new ArgParser('network-graph.js', 'Scan the network for devices and display as an ASCII tree:\n home\n ├─ n00dles (ROOTED)\n | └─ max-hardware (80|1)\n | └─ neo-net (50|1)\n ├─ foodnstuff (ROOTED)\n └─ sigma-cosmetics (ROOTED)', null, [
|
||||
{name: 'device', desc: 'Point to start scan from, defaults to current machine', optional: true, default: ns.getHostname(), type: 'string'},
|
||||
{name: 'depth', desc: 'Depth to scan to, defaults to 3', flags: ['-d', '--depth'], default: Infinity, type: 'num'},
|
||||
{name: 'filter', desc: 'Display devices matching name', flags: ['-f', '--filter'], type: 'string'},
|
||||
{name: 'regex', desc: 'Display devices matching pattern', flags: ['-r', '--regex'], type: 'string'},
|
||||
{name: 'verbose', desc: 'Displays the required hack level & ports needed to root: (level|port)', flags: ['-v', '--verbose'], type: 'bool'},
|
||||
{name: 'depth', desc: 'Depth to scan to, defaults is 3', flags: ['-d', '--depth'], default: Infinity, type: 'num'},
|
||||
{name: 'filter', desc: 'Filter to device matching name', flags: ['-f', '--filter'], type: 'string'},
|
||||
{name: 'regex', desc: 'Filter to devices matching pattern', flags: ['-e', '--regex'], type: 'string'},
|
||||
{name: 'rooted', desc: 'Filter to devices that have been rooted', flags: ['-r', '--rooted'], type: 'bool'},
|
||||
{name: 'notRooted', desc: 'Filter to devices that have not been rooted', flags: ['-n', '--not-rooted'], type: 'bool'},
|
||||
{name: 'verbose', desc: 'Display the required hack level & number of ports to root: (level|port)', flags: ['-v', '--verbose'], type: 'bool'},
|
||||
]);
|
||||
let args;
|
||||
try {
|
||||
@ -18,81 +34,31 @@ export async function main(ns) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune tree down to devices that match name or pattern.
|
||||
* @param tree {object} - Tree to search
|
||||
* @param find {string} - Device name or pattern to search for
|
||||
* @param regex {boolean} - True to use regex, false for raw check
|
||||
* @returns {object} - Pruned tree
|
||||
*/
|
||||
function filter(tree, find, regex = false) {
|
||||
const found = new Set();
|
||||
function buildWhitelist(tree, find, path = []) {
|
||||
const keys = Object.keys(tree);
|
||||
if(!keys.length) return;
|
||||
Object.keys(tree).forEach(n => {
|
||||
const matches = regex ? new RegExp(find).test(n) : n == find;
|
||||
if(n == 'n00dles') console.log(n, find, matches);
|
||||
if(matches) {
|
||||
found.add(n);
|
||||
path.forEach(p => found.add(p));
|
||||
}
|
||||
buildWhitelist(tree[n], find, [...path, n]);
|
||||
})
|
||||
}
|
||||
function prune(tree, whitelist) {
|
||||
Object.keys(tree).forEach(n => {
|
||||
if(Object.keys(tree[n]).length) prune(tree[n], whitelist);
|
||||
if(!whitelist.includes(n)) delete tree[n];
|
||||
});
|
||||
}
|
||||
buildWhitelist(tree, find);
|
||||
prune(tree, Array.from(found));
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively search network & build a tree
|
||||
* @param host {string} - Point to scan from
|
||||
* @param depth {number} - Current scanning depth
|
||||
* @param blacklist {String[]} - Devices already discovered
|
||||
* @returns Dicionary of discovered devices
|
||||
*/
|
||||
function scan(host, depth = 1, blacklist = [host]) {
|
||||
if(depth > args['depth']) return {};
|
||||
const localTargets = ns.scan(host).filter(target => !blacklist.includes(target));
|
||||
blacklist = [...blacklist, ...localTargets];
|
||||
return localTargets.reduce((acc, target) => {
|
||||
const info = ns.getServer(target);
|
||||
const verb = args['verbose'] ? ` (${info.hasAdminRights ? 'ROOTED' : `${info.requiredHackingSkill}|${info.numOpenPortsRequired}`})` : '';
|
||||
const name = `${target}${verb}`;
|
||||
acc[name] = scan(target, depth + 1, blacklist);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate tree & print to screen
|
||||
* @param tree {object} - Tree to parse
|
||||
* @param tree {Object} - Tree to parse
|
||||
* @param stats {Object} - Pool of stats to pull extra information from
|
||||
* @param spacer {string} - Spacer text for tree formatting
|
||||
*/
|
||||
function render(tree, spacer = ' ') {
|
||||
Object.keys(tree).forEach((key, i, arr) => {
|
||||
function render(tree, stats, spacer = ' ') {
|
||||
Object.keys(tree).forEach((device, i, arr) => {
|
||||
const deviceStats = stats ? stats[device] : null;
|
||||
const stat = deviceStats ? ` (${deviceStats.hasAdminRights ? 'ROOTED' : `${deviceStats.requiredHackingSkill}|${deviceStats.numOpenPortsRequired}`})` : '';
|
||||
const last = i == arr.length - 1;
|
||||
const branch = last ? '└─ ' : '├─ ';
|
||||
ns.tprint(`${spacer}${branch}${key}`);
|
||||
render(tree[key], spacer + (last ? ' ' : '| '));
|
||||
ns.tprint(spacer + branch + device + stat);
|
||||
render(tree[device], stats, spacer + (last ? ' ' : '| '));
|
||||
});
|
||||
}
|
||||
|
||||
// Run
|
||||
const [devices, network] = scanNetwork(ns, args['device'], args['depth']);
|
||||
const stats = devices.reduce((acc, d) => ({...acc, [d]: ns.getServer(d)}), {});
|
||||
if(args['regex']) pruneTree(network, d => RegExp(args['regex']).test(d)); // Regex flag
|
||||
else if(args['filter']) pruneTree(network, d => d == args['filter']); // Filter flag
|
||||
if(args['rooted']) pruneTree(network, d => stats[d].hasAdminRights); // Rooted flag
|
||||
else if(args['notRooted']) pruneTree(network, d => !stats[d].hasAdminRights); // Not rooted flag
|
||||
ns.tprint(args['device']);
|
||||
const found = scan(args['device']);
|
||||
if(args['regex']) filter(found, args['regex'], true);
|
||||
else if(args['filter']) filter(found, args['filter']);
|
||||
render(found);
|
||||
render(network, args['verbose'] ? stats : null);
|
||||
ns.tprint('');
|
||||
}
|
||||
|
||||
export function autocomplete(data) {
|
||||
return [...data.servers];
|
||||
}
|
||||
|
@ -136,8 +136,7 @@ export async function main(ns) {
|
||||
'hacknet-manager.js',
|
||||
'miner.js',
|
||||
'network-graph.js',
|
||||
'rootkit.js',
|
||||
'vanguard.js'
|
||||
'rootkit.js'
|
||||
];
|
||||
let args;
|
||||
try {
|
||||
|
@ -1,54 +0,0 @@
|
||||
import {ArgError, ArgParser} from './scripts/lib/arg-parser';
|
||||
|
||||
/**
|
||||
* Weaken a device indefinitely.
|
||||
* @params ns {NS} - BitBurner API
|
||||
*/
|
||||
export async function main(ns) {
|
||||
// Setup
|
||||
ns.disableLog('ALL');
|
||||
let args, counter = 0, orgSecurity, security;
|
||||
const historyLength = 17;
|
||||
const messageHistory = Array(historyLength).fill('');
|
||||
const argParser = new ArgParser('vanguard.js', 'Weaken a device indefinitely.', null, [
|
||||
{name: 'device', desc: 'Device to weaken, defaults to the current machine', optional: true, default: ns.getHostname(), type: 'string'},
|
||||
{name: 'limit', desc: 'Limit the number of times to run', flags: ['-l', '--limit'], default: Infinity, type: 'num'}
|
||||
]);
|
||||
try {
|
||||
args = argParser.parse(ns.args);
|
||||
orgSecurity = security = ns.getServerSecurityLevel(args['device']);
|
||||
} catch(err) {
|
||||
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print header with logs
|
||||
* @param message - message to append to logs
|
||||
*/
|
||||
function log(message) {
|
||||
ns.clearLog();
|
||||
ns.print('===================================================');
|
||||
ns.print(`Vanguard: ${args['device']}`);
|
||||
ns.print('===================================================');
|
||||
ns.print(`Security: ${security}/${orgSecurity}`);
|
||||
ns.print('===================================================');
|
||||
if(message != null) messageHistory.push(message);
|
||||
messageHistory.splice(0, messageHistory.length - historyLength);
|
||||
messageHistory.forEach(m => ns.print(m));
|
||||
}
|
||||
|
||||
// Run
|
||||
log();
|
||||
do {
|
||||
security = ns.getServerSecurityLevel(args['device']);
|
||||
log(`Attacking...`);
|
||||
log(await ns.weaken(args['device']));
|
||||
counter++;
|
||||
} while (counter < args['limit']);
|
||||
ns.print('Complete!');
|
||||
}
|
||||
|
||||
export function autocomplete(data) {
|
||||
return [...data.servers];
|
||||
}
|
Loading…
Reference in New Issue
Block a user