scripts/net-monitor.js
/**
 * Print our fancy overview display into the box.
 * @param {string} logType
 * @param {Object.<string,Server>} servers
 * @param {Element} box
 * @param {NS} ns
 */
Print our fancy overview display into the box.
Print our fancy overview display into the box .
function printOverviewStatus(logType, servers, box, ns) {
    const insideWidth = 48;
    let lines = [];
    let printfn = ns.print;
    let sections = {
        home: [],
        subsystems: [],
        swarmStatus: [],
        targetStatus: [],
    };
    let output = [];
    printfn = (obj) => output.push(obj);
    let print1Column = (data) => printItemsNColumns(data, 1, printfn);
    let aFewSecondsAgo = Date.now() - 45 * 1000;
    let targets = Object.values(servers);
    targets = targets.filter((s) => s.lastTimeSeenTargetedBy.hack > aFewSecondsAgo || s.lastTimeSeenTargetedBy.grow > aFewSecondsAgo || s.lastTimeSeenTargetedBy.weaken > aFewSecondsAgo);
    let hackTargets = targets.filter((t) => t.lastTimeSeenTargetedBy.hack > aFewSecondsAgo);
    let prepTargets = targets.filter((t) => t.lastTimeSeenTargetedBy.hack <= aFewSecondsAgo);
    sections.home.push(formatHomeSection(servers, ns, insideWidth));
    sections.subsystems.push(formatSubsystemSection(ns, insideWidth));
    sections.swarmStatus.push(formatSwarmSection(servers, ns, insideWidth));
    lines = [`  Being Hacked: ${hackTargets.length}, Being Prepared: ${prepTargets.length}`];
    let data = boxdraw(lines, 'Target Summary', insideWidth);
    sections.targetStatus.push(data);
    for (let i = 0; i < sections.subsystems[0].length; i++) {
        let line = sections.subsystems[0][i];
        let sysname = line.match(/\w+-*\w*-*\w*/g);
        if (sysname != null) {
            sysname = sysname[0];
            let sys = subsystems.find((s) => s.name === sysname);
            if (sys && sys.shouldTail) {
                line = line.replace(/(\d+\.\d+ GB)/g, `<a class="tail" style="text-decoration: underline">$1</a>`);
            }
            if (sys && sys.name === 'daemon') {
                line = line.replace(/(daemon)/, `<a class="showTarget" style="text-decoration: underline">$1</a>`);
            }
            if (sys && sys.name === 'stockmaster') {
                line = line.replace(/(stockmaster)/, `<a class="showStocks" style="text-decoration: underline">$1</a>`);
            }
            sections.subsystems[0][i] = line;
        }
    }
    if (logType === 'Short') {
        print1Column([sections.home, sections.subsystems, sections.swarmStatus, sections.targetStatus].flat(1));
    }
    let htmlFormat = (s) => {
        if (s === '') return '</br>';
        return `<p>${s}</p>`;
    };
    let monitorElem = box.querySelector('.panopticon-monitor');
    monitorElem.innerHTML = output.map((line) => htmlFormat(line)).join('');
    box.querySelectorAll('.tail').forEach((q) => q.addEventListener('click', () => tailSubsystem(q.parentNode.textContent, ns)));
    box.querySelectorAll('.showTarget').forEach((q) => q.addEventListener('click', () => addDisplayType('Targets1Up')));
    box.querySelectorAll('.showStocks').forEach((q) => q.addEventListener('click', () => addDisplayType('Stocks')));
}
function printOverviewStatus ( logType , servers , box , ns ) { const insideWidth = 48 ; let lines = [ ] ; let printfn = ns . print ; let sections = { home : [ ] , subsystems : [ ] , swarmStatus : [ ] , targetStatus : [ ] , } ; let output = [ ] ; printfn = ( obj ) => output . push ( obj ) ; let print1Column = ( data ) => printItemsNColumns ( data , 1 , printfn ) ; let aFewSecondsAgo = Date . now ( ) - 45 * 1000 ; let targets = Object . values ( servers ) ; targets = targets . filter ( ( s ) => s . lastTimeSeenTargetedBy . hack > aFewSecondsAgo || s . lastTimeSeenTargetedBy . grow > aFewSecondsAgo || s . lastTimeSeenTargetedBy . weaken > aFewSecondsAgo ) ; let hackTargets = targets . filter ( ( t ) => t . lastTimeSeenTargetedBy . hack > aFewSecondsAgo ) ; let prepTargets = targets . filter ( ( t ) => t . lastTimeSeenTargetedBy . hack <= aFewSecondsAgo ) ; sections . home . push ( formatHomeSection ( servers , ns , insideWidth ) ) ; sections . subsystems . push ( formatSubsystemSection ( ns , insideWidth ) ) ; sections . swarmStatus . push ( formatSwarmSection ( servers , ns , insideWidth ) ) ; lines = [ ` ${ hackTargets . length } ${ prepTargets . length } ` ] ; let data = boxdraw ( lines , 'Target Summary' , insideWidth ) ; sections . targetStatus . push ( data ) ; for ( let i = 0 ; i < sections . subsystems [ 0 ] . length ; i ++ ) { let line = sections . subsystems [ 0 ] [ i ] ; let sysname = line . match ( / \w+-*\w*-*\w* / g ) ; if ( sysname != null ) { sysname = sysname [ 0 ] ; let sys = subsystems . find ( ( s ) => s . name === sysname ) ; if ( sys && sys . shouldTail ) { line = line . replace ( / (\d+\.\d+ GB) / g , ` ` ) ; } if ( sys && sys . name === 'daemon' ) { line = line . replace ( / (daemon) / , ` ` ) ; } if ( sys && sys . name === 'stockmaster' ) { line = line . replace ( / (stockmaster) / , ` ` ) ; } sections . subsystems [ 0 ] [ i ] = line ; } } if ( logType === 'Short' ) { print1Column ( [ sections . home , sections . subsystems , sections . swarmStatus , sections . targetStatus ] . flat ( 1 ) ) ; } let htmlFormat = ( s ) => { if ( s === '' ) return '</br>' ; return ` ${ s } ` ; } ; let monitorElem = box . querySelector ( '.panopticon-monitor' ) ; monitorElem . innerHTML = output . map ( ( line ) => htmlFormat ( line ) ) . join ( '' ) ; box . querySelectorAll ( '.tail' ) . forEach ( ( q ) => q . addEventListener ( 'click' , ( ) => tailSubsystem ( q . parentNode . textContent , ns ) ) ) ; box . querySelectorAll ( '.showTarget' ) . forEach ( ( q ) => q . addEventListener ( 'click' , ( ) => addDisplayType ( 'Targets1Up' ) ) ) ; box . querySelectorAll ( '.showStocks' ) . forEach ( ( q ) => q . addEventListener ( 'click' , ( ) => addDisplayType ( 'Stocks' ) ) ) ; }
Print our fancy overview display into the box.
Print our fancy overview display into the box .
/* Let's try to get organized. Each section is an array of already-formatted lines. 
       Generate all of them first, then print them at the end based on what's populated 
       and what our logType calls for. */ /**@type{Object.<string, string[][]>} */ // Since we want to stuff all our output into a box, collect it into an array instead of printing it. // Simply filtering by being the target of an attack is fine, but it results in too much churn. Let's do some sort of decay time instead. // --- HOME DATA --- // --- SWARM STATUS --- // --- Target Summary --- // Add hyperlinks to the subsystems section. // grab the first word from the line. // Add the link to open a tail window. // Special displays // Print any common trailer stuff here. // Link up the <a> elements to their onClick() handlers.