Advertisement
ouija_bh

hm-manager.js

Mar 5th, 2023 (edited)
578
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 38.28 KB | Gaming | 0 0
  1. /** buildServerInfo()
  2.  * @param {NS} ns NS2 namespace
  3.  * @param {string[]} callScript ["weakenScript", "growScript", "hackScript"]
  4.  * @returns {Array[]} []["serverName", ram, freeRam]
  5.  */
  6. function buildServerInfo(ns, callScript) {
  7.     var servers = [];
  8.     // Purchased servers
  9.     var serversPurch = ns.getPurchasedServers();
  10.     for (var i = 0; i < serversPurch.length; i++) {
  11.         var serverName = serversPurch[i];
  12.         var ram = ns.getServerMaxRam(serverName);
  13.         if (ram < 64) {
  14.             ns.tprint(serverName + " RAM too low, need 64 GB minimum.");
  15.         } else {
  16.             ns.scp(callScript[0], serverName);
  17.             ns.scp(callScript[1], serverName);
  18.             ns.scp(callScript[2], serverName);
  19.             servers[servers.length] = [serverName, ram, ram];
  20.         }
  21.     }
  22.     // Home
  23.     var homeRam = 512;
  24.     servers[servers.length] = [ns.getHostname(), homeRam, homeRam];
  25.     return servers;
  26. }
  27.  
  28. /** monitorMoney()
  29.  * @param {NS} ns NS2 namespace
  30.  * @param {number} moneyMax maximum money of target
  31.  * @param {number} moneyAvail money available on target
  32.  * @param {string} target server to display values for
  33.  */
  34. function monitorMoney(ns, moneyMax, moneyAvail, target) {
  35.     ns.tprint(target + ":  Money=" + ns.formatPercent(moneyAvail / moneyMax, 3));
  36. }
  37.  
  38. /** waitOnJob()
  39.  * @param {NS} ns NS2 namespace
  40.  * @param {number} delay time to wait (ms)
  41.  * @param {Array[]} servers []["scriptName", "serverName", bound, "target"]
  42.  * @param {number} timeExec maximum time needed for exec() to complete (ms)
  43.  */
  44. async function waitOnJob(ns, delay, servers, timeExec) {
  45.     await ns.sleep(delay);
  46.     for (var i = 0; i < servers.length; i++) {
  47.         while (ns.isRunning(servers[i][0], servers[i][1], servers[i][2], servers[i][3])) {
  48.             await ns.sleep(timeExec);
  49.         }
  50.     }
  51. }
  52.  
  53. /** performJob()
  54.  * @param {NS} ns NS2 namespace
  55.  * @param {Array[]} servers []["scriptName", "serverName", numThreads, "target"]
  56.  * @param {number} timeExec maximum time needed for exec() to complete (ms)
  57.  * @param {number} timeDelay maximum sleep time until weaken, grow, or hack (ms)
  58.  * @returns {Array[]} []["scriptName", "serverName", bound, "target"]
  59.  */
  60. async function performJob(ns, servers, timeExec, timeDelay) {
  61.     var retServers = [];
  62.     var delta = 0;
  63.     for (var i = 0; i < servers.length; i++) {
  64.         var start = Date.now();
  65.         if (servers[i][2] > 0) {
  66.             ns.exec(servers[i][0], servers[i][1], servers[i][2], start + timeDelay, servers[i][3]);
  67.             var elapsedTime = Date.now() - start;
  68.             delta = timeExec - elapsedTime;
  69.             if ((i != servers.length - 1) && (delta > 0)) {
  70.                 await ns.sleep(delta);
  71.             }
  72.         }
  73.         retServers[retServers.length] = [servers[i][0], servers[i][1], start + timeDelay, servers[i][3]];
  74.     }
  75.     if (delta < 0) { delta = 0; }
  76.     await ns.sleep(timeDelay + delta);
  77.     return retServers;
  78. }
  79.  
  80. /** calculateJob()
  81.  * @param {string[]} callScript ["weakenScript", "growScript", "hackScript"]
  82.  * @param {number[]} callRam [weakenRam, growRam, hackRam]
  83.  * @param {Array[]} servers []["serverName", ram, freeRam]
  84.  * @param {number} numCalls number of calls
  85.  * @param {number} mode modes are 0:weaken, 1:grow, 2:hack
  86.  * @param {string} target server to pull money from
  87.  * @returns {Array[][]} [numCalls, totalFree, []["scriptName", "serverName", numThreads, "target"]]
  88.  */
  89. function calculateJob(callScript, callRam, servers, numCalls, mode, target) {
  90.     var retCalls = 0;
  91.     var retServers = [];
  92.     var fractionalJob = 0;
  93.     var totalFree = 0;
  94.     // Calculate free RAM on all servers
  95.     for (var i = 0; i < servers.length; i++) {
  96.         totalFree += servers[i][2];
  97.     }
  98.     var retFree = totalFree;
  99.     // Calculate RAM being requested
  100.     var totalRequested = numCalls * callRam[mode];
  101.  
  102.     if (totalRequested >= totalFree) {
  103.         // Use all available RAM
  104.         for (var i = 0; i < servers.length; i++) {
  105.             var numThreads = servers[i][2] / callRam[mode];
  106.             var numThreadsFloor = Math.floor(numThreads);
  107.               // add the fractional job
  108.             fractionalJob += numThreads - numThreadsFloor;
  109.             numThreads = numThreadsFloor;
  110.             retServers[retServers.length] = [callScript[mode], servers[i][0], numThreads, target];
  111.             retCalls += numThreads;
  112.             servers[i][2] = 0;
  113.         }
  114.         retFree = 0;
  115.     } else {
  116.         // Use (totalRequested / totalFree) part of ram on each server
  117.         for (var i = 0; i < servers.length; i++) {
  118.             var numThreads = (totalRequested / totalFree) * servers[i][2] / callRam[mode];
  119.             var numThreadsFloor = Math.floor(numThreads);
  120.               // add the fractional job
  121.             fractionalJob += numThreads - numThreadsFloor;
  122.             numThreads = numThreadsFloor;
  123.             retServers[retServers.length] = [callScript[mode], servers[i][0], numThreads, target];
  124.             if (numThreads > 0) {
  125.                 retCalls += numThreads;
  126.                 retFree -= numThreads * callRam[mode];
  127.                 servers[i][2] -= numThreads * callRam[mode];
  128.             }
  129.         }
  130.     }
  131.     // Assign the fractional job. This will increase the number of threads, but
  132.     // will not decrease free RAM on the host because RAM was reserved for this.
  133.     fractionalJob = Math.round(fractionalJob);
  134.     retCalls += fractionalJob;
  135.     for (var i = 0; i < fractionalJob; i++) {
  136.         retServers[i][2]++;
  137.     }
  138.     return [retCalls, retFree, retServers];
  139. }
  140.  
  141. /** getStdDev()
  142.  * @param {Array[]} servers []["serverName", ram, freeRam]
  143.  * @returns {number} standard deviation of free RAM on hosts
  144.  */
  145. function getStdDev(servers) {
  146.     var meanRam = 0, sdRam = 0;
  147.     for (var i = 0; i < servers.length; i++) {
  148.         meanRam += servers[i][2];
  149.     }
  150.     meanRam /= servers.length;
  151.     for (var i = 0; i < servers.length; i++) {
  152.         sdRam += (servers[i][2] - meanRam) ** 2;
  153.     }
  154.     sdRam = Math.sqrt(sdRam / servers.length);
  155.     return sdRam;
  156. }
  157.  
  158. /** getHostMult() Gets host thread multiplier for hacking money from max to 60%.
  159.  * @param {Array[]} servers []["serverName", ram, freeRam]
  160.  * @returns {number} host thread multiplier
  161.  */
  162. function getHostMult(servers) {
  163.     var retval;
  164.     if (servers.length >= 3) {
  165.         retval = 0.175 + (servers.length - 3) * 0.015;
  166.     } else if (servers.length == 2) {
  167.         retval = 0.125;
  168.     } else {
  169.         return 0;
  170.     }
  171.     retval -= getStdDev(servers) * 0.000225;
  172.     if (retval < 0) { retval = 0; }
  173.     return retval;
  174. }
  175.  
  176. /** setFreeRam()
  177.  * @param {number} numJobs number of concurrent jobs
  178.  * @param {Array[]} servers []["serverName", ram, freeRam]
  179.  * @param {number} scriptRam max RAM needed for host script
  180.  */
  181. function setFreeRam(numJobs, servers, scriptRam) {
  182.     // Reserve (numJobs * scriptRam) RAM from each host.
  183.     for (var i = 0; i < servers.length; i++) {
  184.         servers[i][2] = servers[i][1] - numJobs * scriptRam;
  185.     }
  186. }
  187.  
  188. /** printTotalIncome()
  189.  * @param {NS} ns NS2 namespace
  190.  * @param {number} totalIncome total $ produced
  191.  * @param {number} startTime manager start time
  192.  * @param {string} target server to pull money from
  193.  */
  194. function printTotalIncome(ns, totalIncome, startTime, target) {
  195.     ns.tprint(target + ":  Total=$" + ns.formatNumber(totalIncome, 3, 1000, true) +
  196.             "  Per second=$" + ns.formatNumber(totalIncome / ((Date.now() - startTime) / 1000), 3, 1000, true));
  197. }
  198.  
  199. /**
  200.  * @param {NS} ns NS2 namespace
  201.  * @version 1.1
  202.  */
  203. export async function main(ns) {
  204.     if (ns.args.length < 1) {
  205.         ns.tprint("Usage: " + ns.getScriptName() + " <target>");
  206.         ns.exit();
  207.     }
  208.     var target = ns.args[0];    // server to pull money from
  209.     ns.disableLog("ALL");
  210.     // Check for running script
  211.     var callScript = ["hm-weaken.js", "hm-grow.js", "hm-hack.js"];
  212.     if (ns.scriptRunning(callScript[0], ns.getHostname()) ||
  213.             ns.scriptRunning(callScript[1], ns.getHostname()) ||
  214.             ns.scriptRunning(callScript[2], ns.getHostname())) {
  215.         ns.tprint("Host script already running.");
  216.     }
  217.     // Get root access on the target
  218.     if (ns.fileExists("BruteSSH.exe", "home")) { ns.brutessh(target); }
  219.     if (ns.fileExists("FTPCrack.exe", "home")) { ns.ftpcrack(target); }
  220.     if (ns.fileExists("relaySMTP.exe", "home")) { ns.relaysmtp(target); }
  221.     if (ns.fileExists("HTTPWorm.exe", "home")) { ns.httpworm(target); }
  222.     ns.nuke(target);
  223.    
  224.     var bFormulas = ns.fileExists("Formulas.exe", "home");
  225.     if (bFormulas) { ns.tprint("Using Formulas.exe."); }
  226.     var callRam = [ns.getScriptRam(callScript[0]), ns.getScriptRam(callScript[1]), ns.getScriptRam(callScript[2])];
  227.     var moneyMax = ns.getServerMaxMoney(target);
  228.     var threshMoney = moneyMax * 0.75;  // money threshold
  229.     var secLevelMin = ns.getServerMinSecurityLevel(target);
  230.     var threshSec = secLevelMin + 3.25;  // security threshold
  231.     var moneyAvail = ns.getServerMoneyAvailable(target);
  232.     var secLevel = ns.getServerSecurityLevel(target);
  233.     // maximum time needed for exec() to complete (ms)
  234.     var timeExec = 25;
  235.     // maximum sleep time until weaken, grow, or hack (ms)
  236.     var timeDelay;
  237.     // total $ produced
  238.     var totalIncome = 0;
  239.     // hacking skill multiplier uses result of hacking money from max to 60%.
  240.     var skillM = (ns.getServerRequiredHackingLevel(target) / ns.getHackingLevel() - 1 / 3) * 0.67;
  241.     // If not using formulas:
  242.       // Part per hack value. (Normalize for security level below threshold).
  243.     var pphCurrent = -1;
  244.       // Part per hack values for security level below/above threshold.
  245.     var pphSecLow = -1, pphSecHigh = -1;
  246.       // Part per grow values. (SL/SH for security level below/above threshold).
  247.     var ppg60to85SL = -1, ppg60to100SL = -1, ppg75to100SL = -1;
  248.     var ppg60to85SH = -1, ppg60to100SH = -1, ppg75to100SH = -1;
  249.       // Multipliers used to normalize part per hack and part per grow.
  250.     var pphNorm = 0.043, ppg60Norm = 0.15, ppg100Norm = 0.15;
  251.  
  252.     // Build array of server information
  253.     var servers = buildServerInfo(ns, callScript);
  254.     ns.tprint("Managing " + servers.length + " servers.");
  255.     // host thread multiplier for hacking money from max to 60%
  256.     var hostM;
  257.     // Display estimated RAM needed and total RAM.
  258.     {
  259.         setFreeRam(3, servers, Math.max.apply(null, callRam));
  260.         hostM = getHostMult(servers);
  261.         // calculate number of hack calls
  262.         var partPerHack, mockTarget, norm = 1;
  263.         if (bFormulas) {
  264.             mockTarget = ns.getServer(target);
  265.             mockTarget.hackDifficulty = secLevelMin + 1;
  266.             partPerHack = ns.formulas.hacking.hackPercent(mockTarget, ns.getPlayer());
  267.         } else {
  268.             partPerHack = ns.hackAnalyze(target);
  269.             if (secLevel > threshSec) { norm += pphNorm; }
  270.             partPerHack *= norm;
  271.         }
  272.         var partToHack = 0.4 * (skillM + hostM + 1);
  273.         var numHack1 = Math.ceil(partToHack / (partPerHack + Number.EPSILON));
  274.         // calculate number of grow calls
  275.         var numGrow;
  276.         if (bFormulas) {
  277.             mockTarget.hackDifficulty += numHack1 * 0.002;
  278.             mockTarget.moneyAvailable = 0.6 * moneyMax;
  279.             numGrow = ns.formulas.hacking.growThreads(mockTarget, ns.getPlayer(), moneyMax);
  280.         } else {
  281.             if (moneyAvail >= threshMoney) { norm -= ppg60Norm; }
  282.             numGrow = ns.growthAnalyze(target, norm / 0.6);
  283.         }
  284.         // calculate number of hack calls
  285.         if (bFormulas) {
  286.             mockTarget.hackDifficulty += numGrow * 0.004;
  287.             partPerHack = ns.formulas.hacking.hackPercent(mockTarget, ns.getPlayer());
  288.         } else {
  289.             partPerHack = ns.hackAnalyze(target);
  290.             if (secLevel <= threshSec) { partPerHack /= pphNorm + 1; }
  291.         }
  292.         var numHack2 = Math.ceil(partToHack / partPerHack);
  293.         var neededRam = numHack1 * callRam[2] + numGrow * callRam[1] + numHack2 * callRam[2];
  294.         ns.tprint("Estimated RAM needed for hack, grow, hack #2: "
  295.                 + ns.formatRam(neededRam, 1));
  296.         // calculate total RAM on all servers
  297.         var totalRam = 0;
  298.         for (var i = 0; i < servers.length; i++) {
  299.             totalRam += servers[i][1];
  300.         }
  301.         ns.tprint("Total host RAM: " + ns.formatRam(totalRam, 1));
  302.     }
  303.  
  304.     var startTime = Date.now();
  305.     while (true) {
  306.         var timeWeaken = ns.getWeakenTime(target);
  307.         var timeGrow = ns.getGrowTime(target);
  308.         var timeHack = ns.getHackTime(target);
  309.           // time between end of one job and the previous (ms)
  310.         var timeDistance = timeHack / 50;
  311.         if (timeDistance < 200) {   // set to minimum
  312.             timeDistance = 200;
  313.         }
  314.         var bSecHigh = secLevel > threshSec;
  315.         var bMoneyLow = moneyAvail < threshMoney;
  316.  
  317.         if (!bFormulas) {
  318.             pphCurrent = ns.hackAnalyze(target);
  319.             // Get multiplier to normalize part per hack.
  320.             if (secLevel >= secLevelMin && secLevel <= secLevelMin + 1.25) {
  321.                 pphSecLow = pphCurrent;
  322.             } else if (secLevel > threshSec && secLevel <= threshSec + 1.5) {
  323.                 pphSecHigh = pphCurrent;
  324.             }
  325.             if (pphSecLow != -1 && pphSecHigh != -1) {
  326.                 pphNorm = (pphSecLow - pphSecHigh) / pphSecHigh;
  327.             }
  328.             // Get part per grow value(s).
  329.             if ((0.594 < moneyAvail / moneyMax) && (moneyAvail / moneyMax < 0.606)) {
  330.                 var numGrow = ns.growthAnalyze(target, moneyMax / moneyAvail);
  331.                 var ppgTo100 = ((moneyMax - moneyAvail) / moneyMax) / numGrow;
  332.                 numGrow = ns.growthAnalyze(target, 0.85 * moneyMax / moneyAvail);
  333.                 var ppgTo85 = (0.85 - (moneyAvail / moneyMax)) / numGrow;
  334.                 if (secLevel >= secLevelMin && secLevel <= secLevelMin + 1.25) {
  335.                     ppg60to100SL = ppgTo100;
  336.                     ppg60to85SL = ppgTo85;
  337.                 } else if (secLevel > threshSec && secLevel <= threshSec + 1.5) {
  338.                     ppg60to100SH = ppgTo100;
  339.                     ppg60to85SH = ppgTo85;
  340.                 }
  341.             } else if (moneyAvail / moneyMax > 0.994) {
  342.                 var numGrow = ns.growthAnalyze(target, 1.33 * moneyMax / moneyAvail);
  343.                 var ppgTo100 = (1.33 - (moneyAvail / moneyMax)) / numGrow;
  344.                 if (secLevel >= secLevelMin && secLevel <= secLevelMin + 1.25) {
  345.                     ppg75to100SL = ppgTo100;
  346.                 } else if (secLevel > threshSec && secLevel <= threshSec + 1.5) {
  347.                     ppg75to100SH = ppgTo100;
  348.                 }
  349.             }
  350.             // Get multiplier to normalize part per grow.
  351.             if (ppg60to100SL != -1 && ppg60to100SH != -1) {
  352.                 ppg60Norm = (ppg60to100SL - ppg60to100SH) / ppg60to100SH;
  353.                 if (ppg75to100SL == -1 || ppg75to100SH == -1) {   // use ppg60Norm as estimate
  354.                     ppg100Norm = ppg60Norm;
  355.                 }
  356.             }
  357.             if (ppg75to100SL != -1 && ppg75to100SH != -1) {
  358.                 ppg100Norm = (ppg75to100SL - ppg75to100SH) / ppg75to100SH;
  359.                 if (ppg60to100SL == -1 || ppg60to100SH == -1) {   // use ppg100Norm as estimate
  360.                     ppg60Norm = ppg100Norm;
  361.                 }
  362.             }
  363.             // Normalize part per hack value.
  364.             if (bSecHigh) { pphCurrent *= pphNorm + 1; }
  365.         }
  366.        
  367.         ns.tprint(target + ":  Money=" + ns.formatPercent(moneyAvail / moneyMax, 3) +
  368.             "  secMin=" + secLevelMin + "  Sec=" + ns.formatNumber(secLevel, 3));
  369.         if (bSecHigh && bMoneyLow) {
  370.             setFreeRam(3, servers, Math.max.apply(null, callRam));
  371.             hostM = getHostMult(servers);
  372.             ns.tprint(target + ": weaken[, grow, weaken #2]");
  373.             var doOptional = false, resCG = null, resCW2 = null;
  374.             // calculate number of grow calls
  375.             var numGrow;
  376.             if (bFormulas) {
  377.                 var mockTarget = ns.getServer(target);
  378.                 mockTarget.hackDifficulty = secLevelMin;
  379.                 numGrow = ns.formulas.hacking.growThreads(mockTarget, ns.getPlayer(), moneyMax);
  380.             } else {
  381.                 numGrow = Math.ceil(ns.growthAnalyze(target, moneyMax / (ppg60Norm * 0.5 + 1) / (moneyAvail + Number.EPSILON)));
  382.             }
  383.             // calculate number of weaken calls
  384.             var numWeaken1 = Math.ceil((secLevel - secLevelMin) / 0.05);
  385.             var numWeaken2 = Math.ceil((numGrow * 0.004) / 0.05);
  386.             // calculate weaken job
  387.             var resCW1 = calculateJob(callScript, callRam, servers, numWeaken1, 0, target);
  388.             // Was enough free RAM found to weaken secLevel to min, and
  389.             // is there enough free RAM to perform a second weaken?
  390.             if ((resCW1[0] >= numWeaken1) && (resCW1[1] >= servers.length * callRam[0])) {
  391.                 // calculate weaken #2 job
  392.                 resCW2 = calculateJob(callScript, callRam, servers, numWeaken2, 0, target);
  393.                 // Were enough weaken threads calculated to balance the grow threads and
  394.                 // is there enough free RAM to perform grow?
  395.                 if ((resCW2[0] >= numWeaken2) && (resCW2[1] >= servers.length * callRam[1])) {
  396.                     doOptional = true;
  397.                     // calculate grow job
  398.                     resCG = calculateJob(callScript, callRam, servers, numGrow, 1, target);
  399.                 }
  400.             }
  401.             if (doOptional) {
  402.                 timeDelay = Math.ceil((resCW1[0] + resCG[0]) / 2.5);
  403.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  404.                     timeDistance = timeExec * servers.length + timeDelay;
  405.                 }
  406.                 // weaken
  407.                 await performJob(ns, resCW1[2], timeExec, timeDelay);
  408.                 await ns.sleep(2 * timeDistance);
  409.                 // weaken #2
  410.                 var resPW2 = await performJob(ns, resCW2[2], timeExec, timeDelay);
  411.                 await ns.sleep(timeWeaken - timeDistance - timeGrow - (timeExec * servers.length + timeDelay));
  412.                 // grow
  413.                 await performJob(ns, resCG[2], timeExec, timeDelay);
  414.                 // wait on weaken #2
  415.                 await waitOnJob(ns, timeGrow + timeDistance, resPW2, timeExec);
  416.                 moneyAvail = ns.getServerMoneyAvailable(target);
  417.             } else {
  418.                 timeDelay = Math.ceil(resCW1[0] / 2);
  419.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  420.                     timeDistance = timeExec * servers.length + timeDelay;
  421.                 }
  422.                 // weaken
  423.                 var resPW1 = await performJob(ns, resCW1[2], timeExec, timeDelay);
  424.                 // wait on weaken
  425.                 await waitOnJob(ns, timeWeaken, resPW1, timeExec);
  426.             }
  427.         } else if (!bSecHigh && bMoneyLow) {
  428.             setFreeRam(3, servers, Math.max.apply(null, callRam));
  429.             hostM = getHostMult(servers);
  430.             ns.tprint(target + ": grow[, hack, grow #2]");
  431.             var doOptional = false, resCG2 = null, resCH = null;
  432.             // calculate number of calls for first grow
  433.             var numGrow1 = Math.ceil(ns.growthAnalyze(target, moneyMax / (moneyAvail + Number.EPSILON)));
  434.             // calculate number of hack calls
  435.             var partPerHack;
  436.             if (bFormulas) {
  437.                 var mockTarget = ns.getServer(target);
  438.                 mockTarget.hackDifficulty += numGrow1 * 0.004;
  439.                 partPerHack = ns.formulas.hacking.hackPercent(mockTarget, ns.getPlayer());
  440.             } else {
  441.                 partPerHack = pphCurrent;
  442.                 if (threshSec < secLevel + numGrow1 * 0.004) {
  443.                     partPerHack /= pphNorm + 1;
  444.                 }
  445.             }
  446.             var partToHack = 0.25 * (skillM + hostM * 0.6 + 1);
  447.             var numHack = Math.ceil(partToHack / (partPerHack + Number.EPSILON));
  448.             // calculate number of grow calls needed after hack
  449.             var numGrow2;
  450.             if (bFormulas) {
  451.                 var mockTarget = ns.getServer(target);
  452.                 mockTarget.moneyAvailable = 0.75 * moneyMax;
  453.                 mockTarget.hackDifficulty += numHack * 0.002 + numGrow1 * 0.004;
  454.                 numGrow2 = ns.formulas.hacking.growThreads(mockTarget, ns.getPlayer(), moneyMax);
  455.             } else {
  456.                 var norm = pphNorm + 1;
  457.                 if (threshSec < secLevel + numHack * 0.002 + numGrow1 * 0.004) {
  458.                     if (ppg75to100SH != -1) {
  459.                         numGrow2 = Math.ceil(0.33 * norm / ppg75to100SH);
  460.                     } else {
  461.                         norm += ppg100Norm;
  462.                         if (ppg75to100SL != -1) {
  463.                             numGrow2 = Math.ceil(0.33 * norm / ppg75to100SL);
  464.                         } else {
  465.                             numGrow2 = Math.ceil(ns.growthAnalyze(target, 1.33 * moneyMax * norm / (moneyAvail + Number.EPSILON))) - numGrow1;
  466.                         }
  467.                     }
  468.                 } else {
  469.                     if (ppg75to100SL != -1) {
  470.                         numGrow2 = Math.ceil(0.33 * norm / ppg75to100SL);
  471.                     } else if (ppg75to100SH != -1) {
  472.                         norm -= ppg100Norm / 2;
  473.                         numGrow2 = Math.ceil(0.33 * norm / ppg75to100SH);
  474.                     } else {
  475.                         numGrow2 = Math.ceil(ns.growthAnalyze(target, 1.33 * moneyMax * norm / (moneyAvail + Number.EPSILON))) - numGrow1;
  476.                     }
  477.                 }
  478.             }
  479.             // calculate grow job
  480.             var resCG1 = calculateJob(callScript, callRam, servers, numGrow1, 1, target);
  481.             // Was enough free RAM found to grow money to max, and
  482.             // is there enough free RAM to perform a second grow?
  483.             if ((resCG1[0] >= numGrow1) && (resCG1[1] >= servers.length * callRam[1])) {
  484.                 // calculate grow #2 job
  485.                 resCG2 = calculateJob(callScript, callRam, servers, numGrow2, 1, target);
  486.                 // Was enough free RAM found to grow money back to max after hack, and
  487.                 // is there enough free RAM to perform hack?
  488.                 if ((resCG2[0] >= numGrow2) && (resCG2[1] >= servers.length * callRam[2])) {
  489.                     // calculate hack job
  490.                     resCH = calculateJob(callScript, callRam, servers, numHack, 2, target);
  491.                     // Is there enough free RAM to hack money to 75% of max?
  492.                     if (resCH[0] >= numHack) {
  493.                         doOptional = true;
  494.                     }
  495.                 }
  496.             }
  497.             timeDelay = Math.ceil(resCG1[0] / 2);
  498.             if (timeDistance < timeExec * servers.length + timeDelay) {
  499.                 timeDistance = timeExec * servers.length + timeDelay;
  500.             }
  501.             if (doOptional) {
  502.                 // grow
  503.                 var resPG1 = await performJob(ns, resCG1[2], timeExec, timeDelay);
  504.                 await ns.sleep(2 * timeDistance);
  505.                 // grow #2
  506.                 var resPG2 = await performJob(ns, resCG2[2], timeExec, timeDelay);
  507.                 await ns.sleep(timeGrow - timeDistance - timeHack - (timeExec * servers.length + timeDelay));
  508.                 // hack
  509.                 var resPH = await performJob(ns, resCH[2], timeExec, timeDelay);
  510.                 // wait on grow
  511.                 await waitOnJob(ns, timeHack - timeDistance, resPG1, timeExec);
  512.                 var prevMoneyAvail = ns.getServerMoneyAvailable(target);
  513.                 monitorMoney(ns, moneyMax, prevMoneyAvail, target);
  514.                 // wait on hack
  515.                 await waitOnJob(ns, timeDistance, resPH, timeExec);
  516.                 // calculate income
  517.                 moneyAvail = ns.getServerMoneyAvailable(target);
  518.                 totalIncome += prevMoneyAvail - moneyAvail;
  519.                 printTotalIncome(ns, totalIncome, startTime, target);
  520.                 monitorMoney(ns, moneyMax, moneyAvail, target);
  521.                 // wait on grow #2
  522.                 await waitOnJob(ns, timeDistance, resPG2, timeExec);
  523.             } else {
  524.                 // grow
  525.                 var resPG1 = await performJob(ns, resCG1[2], timeExec, timeDelay);
  526.                 // wait on grow
  527.                 await waitOnJob(ns, timeGrow, resPG1, timeExec);
  528.             }
  529.             moneyAvail = ns.getServerMoneyAvailable(target);
  530.         } else if (bSecHigh && !bMoneyLow) {
  531.             // If not using formulas, run [hack, ]weaken until a value for ppg60to100SL has been
  532.             // obtained, then run [hack, [grow, ]]weaken.
  533.             if (bFormulas || ppg60to100SL != -1) {
  534.                 setFreeRam(3, servers, Math.max.apply(null, callRam));
  535.                 ns.tprint(target + ": [hack, [grow, ]]weaken");
  536.             } else {
  537.                 setFreeRam(2, servers, Math.max.apply(null, callRam));
  538.                 ns.tprint(target + ": [hack, ]weaken");
  539.             }
  540.             hostM = getHostMult(servers);
  541.             var doOptionalH = false, doOptionalG = false, resCH = null, resCG = null;
  542.             var prevMoneyAvail = moneyAvail;
  543.             // calculate number of hack calls
  544.             var partToHack = ((moneyAvail / moneyMax) - 0.6) * (skillM + hostM + pphNorm * 0.5 + 1);
  545.             var partPerHack;
  546.             if (bFormulas) {
  547.                 partPerHack = ns.formulas.hacking.hackPercent(ns.getServer(target), ns.getPlayer());
  548.             } else {
  549.                 partPerHack = pphCurrent / (pphNorm + 1);
  550.             }
  551.             var numHack = Math.ceil(partToHack / partPerHack);
  552.             // calculate number of weaken calls
  553.             var numWeaken = Math.ceil((secLevel - secLevelMin + (numHack * 0.002)) / 0.05);
  554.             // calculate weaken job
  555.             var resCW = calculateJob(callScript, callRam, servers, numWeaken, 0, target);
  556.             // is there enough free RAM to run hack?
  557.             if (resCW[1] >= servers.length * callRam[2]) {
  558.                 doOptionalH = true;
  559.                 // calculate hack job
  560.                 resCH = calculateJob(callScript, callRam, servers, numHack, 2, target);
  561.                 // Is it time to [grow], and was enough free RAM found to hack money to 60%, and
  562.                 // is there enough free RAM to perform grow?
  563.                 if ((bFormulas || ppg60to100SL != -1) && (resCH[0] >= numHack)
  564.                             && (resCH[1] >= servers.length * callRam[1])) {
  565.                     // calculate number of grow calls
  566.                     var numGrow;
  567.                     if (bFormulas) {
  568.                         var mockTarget = ns.getServer(target);
  569.                         mockTarget.moneyAvailable = 0.6 * moneyMax;
  570.                         mockTarget.hackDifficulty += numHack * 0.002;
  571.                         numGrow = ns.formulas.hacking.growThreads(mockTarget, ns.getPlayer(), 0.85 * moneyMax);
  572.                     } else {
  573.                         if (ppg60to85SH != -1) {
  574.                             numGrow = Math.ceil(0.25 / ppg60to85SH);
  575.                         } else if (ppg60to85SL != -1) {
  576.                             numGrow = Math.ceil(0.25 * (ppg60Norm + 1) / ppg60to85SL);
  577.                         } else {
  578.                             numGrow = Math.ceil(ns.growthAnalyze(target, 0.85 / 0.6));
  579.                         }
  580.                     }
  581.                     // calculate grow job
  582.                     resCG = calculateJob(callScript, callRam, servers, numGrow, 1, target);
  583.                     // Was enough free RAM found to grow money from 60% to 85%, and
  584.                     // is there enough free RAM to perform weaken?
  585.                     if ((resCG[0] >= numGrow) && (resCG[1] >= servers.length * callRam[0])) {
  586.                         // calculate number of additional weaken calls
  587.                         var numWeaken2 = Math.ceil((numGrow * 0.004) / 0.05);
  588.                         // calculate additional weaken
  589.                         var resCW2 = calculateJob(callScript, callRam, servers, numWeaken2, 0, target);
  590.                         // Were enough weaken threads calculated to balance the grow threads?
  591.                         if (resCW2[0] >= numWeaken2) {
  592.                             doOptionalG = true;
  593.                             // add additonal weaken threads
  594.                             for (var i = 0; i < resCW[2].length; i++) {
  595.                                 resCW[2][i][2] += resCW2[2][i][2];
  596.                             }
  597.                         }
  598.                     }
  599.                 }
  600.             }
  601.             if (doOptionalG && doOptionalH) {
  602.                 timeDelay = Math.ceil((resCG[0] + resCH[0]) / 4);
  603.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  604.                     timeDistance = timeExec * servers.length + timeDelay;
  605.                 }
  606.                 // weaken
  607.                 var resPW = await performJob(ns, resCW[2], timeExec, timeDelay);
  608.                 await ns.sleep(timeWeaken - timeDistance - timeGrow - (timeExec * servers.length + timeDelay));
  609.                 // grow
  610.                 await performJob(ns, resCG[2], timeExec, timeDelay);
  611.                 await ns.sleep(timeGrow - timeDistance - timeHack - (timeExec * servers.length + timeDelay));
  612.                 // hack
  613.                 var resPH = await performJob(ns, resCH[2], timeExec, timeDelay);
  614.                 // wait on hack
  615.                 await waitOnJob(ns, timeHack, resPH, timeExec);
  616.                 // calculate income
  617.                 moneyAvail = ns.getServerMoneyAvailable(target);
  618.                 totalIncome += prevMoneyAvail - moneyAvail;
  619.                 printTotalIncome(ns, totalIncome, startTime, target);
  620.                 monitorMoney(ns, moneyMax, moneyAvail, target);
  621.                 // wait on weaken
  622.                 await waitOnJob(ns, 2 * timeDistance, resPW, timeExec);
  623.                 moneyAvail = ns.getServerMoneyAvailable(target);
  624.             } else if (doOptionalH) {
  625.                 timeDelay = Math.ceil(resCH[0] / 2);
  626.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  627.                     timeDistance = timeExec * servers.length + timeDelay;
  628.                 }
  629.                 // weaken
  630.                 var resPW = await performJob(ns, resCW[2], timeExec, timeDelay);
  631.                 await ns.sleep(timeWeaken - timeDistance - timeHack - (timeExec * servers.length + timeDelay));
  632.                 // hack
  633.                 await performJob(ns, resCH[2], timeExec, timeDelay);
  634.                 // wait on weaken
  635.                 await waitOnJob(ns, timeHack + timeDistance, resPW, timeExec);
  636.                 // calculate income
  637.                 moneyAvail = ns.getServerMoneyAvailable(target);
  638.                 totalIncome += prevMoneyAvail - moneyAvail;
  639.                 printTotalIncome(ns, totalIncome, startTime, target);
  640.             } else {
  641.                 timeDelay = Math.ceil(resCW[0] / 2);
  642.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  643.                     timeDistance = timeExec * servers.length + timeDelay;
  644.                 }
  645.                 // weaken
  646.                 var resPW = await performJob(ns, resCW[2], timeExec, timeDelay);
  647.                 // wait on weaken
  648.                 await waitOnJob(ns, timeWeaken, resPW, timeExec);
  649.             }
  650.         } else {
  651.             setFreeRam(3, servers, Math.max.apply(null, callRam));
  652.             hostM = getHostMult(servers);
  653.             ns.tprint(target + ": hack[, grow, hack #2]");
  654.             var doOptional = false;
  655.             var resCG = null, resCH2 = null;
  656.             var prevMoneyAvail = moneyAvail;
  657.             // calculate number of hack calls
  658.             var partToHack = ((moneyAvail / moneyMax) - 0.6) * (skillM + hostM + 1);
  659.             var partPerHack;
  660.             if (bFormulas) {
  661.                 partPerHack = ns.formulas.hacking.hackPercent(ns.getServer(target), ns.getPlayer());
  662.             } else {
  663.                 partPerHack = pphCurrent;
  664.             }
  665.             var numHack1 = Math.ceil(partToHack / partPerHack);
  666.             // calculate hack job
  667.             var resCH = calculateJob(callScript, callRam, servers, numHack1, 2, target);
  668.             // Was enough free RAM found to hack money to 60%, and
  669.             // is there enough free RAM to perform grow?
  670.             if ((resCH[0] >= numHack1) && (resCH[1] >= servers.length * callRam[1])) {
  671.                 // calculate number of grow calls
  672.                 var numGrow;
  673.                 if (bFormulas) {
  674.                     var mockTarget = ns.getServer(target);
  675.                     mockTarget.moneyAvailable = 0.6 * moneyMax;
  676.                     mockTarget.hackDifficulty += numHack1 * 0.002;
  677.                     numGrow = ns.formulas.hacking.growThreads(mockTarget, ns.getPlayer(), moneyMax);
  678.                 } else {
  679.                     var norm = pphNorm + 1;
  680.                     if (threshSec < secLevel + numHack1 * 0.002) {
  681.                         if (ppg60to100SH != -1) {
  682.                             numGrow = Math.ceil(0.4 * norm / ppg60to100SH);
  683.                         } else {
  684.                             norm += ppg60Norm;
  685.                             if (ppg60to100SL != -1) {
  686.                                 numGrow = Math.ceil(0.4 * norm / ppg60to100SL);
  687.                             } else {
  688.                                 numGrow = Math.ceil(ns.growthAnalyze(target, norm / 0.6));
  689.                             }
  690.                         }
  691.                     } else {
  692.                         if (ppg60to100SL != -1) {
  693.                             numGrow = Math.ceil(0.4 * norm / ppg60to100SL);
  694.                         } else if (ppg60to100SH != -1) {
  695.                             norm -= ppg60Norm;
  696.                             numGrow = Math.ceil(0.4 * norm / ppg60to100SH);
  697.                         } else {
  698.                             numGrow = Math.ceil(ns.growthAnalyze(target, norm / 0.6));
  699.                         }
  700.                     }
  701.                 }
  702.                 // calculate grow job
  703.                 resCG = calculateJob(callScript, callRam, servers, numGrow, 1, target);
  704.                 // Was enough free RAM found to grow money back to max after hack, and
  705.                 // is there enough free RAM to perform a second hack?
  706.                 if ((resCG[0] >= numGrow) && (resCG[1] >= servers.length * callRam[2])) {
  707.                     // calculate number of hack calls
  708.                     partToHack = 0.4 * (skillM + hostM + 1);
  709.                     if (bFormulas) {
  710.                         var mockTarget = ns.getServer(target);
  711.                         mockTarget.hackDifficulty += numHack1 * 0.002 + numGrow * 0.004;
  712.                         partPerHack = ns.formulas.hacking.hackPercent(mockTarget, ns.getPlayer());
  713.                     } else {
  714.                         var norm = pphNorm * 0.5 + 1;
  715.                         if (threshSec < secLevel + numHack1 * 0.002 + numGrow * 0.004) {
  716.                             norm += pphNorm * 0.5;
  717.                         }
  718.                         partPerHack /= norm;
  719.                     }
  720.                     var numHack2 = Math.ceil(partToHack / partPerHack);
  721.                     // calculate second hack job
  722.                     resCH2 = calculateJob(callScript, callRam, servers, numHack2, 2, target);
  723.                     if (resCH2[0] >= numHack2) {
  724.                         doOptional = true;
  725.                     }
  726.                 }
  727.             }
  728.             if (doOptional) {
  729.                 timeDelay = Math.ceil((resCH[0] + resCG[0]) / 2.5);
  730.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  731.                     timeDistance = timeExec * servers.length + timeDelay;
  732.                 }
  733.                 // grow
  734.                 var resPG = await performJob(ns, resCG[2], timeExec, timeDelay);
  735.                 await ns.sleep(timeGrow - timeHack - timeDistance - (timeExec * servers.length + timeDelay));
  736.                 // hack
  737.                 var resPH = await performJob(ns, resCH[2], timeExec, timeDelay);
  738.                 await ns.sleep(2 * timeDistance);
  739.                 // hack #2
  740.                 var resPH2 = await performJob(ns, resCH2[2], timeExec, timeDelay);
  741.                 // wait on hack
  742.                 await waitOnJob(ns, timeHack - 2 * timeDistance - (timeExec * servers.length + timeDelay), resPH, timeExec);
  743.                 moneyAvail = ns.getServerMoneyAvailable(target);
  744.                 totalIncome += prevMoneyAvail - moneyAvail;
  745.                 monitorMoney(ns, moneyMax, moneyAvail, target);
  746.                 // wait on grow
  747.                 await waitOnJob(ns, timeDistance, resPG, timeExec);
  748.                 moneyAvail = ns.getServerMoneyAvailable(target);
  749.                 monitorMoney(ns, moneyMax, moneyAvail, target);
  750.                 prevMoneyAvail = moneyAvail;
  751.                 // wait on hack #2
  752.                 await waitOnJob(ns, timeDistance, resPH2, timeExec);
  753.                 moneyAvail = ns.getServerMoneyAvailable(target);
  754.                 // adjust hacking skill multiplier, if needed
  755.                 if (moneyAvail / moneyMax < 0.595) {
  756.                     skillM -= 0.004;
  757.                 } else if (moneyAvail / moneyMax > 0.605) {
  758.                     skillM += 0.004;
  759.                 }
  760.             } else {
  761.                 timeDelay = Math.ceil(resCH[0] / 2);
  762.                 if (timeDistance < timeExec * servers.length + timeDelay) {
  763.                     timeDistance = timeExec * servers.length + timeDelay;
  764.                 }
  765.                 // hack
  766.                 var resPH = await performJob(ns, resCH[2], timeExec, timeDelay);
  767.                 // wait on hack
  768.                 await waitOnJob(ns, timeHack, resPH, timeExec);
  769.                 moneyAvail = ns.getServerMoneyAvailable(target);
  770.                 // Was money at max, and was enough free RAM found to hack money to 60%?
  771.                 if ((resCH[0] >= numHack1) && (prevMoneyAvail / moneyMax > 0.997)) {
  772.                     // adjust hacking skill multiplier, if needed
  773.                     if (moneyAvail / moneyMax < 0.595) {
  774.                         skillM -= 0.004;
  775.                     } else if (moneyAvail / moneyMax > 0.605) {
  776.                         skillM += 0.004;
  777.                     }
  778.                 }
  779.             }
  780.             // calculate income
  781.             totalIncome += prevMoneyAvail - moneyAvail;
  782.             printTotalIncome(ns, totalIncome, startTime, target);
  783.         }
  784.         secLevel = ns.getServerSecurityLevel(target);
  785.     }
  786. }
Tags: Bitburner
Advertisement
Comments
  • ouija_bh
    2 years
    # text 0.14 KB | 0 0
    1. Bug fixed in 1.1:
    2. - If only running hack job, skillM is adjusted even if money was not max or free RAM was not found to hack money to 60%.
Add Comment
Please, Sign In to add comment
Advertisement