weaken_manager.js: add. lib_server_used.js: move to lib_ram_script. lib_ps: delete. main.js, hacker.js, lib_ram_script.js: refactor. README.md: update.

[?]
May 14, 2020, 2:49 PM
JS52JD4QKFTHK2HUV5FXTWZ7HAC5ES7BZQX6M2A4XZFIYKKPBSGQC

Dependencies

  • [2] JGNALSUQ add "cyclic_weaken.js" feature. hacker.js, main.js, libs: refactor. README.md: update.
  • [3] DJDWBCCQ add missing "nop.js". killall.js: rename to kill.js. add `--script` and `--server` options.
  • [4] CJBGAILA add optional `--target` parameter for `main.js`. update `README.md`.
  • [5] HLC2L3NJ add "tor.js" and "programs.js". use `minimist` for "main.js" argument parsing.
  • [6] Y5OWMCQR all: remove unecessary uses of `exec`. refactor. main.js: add RAM reservation logic. lib_ram.js: renamed to lib_ram_server.js. README.js: update.
  • [7] FBAPT2WW executables: dynamically load help messages. lshw.js, main.js: add options to change score correction method and score factor multipliers. README.md: update.
  • [8] V4DMWF25 remove redundant preparation steps in "hacker.js".
  • [9] SXEJJKPI executables: add `--help` flag. hacker.js: change scheduling logic. refactor. kill.js: allow handling more than one server or script at a time. cyclic_weaken.js: add. README.md: update.
  • [10] 2BKHJI2S init
  • [11] NQ22FUSW add more options to `main.js`. update `README.md`.
  • [12] HSNSECD5 all: refactor. main.js: fix call to `void_kill_script_named_server_named`.
  • [13] IFVY3INI contracts.js: add --verbose and --check-delay options. README.md: update.
  • [14] AXGQ7FML split and refactor hacking logic to "hacker.js" and argument parsing and script execution logic to "main.js". update "README.md".
  • [15] VMXI7PS4 added action cap. improved scoring system. fixed parts of security and cash predictors. made lshw loopable.
  • [16] RWMZ7DVL split and refactor various logics. update "README.md".
  • [17] ZRPOW4ER hacker.js, lib_time.js: supress error messages. hacker.js: use `getBitNodeMultipliers`. lib_time.js: use `getStats`. README.md: update.
  • [18] 6MBUKAG6 remove unneeded functions and comments. update readme.
  • [19] FCJA5EXS contracts.js: add. README.md: update.
  • [20] 2WOLGB42 README.md: update. kill.js: fix argument parser. lshw.js: add `-p` option. increase information given. main.js: fix error message. set saner defaults. hacker.js: split some functions into "lib_time.js" and "lib_score.js". ram.js: fix.
  • [21] BKG7YVUV main.js, hacker.js, servers.js, ram.js: refactor.
  • [22] ZVQK2652 executables: fix help message.

