R7GUJZZKZILEMTKMXUUWUCEKKBFXDRYGTOXTTJA2RIBRIZGG5KWAC 6CV2IKC2HYT6YTQU3RQKPZSH3BRFPDGLHTU3LF7D66SO2GCVNQWAC CKC6UBEAMW64UFYH6N35ABNANLREXBV5M3FYCXJGHSBPDD67F26AC HW5NMIX3G5GP5PXMZBBINVSO556SLG2H3GSRE7UURMDA7KR427MAC LHTN3EJKWSSJFMA73IRRU2BXRSWF2UJEETTTF5PG2C2HMNH7YBXAC 6BXWZXOGNFFSE2F6OY77ZKPQSFESZSBWPZU7RRMZ7QOZ6CGJIPWQC 7FO2D5SSE3BHZFJU3PU2PEOIMDS6HSUVYAPVZQ5QPCPA32DF56XQC D375ZXT3VSESKCNO3ZP7N4FHYMTB6KKKRMEN2H5A74YI7XADGD7QC EDSOZNELN4QFPJ4RGPWTWVL5IWEET5DGFAMNN3QQYBR7S3OAG2GQC OLJLC35THUTM6VBA4R3XZWVJHD4X7FD773LKATHQPTP6UPAUQOFQC 2BKHJI2SJ3VXTFBK2BWNN3I3BDNMUU5YTJGKTQCOXV66VVRHCGKAC HSNSECD5D3ACWDKZNIEV7RZZ54IE5K33WS3DR37ABHM5QP5JJPIAC TDBVUKLOAGANU3DGDSQBTFOADRDFRS2E7OQIVFRCMWU7NPWJ2KCQC SXEJJKPIZE6AFCHQ32SROLWQUP733MRJZXNAR7OR37VVSRJIFFJQC SLSWBNYTIFKBFLKXZTMONGDMEOHSOOCOSU4KVJCONZG2DK3BBIUQC JGNALSUQSZ42WSYKTRIDDZQ2P4HRICMEJUABH6PDA7RUXBZEGLQAC MKHG4OQBVXNOJFRUKKI2KN7VXJHXDWZUUYKGF22TKTBYEUEFCC5AC AXGQ7FMLMADYBZWHFQPYL6Q4W5G6AE4GTYTWAON4MIJRI7G6FE4AC BKG7YVUVECDMXYJHUCUG2OULA4MSHZURNSDR7PYPPCSFM5ZV326QC ZRPOW4ERZN63I6GSUF3DGU77MI4DVWBHOZQAMGJO57YVSYJ4CUDAC JS52JD4QKFTHK2HUV5FXTWZ7HAC5ES7BZQX6M2A4XZFIYKKPBSGQC TXTXXNNBGMGN3POGN5VMGWGN5IF3VF5KAYUWJIQ7HKIONGTBZLBQC PUMDUVMZOIZW5AREIFGE6ONJSN6AYTOYMM3IVKIFWUBEUHKBG3LAC U2SGR33GHWKKY4LEVFP3GYLFOSX7NAJN7HIKW4SDNY6G2JVX42SAC OUSJMLGRPRFB46IMATOS7ZZ64HERJSRWD5BXGAQYVMCZOZICKQPAC QAPXJ43A5E5EHL7CBKSJVWJV574IAYK2CIUEGOL6YHQZVYWU76YQC ZNH2OJ3CP2SRIGFJATPNLT7HQ5YNNLP4M2ZVO7QN3P3HSTVJJHOAC Y5OWMCQRLGQ56HMM53HR6CVZEMAHOEKDYMFLBDEQOJ4HLUJL7HUAC FCJA5EXSTV7M22UWY4AR64LDZVNREPWSREZNXHGOH3IC3AIT7UBAC P6ZJC2SHPVYCBRAQPEF4727M5GSKSI7WSW3HBPAXFR7D6CGZUSYQC 2WOLGB42T4EO7ZKLA5KFUYWVPTR6I3ET3FPJT4BSJFL43RRFRUBAC 3TZILRX2OJIN4CH4P5MZ2PB56CJAPTDXGSU46FOTECHLQQBCPMNQC 5DIUM5GJ2DL4NTIJVPO4PCZD3TGFSZAFYWN2DOTZRH3ZXL6XUVBQC XUZPBRE6E2XZPQVFLLZ24H6U42SSBJPKCMSCEUVBVXGWXBIUSB3QC 5TPN2FMT5IKBTZ4YMFZAIB7R5MUCOT2EZFFS3OMYHHSGUML5BTWAC G7YVCY6HM6W46JYZWU6HY4VO4SQCHBP73LW2RTI2LPNRQD2TNKCAC FBAPT2WW2IUZTIHZP3BMVWKAIAGICTTH2QRPLDJXWNSYBW5AMO6AC IVSW4A6P6V4K5ZCXMOB4ENW45U6LNKX7HD7AYTCHNRBGC64FK5IAC 6PAXZMAIQNBD7GQDSQVF7NI2UW3GSPBL6UOUXGLLEVI4LJ6YMK2AC ZVQK2652XNKQ4QBNOFSROAP4QRJQCBYH2DQW7RCWZVRBRLUZ46SAC IFVY3INITLTHXUCAU5ZTYELKOD2CP45KVYP77ZT6BNKF34BNHROAC 6TF4T3E2TNJENBEZ2O6FCNF6XTQPPZ7WM2GMMH453BWXE7PKZUMQC VMXI7PS4GFDOWPFLHQ7TYKJ5K3K7FXNPJCBEVYHTTRN7YB5ZHEQAC 7SRULDRFXA6ZZUEXRPCDO7NIUJDREKYI3ESUYTOXMSPVMORDJXIQC DJDWBCCQHQRKHGRKKQ32QY3WDEM7EKDDQ2YQLSSCS7HZTLHDRCFQC CEZ56FCMUQARV6EAVERV6VCQHODPUMID3TCZKB6BBSIHKN7TUMEQC J7PIMHBDTNGC6W64W7KR4Q32677W27CNR5WZ5ABQYKJYV4T5XUDAC QU6T4CIVWUDWW6R2KMHVZAQS4FA4A5IHCYA54D5RKI44BNE3VBTQC VTCBEUHDJI5KDQNFQ6AF2QXDM7KDEQVBNXJKNY3UQAKQNE7CJV2QC NQ22FUSWN6CBJKJ5H7UV5N2KEXBIXVNQDNL2EK6UJ3E7RFLWNVDQC HLC2L3NJJSZLGSQ7JN6CTRE4YALVPLQSADZP3MDNLGB7BWPPH22QC V4DMWF25DAT3WBCJTC6Q4I54FYPGBQR4NVZI6RUZFY3T67TQTTZAC 3NFCZ6IPQPUCWANJN5WMUHUCHEQN7U5HZXMHDKVC6V6HXA3FG5YQC 6MBUKAG6VK6XXGRSER273IP2R35P3C5K3KOY4QVSZXEOYD3H4WRAC CJBGAILAK7G3WXYUBNUZMUMM3U5CPHWVK6ZAJWYBL4IOB5SZN32AC FA3U4WUJ3YT2G2WIAXBHEZ4O4RWXX55BBFYQKODHUMF7I6Z37XUAC TDRFRQLATOZOPPQLTXFVNL4RGC7HQM7ZFBJPOORITRQYWGBHMS7AC YIGMC2DMLXHG7OGHFKQKFLAX4UTJUNDAJJCGDGBXHJ7DEWPXJOWQC try {ns.nuke(string_server_unrooted);} catch (error) {ns.print(JSON.stringify(error));}}await ns.sleep(float_period_check);}};for () {const string_server_unrooted = array_servers_unrooted[integer_index_server];for (let integer_index_exploit = 0;integer_index_exploit < array_exploits_length;++integer_index_exploit) {try {array_exploits[integer_index_exploit](string_server_unrooted);} catch (error) {ns.print(JSON.stringify(error));}}let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_unrooted_length;// mainexport const main = async function (ns) {for (;;) {constarray_servers_unrooted = array_get_servers_unrooted(ns),array_servers_unrooted_length = array_servers_unrooted.length;if (0 === array_servers_unrooted_length) break;constfloat_period_check = 1e3 * ns.args[0],array_exploits = [ns.brutessh,ns.ftpcrack,ns.relaysmtp,ns.httpworm,ns.sqlinject],array_exploits_length = array_exploits.length;// botnet.js - 2.2GB - opens ports and nukes any unrooted servers if the player's hacking level is high enough to do so and the appropriate number of object_exploits are presentimport { array_get_servers_unrooted } from "lib_root.js";
export const main = async function (ns) {};constfloat_duration_sleep = ns.args[0] * 1e3,for (;) {try {} catch (error) {await ns.sleep(float_duration_sleep);}await ns.sleep(float_duration_sleep);}await ns.weaken(object_document.string_server_target);;// exposes document for freeobject_document = parent["document"];
};export const main = async function (ns) {await ns.sleep(Date.now() + ns.args[1]), await ns.grow(ns.args[0]);
};export const main = async function (ns) {await ns.sleep(Date.now() + ns.args[1]), await ns.hack(ns.args[0]);
*/// mainconst array_arguments = ns.args;let integer_time_finishes = Date.now();};// functions};// factor used in determining the amount security increases by from a grow or hackServerFortifyAmount: 0.002,// amount security decreases by from a weakenServerWeakenAmount: 0.05,// base percentage cash increases by from a growServerBaseGrowthRate: 1.03,// max percentage cash increases by from a grow (accounts for server security)ServerMaxGrowthRate: 1.0035,// hacking multipliersobject_hacking_multipliers: ns.getHackingMultipliers(),// bitnode multipliersobject_bitnode_multipliers: object_get_bitnode_multipliers(ns),};};// scheduling// return an object of job durations in secondsconst 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 itemconst void_get_job = function (ns,object_server_target,object_time_jobs,array_servers_used,array_schedule,float_padding_seconds,float_precision,float_steal_cap) {constobject_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 appliedfloat_server_target_security_before:float_server_target_security_before,},object_server_target_after = object_get_clone(object_server_target);};// makes a hacking scheduleconst array_make_schedule_hacking = function (ns,integer_job_cap,float_precision,float_steal_cap,float_padding_seconds,string_server_target) {constobject_time_jobs = object_get_time_jobs(ns, string_server_target),object_server_target = object_make_server_target(ns,string_server_target),array_schedule = [];ns,array_get_servers_useable,object_make_server_usedfor (;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 itemobject_server_target.apply_job(object_job),(array_servers_used = array_get_servers_used_updated(array_servers_used,object_job));}};// runs a hacking scheduleconst void_schedule_hacking_runner = function (ns,array_schedule) {for (let integer_index_job = 0;++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) {if (boolean_discrete) {letinteger_time_start = Date.now(),// if no target was given, pick onestring_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));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());}{letarray_schedule = [],// if no target was given, pick one"" === string_server_target_argument &&0 === array_schedule.lengthns,integer_job_cap,float_precision,float_steal_cap,float_padding_seconds,string_server_targetns,integer_job_cap,float_precision,float_steal_cap,float_padding_seconds,string_server_target}};)));)): (await ns.sleep(array_schedule.length * float_padding_seconds * 1e3 -integer_time_start +Date.now()),(integer_time_start = await void_runner_loop(? (integer_time_start = await void_runner_loop((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)),// tell cyclic_weaken.js what to target(object_document.string_server_target = string_server_target),string_server_target = string_server_target_argument;for (;;)integer_time_start,const void_runner_loop = async function (ns,integer_job_cap,float_precision,float_steal_cap,float_padding_seconds,string_server_target) {const integer_time_start = Date.now();return ((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),integer_time_start);};// makes and runs a schedule, sleeps for the length of the sum of the paddings of the previous schedule, repeats.object_document.string_server_target = string_server_target;// makes and runs a schedule, returns the the time it'll take to finish in milliseconds.// exposes document for freeconst object_document = parent["document"];void_copy_script_to(ns,object_job.string_script,object_job.string_server_used);integer_index_job < array_schedule_length;const array_schedule_length = array_schedule.length;// return 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.return (integer_last_seen_job_index_with_security_minimum > 0)? array_schedule.slice(0, integer_last_seen_job_index_with_security_minimum + 1): array_schedule;if (object_job.float_server_target_security_after ===float_server_target_security_minimum) {integer_last_seen_job_index_with_security_minimum = array_schedule.length;}),integer_last_seen_job_index_with_security_minimum = -1;letarray_servers_used = array_make_servers(float_server_target_security_minimum = ns.getServerMinSecurityLevel(string_server_target),object_server_target_after.apply_job(object_job);object_job.float_server_target_security_after = object_server_target_after.security_current;return object_job;// filenames and ram cost of helper scriptsarray_workers: [{name: "weaken.js",ram: function () {return ns.getScriptRam(this.name);},},{name: "grow.js",ram: function () {return ns.getScriptRam(this.name);},},{name: "hack.js",ram: function () {return ns.getScriptRam(this.name);},},],};};for (let integer_index_server = 0;++integer_index_server) {for (let integer_index_script = 0;++integer_index_script}};// returns the appropriate script nameconst 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.tsconst 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 minimumconst 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.tsconst 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.tsconst 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_cashconst 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.tsconst 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.jsconst 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_targetconst 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.tsconst 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 valuemaxThreadNeeded = 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 provideconst 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.jsfloat_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_securityconst 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_securityconst 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) {constfloat_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 integerconst 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 algorithmconst 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);letfloat_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 casesreturn 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 highestconst 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 serverconst 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 objectconst 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.jsthis.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.tsthis.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 copyconst 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}".`);}},return !1;for (let integer_index_scripts = 0;++integer_index_scriptsif (array_scripts_running[integer_index_script].filename ===array_scripts[integer_index_scripts])return !0;}}}) {integer_index_scripts < array_scripts_length;) {integer_index_script < array_scripts_running_length;constarray_scripts_running = ns.ps(array_servers[integer_index_server]),array_scripts_running_length = array_scripts_running.length;if (array_scripts_running_length > 0) {integer_index_server < array_servers_length;// returns true if any of the scripts in an array is running on any serverconst boolean_array_scripts_any_running = function (ns, array_scripts) {constarray_scripts_length = array_scripts.length,array_servers = array_get_servers(ns),array_servers_length = array_servers.length;return {// from https://github.com/danielyxie/bitburner/blob/master/src/Constants.jstry {// comment out the following line to save ~4GBreturn ns.getBitNodeMultipliers();throw new Error("WARNING: Uncommented the call to `getBitNodeMultipliers`.");}catch (error) {return (ns.print(`${JSON.stringify(error)}\nUsing default values instead.`),// from BitNode/BitNodeMultipliers{HackingLevelMultiplier: 1,StrengthLevelMultiplier: 1,DefenseLevelMultiplier: 1,DexterityLevelMultiplier: 1,AgilityLevelMultiplier: 1,CharismaLevelMultiplier: 1,ServerGrowthRate: 1,ServerMaxMoney: 1,ServerStartingMoney: 1,ServerStartingSecurity: 1,ServerWeakenRate: 1,HomeComputerRamCost: 1,PurchasedServerCost: 1,PurchasedServerLimit: 1,PurchasedServerMaxRam: 1,CompanyWorkMoney: 1,CrimeMoney: 1,HacknetNodeMoney: 1,ManualHackMoney: 1,ScriptHackMoney: 1,CodingContractMoney: 1,ClassGymExpGain: 1,CompanyWorkExpGain: 1,CrimeExpGain: 1,FactionWorkExpGain: 1,HackExpGain: 1,FactionPassiveRepGain: 1,FactionWorkRepGain: 1,RepToDonateToFaction: 1,AugmentationMoneyCost: 1,AugmentationRepCost: 1,InfiltrationMoney: 1,InfiltrationRep: 1,FourSigmaMarketDataCost: 1,FourSigmaMarketDataApiCost: 1,CorporationValuation: 1,BladeburnerRank: 1,BladeburnerSkillCost: 1,DaedalusAugsRequirement: 1,});}import { array_get_servers } from "lib_servers.js";import {array_get_servers_useable} from "lib_ram_server.js";import {object_get_server_ram_free_biggest,array_get_servers_used_updated,array_make_servers,object_get_clone,float_clamp,} from "lib_no_ns.js";import { array_get_servers_hackable } from "lib_score.js";import {float_get_time_hack,float_get_time_grow,float_get_time_weaken,} from "lib_time.js";import {float_get_server_score,} from "lib_score.js";const object_get_constants = function (ns) {const object_get_bitnode_multipliers = function (ns) {import {object_make_server_used,void_copy_script_to,} from "lib_ram_script.js";for (;;)integer_time_finishes <= Date.now() &&!boolean_array_scripts_any_running(ns,)? ((integer_time_finishes =await ns.sleep(integer_time_finishes - Date.now())): await ns.sleep(integer_time_finishes - Date.now());await void_runner(ns, ...array_arguments) + Date.now()),[string_get_script(ns, "weaken"),string_get_script(ns, "grow"),string_get_script(ns, "hack")]export const main = async function (ns) {* add a way to be able to target more than one server at a time?* refactor unecessary cloning/copying* add a way to notify weaken_manager if hacker.js needs more ram so weaken_manager can kill some cyclic weakens and adjust float_ram_fraction_for_weaken_cyclic* add a way to determine the optimal weights for the factors used in the server scoring function* add a job cap thing that prevents running more jobs if the first worker in a cycle finishes. add a thing to worker script that writes to a file (or to `window`) its identifier, when it started, and when it finishes. add a padding optimiser that detects when tail collision occurs and increases padding each cycle if it does occur, and decreases it by half of how much it increases everytime no tail collision occurs* add functionality that allows on-the-fly hot loading of settings from a file?/* hacker.js - 13.35GB - TODO:
// programs.js - 3.7GB - tries to continually buy programstry {ns.purchaseProgram(string_program);} catch (error) {ns.print(JSON.stringify(error));}}}};boolean_program_missing || (boolean_has_all_programs = !0),await ns.sleep(float_period_check);ns.fileExists(string_program, "home") || (boolean_program_missing = !0);export const main = async function (ns) {let boolean_has_all_programs = !1;for (; !boolean_has_all_programs; ) {let boolean_program_missing = !1;for () {const string_program = array_programs[integer_index_program];let integer_index_program = 0;++integer_index_programinteger_index_program < array_programs_length;constfloat_period_check = 1e3 * ns.args[0],array_programs = ns.args[1],array_programs_length = array_programs.length;
await ns.sleep(float_period_check);}};}ns.upgradeHomeRam();} catch (error) {ns.print(JSON.stringify(error));// ram.js - 6.6GB - tries to continually upgrade the RAM of "home" as long as the ram utilisation of your network is over threshold and you have sufficient cash.)import { float_get_network_ram_utilisation } from "lib_ram_server.js";export const main = async function (ns) {float_ram_utilisation_threshold = ns.args[1];for (;;) {try {for (;ns.getServerMoneyAvailable("home") >= ns.getUpgradeHomeRamCost() &&float_get_network_ram_utilisation(ns) > float_ram_utilisation_threshold;constfloat_period_check = 1e3 * ns.args[0],
};};}}};};// your servers do not all have the maximum RAM possible for purchased servers// is cash at least equal to the price of the cheapest server bought + the next highest server after that, which is twice the price of the former, thus 3. this check is so that a server with the same RAM as before isn't bought.ns.getServerMoneyAvailable("home") >=3 *object_constants.BaseCostFor1GBOfRamServer *float_get_server_ram_total(ns, string_get_server_bought_smallest(ns)));!boolean_servers_bought_all_max(ns,object_constants.PurchasedServerMaxRam) &&const boolean_conditions_server_delete_purchase = function (ns) {const object_constants = object_get_constants();return (// you currently own the maximum amount of purchased servers allowedns.getPurchasedServers().length == object_constants.PurchasedServerLimit &&// you currently own less than the maximum amount of purchased servers allowedinteger_servers_bought_amount < object_constants.PurchasedServerLimit &&// you already bought a server with max ram, buy another server the max possible ramfloat_get_server_ram_total(ns, string_get_server_bought_biggest(ns)) ==float_ram_server_bought_maximum &&integer_get_server_ram_biggest_afforded(ns) >=float_ram_server_bought_maximum);const boolean_conditions_server_purchase_3 = function (ns) {object_constants = object_get_constants(),float_ram_server_bought_maximum = object_constants.PurchasedServerMaxRam;// you have one or more servers alreadyinteger_servers_bought_amount > 0 &&return (constinteger_servers_bought_amount = ns.getPurchasedServers().length,}};}};// return the RAM of the server with the biggest RAM that you can afford};// RAM is at least equal to the minimum RAM possible for purchased servers// RAM is at least equal to the RAM of "home" (probably a bad idea to hardcode this since the string_name of "home" might change in the future) or max ram.};// you currently own less than the maximum amount of purchased servers allowed) {float_ram_server_bought_biggest !=object_constants.PurchasedServerMaxRam &&float_ram_server_bought_biggest <integer_get_server_ram_biggest_afforded(ns));const float_ram_server_bought_biggest = float_get_server_ram_total(ns,string_get_server_bought_biggest(ns));// you dont own a server with max RAM yet, buy a server with RAM greater than the RAM of your biggest bought serverreturn (integer_servers_bought_amount < object_constants.PurchasedServerLimitconst boolean_conditions_server_purchase_2 = function (ns) {object_constants = object_get_constants();if (// you have one or more servers alreadyinteger_servers_bought_amount > 0 &&constinteger_servers_bought_amount = ns.getPurchasedServers().length,(integer_server_ram_biggest_afforded >=float_get_server_ram_total(ns, "home") ||integer_server_ram_biggest_afforded >=object_constants.PurchasedServerMaxRam));integer_server_ram_biggest_afforded >=object_constants.integer_server_ram_min &&const boolean_conditions_server_purchase_1 = function (ns) {ns),object_constants = object_get_constants();// you have no bought servers yet0 === ns.getPurchasedServers().length &&return (constinteger_server_ram_biggest_afforded = integer_get_server_ram_biggest_afforded(const integer_get_server_ram_biggest_afforded = function (ns) {const object_constants = object_get_constants();let integer_server_ram_biggest_afforded = Math.pow(2,Math.trunc(Math.log2(ns.getServerMoneyAvailable("home") /object_constants.BaseCostFor1GBOfRamServer) / Math.log2(2)));return (integer_server_ram_biggest_afforded >object_constants.PurchasedServerMaxRam &&(integer_server_ram_biggest_afforded =object_constants.PurchasedServerMaxRam),integer_server_ram_biggest_afforded);return string_server_biggest;return string_server_smallest;}};// returns bought server with biggest RAMlet string_server_biggest,integer_size_biggest = object_get_constants().integer_server_ram_min;for () {ns,);integer_server_ram_total > integer_size_biggest &&(integer_size_biggest = integer_server_ram_total));((string_server_biggest = array_servers_bought[integer_index_server]),array_servers_bought[integer_index_server]const integer_server_ram_total = float_get_server_ram_total(let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_bought_length;const string_get_server_bought_biggest = function (ns) {constarray_servers_bought = ns.getPurchasedServers(),array_servers_bought_length = array_servers_bought.length;if (array_servers_bought_length > 0) {return boolean_tripwire;}};// returns bought server with smallest RAMlet string_server_smallest,integer_size_smallest = object_get_constants().PurchasedServerMaxRam;for () {ns,);integer_server_ram_total < integer_size_smallest &&(integer_size_smallest = integer_server_ram_total));((string_server_smallest = array_servers_bought[integer_index_server]),array_servers_bought[integer_index_server]const integer_server_ram_total = float_get_server_ram_total(let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_bought_length;const string_get_server_bought_smallest = function (ns) {constarray_servers_bought = ns.getPurchasedServers(),array_servers_bought_length = array_servers_bought.length;if (array_servers_bought_length > 0) {// true if all bought servers have RAM == PurchasedServerMaxRamlet boolean_tripwire = !0;for ()object_get_constants().PurchasedServerMaxRam && (boolean_tripwire = !1);float_get_server_ram_total(ns, array_servers_bought[integer_index_server]) <let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_bought_length;const boolean_servers_bought_all_max = function (ns) {constarray_servers_bought = ns.getPurchasedServers(),array_servers_bought_length = array_servers_bought.length;if (array_servers_bought_length > 0) {// cost of server per 1 GB of RAMBaseCostFor1GBOfRamServer: 55000,// maximum amount of purchased servers allowedPurchasedServerLimit: 25,// minimum RAM of purchased servers possibleinteger_server_ram_min: 2,// maximum RAM of purchased servers possible. 2^20PurchasedServerMaxRam: 1048576,const object_get_constants = function () {return {// functionsawait ns.sleep(float_period_check);}};boolean_conditions_server_purchase_2(ns) ||)ns.purchaseServer(string_servers_bought_name,integer_get_server_ram_biggest_afforded(ns)),await ns.sleep(float_period_check);boolean_conditions_server_purchase_1(ns));)ns.deleteServer(string_get_server_bought_smallest(ns)),ns.purchaseServer(string_servers_bought_name,integer_get_server_ram_biggest_afforded(ns)),await ns.sleep(float_period_check);for (;!boolean_servers_bought_all_max(ns) &&float_get_network_ram_utilisation(ns) > float_ram_utilisation_threshold &&(boolean_conditions_server_purchase_3(ns) ||import {float_get_network_ram_utilisation,export const main = async function (ns) {string_servers_bought_name = ns.args[1],float_ram_utilisation_threshold = ns.args[2];for (;!boolean_servers_bought_all_max(ns) &&float_get_network_ram_utilisation(ns) > float_ram_utilisation_threshold &&boolean_conditions_server_delete_purchase(ns);for (;;) {constfloat_period_check = 1e3 * ns.args[0],float_get_server_ram_total,} from "lib_ram_server.js";/* servers.js - 8.85GB - continually buys the best server with cash available if ram utilisation of the network is over threshold, unless there are 25 servers already, in which case deletes the worst server, unless all 25 have RAM == PurchasedServerMaxRam. TODO:* reduce duplicate code*/
// tor.js - 3.8GB - tries to continually buy TOR Routertry {ns.purchaseTor();} catch (error) {ns.print(JSON.stringify(error));}await ns.sleep(float_period_check);}};export const main = async function (ns) {const float_period_check = 1e3 * ns.args[0];for (; !ns.scan("home").includes("darkweb"); ) {
};export const main = async function (ns) {await ns.sleep(Date.now() + ns.args[1]), await ns.weaken(ns.args[0]);
import {array_make_schedule_script,void_schedule_script_runner} from "lib_ram_script.js";// mainexport const main = async function (ns) {for (;;)void_schedule_script_runner(ns,array_make_schedule_script(ns, [{},])),};await ns.sleep(float_period_check);file: string_file,threads_or_ram_botnet: integer_threads,args: array_arguments,constfloat_period_check = 1e3 * ns.args[0],string_file = ns.args[1],integer_threads = ns.args[2],array_arguments = [ns.args[3]];// weaken_manager.js - 4GB - continuously runs enough threads of cyclic_weaken.js to meet float_ram_fraction_for_weaken_cyclic.
// lib_kill.js - 2.3GB// kills running instances of the named script on a named serverexport const void_kill_script_named_server_named = function (ns,string_server,string_script) {for (let integer_indices_0 = 0;++integer_indices_0) {string_script_running = object_script.filename;string_script_running === string_script &&ns.kill(string_script_running, string_server, ...object_script.args);}};constobject_script = array_scripts_running[integer_indices_0],integer_indices_0 < array_scripts_running_length;constarray_scripts_running = ns.ps(string_server),array_scripts_running_length = array_scripts_running.length;
// lib_ls.js - 1.8GB// build array of files to copy from string_server_source}};ns,switch (string_type_substring) {case "string":default:const string_message_error = `Invalid input "${substring}" of type ${string_type_substring}.`;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));return ns.ls(string_server, substring);case "object":return substring.flatMap((string_file) => {return array_get_files_with_string(ns, string_server, string_file);});substring) => {const string_type_substring = typeof substring;string_server,export const array_get_files_with_string = (
// lib_ram_server.js - 2GBimport {array_get_servers_rooted}from "lib_root.js";// returns the total ram of a server};// returns the used ram of a server};// returns the amount of free ram of a server};for ()ns,);};return ();};};// returns an array of rooted servers that have ram > 0export const array_get_servers_useable = function (ns) {let array_servers_useable = [];for (let integer_index_server_rooted = 0;++integer_index_server_rooted) {const string_server_rooted =array_servers_rooted[integer_index_server_rooted];float_get_server_ram_total(ns, string_server_rooted) > 0 &&array_servers_useable.push(string_server_rooted);}return array_servers_useable;integer_index_server_rooted < array_servers_rooted_length;constarray_servers_rooted = array_get_servers_rooted(ns),array_servers_rooted_length = array_servers_rooted.length;float_get_network_ram_trait(ns, float_get_server_ram_used) /float_get_network_ram_trait(ns, float_get_server_ram_total)// returns the RAM utilisation of the botnet as a decimalexport const float_get_network_ram_utilisation = function (ns) {return float_network_ram_trait;array_servers_rooted[integer_index_server_rooted]float_network_ram_trait += float_get_ram_trait(let integer_index_server_rooted = 0;++integer_index_server_rootedinteger_index_server_rooted < array_servers_rooted_length;let float_network_ram_trait = 0;// returns the total RAM trait from all the servers you have root access toexport const float_get_network_ram_trait = function (ns, float_get_ram_trait) {constarray_servers_rooted = array_get_servers_rooted(ns),array_servers_rooted_length = array_servers_rooted.length;export const float_get_server_ram_free = function (ns, string_server) {return (float_get_server_ram_total(ns, string_server) -float_get_server_ram_used(ns, string_server));export const float_get_server_ram_used = function (ns, string_server) {return ns.getServerRam(string_server)[1];export const float_get_server_ram_total = function (ns, string_server) {return ns.getServerRam(string_server)[0];
// lib_root.js - 1.9GBimport {array_get_servers}from "lib_servers.js";// returns an array of all rooted serversreturn array_servers_rooted;};// returns an array of all servers that are yet to be rootedreturn array_servers_unrooted;};export const array_get_servers_unrooted = function (ns) {array_servers_unrooted = [];for ()ns.hasRootAccess(array_servers[integer_index_server]) ||array_servers_unrooted.push(array_servers[integer_index_server]);let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;constarray_servers = array_get_servers(ns),array_servers_length = array_servers.length,export const array_get_servers_rooted = function (ns) {array_servers_rooted = [];for ()ns.hasRootAccess(array_servers[integer_index_server]) &&array_servers_rooted.push(array_servers[integer_index_server]);let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;constarray_servers = array_get_servers(ns),array_servers_length = array_servers.length,
// lib_score.js - 2.25GBimport { array_get_servers_rooted } from "lib_root.js";const float_get_mean = function (array_numbers) {let float_total = 0;for ()};for ()return array_servers_trait;};const float_get_skill_against = function (ns, string_server) {const float_player_hacking_level = ns.getHackingLevel();return (float_player_hacking_level - ns.getServerRequiredHackingLevel(string_server)) / float_player_hacking_level;};const float_get_server_cash_max = function (ns, string_server) {return ns.getServerMaxMoney(string_server);};const float_get_server_growth = function (ns, string_server) {return ns.getServerGrowth(string_server);};constreturn ();};float_multiplier_factor_skill * float_factor_skill +float_multiplier_factor_max_cash * float_factor_max_cash +float_multiplier_factor_growth * float_factor_growth// can adjust the weights of the factors. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect.float_get_score_factor = function (ns,string_server,float_method_score_correction,float_get_trait_score) {return float_get_corrected_score(float_get_trait_score(ns, string_server),array_get_servers_trait(ns,array_get_servers_hackable(ns),float_get_trait_score),float_method_score_correction);},float_factor_skill = float_get_score_factor(ns,string_server,float_method_score_correction,float_get_skill_against),ns,string_server,float_method_score_correction,float_get_server_cash_max),ns,string_server,float_method_score_correction,float_get_server_growth);float_factor_growth = float_get_score_factor(float_factor_max_cash = float_get_score_factor(// return array of rooted servers that have required hacking levels <= current hacking level, growth rates > 0 and max cash > 0export const array_get_servers_hackable = function (ns) {for (let integer_index_server = 0;++integer_index_server) {const string_server = array_servers_rooted[integer_index_server];ns.getServerMaxMoney(string_server) > 0 &&ns.getServerGrowth(string_server) > 0 &&array_servers_hackable.push(string_server);}return array_servers_hackable;};ns.getHackingLevel() >= ns.getServerRequiredHackingLevel(string_server) &&integer_index_server < array_servers_rooted_length;constarray_servers_rooted = array_get_servers_rooted(ns),array_servers_rooted_length = array_servers_rooted.length,array_servers_hackable = [];// returns the score of a server which is calculated by taking into account its max cash, its growth rate and your skill against it as factors which are corrected and summed.export const float_get_server_score = function (ns,string_server,string_method_score_correction,float_multiplier_factor_skill_argument,float_multiplier_factor_max_cash_argument,float_multiplier_factor_growth_argument) {letfloat_method_score_correction = float_get_standard_score,float_multiplier_factor_skill = 1,float_multiplier_factor_max_cash = 1,float_multiplier_factor_growth = 1;switch (string_method_score_correction) {case "standard":float_method_score_correction = float_get_standard_score;break;case "normal":float_method_score_correction = float_get_mean_normalised_score;break;default:ns.tprint(`WARNING: "${string_method_score_correction}" is not a valid value for the \`string_method_score_correction\` variable. Defaulting to "standard" method.`);}null !== float_multiplier_factor_skill_argument &&(float_multiplier_factor_skill = float_multiplier_factor_skill_argument),null !== float_multiplier_factor_max_cash_argument &&(float_multiplier_factor_max_cash = float_multiplier_factor_max_cash_argument),null !== float_multiplier_factor_growth_argument &&(float_multiplier_factor_growth = float_multiplier_factor_growth_argument);// gives a score for how well you will be able to hack a server (how much cash you can take per hack, how long it takes and your chances of hacking it successfully) given your current hacking level and its required hacking level. adapted from various functions in Hacking.jsarray_servers_trait.push(float_get_trait_score(ns, array_servers[integer_index_server]));let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;// score correction methodsconst float_get_standard_score = function (float_original, array_numbers) {constfloat_mean = float_get_mean(array_numbers),float_get_variance = function (array_numbers) {let float_sum_squared_differences = 0;for ()float_sum_squared_differences += Math.pow(2);},float_get_standard_deviation = function (array_numbers) {return Math.sqrt(float_get_variance(array_numbers));};return (float_get_standard_deviation(array_numbers));};const float_get_mean_normalised_score = function (float_original,array_numbers) {return ((float_original - float_get_mean(array_numbers)) /(Math.max(...array_numbers) - Math.min(...array_numbers)));};// returns a corrected score using a chosen correction methodconst float_get_corrected_score = function (float_original, array_numbers, float_method_score_correction) {return float_method_score_correction(float_original, array_numbers);};const array_get_servers_trait = function (ns, array_servers, float_get_trait_score) {constarray_servers_length = array_servers.length,array_servers_trait = [];(float_original - float_mean) /return float_sum_squared_differences / array_numbers_length;array_numbers[integer_index_number] - float_mean,let integer_index_number = 0;++integer_index_numberinteger_index_number < array_numbers_length;const array_numbers_length = array_numbers.length;float_total += array_numbers[integer_index_number];return float_total / array_numbers_length;let integer_index_number = 0;++integer_index_numberinteger_index_number < array_numbers_length;const array_numbers_length = array_numbers.length;
// lib_servers.js - 1.85GB// returns an array of all servers in the gamereturn array_servers;};export const array_get_servers = (ns) => {const array_servers = [ns.getHostname()];array_servers.forEach(string_server => {ns.scan(string_server).forEach(string_scan_result => {-1 === array_servers.indexOf(string_scan_result) &&array_servers.push(string_scan_result);});});
// lib_time.js - 6.25GBtry {return ns.getStats();}catch (error) {return {hacking: ns.getHackingLevel(),strength: 1,defense: 1,dexterity: 1,agility: 1,charisma: 1,intelligence: 1};}};// object_constants are from https://github.com/danielyxie/bitburner/blob/master/src/Constants.jsreturn {// hacking multipliersobject_hacking_multipliers: ns.getHackingMultipliers(),// player statsobject_stats: object_get_stats(ns)};};// Returns time it takes to complete a hack on a server, in seconds. Adapted from `calculateHackingTime` in Hacking.jsconst object_constants = object_get_constants(ns);const difficultyMult = ns.getServerRequiredHackingLevel(string_server_target) * float_server_target_security;const baseDiff = 500;const baseSkill = 50;const diffFactor = 2.5;const intFactor = 0.1;const hack_stat = object_constants.object_stats.hacking;const int = object_constants.object_stats.intelligence;var skillFactor = (diffFactor * difficultyMult + baseDiff);// tslint:disable-next-lineskillFactor /= (hack_stat + baseSkill + (intFactor * int));const hackTimeMultiplier = 5;const hackingTime = hackTimeMultiplier * skillFactor / object_constants.object_hacking_multipliers.speed;return hackingTime;};// Returns time it takes to complete a grow operation on a server, in seconds. Adapted from `calculateGrowTime` in Hacking.jsconst growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2return growTimeMultiplier * float_get_time_hack(ns, string_server_target, float_server_target_security);};// Returns time it takes to complete a weaken operation on a server, in seconds. Adapted from `calculateHackingTime` in Hacking.jsconst weakenTimeMultiplier = 4; // Relative to hacking timereturn weakenTimeMultiplier * float_get_time_hack(ns, string_server_target, float_server_target_security);};export const float_get_time_weaken = function (ns, string_server_target, float_server_target_security) {export const float_get_time_grow = function (ns, string_server_target, float_server_target_security) {export const float_get_time_hack = function (ns, string_server_target, float_server_target_security) {ns.print(`${JSON.stringify(error)}\nUsing default values instead.`);throw new Error("WARNING: Uncommented the call to `getStats`.");// comment out the following line to save ~0.5GBconst object_get_constants = function (ns) {const object_get_stats = function (ns) {
// lib_no_ns.js - 1.6GB - functions that don't use NetScript// make an array of server objectsexport const array_make_servers = function (ns,array_method_get_servers,object_method_make_server) {constarray_servers = array_method_get_servers(ns),array_servers_length = array_servers.length,array_object_servers = [];for (let integer_index_server = 0;++integer_index_server) {}return array_object_servers;};// return a new array of useable server state objects after simulating a change based on a schedule item on to an older array of useable server state objectsexport const array_get_servers_used_updated = function (array_servers_used,object_job) {for (let integer_index_server = 0;++integer_index_server) {const object_server = array_servers_used_updated[integer_index_server];object_server.name === object_job.string_server_used &&object_server.apply_job(object_job);}return array_servers_used_updated;};integer_index_server < array_servers_used_updated_length;const// clone array of servers used to preserve originalarray_servers_used_updated = array_get_clone(array_servers_used),array_servers_used_updated_length = array_servers_used_updated.length;array_object_servers.push(object_method_make_server(ns, array_servers[integer_index_server]));integer_index_server < array_servers_length;// https://stackoverflow.com/a/979325. Thanks Kozd for making this work with methods.const sort_by = (string_property,boolean_reverse,primer) => {const key = function (object) {return primer? primer(object, string_property): object[string_property];};return function (element_0, element_1) {return ((element_0 = key(element_0)),(element_1 = key(element_1)),(boolean_reverse ? -1 : 1) *((element_0 > element_1) - (element_1 > element_0)));};};// wrapper function to evaluate method property givenconst void_method_evaluate = function (object,string_property) {return object[string_property]();};// returns server object with biggest ram free from array of server objectsexport const object_get_server_ram_free_biggest = function (array_servers) {const array_server_sorted_ram = array_get_clone(array_servers).sort(sort_by("get_ram_free", !1, void_method_evaluate));return array_server_sorted_ram[array_server_sorted_ram.length - 1];};// https://github.com/30-seconds/30-seconds-of-code/commit/611729214af360d935b8a96ec9c5a45f2c7bfb37// Clamps float_number within the inclusive range specified by the boundary values float_limit_a and float_limit_b.// If float_number falls within the range, return float_number. Otherwise, return the nearest number in the range.export const float_clamp = function (float_number,float_limit_a,float_limit_b) {return Math.max(Math.min(float_number, Math.max(float_limit_a, float_limit_b)),Math.min(float_limit_a, float_limit_b));};// https://stackoverflow.com/a/54157459export const object_get_clone = function (object_original) {const object_serialised_deserialised = JSON.parse(JSON.stringify(object_original)),object_merged = Object.assign({}, object_original);return (Object.assign(object_merged, object_serialised_deserialised), object_merged);};for (let integer_index_element = 0;++integer_index_element) {const element = array_original[integer_index_element];switch (typeof element) {case "object":// fall-throughcase "function":array.push(object_get_clone(element));break;default:array.push(element);}}return array;};integer_index_element < array_original_length;const array_get_clone = function (array_original) {constarray_original_length = array_original.length,array = [];// https://stackoverflow.com/a/30376762export const string_sanitise = function (string) {const object_map = {"&": "&","<": "<",">": ">",'"': """,};return string.replace(/[&<>"']/g, (string_match) => object_map[string_match]);};// minimist - adapted from https://github.com/substack/minimist/blob/38a4d1caead72ef99e824bb420a2528eec03d9ab/index.js// This software is released under the MIT license:// 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.export const object_parse_arguments = function (args, opts) {if (!opts) opts = {};var flags = { bools : {}, strings : {}, unknownFn: null };if (typeof opts['unknown'] === 'function') {flags.unknownFn = opts['unknown'];}if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {flags.allBools = true;} else {[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {flags.bools[key] = true;});}var aliases = {};Object.keys(opts.alias || {}).forEach(function (key) {aliases[key] = [].concat(opts.alias[key]);aliases[key].forEach(function (x) {aliases[x] = [key].concat(aliases[key].filter(function (y) {return x !== y;}));});});[].concat(opts.string).filter(Boolean).forEach(function (key) {flags.strings[key] = true;if (aliases[key]) {flags.strings[aliases[key]] = true;}});var defaults = opts['default'] || {};var argv = { _ : [] };Object.keys(flags.bools).forEach(function (key) {setArg(key, defaults[key] === undefined ? false : defaults[key]);});var notFlags = [];if (args.indexOf('--') !== -1) {notFlags = args.slice(args.indexOf('--')+1);args = args.slice(0, args.indexOf('--'));}function argDefined(key, arg) {return (flags.allBools && /^--[^=]+$/.test(arg)) ||flags.strings[key] || flags.bools[key] || aliases[key];}function setArg (key, val, arg) {if (arg && flags.unknownFn && !argDefined(key, arg)) {if (flags.unknownFn(arg) === false) return;}var value = !flags.strings[key] && isNumber(val)? Number(val) : val;setKey(argv, key.split('.'), value);(aliases[key] || []).forEach(function (x) {setKey(argv, x.split('.'), value);});}function setKey (obj, keys, value) {var o = obj;for (var i = 0; i < keys.length-1; i++) {var key = keys[i];if (key === '__proto__') return;if (o[key] === undefined) o[key] = {};if (o[key] === Object.prototype || o[key] === Number.prototype|| o[key] === String.prototype) o[key] = {};if (o[key] === Array.prototype) o[key] = [];o = o[key];}var key = keys[keys.length - 1];if (key === '__proto__') return;if (o === Object.prototype || o === Number.prototype|| o === String.prototype) o = {};if (o === Array.prototype) o = [];if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {o[key] = value;}else if (Array.isArray(o[key])) {o[key].push(value);}else {o[key] = [ o[key], value ];}}function aliasIsBoolean(key) {return aliases[key].some(function (x) {return flags.bools[x];});}for (var i = 0; i < args.length; i++) {var arg = args[i];if (/^--.+=/.test(arg)) {// Using [\s\S] instead of . because js doesn't support the// 'dotall' regex modifier. See:// http://stackoverflow.com/a/1068308/13216var m = arg.match(/^--([^=]+)=([\s\S]*)$/);var key = m[1];var value = m[2];if (flags.bools[key]) {value = value !== 'false';}setArg(key, value, arg);}else if (/^--no-.+/.test(arg)) {var key = arg.match(/^--no-(.+)/)[1];setArg(key, false, arg);}else if (/^--.+/.test(arg)) {var key = arg.match(/^--(.+)/)[1];var next = args[i + 1];if (next !== undefined && !/^-/.test(next)&& !flags.bools[key]&& !flags.allBools&& (aliases[key] ? !aliasIsBoolean(key) : true)) {setArg(key, next, arg);i++;}else if (/^(true|false)$/.test(next)) {setArg(key, next === 'true', arg);i++;}else {setArg(key, flags.strings[key] ? '' : true, arg);}}else if (/^-[^-]+/.test(arg)) {var letters = arg.slice(1,-1).split('');var broken = false;for (var j = 0; j < letters.length; j++) {var next = arg.slice(j+2);if (next === '-') {setArg(letters[j], next, arg)continue;}if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {setArg(letters[j], next.split('=')[1], arg);broken = true;break;}if (/[A-Za-z]/.test(letters[j])&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {setArg(letters[j], next, arg);broken = true;break;}if (letters[j+1] && letters[j+1].match(/\W/)) {setArg(letters[j], arg.slice(j+2), arg);broken = true;break;}else {setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);}}var key = arg.slice(-1)[0];if (!broken && key !== '-') {if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])&& !flags.bools[key]&& (aliases[key] ? !aliasIsBoolean(key) : true)) {setArg(key, args[i+1], arg);i++;}else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {setArg(key, args[i+1] === 'true', arg);i++;}else {setArg(key, flags.strings[key] ? '' : true, arg);}}}else {if (!flags.unknownFn || flags.unknownFn(arg) !== false) {argv._.push(flags.strings['_'] || !isNumber(arg) ? arg : Number(arg));}if (opts.stopEarly) {argv._.push.apply(argv._, args.slice(i + 1));break;}}}Object.keys(defaults).forEach(function (key) {if (!hasKey(argv, key.split('.'))) {setKey(argv, key.split('.'), defaults[key]);(aliases[key] || []).forEach(function (x) {setKey(argv, x.split('.'), defaults[key]);});}});if (opts['--']) {argv['--'] = new Array();notFlags.forEach(function(key) {argv['--'].push(key);});}else {notFlags.forEach(function(key) {argv._.push(key);});}return argv;};function hasKey (obj, keys) {var o = obj;keys.slice(0,-1).forEach(function (key) {o = (o[key] || {});});var key = keys[keys.length - 1];return key in o;}function isNumber (x) {if (typeof x === 'number') return true;if (/^0x[0-9a-f]+$/i.test(x)) return true;return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);}"'": "'",
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 objectexport 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 scheduleexport const array_make_schedule_script = function (ns, array_scripts) {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) {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 insteadconst 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);) {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 scheduleexport const void_schedule_script_runner = function (ns,array_schedule) {const array_schedule_length = array_schedule.length;for (let integer_index_job = 0;++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);}};void_copy_script_to(ns,object_job.string_script,object_job.string_server_used);integer_index_job < array_schedule_length;// copies script in current server to a target serverexport const void_copy_script_to = function (ns,string_script,string_server_used) {ns.scp(string_script,ns.getHostname(),string_server_used);}constobject_server_ram_free_biggest = object_get_server_ram_free_biggest(constobject_script = array_scripts[integer_index_script],integer_index_script < array_scripts_length;constarray_scripts_length = array_scripts.length,array_schedule = [];// lib_ram_script.js - 4GB
/* contracts.js - 22.05 GB - attempts to solve existing coding contracts - TODO:* should this be ran by main.js?*/import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";import { array_get_files_with_string } from "lib_ls.js";import { array_get_servers } from "lib_servers.js";// mainexport const main = async function (ns) {// argument parsingconstfor (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {// fall-throughfloat_period_check_seconds = argument_value;break;case object_argument_names.verbose.short:// fall-throughcase object_argument_names.verbose.long:boolean_verbose = argument_value;break;case object_argument_names.delay.long:case object_argument_names.help.short:// fall-throughcase object_argument_names.help.long:boolean_print_help = argument_value;break;case "_":continue;default:const string_message_error = `Unknown argument passed: "${string_argument}".`;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));}}if (boolean_print_help)return void_print_help(ns);};const object_get_constants = function () {object_solvers["Find Largest Prime Factor"] = function (data) {let fac = 2;let n = data;while (n > ((fac - 1) * (fac - 1))) {while (n % fac === 0) {n = Math.round(n / fac);}++fac;}return (n === 1 ? (fac - 1) : n);};object_solvers["Subarray with Maximum Sum"] = function (data) {const nums = data.slice();for (let i = 1; i < nums.length; i++) {nums[i] = Math.max(nums[i], nums[i] + nums[i - 1]);}return Math.max(...nums);};object_solvers["Total Ways to Sum"] = function (data) {const ways = [1];ways.length = data + 1;ways.fill(0, 1);for (let i = 1; i < data; ++i) {for (let j = i; j <= data; ++j) {ways[j] += ways[j - i];}}return ways[data];};object_solvers["Spiralize Matrix"] = function (data) {const spiral = [];const m = data.length;const n = data[0].length;let u = 0;let d = m - 1;let l = 0;let r = n - 1;let k = 0;while (true) {// Upfor (let col = l; col <= r; col++) {spiral[k] = data[u][col];++k;}if (++u > d) {break;}// Rightfor (let row = u; row <= d; row++) {spiral[k] = data[row][r];++k;}if (--r < l) {break;}// Downfor (let col = r; col >= l; col--) {spiral[k] = data[d][col];++k;}if (--d < u) {break;}// Leftfor (let row = d; row >= u; row--) {spiral[k] = data[row][l];++k;}if (++l > r) {break;}}return spiral;};object_solvers["Array Jumping Game"] = function (data) {const n = data.length;let i = 0;for (let reach = 0; i < n && i <= reach; ++i) {reach = Math.max(i + data[i], reach);}return i === n ? 1 : 0;};object_solvers["Merge Overlapping Intervals"] = function (data) {const intervals = data.slice();intervals.sort((a, b) => {return a[0] - b[0];});const result = [];let start = intervals[0][0];let end = intervals[0][1];for (const interval of intervals) {if (interval[0] <= end) {end = Math.max(end, interval[1]);}else {result.push([start, end]);start = interval[0];end = interval[1];}}result.push([start, end]);return result;};object_solvers["Generate IP Addresses"] = function (data) {const ret = [];for (let a = 1; a <= 3; ++a) {for (let b = 1; b <= 3; ++b) {for (let c = 1; c <= 3; ++c) {for (let d = 1; d <= 3; ++d) {if (a + b + c + d === data.length) {const A = parseInt(data.substring(0, a), 10);const B = parseInt(data.substring(a, a + b), 10);const C = parseInt(data.substring(a + b, a + b + c), 10);const D = parseInt(data.substring(a + b + c, a + b + c + d), 10);if (A <= 255 && B <= 255 && C <= 255 && D <= 255) {const ip = [A.toString(), ".",B.toString(), ".",C.toString(), ".",D.toString()].join("");if (ip.length === data.length + 3) {ret.push(ip);}}}}}}}return ret;};object_solvers["Algorithmic Stock Trader I"] = function (data) {let maxCur = 0;let maxSoFar = 0;for (let i = 1; i < data.length; ++i) {maxCur = Math.max(0, maxCur += data[i] - data[i - 1]);maxSoFar = Math.max(maxCur, maxSoFar);}return maxSoFar.toString();};object_solvers["Algorithmic Stock Trader II"] = function (data) {let profit = 0;for (let p = 1; p < data.length; ++p) {profit += Math.max(data[p] - data[p - 1], 0);}return profit.toString();};object_solvers["Algorithmic Stock Trader III"] = function (data) {let hold1 = Number.MIN_SAFE_INTEGER;let hold2 = Number.MIN_SAFE_INTEGER;let release1 = 0;let release2 = 0;for (const price of data) {release2 = Math.max(release2, hold2 + price);hold2 = Math.max(hold2, release1 - price);release1 = Math.max(release1, hold1 + price);hold1 = Math.max(hold1, price * -1);}return release2.toString();};object_solvers["Algorithmic Stock Trader IV"] = function (data) {const k = data[0];const prices = data[1];const len = prices.length;if (len < 2) {return 0;}if (k > len / 2) {let res = 0;for (let i = 1; i < len; ++i) {res += Math.max(prices[i] - prices[i - 1], 0);}return res;}const hold = [];const rele = [];hold.length = k + 1;rele.length = k + 1;for (let i = 0; i <= k; ++i) {hold[i] = Number.MIN_SAFE_INTEGER;rele[i] = 0;}let cur;for (let i = 0; i < len; ++i) {cur = prices[i];for (let j = k; j > 0; --j) {rele[j] = Math.max(rele[j], hold[j] + cur);hold[j] = Math.max(hold[j], rele[j - 1] - cur);}}return rele[k];};object_solvers["Minimum Path Sum in a Triangle"] = function (data) {let n = data.length;let dp = data[n - 1].slice();for (let i = n - 2; i > -1; --i) {for (let j = 0; j < data[i].length; ++j) {dp[j] = Math.min(dp[j], dp[j + 1]) + data[i][j];}}return dp[0];};object_solvers["Unique Paths in a Grid I"] = function (data) {let n = data[0]; // Number of rowslet m = data[1]; // Number of columnslet currentRow = [];currentRow.length = n;for (let i = 0; i < n; i++) {currentRow[i] = 1;}for (let row = 1; row < m; row++) {for (let i = 1; i < n; i++) {currentRow[i] += currentRow[i - 1];}}return currentRow[n - 1];};object_solvers["Unique Paths in a Grid II"] = function (data) {let obstacleGrid = [];obstacleGrid.length = data.length;for (let i = 0; i < obstacleGrid.length; ++i) {obstacleGrid[i] = data[i].slice();}for (let i = 0; i < obstacleGrid.length; i++) {for (let j = 0; j < obstacleGrid[0].length; j++) {if (obstacleGrid[i][j] == 1) {obstacleGrid[i][j] = 0;}else if (i == 0 && j == 0) {obstacleGrid[0][0] = 1;}else {obstacleGrid[i][j] = (i > 0 ? obstacleGrid[i - 1][j] : 0) + (j > 0 ? obstacleGrid[i][j - 1] : 0);}}}return obstacleGrid[obstacleGrid.length - 1][obstacleGrid[0].length - 1];};object_solvers["Sanitize Parentheses in Expression"] = function (data) {let left = 0;let right = 0;let res = [];for (let i = 0; i < data.length; ++i) {if (data[i] === '(') {++left;}else if (data[i] === ')') {(left > 0) ? --left : ++right;}}function dfs(pair, index, left, right, s, solution, res) {if (s.length === index) {if (left === 0 && right === 0 && pair === 0) {for (var i = 0; i < res.length; i++) {if (res[i] === solution) {return;}}res.push(solution);}return;}if (s[index] === '(') {if (left > 0) {dfs(pair, index + 1, left - 1, right, s, solution, res);}dfs(pair + 1, index + 1, left, right, s, solution + s[index], res);}else if (s[index] === ')') {if (right > 0)dfs(pair, index + 1, left, right - 1, s, solution, res);if (pair > 0)dfs(pair - 1, index + 1, left, right, s, solution + s[index], res);}else {dfs(pair, index + 1, left, right, s, solution + s[index], res);}}dfs(0, 0, left, right, data, "", res);return res;};object_solvers["Find All Valid Math Expressions"] = function (data) {const num = data[0];const target = data[1];function helper(res, path, num, target, pos, evaluated, multed) {if (pos === num.length) {if (target === evaluated) {res.push(path);}return;}for (let i = pos; i < num.length; ++i) {if (i != pos && num[pos] == '0') {break;}let cur = parseInt(num.substring(pos, i + 1));if (pos === 0) {helper(res, path + cur, num, target, i + 1, cur, cur);}else {helper(res, path + "+" + cur, num, target, i + 1, evaluated + cur, cur);helper(res, path + "-" + cur, num, target, i + 1, evaluated - cur, -cur);helper(res, path + "*" + cur, num, target, i + 1, evaluated - multed + multed * cur, multed * cur);}}}let result = [];helper(result, "", num, target, 0, 0, 0);return result;};return {object_solvers,};};const void_print_help = function (ns) {const object_argument_names = object_get_constants().object_argument_names;ns.tprint(string_sanitise(`DESCRIPTIONUSAGEFLAGS-${object_argument_names.help.short}, --${object_argument_names.help.long}));};const array_get_contracts = function (ns) {constarray_contracts = [],for (let integer_index_server = 0;++integer_index_server) {conststring_server = array_servers[integer_index_server],array_contract_names = array_get_files_with_string(ns,string_server,".cct"for (let integer_index_contracts = 0;++integer_index_contracts) {// check if this really is a contract or just a file with .cct in its nameconst string_contract = array_contract_names[integer_index_contracts];"string" ==typeof ns.codingcontract.getContractType(string_contract,string_server) &&array_contracts.push({name: string_contract,location: string_server,type: ns.codingcontract.getContractType(string_contract,string_server),data: ns.codingcontract.getData(string_contract, string_server),return ns.codingcontract.attempt(answer,string_contract,string_server,{});},});}}return array_contracts;};constobject_solvers = object_get_constants().object_solvers,for (let integer_index_contract = 0;++integer_index_contract) {constobject_contract = array_contracts[integer_index_contract],answer = object_solvers[object_contract.type](object_contract.data),`Failed to solve:${JSON.stringify(object_contract)}Using input:${answer}`);}};break;case !0:break;default:ns.tprint(`${output}`);break;}output = object_contract.solve(answer, boolean_verbose);switch (output) {case "":// fall-throughcase !1:ns.tprint(integer_index_contract < array_contracts_length;array_contracts = array_get_contracts(ns),array_contracts_length = array_contracts.length;const void_contracts_solver = function (ns,boolean_verbose) {returnReward: boolean_verbose,solve: function (answer, boolean_verbose) {integer_index_contracts < array_contract_names_length;),array_contract_names_length = array_contract_names.length;integer_index_server < array_servers_length;array_servers = array_get_servers(ns),array_servers_length = array_servers.length;Displays this message then exits.-${object_argument_names.verbose.short}, --${object_argument_names.verbose.long}OPTIONSSECONDS = The duration of delay between each network-wide contract search and solve attempts, in seconds. Should be a floating-point number >= 0.001. By default, the script will only search for and attempt to solve contracts once, unless this option is manually set.`-${object_argument_names.delay.short}, --${object_argument_names.delay.long} <SECONDS>If set, displays messages regarding successful attempts (in addition to standard failed attempt messages).run ${ns.getScriptName()} [FLAGS ...] [OPTIONS]Attempts to solve existing coding contracts in the network.object_defaults,object_argument_names,constobject_argument_names = {},help: {short: "h",long: "help",},verbose: {short: "v",long: "verbose",},},object_defaults = {// time period used for checking the time in secondsfloat_period_check_seconds: 0,// whether to display notification messages or notboolean_verbose: !1,// whether to display help and exitboolean_print_help: !1,},object_solvers = {};delay: {short: "d",long: "delay",// functionsif (float_period_check_seconds > 0) {const float_period_check = 1e3 * float_period_check_seconds;for (;;)void_contracts_solver(ns, float_period_check_seconds, boolean_verbose),await ns.sleep(float_period_check);}else void_contracts_solver(ns, float_period_check_seconds, boolean_verbose);case object_argument_names.delay.short:object_constants = object_get_constants(),// defaultsobject_defaults = object_constants.object_defaults,// argument namesobject_argument_names = object_constants.object_argument_names;letfloat_period_check_seconds = object_defaults.float_period_check_seconds,boolean_verbose = object_defaults.boolean_verbose,boolean_print_help = object_defaults.boolean_print_help;const object_arguments = object_parse_arguments(ns.args);
// functionsconst void_print_help = function (ns) {ns.tprint(DESCRIPTIONCopy all files that contain particular substring(s) in their filenames from all servers to the current server.USAGEARGUMENT = Substring contained in the names of files to be copied to the current server.FLAGSDisplays this message then exits.`);};)-${object_argument_names.help.short}, --${object_argument_names.help.long}run ${ns.getScriptName()} [FLAGS ...] <ARGUMENT [ARGUMENT ...]>string_sanitise(`const object_argument_names = object_get_constants().object_argument_names;// copies string_file_to_copy from string_server_source to the current servertry {}};// copies files that contain a substring from all servers to the current server}};for () {conststring_server_source = array_servers[integer_index_server];void_copy_to_current(ns, string_server_source, array_get_files_with_string(ns,string_server_source,substring));let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;const void_copy_files_with_to_current = function (ns, substring) {constarray_servers = array_get_servers(ns),array_servers_length = array_servers.length;ns.tprint();}catch (error) {ns.tprint();`${error}\nAttempted to copy "${string_input}" located in the server "${string_server_source}".``Copied "${string_input}" located in the server "${string_server_source}".`ns.scp(files_to_copy, string_server_source, ns.getHostname());const void_copy_to_current = function (ns,string_server_source,) {const string_input = JSON.stringify(files_to_copy);files_to_copy// mainexport const main = async function (ns) {};// argument parsinglet array_substrings = [];for (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {// fall-throughboolean_print_help = argument_value;break;case "_":"object" == typeof argument_value? array_substrings.push(...argument_value): array_substrings.push(argument_value);break;default:const string_message_error = `Unknown argument passed: "${string_argument}".`;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));}}// mainif (boolean_print_help)return void_print_help(ns);void_copy_files_with_to_current(ns, array_substrings);case object_argument_names.help.long:case object_argument_names.help.short:constobject_argument_names = object_get_constants().object_argument_names,object_arguments = object_parse_arguments(ns.args);// variableslet boolean_print_help = !1;import { array_get_servers } from "lib_servers.js";const object_get_constants = function () {return {object_argument_names: {help: {short: "h",long: "help",},}}};import { array_get_files_with_string } from "lib_ls.js";import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";/* cp.js - 2.65GB - TODO:* set default to silent* add verbose option*/
// variables// argument parsingfor (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {// fall-throughbreak;// fall-throughcase "_":continue;default:const string_message_error = `Unknown argument passed: \"${string_argument}\".`;ns.tprint(`ERROR: ${string_message_error}`);throw new Error(string_message_error);}}// mainarray_scripts.length > 0? void_kill_scripts_named_servers_named(ns, array_servers, array_scripts): void_kill_scripts_named(ns, array_scripts)? void_kill_scripts_servers_named(ns, array_servers): void_kill_scripts(ns);};// functions// kills running instances of named scripts on a named serverconst void_kill_scripts_named_server_named = function (ns,string_server,array_scripts) {for () {}};// kills running instances of named scripts on named serversconst void_kill_scripts_named_servers_named = function (ns,array_servers,array_scripts) {for () {}};// kills running instances of named scripts on all serversconst void_kill_scripts_named = function (ns, array_scripts) {void_kill_scripts_named_servers_named(ns, array_get_servers(ns), array_scripts);};// kills all but this script on a named serverconst void_kill_scripts_server_named = function (ns, string_server) {for () {string_script !== ns.getScriptName() &&void_kill_script_named_server_named(ns, string_server, string_script);}};// kills all but this script on named serversconst void_kill_scripts_servers_named = function (ns, array_servers) {for () {}};// kills running scripts on all serversconst void_kill_scripts = function (ns) {void_kill_scripts_servers_named(ns, array_get_servers(ns));};void_kill_scripts_server_named(ns, array_servers[integer_index_server]);let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;const array_servers_length = array_servers.length;const string_script = array_scripts_running[integer_index_script].filename;let integer_index_script = 0;++integer_index_scriptinteger_index_script < array_scripts_running_length;constarray_scripts_running = ns.ps(string_server),array_scripts_running_length = array_scripts_running.length;void_kill_scripts_named_server_named(ns, array_servers[integer_index_server], array_scripts);let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;const array_servers_length = array_servers.length;void_kill_script_named_server_named(ns, string_server, array_scripts[integer_index_script]);let integer_index_script = 0;++integer_index_scriptinteger_index_script < array_scripts_length;const array_scripts_length = array_scripts.length;const void_print_help = function (ns) {ns.tprint(DESCRIPTIONKill all running scripts.Optionally, kill only named scripts instead.Optionally, kill only scripts on named servers instead.Optionally, kill only named scripts on named servers instead.USAGEOPTIONSSCRIPT = The name of a script to kill.);};)-${object_argument_names.server.short}, --${object_argument_names.server.long} <SERVER>SERVER = The name of a server on which scripts will be killed.`-${object_argument_names.script.short}, --${object_argument_names.script.long} <SCRIPT>run ${ns.getScriptName()} [FLAGS ...] [OPTIONS ...]FLAGS-${object_argument_names.help.short}, --${object_argument_names.help.long}Displays this message then exits.string_sanitise(`const object_argument_names = object_get_constants().object_argument_names;: array_servers_length > 0? array_servers_length > 0if (boolean_print_help)return void_print_help(ns);const array_servers_length = array_servers.length;"object" == typeof argument_value? array_servers.push(...argument_value): array_servers.push(argument_value);break;// fall-throughboolean_print_help = argument_value;break;case object_argument_names.help.long:case object_argument_names.help.short:case object_argument_names.server.long:case object_argument_names.server.short:"object" == typeof argument_value? array_scripts.push(...argument_value): array_scripts.push(argument_value);case object_argument_names.script.long:case object_argument_names.script.short:constobject_argument_names = object_get_constants().object_argument_names,object_arguments = object_parse_arguments(ns.args);array_servers = [],array_scripts = [];let boolean_print_help = !1;constexport const main = async function (ns) {const object_get_constants = function () {return {object_argument_names: {script: {short: "c",long: "script",},server: {short: "e",long: "server",},help: {short: "h",long: "help",},}};};import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";import { array_get_servers } from "lib_servers.js";import { void_kill_script_named_server_named } from "lib_kill.js";/* kill.js - 2.55GB - TODO:* maybe implement a loop that repeats logic until all appropriate scripts have actually been killed.*/
// mainexport const main = async function (ns) {for () {try {} catch (error) {ns.tprint(JSON.stringify(error));}}}};// functions);// comment out unneeded info`Time: ${new Date().toISOString()}Name: ${string_server}Root access: ${ns.hasRootAccess(string_server)}Current security (x): ${(float_security_current / float_security_minimum).toFixed(integer_precision)}Growth rate: ${ns.getServerGrowth(string_server)}Ports needed for root: ${ns.getServerNumPortsRequired(string_server)}`;ns.tprint(string_server_information);};RAM total (GB): ${float_ram_total.toFixed(integer_precision)}RAM used (GB): ${float_ram_used.toFixed(integer_precision)}RAM used (%): ${((float_ram_used * 100) / float_ram_total).toFixed(integer_precision)}RAM free (GB): ${float_ram_free.toFixed(integer_precision)}RAM free (%): ${((float_ram_free * 100) / float_ram_total).toFixed(integer_precision)}hack() time (s): ${float_get_time_hack(ns, string_server, float_security_current).toFixed(integer_precision)}grow() time (s): ${float_get_time_grow(ns, string_server, float_security_current).toFixed(integer_precision)}weaken() time (s): ${float_get_time_weaken(ns, string_server, float_security_current).toFixed(integer_precision)}Hacking level needed: ${ns.getServerRequiredHackingLevel(string_server)}Score: ${float_get_server_score(ns,string_server,string_method_score_correction,float_multiplier_factor_skill,float_multiplier_factor_max_cash,float_multiplier_factor_growth).toFixed(integer_precision)}Maximum cash ($): ${float_cash_max.toFixed(integer_precision)}Current cash ($): ${float_cash_current.toFixed(integer_precision)}Current cash (%): ${((float_cash_current * 100) / float_cash_max).toFixed(integer_precision)}Minimum security: ${float_security_minimum.toFixed(integer_precision)}Current security: ${float_security_current.toFixed(integer_precision)}};const void_print_information = function (ns,string_server,) {constfloat_cash_max = ns.getServerMaxMoney(string_server),float_cash_current = ns.getServerMoneyAvailable(string_server),float_security_minimum = ns.getServerMinSecurityLevel(string_server),float_security_current = ns.getServerSecurityLevel(string_server),array_ram = ns.getServerRam(string_server),float_ram_total = array_ram[0],float_ram_used = array_ram[1],float_ram_free = array_ram[0] - array_ram[1],string_server_information =integer_precision,string_method_score_correction,float_multiplier_factor_skill,float_multiplier_factor_max_cash,float_multiplier_factor_growthns.tprint(DESCRIPTIONDisplay information about one or more servers.Optionally, display the information at regular intervals.USAGEARGUMENT = Server to display the information about.OPTIONS)-${object_argument_names.precision.short}, --${object_argument_names.precision.long} <INTEGER>INTEGER = The decimal places to display floating point values with. Should be an integer >= 0. Defaults to ${object_defaults.integer_precision}.-${object_argument_names.score_correction.short}, --${object_argument_names.score_correction.long} <METHOD>METHOD = The method used to correct the factors used in the server scoring system. Can be "standard" (uses standard scoring) or "normal" (uses mean normalised scoring). Defaults to "${object_defaults.string_method_score_correction}".`-${object_argument_names.multiplier_skill.short}, --${object_argument_names.multiplier_skill.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_skill}.-${object_argument_names.multiplier_cash.short}, --${object_argument_names.multiplier_cash.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_max_cash}.-${object_argument_names.multiplier_growth.short}, --${object_argument_names.multiplier_growth.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_growth}.-${object_argument_names.delay.short}, --${object_argument_names.delay.long} <SECONDS>SECONDS = The duration of delay between updates, in seconds. Should be a floating-point number >= 0.001. By default, the script will only display server information once, unless this option is manually set.FLAGS-${object_argument_names.help.short}, --${object_argument_names.help.long}Displays this message then exits.run ${ns.getScriptName()} [OPTIONS ...] <ARGUMENT [ARGUMENT ...]>string_sanitise(`const void_print_help = function (ns) {constobject_argument_names = object_get_constants().object_argument_names,object_defaults = object_get_constants().object_defaults;if (float_sleep_duration_seconds < 1) break;await ns.sleep(float_period_check);void_print_information(ns,integer_precision,string_method_score_correction,float_multiplier_factor_skill,float_multiplier_factor_max_cash,float_multiplier_factor_growth);array_servers[integer_index_server],let integer_index_server = 0;++integer_index_serverinteger_index_server < array_servers_length;// variablesarray_servers = [],boolean_print_help = !1;// whether to display help and exit// argument parsingconst object_arguments = object_parse_arguments(ns.args);for (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {// fall-throughbreak;// fall-throughboolean_print_help = argument_value;break;// fall-throughinteger_precision = argument_value;break;case object_argument_names.score_correction.short:// fall-throughcase object_argument_names.score_correction.long:string_method_score_correction = argument_value;break;case "_":array_servers = argument_value;break;default:const string_message_error = `Unknown argument passed: "${string_argument}".`;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));}}// mainif (boolean_print_help)return void_print_help(ns);const float_period_check = 1e3 * float_sleep_duration_seconds;for (0 === array_servers.length && array_servers.push(ns.getHostname()); ; ) {const array_servers_length = array_servers.length;case object_argument_names.precision.long:case object_argument_names.multiplier_skill.short:// fall-throughcase object_argument_names.multiplier_skill.long:float_multiplier_factor_skill = argument_value;break;case object_argument_names.multiplier_cash.short:// fall-throughcase object_argument_names.multiplier_cash.long:float_multiplier_factor_max_cash = argument_value;break;case object_argument_names.multiplier_growth.short:// fall-throughcase object_argument_names.multiplier_growth.long:float_multiplier_factor_growth = argument_value;break;case object_argument_names.precision.short:case object_argument_names.help.long:case object_argument_names.help.short:case object_argument_names.delay.long:float_sleep_duration_seconds = argument_value;case object_argument_names.delay.short:letfloat_multiplier_factor_skill = object_defaults.float_multiplier_factor_skill,float_multiplier_factor_max_cash = object_defaults.float_multiplier_factor_max_cash,float_multiplier_factor_growth = object_defaults.float_multiplier_factor_growth,string_method_score_correction = object_defaults.string_method_score_correction,integer_precision = object_defaults.integer_precision,// initial state of the servers arrayfloat_sleep_duration_seconds = object_defaults.float_sleep_duration_seconds,const// defaultsobject_defaults = object_get_constants().object_defaults,// argument namesobject_argument_names = object_get_constants().object_argument_names;import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";import {float_get_time_hack,float_get_time_grow,float_get_time_weaken,} from "lib_time.js";import { float_get_server_score } from "lib_score.js";const object_get_constants = function () {return {// default valuesobject_defaults: {// decimal places to use for displaying numerical informationinteger_precision: 2,// multiplier for skill factor used in server scoring systemfloat_multiplier_factor_skill: 1,// multiplier for max cash factor used in server scoring systemfloat_multiplier_factor_max_cash: 1,// multiplier for growth factor used in server scoring systemfloat_multiplier_factor_growth: 1,// correction method for factors used in server scoring system. can be "standard" or "normal"string_method_score_correction: "standard",},object_argument_names: {delay: {short: "d",long: "delay",},help: {short: "h",long: "help",},multiplier_skill: {short: "k",long: "multiplier-skill",},multiplier_cash: {short: "l",long: "multiplier-cash",},multiplier_growth: {short: "m",long: "multiplier-growth",},precision: {short: "p",long: "precision",},score_correction: {short: "q",long: "score-correction",},}};};// time period used for checking the time in secondsfloat_sleep_duration_seconds: 0,/* lshw.js - 7.25GB - Display information about one or more servers. TODO:* add flags that prevent certain information from being displayed.*/
* Separate logic that requires source files so that they are only ran when you have the required source file - need a cheap way to check if you have source file?* add a way to determine and notify if an unrecognised argument was passed* figure out a better way for this to run "hacker.js"* Maybe make a cache script that saves runtime constants like max money of servers to a cache file to potentially reduce RAM usage further.*/import {string_sanitise,} from "lib_no_ns.js";object_parse_arguments,import {} from "lib_ram_server.js";import { array_get_servers } from "lib_servers.js";import { void_kill_script_named_server_named } from "lib_kill.js";const object_get_constants = function () {return {// default valuesobject_defaults: {// time period used for checking the time in secondsfloat_period_check_seconds: 10,// duration between each job used to prevent collisions between them to keep them in sequencefloat_padding_seconds: 2,// maximum amount of jobs to execute per schedule, used to prevent using up too much IRL RAMinteger_job_cap: 100,// name of purchased serversstring_servers_bought_name: "server",// targetstring_server_target: "",// precision of the percentage to steal calculatorfloat_precision: 0.01,// ram utilisiation threshold. upgrade ram or buy or replace servers when reached.float_ram_utilisation_threshold: 0.9,// the maximum percentage of cash that should be stolen from a serverfloat_steal_cap: 0.9,// multiplier for skill factor used in server scoring systemfloat_multiplier_factor_skill: 1,// multiplier for max cash factor used in server scoring systemfloat_multiplier_factor_max_cash: 1,// multiplier for growth factor used in server scoring systemfloat_multiplier_factor_growth: 1,// correction method for factors used in server scoring system. can be "standard" or "normal"string_method_score_correction: "standard",// fraction of botnet's ram to use for cyclic weakenfloat_ram_fraction_for_weaken_cyclic: 0.5,// whether to run discrete batches or continuouslyboolean_discrete: !1,},// helper scriptsobject_helpers: {string_nop: "nop.js",string_hacker: "hacker.js",string_ram: "ram.js",string_servers: "servers.js",string_tor: "tor.js",string_programs: "programs.js",string_botnet: "botnet.js",string_weaken_manager: "weaken_manager.js",string_cyclic_weaken: "cyclic_weaken.js",},// argument namesobject_argument_names: {check_delay: {short: "c",long: "check-delay",},job_delay: {short: "d",long: "job-delay",},discrete: {short: "f",long: "discrete",},help: {short: "h",long: "help",},target: {short: "i",long: "target",},job_cap: {short: "j",long: "job-cap",},multiplier_skill: {short: "k",long: "multiplier-skill",},multiplier_cash: {short: "l",long: "multiplier-cash",},multiplier_growth: {short: "m",long: "multiplier-growth",},server_name: {short: "n",long: "server-name",},precision: {short: "p",long: "precision",},score_correction: {short: "q",long: "score-correction",},ram_utilisation: {short: "r",long: "ram-utilisation",},steal_cap: {short: "s",long: "steal-cap",},short: "u",},ram_cyclic_weaken: {short: "v",long: "ram-cyclic-weaken",ram: {short: "a",long: "ram",},servers: {short: "e",long: "servers",},tor: {short: "o",long: "tor",},programs: {short: "g",long: "programs",},botnet: {short: "b",long: "botnet",},// programsarray_programs: ["BruteSSH.exe","FTPCrack.exe","relaySMTP.exe","HTTPWorm.exe","SQLInject.exe","DeepscanV1.exe","DeepscanV2.exe","Autolink.exe",],// script extensionsarray_script_extensions: [".js",".ns",".script"],};};// mainexport const main = async function (ns) {// variablesconst// defaultsobject_defaults = object_get_constants().object_defaults,// argument namesobject_argument_names = object_get_constants().object_argument_names,// helper scriptsobject_helpers = object_get_constants().object_helpers,// threads of "nop.js" required to reserve enough RAM to run "hacker.js"integer_threads_nop = integer_get_threads_nop(ns, object_helpers.string_hacker, ns.getScriptName());// if this server doesn't have enough RAM to run "hacker.js", ejectif (!boolean_can_server_run_script_threads(ns,float_get_server_ram_free(ns, ns.getHostname()),object_helpers.string_nop,integer_threads_nop)) {const string_message_error = `This server has insufficient RAM to run "${object_helpers.string_nop}" with "${integer_threads_nop}" thread(s).`;}letstring_servers_bought_name = object_defaults.string_servers_bought_name,integer_job_cap = object_defaults.integer_job_cap,float_padding_seconds = object_defaults.float_padding_seconds,float_precision = object_defaults.float_precision,float_steal_cap = object_defaults.float_steal_cap,float_period_check_seconds = object_defaults.float_period_check_seconds,string_server_target = object_defaults.string_server_target,float_ram_utilisation_threshold = object_defaults.float_ram_utilisation_threshold,float_multiplier_factor_skill = object_defaults.float_multiplier_factor_skill,float_multiplier_factor_max_cash = object_defaults.float_multiplier_factor_max_cash,float_multiplier_factor_growth = object_defaults.float_multiplier_factor_growth,string_method_score_correction = object_defaults.string_method_score_correction,float_ram_fraction_for_weaken_cyclic = object_defaults.float_ram_fraction_for_weaken_cyclic,boolean_discrete = object_defaults.boolean_discrete,// argument parsingconst object_arguments = object_parse_arguments(ns.args);for (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {case object_argument_names.check_delay.short:// fall-throughcase object_argument_names.check_delay.long:float_period_check_seconds = argument_value;break;case object_argument_names.job_delay.short:// fall-throughcase object_argument_names.job_delay.long:float_padding_seconds = argument_value;break;case object_argument_names.discrete.short:// fall-throughcase object_argument_names.discrete.long:boolean_discrete = argument_value;break;case object_argument_names.help.short:// fall-throughcase object_argument_names.help.long:boolean_print_help = argument_value;break;case object_argument_names.target.short:// fall-throughcase object_argument_names.target.long:string_server_target = argument_value;break;case object_argument_names.job_cap.short:// fall-throughcase object_argument_names.job_cap.long:integer_job_cap = argument_value;break;case object_argument_names.multiplier_skill.short:// fall-throughcase object_argument_names.multiplier_skill.long:float_multiplier_factor_skill = argument_value;break;case object_argument_names.multiplier_cash.short:// fall-throughcase object_argument_names.multiplier_cash.long:float_multiplier_factor_max_cash = argument_value;break;case object_argument_names.multiplier_growth.short:// fall-throughcase object_argument_names.multiplier_growth.long:float_multiplier_factor_growth = argument_value;break;case object_argument_names.server_name.short:// fall-throughcase object_argument_names.server_name.long:string_servers_bought_name = argument_value;break;case object_argument_names.precision.short:// fall-throughcase object_argument_names.precision.long:float_precision = argument_value;break;case object_argument_names.score_correction.short:// fall-throughcase object_argument_names.score_correction.long:string_method_score_correction = argument_value;break;case object_argument_names.ram_utilisation.short:// fall-throughcase object_argument_names.ram_utilisation.long:float_ram_utilisation_threshold = argument_value;break;case object_argument_names.steal_cap.short:// fall-throughcase object_argument_names.steal_cap.long:float_steal_cap = argument_value;break;case object_argument_names.ram_cyclic_weaken.short:// fall-throughcase object_argument_names.ram_cyclic_weaken.long:float_ram_fraction_for_weaken_cyclic = argument_value;break;}}let array_helpers = [{file: object_helpers.string_ram,threads_or_ram_botnet: 1,args: [float_period_check_seconds, float_ram_utilisation_threshold],},{file: object_helpers.string_servers,threads_or_ram_botnet: 1,args: [float_period_check_seconds,string_servers_bought_name,float_ram_utilisation_threshold,],},{file: object_helpers.string_tor,threads_or_ram_botnet: 1,args: [float_period_check_seconds],},{file: object_helpers.string_programs,threads_or_ram_botnet: 1,args: [float_period_check_seconds,],},{file: object_helpers.string_botnet,threads_or_ram_botnet: 1,args: [float_period_check_seconds],},{],},];for (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];((object_argument_names.ram.short === string_argument && argument_value) ||(object_argument_names.ram.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers, object_helpers.string_ram),1),((object_argument_names.servers.short === string_argument && argument_value) ||(object_argument_names.servers.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers,object_helpers.string_servers),1),((object_argument_names.tor.short === string_argument && argument_value) ||(object_argument_names.tor.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers, object_helpers.string_tor),1),((object_argument_names.programs.short === string_argument && argument_value) ||(object_argument_names.programs.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers,object_helpers.string_programs),1),((object_argument_names.botnet.short === string_argument && argument_value) ||(object_argument_names.botnet.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers,object_helpers.string_botnet((object_argument_names.weaken_manager.short === string_argument && argument_value) ||(object_argument_names.weaken_manager.long === string_argument && !argument_value)) &&array_helpers.splice(integer_get_index_of_file(array_helpers,),1);}// mainif (boolean_print_help)return void_print_help(ns);// reserve enough RAM for "hacker.js"ns.exec(object_helpers.string_nop, ns.getHostname(), integer_threads_nop);void_copy_scripts(ns);void_schedule_script_runner(ns, array_make_schedule_script(ns, array_helpers));// kill "nop.js" scripts to free RAMvoid_kill_script_named_server_named(ns,ns.getHostname(),object_helpers.string_nop);ns.spawn(object_helpers.string_hacker,1,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);};// functionsconst void_print_help = function (ns) {constobject_defaults = object_get_constants().object_defaults,object_argument_names = object_get_constants().object_argument_names,object_helpers = object_get_constants().object_helpers;ns.tprint(string_sanitise(`USAGErun ${ns.getScriptName()} [FLAGS ...] [OPTIONS ...]FLAGS-${object_argument_names.ram.short}, --no-${object_argument_names.ram.long}-${object_argument_names.botnet.short}, --no-${object_argument_names.botnet.long}Prevents the "${object_helpers.string_botnet}" script from being started which is responsible for rooting servers in the network.-${object_argument_names.servers.short}, --no-${object_argument_names.servers.long}Prevents the "${object_helpers.string_servers}" script from being started which is responsible for buying and replacing bought servers.-${object_argument_names.discrete.short}, --${object_argument_names.discrete.long}Run discrete batches instead of continuously. The former mode has downtime but may result in more correctly scheduled jobs compared to the latter.-${object_argument_names.programs.short}, --no-${object_argument_names.programs.long}Prevents the "${object_helpers.string_programs}" script from being started which is responsible for buying programs from the "darkweb" server.-${object_argument_names.help.short}, --${object_argument_names.help.long}Displays this message then exits.-${object_argument_names.tor.short}, --no-${object_argument_names.tor.long}Prevents the "${object_helpers.string_tor}" script from being started which is responsible for buying a TOR Router.OPTIONS-${object_argument_names.check_delay.short}, --${object_argument_names.check_delay.long} <SECONDS>-${object_argument_names.job_delay.short}, --${object_argument_names.job_delay.long} <SECONDS>SECONDS = The duration of delay between each job, in seconds. Should be a floating-point number > 0. Defaults to ${object_defaults.float_padding_seconds}.-${object_argument_names.target.short}, --${object_argument_names.target.long} <SERVER>SERVER = The server that should be targetted by the \`weaken\`, \`grow\` and \`hack\` functions. Should be a string. Defaults to choosing an optimal target using a scoring system based on the server's maximum cash, growth, required hacking level, and the player's current hacking level.-${object_argument_names.job_cap.short}, --${object_argument_names.job_cap.long} <CAP>CAP = The maximum amount of jobs to execute per schedule. This is ignored when running in continuous mode. Should be an integer > 0. Defaults to ${object_defaults.integer_job_cap}.-${object_argument_names.server_name.short}, --${object_argument_names.server_name.long} <NAME>NAME = The name to be used for purchased servers. Should be a string. Defaults to "${object_defaults.string_servers_bought_name}".-${object_argument_names.precision.short}, --${object_argument_names.precision.long} <PRECISION>PRECISION = A value used in determining how many cycles of bisection the binary search algorithm used for the percentage to steal calculator should use. Should be a floating point number > 0 <= 1. Values closer to 0 will result in greater precision in the calculation, but potentially longer run-times and compared to values closer to 1. Defaults to ${object_defaults.float_precision}.-${object_argument_names.ram_utilisation.short}, --${object_argument_names.ram_utilisation.long} <THRESHOLD>THRESHOLD = The botnet's ram utilisation threshold after which upgrades/replacements should be bought for servers and the RAM of "home". Should be a floating point number >= 0 <= 1. Values closer to 0 will result in attempting more frequent upgrades/replacements at the cost of less efficient RAM utilisation to cash spenditure ratios. Defaults to ${object_defaults.float_ram_utilisation_threshold}.-${object_argument_names.steal_cap.short}, --${object_argument_names.steal_cap.long} <CAP>-${object_argument_names.multiplier_skill.short}, --${object_argument_names.multiplier_skill.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_skill}.-${object_argument_names.multiplier_cash.short}, --${object_argument_names.multiplier_cash.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_max_cash}.-${object_argument_names.multiplier_growth.short}, --${object_argument_names.multiplier_growth.long} <FLOAT>FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to ${object_defaults.float_multiplier_factor_growth}.-${object_argument_names.score_correction.short}, --${object_argument_names.score_correction.long} <METHOD>METHOD = The method used to correct the factors used in the server scoring system. Can be "standard" (uses standard scoring) or "normal" (uses mean normalised scoring). Defaults to "${object_defaults.string_method_score_correction}".-${object_argument_names.ram_cyclic_weaken.short}, --${object_argument_names.ram_cyclic_weaken.long} <FLOAT>));};// return true if a server has enough RAM to run a script with a stated number of threadsconst boolean_can_server_run_script_threads = function (ns,float_server_used_ram_free,string_script,integer_threads) {return !(ns.getScriptRam(string_script) * integer_threads >float_server_used_ram_free);};// return the difference in RAM requirements between two scriptsconst float_get_ram_difference = function (ns,string_script_0,string_script_1) {return ns.getScriptRam(string_script_0) - ns.getScriptRam(string_script_1);};// return the amount of threads of "nop.js" is required to make up RAM difference between two scriptsconst integer_get_threads_nop = function (ns,string_script_0,string_script_1) {return Math.ceil(float_get_ram_difference(ns, string_script_0, string_script_1) /ns.getScriptRam(object_get_constants().object_helpers.string_nop));};// copies files to all rooted serversconst void_copy_files_to_servers = function (ns,array_files,string_source) {for (let integer_index_server = 0;++integer_index_server)};// copy all scripts from the current server to all serversconst void_copy_scripts = function (ns) {ns,};// returns the index of the scripts array which matches the filename inputconst integer_get_index_of_file = function (array_scripts,string_file) {for (let integer_index_script = 0;integer_index_script < array_scripts.length;++integer_index_script) {}};if (array_scripts[integer_index_script].file === string_file) return integer_index_script;string_host,object_get_constants().array_script_extensions),string_host);const string_host = ns.getHostname();void_copy_files_to_servers(ns,array_get_files_with_string(ns.scp(array_files,string_source,array_servers[integer_index_server]);integer_index_server < array_servers_length;constarray_servers = array_get_servers(ns),array_servers_length = array_servers.length;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}.`CAP = The maximum fraction of cash to steal from the target server per \`hack\` job. Should be a floating point number >= 0 <=1. Defaults to ${object_defaults.float_steal_cap}.SECONDS = The duration of delay between each repeat of the helper scripts' main loops, in seconds. Should be a floating-point number > 0. Defaults to ${object_defaults.float_period_check_seconds}.-${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.Prevents the "${object_helpers.string_ram}" script from being started which is responsible for upgrading the RAM of the "home" server.object_helpers.string_weaken_manager),1),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_secondsobject_get_constants().array_programs,boolean_print_help = object_defaults.boolean_print_help;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));},},long: "weaken-manager",weaken_manager: {// whether to display help and exitboolean_print_help: !1,import { array_get_files_with_string } from "lib_ls.js";import {array_make_schedule_script,void_schedule_script_runner} from "lib_ram_script.js";float_get_server_ram_free/* main.js - 6.9GB - TODO:
/* rm.js - 3.05GB - removes files */import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";// functionsconst object_argument_names = object_get_constants().object_argument_names;ns.tprint(string_sanitise(`DESCRIPTIONRemoves all removable files (which excludes currently running scripts, including this one).Optionally, removes only files whose names match a given regular expression.Optionally, removes only files on servers whose names match a given regular expression.Optionally, removes only files whose names match a given regular expression on servers whose names match a given regular expression.USAGErun ${ns.getScriptName()} [FLAGS ...] [OPTIONS ...]FLAGS-${object_argument_names.help.short}, --${object_argument_names.help.long}Displays this message then exits.OPTIONS-${object_argument_names.server_regex.short}, --${object_argument_names.server_regex.long} <REGEX>REGEX = Regular expression used for server names.-${object_argument_names.file_regex.short}, --${object_argument_names.file_regex.long} <REGEX>REGEX = Regular expression used for filenames.`));};const array_get_servers_matching_regexes = (ns,array_string_server_regexes) => {if (array_string_server_regexes.length > 0) {array_string_server_regexes.forEach(string_server_regex => {array_server_regexes.push(new RegExp(string_server_regex));});});});} else {}};const array_get_files_on_server_matching_regexes = (ns,string_server,array_string_file_regexes) => {if (array_string_file_regexes.length > 0) {constarray_file_regexes = [],array_string_file_regexes.forEach(string_file_regex => {array_file_regexes.push(new RegExp(string_file_regex));});ns.ls(string_server).forEach(string_file => {array_file_regexes.forEach(object_file_regex => {});});} else {return ns.ls(string_server);}};const void_remove = (ns,array_string_server_regexes,array_string_file_regexes) => {const array_servers = array_get_servers_matching_regexes(ns,array_string_server_regexes);array_servers.forEach(string_server => {const array_files = array_get_files_on_server_matching_regexes(ns,string_server,array_string_file_regexes);array_files.forEach(string_file => {if (!ns.rm(string_file,string_server)) {ns.tprint(`WARNING: Unable to remove file "${string_file}" from server "${string_server}".`);}});});};// main// variableslet boolean_print_help = !1;constarray_server_regexes = [],array_file_regexes = [],object_arguments = object_parse_arguments(ns.args),object_argument_names = object_get_constants().object_argument_names;// argument parsingfor (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {case object_argument_names.server_regex.short:// fall-throughcase object_argument_names.server_regex.long:"object" == typeof argument_value? array_server_regexes.push(...argument_value): array_server_regexes.push(argument_value);break;case object_argument_names.file_regex.short:// fall-throughcase object_argument_names.file_regex.long:"object" == typeof argument_value? array_file_regexes.push(...argument_value): array_file_regexes.push(argument_value);break;case object_argument_names.help.short:// fall-throughcase object_argument_names.help.long:boolean_print_help = argument_value;break;case "_":continue;default:const string_message_error = `Unknown argument passed: \"${string_argument}\".`;ns.tprint(`ERROR: ${string_message_error}`);throw new Error(string_message_error);}}// mainif (boolean_print_help)return void_print_help(ns);void_remove(ns, array_server_regexes, array_file_regexes);};export const main = async (ns) => {return array_files_matching_regexes;object_file_regex.test(string_file) &&array_files_matching_regexes.push(string_file);array_files_matching_regexes = [];return array_get_servers(ns);return array_servers_matching_regexes;array_get_servers(ns).forEach(string_server => {array_server_regexes.forEach(object_server_regex => {object_server_regex.test(string_server) &&array_servers_matching_regexes.push(string_server);constarray_server_regexes = [],array_servers_matching_regexes = [];const void_print_help = (ns) => {const object_get_constants = () => ({object_argument_names: {file_regex: {short: "f",long: "file"},server_regex: {short: "e",long: "server"},help: {short: "h",long: "help"},},});import {array_get_servers} from "lib_servers.js";
/* hacknet.js - 5.6 GB - purchases nodes and upgrades them until the highest gain rate increase per cost ratio of the possible upgrades are below a given threshold. TODO:* Link ratio to time to break-even*/import {string_sanitise,object_parse_arguments} from "lib_no_ns.js";const object_get_constants = function () {return {// default valuesobject_defaults: {// time period used for checking the time in secondsfloat_sleep_duration_seconds: 1,// minimum gain rate increase per cost ratio threshold before the script is killedfloat_minimum_ratio: 0.0005,},object_argument_names: {delay: {short: "d",long: "delay",},help: {short: "h",long: "help",},ratio: {short: "r",long: "ratio",},}};};const void_print_help = function (ns) {constobject_defaults = object_get_constants().object_defaults,object_argument_names = object_get_constants().object_argument_names;ns.tprint(string_sanitise(`DESCRIPTIONBuys Hacknet nodes and upgrades them until the highest gain rate increase per cost ratio of the possible upgrades are below a given threshold.USAGErun ${ns.getScriptName()} [FLAGS ...] [OPTIONS ...]FLAGS-${object_argument_names.help.short}, --${object_argument_names.help.long}Displays this message then exits.OPTIONS-${object_argument_names.delay.short}, --${object_argument_names.delay.long} <SECONDS>SECONDS = The duration of delay between each loop iteration, in seconds. Should be a floating-point number >= 0.001. Defaults to ${object_defaults.float_sleep_duration_seconds}.-${object_argument_names.ratio.short}, --${object_argument_names.ratio.long} <FLOAT>FLOAT = A value used in determining if the script should continue buying new Hacknet nodes/upgrades for these. Should be a floating point number >= 0. Higher values indicates a greater threshold so less upgrades/new nodes will be bought. Defaults to ${object_defaults.float_minimum_ratio}.`));};// Adapted from updateMoneyGainRate function in the src/Hacknet/HacknetNode.ts fileconst float_get_gain_rate = function (level,ram,cores) {return level * Math.pow(1.035, ram - 1) * (cores + 5);};const float_get_gain_rate_increase_cost_ratio = function (ns,integer_node,level,ram,cores) {const object_node_stats = ns.hacknet.getNodeStats(integer_node);return (float_get_gain_rate(object_node_stats.level + level,object_node_stats.ram + ram,object_node_stats.cores + cores) -float_get_gain_rate(object_node_stats.level,object_node_stats.ram,object_node_stats.cores)) /(ns.hacknet.getLevelUpgradeCost(integer_node,level) +ns.hacknet.getRamUpgradeCost(integer_node,ram) +ns.hacknet.getCoreUpgradeCost(integer_node,cores));};export const main = async function (ns) {// variablesconst// defaultsobject_defaults = object_get_constants().object_defaults,// argument namesobject_argument_names = object_get_constants().object_argument_names;letfloat_sleep_duration_seconds = object_defaults.float_sleep_duration_seconds,float_minimum_ratio = object_defaults.float_minimum_ratio,// whether to display help and exitboolean_print_help = !1;// argument parsingconst object_arguments = object_parse_arguments(ns.args);for (const string_argument in object_arguments)if (object_arguments.hasOwnProperty(string_argument)) {const argument_value = object_arguments[string_argument];switch (string_argument) {case object_argument_names.delay.short:// fall-throughcase object_argument_names.delay.long:float_sleep_duration_seconds = argument_value;break;case object_argument_names.help.short:// fall-throughcase object_argument_names.help.long:boolean_print_help = argument_value;break;case object_argument_names.ratio.short:// fall-throughcase object_argument_names.ratio.long:float_minimum_ratio = argument_value;break;case "_":continue;default:const string_message_error = `Unknown argument passed: "${string_argument}".`;throw (ns.tprint(`ERROR: ${string_message_error}`), new Error(string_message_error));}}// mainif (boolean_print_help)return void_print_help(ns);const float_period_check = 1e3 * float_sleep_duration_seconds;for (;ns.hacknet.numNodes() <= 0;) {if (ns.hacknet.purchaseNode() === -1) {await ns.sleep(float_period_check);}}for (;;) {constinteger_nodes = ns.hacknet.numNodes(),object_upgrade = {float_gain_rate_increase_cost_ratio: float_get_gain_rate(1,1,1) /ns.hacknet.getPurchaseNodeCost(),void_upgrade: function () {return ns.hacknet.purchaseNode();}};for (let integer_index_nodes = 0;integer_index_nodes < integer_nodes;++integer_index_nodes) {constfloat_ratio_level = float_get_gain_rate_increase_cost_ratio(ns,integer_index_nodes,1,0,0),float_ratio_ram = float_get_gain_rate_increase_cost_ratio(ns,integer_index_nodes,0,1,0),float_ratio_cores = float_get_gain_rate_increase_cost_ratio(ns,integer_index_nodes,0,0,1);if (float_ratio_level > object_upgrade.float_gain_rate_increase_cost_ratio) {object_upgrade.float_gain_rate_increase_cost_ratio = float_ratio_level;object_upgrade.void_upgrade = function () {ns.hacknet.upgradeLevel(integer_index_nodes, 1);};}if (float_ratio_ram > object_upgrade.float_gain_rate_increase_cost_ratio) {object_upgrade.float_gain_rate_increase_cost_ratio = float_ratio_ram;object_upgrade.void_upgrade = function () {ns.hacknet.upgradeRam(integer_index_nodes, 1);};}if (float_ratio_cores > object_upgrade.float_gain_rate_increase_cost_ratio) {object_upgrade.float_gain_rate_increase_cost_ratio = float_ratio_cores;object_upgrade.void_upgrade = function () {ns.hacknet.upgradeCore(integer_index_nodes, 1);};}}if (object_upgrade.float_gain_rate_increase_cost_ratio >= float_minimum_ratio) {object_upgrade.void_upgrade();} else {break;}await ns.sleep(float_period_check);}};
Save all the `.js` files in this repository to the root directory of a rooted server (one with at least enough RAM to run "hacker.js", e.g. "foodnstuff") using the same filenames (but not including the directory names) that they currently have in this repository.
### Semi-automatic Installation1. Install [Node](https://nodejs.org/en/download/package-manager/).2. Clone this repository to a local directory.3. From a terminal/command prompt, navigate to that directory, run `npm install` (to install dependencies), then `npm start` (to start the install server).4. In-game, save the "nicoty.bin.installer.js" (2.6 GB) file to the root directory of a rooted server (one with at least enough RAM to run "nicoty.sbin.hacker.js", e.g. "foodnstuff"), then run it without any extra arguments, i.e., with `run nicoty.bin.installer.js`.5. Exit from `npm` (i.e., using `Ctrl-C` if ran from a POSIX-compliant terminal).
At the start of a new game or just after resetting, run `run botnet.js 0.001` to increase the RAM available for the scripts and increase the available hackable servers, then `run kill.js` (to kill any currently running scripts).
### Manual Installation1. Save all the `.js` files in this repository that have ".lib." in their name to the root directory of a rooted server (one with at least enough RAM to run "nicoty.sbin.hacker.js", e.g. "foodnstuff") using the same filenames that they currently have in this repository.2. Do the same for the rest of the `.js` files in the repository.### Post-installationAt the start of a new game or just after resetting, run `run nicoty.sbin.botnet.js 0.001` to increase the RAM available for the scripts and increase the available hackable servers, then `run nicoty.bin.kill.js` (to kill any currently running scripts).
* Values delimited by square-brackets (i.e, "[" and "]") = Indicate optional parameters/values.* Values delimited by angle-brackets (i.e., "<" and ">") = Indicate required parameters/values.
* Optional parameters/values = Indicated by values delimited by square-brackets (i.e, "[" and "]"). These are parameters which can be left out when invoking a script.* Required parameters/values = Values delimited by angle-brackets (i.e., "<" and ">"). These are parameters which must be present when invoking a script.* Executable scripts = Scripts with "bin" (but not "sbin") in their name. These can and are meant to be manually ran by the user.* System executable scripts = Scripts with "sbin" in their name. These can be manually run by the user, but are generally meant to be ran automatically by other scripts.* Library scripts = Scripts with "lib" in their name. These can't be run by the user and instead export functions or procedures to be shared with and used by other scripts.
The following section is an overview of what the executable scripts (located in the "bin" directory of this repository) are supposed to do, as well as usage information and examples for each one.
The following section is an overview of what the executable scripts are supposed to do, as well as usage information and examples for each one.
### "main.js" (6.9 GB)* Reserve at least enough RAM to be able to run "hacker.js" (13.35 GB).* Copy all scripts to all rooted servers.* Run the helper scripts (located in the "sbin" directory and aren't really supposed to be ran manually) "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" (4 GB) which should, respectively, attempt to:* Upgrade your home server's RAM.* Buy and replace old servers when appropriate.* Buy a TOR Router.* Buy programs from the dark web.* Exploit and root servers.* 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".* Kill itself by spawning "hacker.js" which should then:* Make and execute a schedule containing information about when, where and how many threads (among other information) the "weaken.js", "grow.js" and "hack.js" worker scripts should be executed with. The schedule is generated such that all the jobs will be ran pretty much concurrently, but will sleep for some time such that each one finishes running just after the previous one in the schedule finishes.* Wait for a duration of time such that jobs in a new schedule will start finishing just after the older schedule finishes.* Repeat.* \* = SourceFile-4 required for these to properly function.
### "nicoty.bin.main.js" (6.9 GB)* Reserve at least enough RAM to be able to run "nicoty.sbin.hacker.js" (13.35 GB).* Copy all scripts to all rooted servers.* Run the helper scripts "nicoty.sbin.ram.js"\* (6.6 GB), "nicoty.sbin.servers.js" (8.85 GB), "nicoty.sbin.tor.js"\* (3.8 GB), "nicoty.sbin.programs.js"\* (3.7 GB), "nicoty.sbin.botnet.js" (2.2 GB) and "nicoty.sbin.weaken.manager.js" (4.2 GB) which should, respectively, attempt to:* Upgrade your home server's RAM.* Buy and replace old servers when appropriate.* Buy a TOR Router.* Buy programs from the dark web.* Exploit and root servers.* Run a variable amount of "nicoty.sbin.weaken.cyclic.js" threads (1.75 GB) which gains hacking experience by continuously weakening the server that will be targeted by "nicoty.sbin.hacker.js".* Kill itself by spawning "nicoty.sbin.hacker.js" which should then:* Make and execute a schedule containing information about when, where and how many threads (among other information) the "weaken.js", "grow.js" and "hack.js" worker scripts should be executed with. The schedule is generated such that all the jobs will be ran pretty much concurrently, but will sleep for some time such that each one finishes running just after the previous one in the schedule finishes.* Wait for a duration of time such that jobs in a new schedule will start finishing just after the older schedule finishes.* Repeat.* \* = SourceFile-4 required for these to properly function.
* Prevents the "weaken_manager.js" script from being started which is responsible for running threads of "cyclic_weaken.js" to gain hacking experience.
* Prevents the "nicoty.sbin.weaken.manager.js" script from being started which is responsible for running threads of "nicoty.bin.weaken.cyclic.js" to gain hacking experience.
`-c, --check-delay <SECONDS>`* SECONDS = The duration of delay between each repeat of the helper scripts' main loops, in seconds. Should be a floating-point number > 0. Defaults to 10.`-d, --job-delay <SECONDS>`
`-c, --check-delay <SECONDS>`
* SECONDS = The duration of delay between each job, in seconds. Should be a floating-point number > 0. Defaults to 2.
* SECONDS = The duration of delay between each repeat of the helper scripts' main loops, in seconds. Should be a floating-point number > 0. Defaults to 10.
* SERVER = The server that should be targetted by the `weaken`, `grow` and `hack` functions. Should be a string. Defaults to choosing an optimal target using a scoring system based on the server's maximum cash, growth, required hacking level, and the player's current hacking level.
* SECONDS = The duration of delay between each job, in seconds. Should be a floating-point number > 0. Defaults to 2.
* CAP = The maximum amount of jobs to execute per schedule. This is ignored when running in continuous mode. Should be an integer > 0. Defaults to 100.
* SERVER = The server that should be targetted by the `weaken`, `grow` and `hack` functions. Should be a string. Defaults to choosing an optimal target using a scoring system based on the server's maximum cash, growth, required hacking level, and the player's current hacking level.
* PRECISION = A value used in determining how many cycles of bisection the binary search algorithm used for the percentage to steal calculator should use. Should be a floating point number > 0 <= 1. Values closer to 0 will result in greater precision in the calculation, but potentially longer run-times and compared to values closer to 1. Defaults to 0.01.
* NAME = The name to be used for purchased servers. Should be a string. Defaults to "server".
* THRESHOLD = The botnet's ram utilisation threshold after which upgrades/replacements should be bought for servers and the RAM of "home". Should be a floating point number >= 0 <= 1. Values closer to 0 will result in attempting more frequent upgrades/replacements at the cost of less efficient RAM utilisation to cash spenditure ratios. Defaults to 0.9.
* PRECISION = A value used in determining how many cycles of bisection the binary search algorithm used for the percentage to steal calculator should use. Should be a floating point number > 0 <= 1. Values closer to 0 will result in greater precision in the calculation, but potentially longer run-times and compared to values closer to 1. Defaults to 0.01.
* CAP = The maximum fraction of cash to steal from the target server per `hack` job. Should be a floating point number >= 0 <=1. Defaults to 0.9.
* THRESHOLD = The botnet's ram utilisation threshold after which upgrades/replacements should be bought for servers and the RAM of "home". Should be a floating point number >= 0 <= 1. Values closer to 0 will result in attempting more frequent upgrades/replacements at the cost of less efficient RAM utilisation to cash spenditure ratios. Defaults to 0.9.
* FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* CAP = The maximum fraction of cash to steal from the target server per `hack` job. Should be a floating point number >= 0 <=1. Defaults to 0.9.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* METHOD = The method used to correct the factors used in the server scoring system. Can be "standard" (uses standard scoring) or "normal" (uses mean normalised scoring). Defaults to "standard".
* FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should be a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* 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.
* FLOAT = The fraction of the botnet's current available RAM to be used by "nicoty.sbin.weaken.manager.js" to run threads of "nicoty.sbin.weaken.cyclic.js". Should be a floating point number > 0. Defaults to 0.5.
* Runs the script with up to 4000 jobs per schedule, targetting "harakiri-sushi", only upgrading/replacing servers when at least 0.7 of your network's total RAM is being used, stealing only up to 50% of harakiri-sushi's cash per "hack.js" job that finishes executing, and using the "mean normalised" score correction method, whilst the remaining variables are set to defaults. The "ram.js", "tor.js" and "botnet.js" helper scripts are also prevented from starting.
* Runs the script with up to 1000 jobs per schedule, targetting "harakiri-sushi", only upgrading/replacing servers when at least 0.7 of your network's total RAM is being used, stealing only up to 50% of harakiri-sushi's cash per "hack" job that finishes executing, and using the "mean normalised" score correction method, whilst the remaining variables are set to defaults. The "nicoty.sbin.ram.js", "nicoty.sbin.tor.js" and "nicoty.sbin.botnet.js" helper scripts are also prevented from starting.
### "kill.js" (2.55 GB)* Kill all running scripts.* Optionally, kill only named scripts instead.* Optionally, kill only scripts on named servers instead.* Optionally, kill only named scripts on named servers instead.
### "nicoty.bin.kill.js" (2.55 GB)* Kill all running scripts.* Optionally, kill only named scripts instead.* Optionally, kill only scripts on named servers instead.* Optionally, kill only named scripts on named servers instead.
`run kill.js -c grow.js --script hack.js`
* Kills all scripts named "nicoty.sbin.grow.js" and "nicoty.sbin.hack.js" on any servers that they are currently running on.`run nicoty.bin.kill.js -e home --server harakiri-sushi`* Kills all scripts currently running on the "home" and "harakiri-sushi" servers.`run nicoty.bin.kill.js -c nicoty.sbin.grow.js --script nicoty.sbin.hack.js -e home --server harakiri-sushi`* Kills all scripts named "nicoty.sbin.grow.js" and "nicoty.sbin.hack.js" currently running on the "home" and "harakiri-sushi" servers.---### "nicoty.bin.hacknet.js" (5.6 GB)* Buys Hacknet nodes and upgrades them until the highest gain rate increase per cost ratio of the possible upgrades are below a given threshold.#### USAGE`run nicoty.bin.hacknet.js [FLAGS ...] [OPTIONS ...]`#### FLAGS`-h, --help`
* Kills all scripts named "grow.js" and "hack.js" currently running on the "home" and "harakiri-sushi" servers.
* FLOAT = A value used in determining if the script should continue buying new Hacknet nodes/upgrades for these. Should be a floating point number >= 0. Higher values indicates a greater threshold so less upgrades/new nodes will be bought. Defaults to 0.0005.
### "hacknet.js" (5.6 GB)* Buys Hacknet nodes and upgrades them until the highest gain rate increase per cost ratio of the possible upgrades are below a given threshold.
### "nicoty.bin.stocks.js" (8.9 GB)* Starts stock-trading related scripts. Requires TIX API access.
`-d, --delay <SECONDS>`
`-c, --investment-capital <FRACTION>`* FRACTION = The fraction of your total cash (invested + not invested in the stock market) that can be used to invest in the stock market. Should be a floating point number > 0 <= 1. Defaults to 1.`-d, --delay <SECONDS>`* SECONDS = The duration of delay between each repeat of the helper scripts' main loops, in seconds. Should be a floating-point number > 0. Defaults to 10.`-r, --range <RANGE>`* RANGE = The length of the stock objects' average price array used to calculate the short range simple moving average of the stock's average price growth. Should be an integer >= 1. Defaults to 10.---### "nicoty.bin.gui.js" (1.6 GB)* Exposes a GUI that can be used to control other scripts.
* FLOAT = A value used in determining if the script should continue buying new Hacknet nodes/upgrades for these. Should be a floating point number >= 0. Higher values indicates a greater threshold so less upgrades/new nodes will be bought. Defaults to 0.0005.
* Displays this message then exits.
* SECONDS = The duration of delay between each network-wide contract search and solve attempts, in seconds. Should be a floating-point number >= 0.001. By default, the script will only search for and attempt to solve contracts once, unless this option is manually set.
* SECONDS = The duration of delay between each network-wide contract search and solve attempts, in seconds. Should be a floating-point number >= 0.001. By default, the script will only search for and attempt to solve contracts once, unless this option is manually set.
### "rm.js" (3.05 GB)* Removes all removable files (which excludes currently running scripts, including this one).* Optionally, removes only files whose names match a given regular expression.* Optionally, removes only files on servers whose names match a given regular expression.* Optionally, removes only files whose names match a given regular expression on servers whose names match a given regular expression.
### "nicoty.bin.rm.js" (3.05 GB)* Removes all removable files (which excludes currently running scripts, including this one).* Optionally, removes only files whose names match a given regular expression.* Optionally, removes only files on servers whose names match a given regular expression.* Optionally, removes only files whose names match a given regular expression on servers whose names match a given regular expression.
* Removes all files from servers whose names match the regular expressions "home" and "harakiri-sushi".
* Removes all files with filenames that match the regular expressions "txt" and "lit" from servers whose names match the regular expressions "home" and "harakiri-sushi".
* Removes all files with filenames that match the regular expressions "txt" and "lit" from servers whose names match the regular expressions "home" and "harakiri-sushi".
* Removes all files from all servers, except for those in servers that have "home" in their name, and are files that have "cct", "exe", "lit", "msg" or "txt" in their name.
### "lshw.js" (7.25 GB)* Display information about one or more servers.* Optionally, display the information at regular intervals.
### "nicoty.bin.lshw.js" (7.35 GB)* Display information about one or more servers.* Optionally, display the information at regular intervals.
* SECONDS = The duration of delay between updates, in seconds. Should be a floating-point number >= 0.001. By default, the script will only display server information once, unless this option is manually set.
* SECONDS = The duration of delay between updates, in seconds. Should be a floating-point number >= 0.001. By default, the script will only display server information once, unless this option is manually set.
* FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.`-l, --multiplier-cash <FLOAT>`* FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing your skill against the target server used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's maximum cash used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* INTEGER = The decimal places to display floating point values with. Should be an integer >= 0. Defaults to 2.
* FLOAT = The multiplier used to change the weight of the factor representing the target server's growth used in the server scoring system. Should a floating point number. 1 = factor has normal importance, > 1 = factor has more importance, < 1 = factor has less importance, 0 = factor is not used, < 0 = factor has negative effect. Defaults to 1.
* METHOD = The method used to correct the factors used in the server scoring system. Can be "standard" (uses standard scoring) or "normal" (uses mean normalised scoring). Defaults to "standard".
* INTEGER = The decimal places to display floating point values with. Should be an integer >= 0. Defaults to 2.
* Causes the terminal to output up-to-date information about the "home" and "foodnstuff" servers every second, using 4 decimal places for the floating point values it displays.
* Causes the terminal to output up-to-date information about the "home" and "foodnstuff" servers every second, using 4 decimal places for the floating point values it displays.
### "cp.js" (2.65 GB)* Copy all files that contain particular substring(s) in their filenames from all servers to the current server.
### "nicoty.bin.cp.js" (2.65 GB)* Copy all files that contain particular substring(s) in their filenames from all servers to the current server.
* Copies all files that contain the strings ".lit", ".script" or ".txt" in their filename from all servers to the current server.
* Copies all files that contain the strings ".lit", ".script" or ".txt" in their filename from all servers to the current server.
### "hacker.js" does not seem to run!* Make sure there is enough RAM for "hacker.js" (see requirements in the "Overview" section above) on the server that you ran "main.js" from. Sometimes, "weaken_manager.js" will run "cyclic_weaken.js" on that server so you might need to look out for and kill any instances of the latter that get executed on that server before "hacker.js" has a chance to get spawned.
### "nicoty.sbin.hacker.js" does not seem to run!* Make sure there is enough RAM for "nicoty.sbin.hacker.js" (see requirements in the "Overview" section above) on the server that you ran "nicoty.bin.main.js" from. Sometimes, "nicoty.sbin.weaken.manager.js" will run "nicoty.sbin.weaken.cyclic.js" on that server so you might need to look out for and kill any instances of the latter that get executed on that server before "nicoty.sbin.hacker.js" has a chance to get spawned.
* Sometimes the game doesn't calculate the RAM requirements of scripts properly which can occur if the scripts weren't saved properly through `nano` or were loaded into the game via other means. Try opening and resaving the scripts using `nano` to allow the game to properly calculate the scripts' RAM requirements.
* Sometimes the game doesn't calculate the RAM requirements of scripts properly which can occur if the scripts weren't loaded into the game in the correct order. The scripts which other scripts depend on need to be installed before installing the dependent scripts. Try opening and resaving the dependent scripts using `nano` to allow the game to properly calculate the scripts' RAM requirements.
* [Post about it in the repository's discussion page](https://nest.pijul.com/nicoty/bitburner_scripts/discussions) or contact me through Matrix (@nicoty:matrix.org) or Reddit (u/VoidNoire). Make sure your message contains the following information:* How you installed the scripts.* The exact command that you ran prior to encountering the issue.* The server from which you ran the command.* The amount of free RAM that the server has.* The outcome you expected.* The actual outcome that occurred instead (including exact error messages).
* [Post about it in the repository's discussion page](https://nest.pijul.com/nicoty/bitburner_scripts/discussions) or contact me through Matrix (@nicoty:matrix.org) or Reddit (u/VoidNoire). Make sure your message contains the following information:* How you installed the scripts.* The exact command that you ran prior to encountering the issue.* The server from which you ran the command.* The amount of free RAM that the server has.* The outcome you expected.* The actual outcome that occurred instead (including exact error messages).
* [See if this discussion about the hacking strategy used answers your questions](https://web.archive.org/web/20201010181949/https://old.reddit.com/r/Bitburner/comments/g2ry1t/can_someone_explain_traditional_hacking_loop/). If it doesn't, feel free to contact me through one of the channels above.
* [See if this discussion about the hacking strategy used answers your questions](https://web.archive.org/web/20201010181949/https://old.reddit.com/r/Bitburner/comments/g2ry1t/can_someone_explain_traditional_hacking_loop/). If it doesn't, feel free to contact me through one of the channels above.
This software is distributed and licensed under the terms of the [Blue Oak Model License 1.0.0](https://web.archive.org/web/20190309191626/https://blueoakcouncil.org/license/1.0.0).
This software is distributed and licensed under the terms of the [Blue Oak Model License 1.0.0](https://web.archive.org/web/20190309191626/https://blueoakcouncil.org/license/1.0.0) and uses code adapted from third party sources that are distributed and licensed under their own terms (see LICENSE-OTHERS).