bitburner/scripts/crawler.js

76 lines
3.1 KiB
JavaScript
Raw Normal View History

2022-03-15 20:41:23 -04:00
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}}'];
}
2022-02-11 01:08:32 -05:00
2022-03-09 14:06:14 -05:00
/**
* Search the network for targets to execute a script against.
* @param ns {NS} - BitBurner API
*/
export async function main(ns) {
2022-03-15 20:41:23 -04:00
// Setup
2022-03-09 14:06:14 -05:00
ns.disableLog('ALL');
const argParser = new ArgParser('crawler.js', 'Search the network for targets to execute a script against.', null, [
{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, type: 'string'},
{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'},
2022-03-15 20:41:23 -04:00
{name: 'level', desc: 'Exclude targets with higher hack level, defaults to current hack level', flags: ['-l', '--level'], default: ns.getHackingLevel(), type: 'num'},
{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: 'ports', desc: 'Exclude targets with too many closed ports', flags: ['-p', '--ports'], default: Infinity, type: 'num'},
2022-03-17 12:19:54 -04:00
{name: 'silent', desc: 'Suppress program output', flags: ['-s', '--silent'], type: 'bool'}
], true);
2022-02-04 11:49:05 -05:00
2022-03-15 20:41:23 -04:00
try {
// Run
const args = argParser.parse(ns.args);
const [devices, network] = scanNetwork(ns);
let complete = 0, failed = 0, skipped = 0;
for(let device of devices) {
// Check root status if needed
const rooted = ns.hasRootAccess(device);
if(args['rooted'] && !rooted) continue;
if(args['notRooted'] && rooted) continue;
2022-03-15 20:41:23 -04:00
// Skip invalid devices
if(device == 'home' || args['level'] < ns.getServerRequiredHackingLevel(device) || args['ports'] < ns.getServerNumPortsRequired(device)) {
skipped++;
continue;
}
2022-02-11 01:08:32 -05:00
2022-03-15 20:41:23 -04:00
// 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++;
continue;
}
2022-02-11 01:08:32 -05:00
2022-03-15 20:41:23 -04:00
// Wait for script to finish
while(ns.scriptRunning(args['script'], 'home'))
await ns.sleep(1000);
complete++;
2022-03-09 14:06:14 -05:00
}
2022-02-11 01:08:32 -05:00
2022-03-15 20:41:23 -04:00
// Output report
if(!args['silent']) {
ns.tprint('===================================================');
ns.tprint(`Crawler Report: ${complete + failed + skipped} Devices`);
2022-03-15 20:41:23 -04:00
ns.tprint('===================================================');
ns.tprint(`Complete: ${complete}\tFailed: ${failed}\tSkipped: ${skipped}`);
ns.tprint('');
2022-03-09 14:06:14 -05:00
}
2022-03-15 20:41:23 -04:00
} catch(err) {
if(err instanceof ArgError) return ns.tprint(argParser.help(err.message));
throw err;
2022-02-11 01:08:32 -05:00
}
2022-02-04 11:49:05 -05:00
}