Change contents

  • edit in sbin/hacker.js at line 34
    [3.1878]
    [3.1878]
    import { array_get_servers } from "lib_servers.js";
  • replacement in sbin/hacker.js at line 38
    [3.2002][2.185:247]()
    import { object_make_server_used } from "lib_server_used.js";
    [3.2002]
    [2.247]
    import { object_make_server_used } from "lib_ram_script.js";
  • edit in sbin/hacker.js at line 56
    [3.2221][3.2221:2284]()
    import { boolean_array_scripts_any_running } from "lib_ps.js";
  • edit in sbin/hacker.js at line 160
    [2.881]
    [3.21168]
    };
    };
    // returns true if a script is running on any server
    const boolean_script_running = function (ns, string_script) {
    const array_servers = array_get_servers(ns);
    for (
    let integer_index_server = 0;
    integer_index_server < array_servers.length;
    ++integer_index_server
    ) {
    const string_server = array_servers[integer_index_server],
    array_scripts_running = ns.ps(string_server);
    if (array_scripts_running.length > 0)
    for (
    let integer_index_script = 0;
    integer_index_script < array_scripts_running.length;
    ++integer_index_script
    ) {
    const object_script = array_scripts_running[integer_index_script],
    string_script_to_check = object_script.filename;
    if (string_script_to_check == string_script) return !0;
    }
    }
    return !1;
    };
    // returns true if any of the scripts in an array is running on any server
    const boolean_array_scripts_any_running = function (ns, array_scripts) {
    for (
    let integer_index_script = 0;
    integer_index_script < array_scripts.length;
    ++integer_index_script
    )
    return boolean_script_running(ns, array_scripts[integer_index_script]);
    };
    // returns the appropriate script name
    const string_get_script = function (
    ns,
    string_job
    ) {
    const array_workers = object_get_constants(ns).array_workers;
    switch (string_job) {
    case "weaken":
    return array_workers[0].name;
    case "grow":
    return array_workers[1].name;
    case "hack":
    return array_workers[2].name;
    default:
    throw new Error(`ERROR: Unrecognised job "${string_job}".`);
    }
    };
    // weaken, grow, hack
    // the threads required for weaken to cause string_server_target's security to decrease by float_weaken_amount. adapted from `weaken` in NetscriptFunctions.js and `weaken` in Server.ts
    const integer_get_threads_required_for_weaken = function (
    ns,
    float_weaken_amount
    ) {
    const object_constants = object_get_constants(ns);
    return (
    float_weaken_amount *
    Math.pow(object_constants.ServerWeakenAmount, -1) *
    Math.pow(object_constants.object_bitnode_multipliers.ServerWeakenRate, -1)
    );
    };
    // returns the threads required for weaken to cause string_server_target's security to reach minimum
    const integer_get_threads_required_for_weaken_minimum_security = function (
    ns,
    string_server_target,
    float_server_target_security
    ) {
    return Math.ceil(
    integer_get_threads_required_for_weaken(
    ns,
    float_server_target_security -
    ns.getServerMinSecurityLevel(string_server_target)
    )
    );
    };
    // returns the security decrease from the weaken threads used. Adapted from `weaken` in NetscriptFunctions.js and `weaken` in Server.ts
    const float_get_security_decrease_from_weaken = function (
    ns,
    integer_threads_weaken
    ) {
    return integer_threads_weaken * object_get_constants(ns).ServerWeakenAmount;
    };
    // grow stuff
    // returns the number of threads of `grow` needed to grow `string_server_target` by the percentage `float_growth` when it has security of `float_server_security`. float_growth = How much the server is being grown by, in DECIMAL form (e.g. 1.5 rather than 50). adapted from `numCycleForGrowth` in https://github.com/danielyxie/bitburner/blob/master/src/Server/ServerHelpers.ts
    const integer_get_threads_for_growth = function (
    ns,
    string_server_target,
    float_server_target_security,
    float_growth
    ) {
    const object_constants = object_get_constants(ns);
    let ajdGrowthRate = 1 + (object_constants.ServerBaseGrowthRate - 1) / float_server_target_security;
    if (ajdGrowthRate > object_constants.ServerMaxGrowthRate) {
    ajdGrowthRate = object_constants.ServerMaxGrowthRate;
    }
    const serverGrowthPercentage = ns.getServerGrowth(string_server_target) / 100;
    const cycles = Math.log(float_growth)/(Math.log(ajdGrowthRate) * object_constants.object_hacking_multipliers.growth * serverGrowthPercentage * object_constants.object_bitnode_multipliers.ServerGrowthRate);
    return Math.ceil(cycles);
    };
    // Inverse function of integer_get_threads_for_growth. Returns the percentage growth in decimal form (e.g., 2 = 100% growth).
    const float_get_growth_from_threads = function (
    ns,
    string_server_target,
    float_server_target_security,
    integer_threads
    ) {
    const object_constants = object_get_constants(ns);
    let ajdGrowthRate = 1 + (object_constants.ServerBaseGrowthRate - 1) / float_server_target_security;
    if (ajdGrowthRate > object_constants.ServerMaxGrowthRate) {
    ajdGrowthRate = object_constants.ServerMaxGrowthRate;
    }
    const serverGrowthPercentage = ns.getServerGrowth(string_server_target) / 100;
    const float_growth = Math.pow(ajdGrowthRate, integer_threads * object_constants.object_hacking_multipliers.growth * serverGrowthPercentage * object_constants.object_bitnode_multipliers.ServerGrowthRate);
    return float_growth;
    };
    // returns the threads required by grow to grow string_server_target's cash to its maximum when security is at float_server_target_security and current cash is at float_server_target_cash
    const integer_get_threads_required_for_grow_cash_maximum = function (
    ns,
    string_server_target,
    float_server_target_security,
    float_server_target_cash
    ) {
    return integer_get_threads_for_growth(
    ns,
    string_server_target,
    float_server_target_security,
    ns.getServerMaxMoney(string_server_target) / float_server_target_cash
    );
    };
    // returns the security increase from the growth threads used. Adapted from `processSingleServerGrowth` in ServerHelpers.ts and `fortify` in Server.ts
    const float_get_security_increase_from_grow = function (
    ns,
    integer_threads_grow
    ) {
    return (
    2 * object_get_constants(ns).ServerFortifyAmount * integer_threads_grow
    );
    };
    // hack stuff
    // returns the percentage of the available cash in string_server_target that is stolen when it is hacked when it has float_server_target_security. adapted from calculatePercentMoneyHacked() in https://github.com/danielyxie/bitburner/blob/master/src/Hacking.js . See also `hackDifficulty` in https://github.com/danielyxie/bitburner/blob/master/src/Server.js
    const float_get_percentage_cash_taken_per_hack = function (
    ns,
    string_server_target,
    float_server_target_security
    ) {
    const object_constants = object_get_constants(ns);
    const balanceFactor = 240;
    const difficultyMult = (100 - float_server_target_security) / 100;
    const skillMult = (ns.getHackingLevel() - (ns.getServerRequiredHackingLevel(string_server_target) - 1)) / ns.getHackingLevel();
    const percentMoneyHacked = difficultyMult * skillMult * object_constants.object_hacking_multipliers.money / balanceFactor;
    if (percentMoneyHacked < 0) { return 0; }
    if (percentMoneyHacked > 1) { return 1; }
    return percentMoneyHacked * object_constants.object_bitnode_multipliers.ScriptHackMoney;
    };
    // returns the threads required to steal "float_percentage_to_steal" of available money in string_server_target
    const integer_get_threads_required_to_hack_percentage = function (
    ns,
    string_server_target,
    float_server_target_security,
    float_percentage_to_steal
    ) {
    return Math.ceil(
    float_percentage_to_steal /
    float_get_percentage_cash_taken_per_hack(
    ns,
    string_server_target,
    float_server_target_security
    )
    );
    };
    // returns the security increase from the hack threads. adapted from `hack` in NetscriptFunctions.js and `fortify` in Server.ts
    const float_get_security_increase_from_hack = function (
    ns,
    string_server_target,
    float_server_target_security,
    float_server_target_cash,
    integer_threads_hack
    ) {
    let maxThreadNeeded = Math.ceil(1/float_get_percentage_cash_taken_per_hack(ns, string_server_target, float_server_target_security)*(float_server_target_cash/ns.getServerMaxMoney(string_server_target)));
    if (isNaN(maxThreadNeeded)) {
    // Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
    maxThreadNeeded = 1e6;
    }
    return object_get_constants(ns).ServerFortifyAmount * Math.min(integer_threads_hack, maxThreadNeeded);
    };
    // depending on the job:
    // if string_get_script(ns, "weaken"): returns the threads required for weaken to cause string_server_target's security to reach minimum if possible, otherwise, return max threads that string_server_used can provide
    // if string_get_script(ns, "grow"): returns the threads required by grow to grow string_server_target's cash to its maximum if possible, otherwise, return max threads that string_server_used can provide
    // if string_get_script(ns, "hack"): returns the threads required to steal "float_percentage_to_steal" of available money in string_server_target if possible, otherwise, return max threads that string_server_used can provide
    const integer_get_threads = function (
    ns,
    float_server_used_ram_free,
    string_script,
    string_server_target,
    float_server_target_security_current,
    float_server_target_cash_current,
    float_percentage_to_steal
    ) {
    const integer_get_threads_required = function (
    ns,
    string_script,
    string_server_target,
    float_server_target_security_current,
    float_server_target_cash_current,
    float_percentage_to_steal
    ) {
    switch (string_script) {
    case string_get_script(ns, "weaken"):
    return integer_get_threads_required_for_weaken_minimum_security(
    ns,
    string_server_target,
    float_server_target_security_current
    );
    case string_get_script(ns, "grow"):
    return integer_get_threads_required_for_grow_cash_maximum(
    ns,
    string_server_target,
    float_server_target_security_current,
    // counts 0 cash as 1 so it can still grow. adapted from `grow` in NetscriptFunctions.js
    float_clamp(float_server_target_cash_current, 1, 1 / 0)
    );
    case string_get_script(ns, "hack"):
    return integer_get_threads_required_to_hack_percentage(
    ns,
    string_server_target,
    float_server_target_security_current,
    float_percentage_to_steal
    );
    }
    };
    return float_clamp(
    integer_get_threads_required(
    ns,
    string_script,
    string_server_target,
    float_server_target_security_current,
    float_server_target_cash_current,
    float_percentage_to_steal
    ),
    0,
    Math.trunc(
    float_server_used_ram_free / ns.getScriptRam(string_script)
    )
    );
    };
    // percentage to steal stuff
    // returns the threads required by grow to grow a string_server_target's money back to its original value after stealing float_percentage_to_steal of it, and assuming security is at float_server_target_security
    const integer_get_threads_required_for_cash_grow_after_percentage_stolen = function (
    ns,
    string_server_target,
    float_server_target_security,
    float_percentage_to_steal
    ) {
    return integer_get_threads_for_growth(
    ns,
    string_server_target,
    float_server_target_security,
    Math.pow(1 - float_percentage_to_steal, -1)
    );
    };
    // should return true if there is enough ram to provide the threads required by weaken to weaken to minimum security, then by grow to grow string_server_target's cash back to maximum after stealing float_percentage_to_steal of the cash, then by weaken to weaken to minimum security again if possible, otherwise, returns false. assumes security is at float_server_target_security
    const boolean_is_ram_enough_after_hack_percentage = function (
    ns,
    float_server_used_ram_free,
    string_server_target,
    float_server_target_cash,
    float_server_target_security,
    float_percentage_to_steal
    ) {
    const
    float_server_target_security_after_hack =
    float_server_target_security +
    float_get_security_increase_from_hack(
    ns,
    string_server_target,
    float_server_target_security,
    float_server_target_cash,
    integer_get_threads(
    ns,
    float_server_used_ram_free,
    string_get_script(ns, "hack"),
    string_server_target,
    float_server_target_security,
    float_server_target_cash,
    float_percentage_to_steal
    )
    ),
    integer_threads_required_for_weaken_minimum_security_after_hack = integer_get_threads_required_for_weaken_minimum_security(
    ns,
    string_server_target,
    float_server_target_security_after_hack
    ),
    float_server_target_security_after_weaken =
    float_server_target_security_after_hack -
    float_get_security_decrease_from_weaken(
    ns,
    integer_threads_required_for_weaken_minimum_security_after_hack
    ),
    integer_threads_required_for_cash_grow_after_percentage_stolen = integer_get_threads_required_for_cash_grow_after_percentage_stolen(
    ns,
    string_server_target,
    float_server_target_security_after_weaken,
    float_percentage_to_steal
    ),
    float_server_target_security_after_grow =
    float_server_target_security_after_weaken +
    float_get_security_increase_from_grow(
    ns,
    integer_threads_required_for_cash_grow_after_percentage_stolen
    ),
    integer_threads_required_for_weaken_minimum_security_after_grow = integer_get_threads_required_for_weaken_minimum_security(
    ns,
    string_server_target,
    float_server_target_security_after_grow
    ),
    ram_weaken = ns.getScriptRam(string_get_script(ns, "weaken")),
    float_ram_required =
    integer_threads_required_for_weaken_minimum_security_after_hack *
    ram_weaken +
    integer_threads_required_for_cash_grow_after_percentage_stolen *
    ns.getScriptRam(string_get_script(ns, "grow")) +
    integer_threads_required_for_weaken_minimum_security_after_grow *
    ram_weaken;
    return float_ram_required < float_server_used_ram_free;
    };
    // returns the number of cycles of bisection to be done to reach a certain precision, rounded up to the nearest integer
    const integer_get_cycles_for_bisection_precision = function (float_precision) {
    return Math.ceil(
    Math.log(Math.pow(float_precision, -1)) * Math.pow(Math.log(2), -1)
    );
    };
    // this should return optimum percentage to steal such that cash stolen at most is as high as float_steal_cap and string_server_target's security is able to be weakened to minimum with one weaken after the hack, its cash grown to 100% after one grow after the weaken, then its security weakened again to minimum with one weaken, all with the ram it has remaining after the hack by using a binary search algorithm
    const float_get_percentage_to_steal = function (
    ns,
    float_server_used_ram_free,
    string_server_target,
    float_server_target_cash,
    float_server_target_security,
    float_precision,
    float_steal_cap
    ) {
    const integer_cycles_for_bisection_precision = integer_get_cycles_for_bisection_precision(
    float_precision
    );
    let
    float_ceiling = 1,
    float_floor = 0,
    float_percentage_to_steal = 0.5 * (float_ceiling + float_floor);
    for (
    let integer_index = 0;
    integer_index < integer_cycles_for_bisection_precision &&
    (boolean_is_ram_enough_after_hack_percentage(
    ns,
    float_server_used_ram_free,
    string_server_target,
    float_server_target_cash,
    float_server_target_security,
    float_percentage_to_steal
    )
    ? (float_floor = float_percentage_to_steal)
    : (float_ceiling = float_percentage_to_steal),
    (float_percentage_to_steal = 0.5 * (float_ceiling + float_floor)),
    !(float_percentage_to_steal > float_steal_cap));
    ++integer_index
    );
    // cap which can be used so not all money is stolen, which can be bad because it's harder to grow from 0 in most cases
    return float_percentage_to_steal > float_steal_cap
    ? float_steal_cap
    : float_percentage_to_steal;
    };
    // servers
    // sort an array of servers by their score, from lowest to highest
    const void_sort_by_server_scores = function (
    ns,
    array_servers,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ) {
    return array_servers.sort(
    (string_element_0, string_element_1) =>
    float_get_server_score(
    ns,
    string_element_0,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ) -
    float_get_server_score(
    ns,
    string_element_1,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    )
    );
    };
    const array_get_servers_hackable_sorted_by_score = function (
    ns,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ) {
    return void_sort_by_server_scores(
    ns,
    array_get_servers_hackable(ns),
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    );
    };
    // return the hackable server at the stated position. 1 = best hackable server
    const string_get_server_hackable_by_score_position = function (
    ns,
    integer_score_position,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ) {
    const array_servers_hackable = array_get_servers_hackable_sorted_by_score(
    ns,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    );
    return array_servers_hackable[
    array_servers_hackable.length - integer_score_position
    ];
    };
    // make a server target object
    const object_make_server_target = function (
    ns,
    string_server
    ) {
    return {
    name: string_server,
    get_security_minimum: function () {
    return ns.getServerMinSecurityLevel(string_server);
    },
    security_current: ns.getServerSecurityLevel(string_server),
    get_cash_maximum: function () {
    return ns.getServerMaxMoney(string_server);
    },
    cash_current: ns.getServerMoneyAvailable(string_server),
    job: function () {
    return this.security_current > this.get_security_minimum()
    ? string_get_script(ns, "weaken")
    : this.cash_current < this.get_cash_maximum()
    ? string_get_script(ns, "grow")
    : string_get_script(ns, "hack");
    },
    apply_job: function (object_job) {
    switch (object_job.string_script) {
    case string_get_script(ns, "weaken"):
    this.security_current = float_clamp(
    this.security_current -
    float_get_security_decrease_from_weaken(
    ns,
    object_job.integer_threads
    ),
    this.get_security_minimum(),
    1 / 0
    );
    break;
    case string_get_script(ns, "grow"):
    // counts 0 cash as 1 so it can still grow. adapted from `grow` in NetscriptFunctions.js
    this.cash_current = float_clamp(
    float_clamp(this.cash_current, 1, 1 / 0) *
    float_get_growth_from_threads(
    ns,
    this.name,
    this.security_current,
    object_job.integer_threads
    ),
    this.get_security_minimum(),
    1 / 0
    );
    // the following is adapted from `processSingleServerGrowth` in ServerHelpers.ts and `fortify` in Server.ts
    this.security_current += float_get_security_increase_from_grow(
    ns,
    object_job.integer_threads
    );
    break;
    case string_get_script(ns, "hack"):
    // the following is adapted from `hack` in NetscriptFunctions.js and `fortify` in Server.ts
    // deep copy
    const float_cash_before = JSON.parse(
    JSON.stringify(this.cash_current)
    );
    this.cash_current = float_clamp(
    this.cash_current -
    Math.floor(
    this.cash_current *
    float_get_percentage_cash_taken_per_hack(
    ns,
    this.name,
    this.security_current
    )
    ) *
    object_job.integer_threads,
    0,
    1 / 0
    );
    this.security_current += float_get_security_increase_from_hack(
    ns,
    this.name,
    this.security_current,
    float_cash_before,
    object_job.integer_threads
    );
    break;
    default:
    throw new Error(
    `ERROR: Unrecognised job "${object_job.string_script}".`
    );
    }
    },
  • edit in sbin/hacker.js at line 727
    [3.21173]
    };
    // scheduling
    // return an object of job durations in seconds
    const object_get_time_jobs = function (ns, string_server_target) {
    const object_time_jobs = {};
    return (
    (object_time_jobs[string_get_script(ns, "weaken")] = float_get_time_weaken(
    ns,
    string_server_target,
    ns.getServerSecurityLevel(string_server_target)
    )),
    (object_time_jobs[string_get_script(ns, "grow")] = float_get_time_grow(
    ns,
    string_server_target,
    ns.getServerSecurityLevel(string_server_target)
    )),
    (object_time_jobs[string_get_script(ns, "hack")] = float_get_time_hack(
    ns,
    string_server_target,
    ns.getServerSecurityLevel(string_server_target)
    )),
    object_time_jobs
    );
    };
    // returns a hacking schedule item
    const void_get_job = function (
    ns,
    object_server_target,
    object_time_jobs,
    array_servers_used,
    array_schedule,
    float_padding_seconds,
    float_precision,
    float_steal_cap
    ) {
    const
    object_server_used = object_get_server_ram_free_biggest(array_servers_used),
    integer_get_time_job_finishes_seconds = function (
    array_schedule,
    object_time_jobs
    ) {
    if (0 === array_schedule.length)
    return Math.max(
    object_time_jobs[string_get_script(ns, "weaken")],
    object_time_jobs[string_get_script(ns, "grow")],
    object_time_jobs[string_get_script(ns, "hack")]
    );
    {
    const object_job_last = array_schedule[array_schedule.length - 1];
    return (
    object_job_last.float_delay_seconds +
    object_time_jobs[object_job_last.string_script]
    );
    }
    },
    string_script = object_server_target.job(),
    string_server_target = object_server_target.name,
    float_server_used_ram_free = object_server_used.get_ram_free(),
    float_server_target_security_before = object_server_target.security_current,
    float_server_target_cash_current = object_server_target.cash_current,
    object_job = {
    string_script: string_script,
    string_server_used: object_server_used.name,
    string_server_target: string_server_target,
    integer_threads: integer_get_threads(
    ns,
    float_server_used_ram_free,
    string_script,
    string_server_target,
    float_server_target_security_before,
    float_server_target_cash_current,
    float_get_percentage_to_steal(
    ns,
    float_server_used_ram_free,
    string_server_target,
    float_server_target_cash_current,
    float_server_target_security_before,
    float_precision,
    float_steal_cap
    )
    ),
    float_delay_seconds:
    integer_get_time_job_finishes_seconds(
    array_schedule,
    object_time_jobs
    ) -
    object_time_jobs[string_script] +
    float_padding_seconds,
    // simulate the effect of the job to the server to get the security after, which is needed to determine if we need to remove any jobs later on
    // this is the target server's security before this job's effects are applied
    float_server_target_security_before:
    float_server_target_security_before,
    },
    object_server_target_after = object_get_clone(object_server_target);
    return (
    object_server_target_after.apply_job(object_job) &&
    (object_job.float_server_target_security_after =
    object_server_target_after.security_current),
    object_job
    );
    };
    // returns a schedule with jobs near the end that prevent it from achieving minimum security removed so the target server has minimum security when the schedule finishes. if no jobs achieve minimum security, return the original schedule.
    const array_get_schedule_corrected = function (
    ns,
    array_schedule
    ) {
    const
    array_schedule_edited = array_get_clone(array_schedule),
    float_server_target_security_minimum = ns.getServerMinSecurityLevel(
    array_schedule_edited[0].string_server_target
    );
    let boolean_have_seen_job_with_security_minimum = !1;
    for (
    ;
    !boolean_have_seen_job_with_security_minimum &&
    array_schedule_edited.length > 0;
    )
    for (
    let integer_index_job = array_schedule_edited.length - 1;
    integer_index_job >= 0 && !boolean_have_seen_job_with_security_minimum;
    --integer_index_job
    ) {
    const object_job = array_schedule_edited[integer_index_job];
    if (
    object_job.float_server_target_security_after ===
    float_server_target_security_minimum
    ) {
    boolean_have_seen_job_with_security_minimum = !0;
    break;
    }
    array_schedule_edited.splice(integer_index_job, 1);
    }
    return boolean_have_seen_job_with_security_minimum &&
    0 !== array_schedule_edited.length
    ? array_schedule_edited
    : array_schedule;
    };
    // makes a hacking schedule
    const array_make_schedule_hacking = function (
    ns,
    integer_job_cap,
    float_precision,
    float_steal_cap,
    float_padding_seconds,
    string_server_target
    ) {
    const
    object_time_jobs = object_get_time_jobs(ns, string_server_target),
    object_server_target = object_make_server_target(
    ns,
    string_server_target
    ),
    array_schedule = [];
    let array_servers_used = array_make_servers(
    ns,
    array_get_servers_useable,
    object_make_server_used
    );
    for (
    ;
    integer_job_cap > array_schedule.length &&
    object_get_server_ram_free_biggest(array_servers_used).can_run_job(
    object_server_target.job(),
    1
    );
    ) {
    const object_job = void_get_job(
    ns,
    object_server_target,
    object_time_jobs,
    array_servers_used,
    array_schedule,
    float_padding_seconds,
    float_precision,
    float_steal_cap
    );
    array_schedule.push(object_job),
    // update object states based on new schedule item
    object_server_target.apply_job(object_job),
    (array_servers_used = array_get_servers_used_updated(
    array_servers_used,
    object_job
    ));
    }
    return array_get_schedule_corrected(ns, array_schedule);
    };
    // runs a hacking schedule
    const void_schedule_hacking_runner = function (
    ns,
    array_schedule
    ) {
    for (
    let integer_index_job = 0;
    integer_index_job < array_schedule.length;
    ++integer_index_job
    ) {
    const object_job = array_schedule[integer_index_job];
    ns.exec(
    object_job.string_script,
    object_job.string_server_used,
    object_job.integer_threads,
    object_job.string_server_target,
    1e3 * object_job.float_delay_seconds - Date.now(),
    integer_index_job
    );
    }
    };
    // picks a target if one isn't already chosen, run schedule(s).
    const void_runner = async function (
    ns,
    integer_job_cap,
    float_precision,
    float_steal_cap,
    float_padding_seconds,
    boolean_discrete,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth,
    string_server_target_argument
    ) {
    const parent_window = parent["window"];
    parent_window.d = parent_window["document"];
    parent_window.w = parent_window;
    if (boolean_discrete) {
    // makes and runs a schedule, returns the the time it'll take to finish in milliseconds.
    let
    integer_time_start = Date.now(),
    // if no target was given, pick one
    string_server_target = string_server_target_argument;
    "" === string_server_target_argument &&
    (string_server_target = string_get_server_hackable_by_score_position(
    ns,
    1,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ));
    d.string_server_target = string_server_target;
    const array_schedule = array_make_schedule_hacking(
    ns,
    integer_job_cap,
    float_precision,
    float_steal_cap,
    float_padding_seconds,
    string_server_target
    );
    return (
    void_schedule_hacking_runner(ns, array_schedule),
    1e3 *
    (array_schedule[array_schedule.length - 1].float_delay_seconds +
    float_padding_seconds) -
    integer_time_start +
    Date.now()
    );
    }
    {
    // makes and runs a schedule, sleeps for the length of the sum of the paddings of the previous schedule, repeats.
    let
    array_schedule = [],
    // if no target was given, pick one
    string_server_target = string_server_target_argument,
    integer_time_start;
    for (
    integer_time_start = Date.now(),
    "" === string_server_target_argument &&
    (string_server_target = string_get_server_hackable_by_score_position(
    ns,
    1,
    string_method_score_correction,
    float_multiplier_factor_skill,
    float_multiplier_factor_max_cash,
    float_multiplier_factor_growth
    ));
    ;
    )
    d.string_server_target = string_server_target,
    0 === array_schedule.length
    ? ((array_schedule = array_make_schedule_hacking(
    ns,
    integer_job_cap,
    float_precision,
    float_steal_cap,
    float_padding_seconds,
    string_server_target
    )),
    array_schedule.length > 0
    ? void_schedule_hacking_runner(ns, array_schedule)
    : await ns.sleep(1e3 * float_padding_seconds))
    : (await ns.sleep((array_schedule.length * float_padding_seconds * 1e3) - integer_time_start + Date.now()),
    (array_schedule = array_make_schedule_hacking(
    ns,
    integer_job_cap,
    float_precision,
    float_steal_cap,
    float_padding_seconds,
    string_server_target
    )),
    array_schedule.length > 0
    ? void_schedule_hacking_runner(ns, array_schedule)
    : await ns.sleep(1e3 * float_padding_seconds));
    }
    };
  • file deletion: lib_server_used.js (----------)
    [3.3711246][3.3715515:3715557](),[3.3715557][3.3714506:3714506]()
    // lib_server_used.js - 2.1GB
    import {
    float_get_server_ram_total,
    float_get_server_ram_used
    } from "lib_ram_server.js";
    // makes a server used object
    export const object_make_server_used = function (
    ns,
    string_server
    ) {
    return {
    name: string_server,
    get_ram_max: function () {
    return float_get_server_ram_total(ns, string_server);
    },
    ram_used: float_get_server_ram_used(ns, string_server),
    get_ram_free: function () {
    return this.get_ram_max() - this.ram_used;
    },
    can_run_job: function (string_script, integer_threads) {
    return (
    ns.getScriptRam(string_script) * integer_threads <=
    this.get_ram_free()
    );
    },
    get_threads_max: function (string_script) {
    return Math.floor(
    this.get_ram_free() / ns.getScriptRam(string_script)
    );
    },
    apply_job: function (object_job) {
    this.ram_used +=
    object_job.integer_threads *
    ns.getScriptRam(object_job.string_script);
    },
    };
    };
  • file deletion: lib_ps.js (----------)
    [3.3711246][3.3725783:3725816](),[3.3725816][3.3724558:3724558]()
    // lib_ps.js - 2.05 GB
    // returns true if a script is running on any server
    import { array_get_servers } from "lib_servers.js";
    const array_servers = array_get_servers(ns);
    for (
    ) {
    array_scripts_running = ns.ps(string_server);
    if (array_scripts_running.length > 0)
    for (
    ) {
    string_script_to_check = object_script.filename;
    if (string_script_to_check == string_script) return !0;
    }
    }
    return !1;
    };
    // returns true if any of the scripts in an array is running on any server
    export const boolean_array_scripts_any_running = function (ns, array_scripts) {
    for (
    )
    };
    return boolean_script_running(ns, array_scripts[integer_index_script]);
    let integer_index_script = 0;
    integer_index_script < array_scripts.length;
    ++integer_index_script
    const object_script = array_scripts_running[integer_index_script],
    let integer_index_script = 0;
    integer_index_script < array_scripts_running.length;
    ++integer_index_script
    const string_server = array_servers[integer_index_server],
    let integer_index_server = 0;
    integer_index_server < array_servers.length;
    ++integer_index_server
    const boolean_script_running = function (ns, string_script) {
  • replacement in lib/lib_ram_server.js at line 26
    [3.3110][3.3110:3183]()
    const float_get_network_ram_trait = function (ns, float_get_ram_trait) {
    [3.3110]
    [3.3720679]
    export const float_get_network_ram_trait = function (ns, float_get_ram_trait) {
  • edit in lib/lib_ram_server.js at line 39
    [3.3307][3.3721051:3721055](),[3.3721051][3.3721051:3721055](),[3.3721055][2.2814:2912](),[2.2912][3.3308:3319](),[3.3721678][3.3308:3319](),[3.3319][2.2913:3042](),[2.3042][3.3722081:3722086](),[3.3722081][3.3722081:3722086]()
    };
    // returns total free ram of the botnet
    export const float_get_network_ram_free = function (ns) {
    return (
    float_get_network_ram_trait(ns, float_get_server_ram_total) -
    float_get_network_ram_trait(ns, float_get_server_ram_used)
    );
  • file addition: lib_ram_script.js (----------)
    [3.3711246]
    // lib_ram_script.js - 3.4GB
    import {
    object_get_server_ram_free_biggest,
    array_get_servers_used_updated,
    array_make_servers,
    float_clamp
    } from "lib_no_ns.js";
    import {
    float_get_server_ram_total,
    float_get_server_ram_used,
    float_get_network_ram_trait,
    float_get_network_ram_utilisation,
    array_get_servers_useable
    } from "lib_ram_server.js";
    // makes a server used object
    export const object_make_server_used = function (
    ns,
    string_server
    ) {
    return {
    name: string_server,
    get_ram_max: function () {
    return float_get_server_ram_total(ns, string_server);
    },
    ram_used: float_get_server_ram_used(ns, string_server),
    get_ram_free: function () {
    return this.get_ram_max() - this.ram_used;
    },
    can_run_job: function (string_script, integer_threads) {
    return (
    ns.getScriptRam(string_script) * integer_threads <=
    this.get_ram_free()
    );
    },
    get_threads_max: function (string_script) {
    return Math.floor(
    this.get_ram_free() / ns.getScriptRam(string_script)
    );
    },
    apply_job: function (object_job) {
    this.ram_used +=
    object_job.integer_threads *
    ns.getScriptRam(object_job.string_script);
    },
    };
    };
    // makes a script schedule
    export const array_make_schedule_script = function (ns, array_scripts) {
    const array_schedule = [];
    let array_servers_used = array_make_servers(
    ns,
    array_get_servers_useable,
    object_make_server_used
    );
    for (
    let integer_index_script = 0;
    integer_index_script < array_scripts.length;
    ++integer_index_script
    ) {
    const object_script = array_scripts[integer_index_script],
    string_script = object_script.file,
    threads_or_ram_botnet = object_script.threads_or_ram_botnet,
    array_arguments = object_script.args;
    if (
    object_get_server_ram_free_biggest(array_servers_used).can_run_job(
    string_script,
    1
    )
    ) {
    let integer_threads;
    if (threads_or_ram_botnet >= 1) integer_threads = threads_or_ram_botnet;
    else {
    // assume we want to use fraction of botnet instead
    const float_ram_utilisation = float_get_network_ram_utilisation(ns);
    if (float_ram_utilisation >= threads_or_ram_botnet)
    break;
    integer_threads = Math.floor(
    (float_get_network_ram_trait(ns, float_get_server_ram_total) *
    (threads_or_ram_botnet - float_ram_utilisation)) /
    ns.getScriptRam(string_script)
    );
    }
    for (
    ;
    integer_threads > 0 &&
    object_get_server_ram_free_biggest(array_servers_used).can_run_job(
    string_script,
    1
    );
    ) {
    const object_server_ram_free_biggest = object_get_server_ram_free_biggest(
    array_servers_used
    ),
    object_job = {
    string_script: string_script,
    string_server_used: object_server_ram_free_biggest.name,
    integer_threads: float_clamp(
    integer_threads,
    1,
    object_server_ram_free_biggest.get_threads_max(string_script)
    ),
    args: array_arguments,
    };
    (integer_threads -= object_job.integer_threads),
    array_schedule.push(object_job),
    (array_servers_used = array_get_servers_used_updated(
    array_servers_used,
    object_job
    ));
    }
    integer_threads > 0 &&
    ns.tprint(
    `WARNING: Failed to run the remaining ${integer_threads} threads of "${string_script}". Skipped.`
    );
    } else ns.tprint(`WARNING: Unable to find a server to run "${string_script}". Skipped.`);
    }
    return array_schedule;
    };
    // runs a script schedule
    export const void_schedule_script_runner = function (
    ns,
    array_schedule
    ) {
    for (
    let integer_index_job = 0;
    integer_index_job < array_schedule.length;
    ++integer_index_job
    ) {
    const object_job = array_schedule[integer_index_job];
    ns.exec(
    object_job.string_script,
    object_job.string_server_used,
    object_job.integer_threads,
    ...object_job.args,
    integer_index_job
    );
    }
    };
  • edit in bin/main.js at line 10
    [3.9720][2.7112:7206]()
    object_get_server_ram_free_biggest,
    array_get_servers_used_updated,
    array_make_servers,
  • edit in bin/main.js at line 12
    [2.7233][2.7233:7247]()
    float_clamp
  • replacement in bin/main.js at line 14
    [3.1776][3.1776:1805](),[3.1805][2.7248:7306]()
    float_get_server_ram_free,
    float_get_network_ram_free,
    array_get_servers_useable
    [3.1665]
    [3.9820]
    float_get_server_ram_free
  • replacement in bin/main.js at line 16
    [3.9848][2.7307:7369]()
    import { object_make_server_used } from "lib_server_used.js";
    [3.9848]
    [2.7369]
    import {
    array_make_schedule_script,
    void_schedule_script_runner
    } from "lib_ram_script.js";
  • edit in bin/main.js at line 68
    [2.9396]
    [2.9396]
    string_weaken_manager: "weaken_manager.js",
  • replacement in bin/main.js at line 129
    [2.10606][2.10606:10629]()
    cyclic_weaken: {
    [2.10606]
    [2.10629]
    weaken_manager: {
  • replacement in bin/main.js at line 131
    [2.10649][2.10649:10680]()
    long: "cyclic-weaken",
    [2.10649]
    [2.10680]
    long: "weaken-manager",
  • edit in bin/main.js at line 158
    [2.11126]
    [2.11126]
    // programs
    array_programs: [
    "BruteSSH.exe",
    "FTPCrack.exe",
    "relaySMTP.exe",
    "HTTPWorm.exe",
    "SQLInject.exe",
    "DeepscanV1.exe",
    "DeepscanV2.exe",
    "Autolink.exe",
    ],
  • replacement in bin/main.js at line 322
    [2.17248][2.17248:17483]()
    [
    "BruteSSH.exe",
    "FTPCrack.exe",
    "relaySMTP.exe",
    "HTTPWorm.exe",
    "SQLInject.exe",
    "DeepscanV1.exe",
    "DeepscanV2.exe",
    "Autolink.exe",
    ],
    [2.17248]
    [2.17483]
    object_get_constants().array_programs,
  • replacement in bin/main.js at line 331
    [2.17634][2.17634:17792]()
    file: object_helpers.string_cyclic_weaken,
    threads_or_ram_botnet: float_ram_fraction_for_weaken_cyclic,
    args: [float_period_check_seconds],
    [2.17634]
    [2.17792]
    file: object_helpers.string_weaken_manager,
    threads_or_ram_botnet: 1,
    args: [
    float_period_check_seconds,
    object_get_constants().object_helpers.string_cyclic_weaken,
    float_ram_fraction_for_weaken_cyclic,
    float_padding_seconds
    ],
  • replacement in bin/main.js at line 384
    [2.19613][2.19613:19799]()
    ((object_argument_names.cyclic_weaken.short === string_argument && argument_value) ||
    (object_argument_names.cyclic_weaken.long === string_argument && !argument_value)) &&
    [2.19613]
    [2.19799]
    ((object_argument_names.weaken_manager.short === string_argument && argument_value) ||
    (object_argument_names.weaken_manager.long === string_argument && !argument_value)) &&
  • replacement in bin/main.js at line 389
    [2.19893][2.19893:19941]()
    object_helpers.string_cyclic_weaken
    [2.19893]
    [2.19941]
    object_helpers.string_weaken_manager
  • replacement in bin/main.js at line 457
    [2.22574][2.22574:22841]()
    -${object_argument_names.cyclic_weaken.short}, --no-${object_argument_names.cyclic_weaken.long}
    Prevents the "${object_helpers.string_cyclic_weaken}" script from being started which is responsible for running \`weaken\` continuously to gain hacking experience.
    [2.22574]
    [2.22841]
    -${object_argument_names.weaken_manager.short}, --no-${object_argument_names.weaken_manager.long}
    Prevents the "${object_helpers.string_weaken_manager}" script from being started which is responsible for running threads of "${object_helpers.string_cyclic_weaken}" to gain hacking experience.
  • replacement in bin/main.js at line 498
    [2.27561][2.27561:27791]()
    FLOAT = The fraction of the botnet's current available RAM to be used to run ${object_helpers.string_cyclic_weaken}. Should be a floating point number > 0. Defaults to ${object_defaults.float_ram_fraction_for_weaken_cyclic}.`
    [2.27561]
    [2.27791]
    FLOAT = The fraction of the botnet's current available RAM to be used by ${object_helpers.string_weaken_manager} to run threads of "${object_helpers.string_cyclic_weaken}". Should be a floating point number > 0. Defaults to ${object_defaults.float_ram_fraction_for_weaken_cyclic}.`
  • edit in bin/main.js at line 593
    [2.30315][2.30315:33088]()
    };
    // scheduling
    // makes a script schedule
    const array_make_schedule_script = function (ns, array_scripts) {
    const array_schedule = [];
    let array_servers_used = array_make_servers(
    ns,
    array_get_servers_useable,
    object_make_server_used
    );
    for (
    let integer_index_script = 0;
    integer_index_script < array_scripts.length;
    ++integer_index_script
    ) {
    const
    object_script = array_scripts[integer_index_script],
    string_script = object_script.file,
    threads_or_ram_botnet = object_script.threads_or_ram_botnet,
    array_arguments = object_script.args;
    if (
    object_get_server_ram_free_biggest(array_servers_used).can_run_job(
    string_script,
    1
    )
    ) {
    let integer_threads = 0;
    for (
    integer_threads =
    threads_or_ram_botnet >= 1
    ? threads_or_ram_botnet
    // assume we want to utilise fraction of botnet ram instead
    : Math.floor(
    (float_get_network_ram_free(ns) * threads_or_ram_botnet) /
    ns.getScriptRam(string_script)
    );
    integer_threads > 0 &&
    object_get_server_ram_free_biggest(array_servers_used).can_run_job(
    string_script,
    1
    );
    ) {
    const object_server_ram_free_biggest = object_get_server_ram_free_biggest(
    array_servers_used
    ),
    object_job = {
    string_script: string_script,
    string_server_used: object_server_ram_free_biggest.name,
    integer_threads: float_clamp(
    integer_threads,
    1,
    object_server_ram_free_biggest.get_threads_max(string_script)
    ),
    args: array_arguments,
    };
    (integer_threads -= object_job.integer_threads),
    array_schedule.push(object_job),
    (array_servers_used = array_get_servers_used_updated(
    array_servers_used,
    object_job
    ));
    }
    integer_threads > 0 &&
    ns.tprint(
    `WARNING: Failed to run the remaining ${integer_threads} threads of "${string_script}". Skipped.`
    );
    } else ns.tprint(`WARNING: Unable to find a server to run "${string_script}". Skipped.`);
    }
    debugger;
    return array_schedule;
    };
    // runs a script schedule
    const void_schedule_script_runner = function (
    ns,
    array_schedule
    ) {
    for (
    let integer_index_job = 0;
    integer_index_job < array_schedule.length;
    ++integer_index_job
    ) {
    const object_job = array_schedule[integer_index_job];
    ns.exec(
    object_job.string_script,
    object_job.string_server_used,
    object_job.integer_threads,
    ...object_job.args,
    integer_index_job
    );
    }
  • replacement in README.md at line 13
    [3.2772][2.33097:33330]()
    * Run the helper scripts "ram.js"\* (6.6 GB), "servers.js" (8.85 GB), "tor.js"\* (3.8 GB), "programs.js"\* (3.7 GB), "botnet.js" (2.2 GB) and variable threads of "cyclic_weaken.js" (1.75 GB) which should, respectively, attempt to:
    [3.2772]
    [3.5832]
    * Run the helper scripts "ram.js"\* (6.6 GB), "servers.js" (8.85 GB), "tor.js"\* (3.8 GB), "programs.js"\* (3.7 GB), "botnet.js" (2.2 GB) and "weaken_manager.js" (3.4 GB) which should, respectively, attempt to:
  • replacement in README.md at line 19
    [3.6016][2.33331:33436]()
    * Gain hacking experience by continuously weakening the server that will be targeted by "hacker.js".
    [3.6016]
    [3.4327]
    * Run a variable amount of "cyclic_weaken.js" threads (1.75 GB) which gains hacking experience by continuously weakening the server that will be targeted by "hacker.js".
  • replacement in README.md at line 58
    [3.12030][3.12030:12057]()
    `-u, --no-cyclic-weaken`
    [3.12030]
    [3.3558]
    `-u, --no-weaken-manager`
  • replacement in README.md at line 60
    [3.3559][2.33561:33749]()
    * Prevents the "cyclic_weaken.js" script from being started which is responsible for running `weaken` continuously against the server targeted by "hacker.js" to gain hacking experience.
    [3.3559]
    [3.12203]
    * Prevents the "weaken_manager.js" script from being started which is responsible for running threads of "cyclic_weaken.js" to gain hacking experience.
  • replacement in README.md at line 113
    [2.35320][2.35320:35477]()
    * FLOAT = The fraction of the botnet's current available RAM to be used to run "cyclic_weaken.js". Should be a floating point number > 0. Defaults to 0.5.
    [2.35320]
    [3.13794]
    * FLOAT = The fraction of the botnet's current available RAM to be used by "weaken_manager.js" to run threads of "cyclic_weaken.js". Should be a floating point number > 0. Defaults to 0.5.