return object_constants;
};
// targetting
// returns the score of a server which is calculated by taking into account its max cash, growth, and required hacking level. adapted from `calculatePercentMoneyHacked` in Hacking.js
const float_get_server_score = function(ns, string_server_target) {
const float_player_hacking_level = ns.getHackingLevel();
return ns.getServerMaxMoney(string_server_target) * ns.getServerGrowth(string_server_target) * ((float_player_hacking_level - (ns.getServerRequiredHackingLevel(string_server_target) - 1)) * Math.pow(float_player_hacking_level, -1));
};
// sort an array of servers by their score, from lowest to highest
const void_sort_by_server_scores = function(ns, array_servers) {
return array_servers.sort((string_element_0, string_element_1) => float_get_server_score(ns, string_element_0) - float_get_server_score(ns, string_element_1));
};
// weaken, grow, hack
// returns integer_threads_required if it's less than or equal to integer_threads_available, otherwise returns integer_threads_available
const integer_get_corrected_threads = function(ns, integer_threads_required, integer_threads_available) {
if (integer_threads_required > integer_threads_available) {
return integer_threads_available;
}
else {
return integer_threads_required;
}
};
// weaken stuff
// the threads required for weaken to cause string_server_target's security to decrease by float_weaken_amount. adapted from `weaken` in NetscriptFunctions.js and `weaken` in Server.ts
const integer_get_threads_required_for_weaken = function(ns, float_weaken_amount) {
const object_constants = object_get_constants(ns);
return float_weaken_amount * Math.pow(object_constants.ServerWeakenAmount, -1) * Math.pow(object_constants.object_bitnode_multipliers.ServerWeakenRate, -1);
};
// returns the threads required for weaken to cause string_server_target's security to reach minimum
const integer_get_threads_required_for_weaken_minimum_security = function(ns, string_server_target, float_server_target_security) {
return Math.ceil(integer_get_threads_required_for_weaken(ns, float_server_target_security - ns.getServerMinSecurityLevel(string_server_target)));
};
// returns the 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
const integer_get_threads_weaken = function(ns, float_server_used_ram_free, string_server_target, float_server_target_security) {
const string_weaken = object_get_constants(ns).array_workers[0];
const integer_threads_available = Math.trunc(float_server_used_ram_free / ns.getScriptRam(string_weaken));
const integer_threads_required = integer_get_threads_required_for_weaken_minimum_security(ns, string_server_target, float_server_target_security);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// returns the security decrease from the weaken threads used. Adapted from `weaken` in NetscriptFunctions.js and `weaken` in Server.ts
const float_get_security_decrease_from_weaken = function(ns, integer_threads_weaken) {
return integer_threads_weaken * object_get_constants(ns).ServerWeakenAmount;
};
// grow stuff
// returns the number of threads of `grow` needed to grow `string_server_target` by the percentage `float_growth` when it has security of `float_server_security`. float_growth = How much the server is being grown by, in DECIMAL form (e.g. 1.5 rather than 50). adapted from `numCycleForGrowth` in https://github.com/danielyxie/bitburner/blob/master/src/Server/ServerHelpers.ts
const integer_get_threads_for_growth = function(ns, string_server_target, float_server_target_security, float_growth) {
const object_constants = object_get_constants(ns);
let ajdGrowthRate = 1 + (object_constants.ServerBaseGrowthRate - 1) / float_server_target_security;
if (ajdGrowthRate > object_constants.ServerMaxGrowthRate) {
ajdGrowthRate = object_constants.ServerMaxGrowthRate;
}
const serverGrowthPercentage = ns.getServerGrowth(string_server_target) / 100;
const cycles = Math.log(float_growth)/(Math.log(ajdGrowthRate) * object_constants.object_hacking_multipliers.growth * serverGrowthPercentage * object_constants.object_bitnode_multipliers.ServerGrowthRate);
return Math.ceil(cycles);
};
// Inverse function of integer_get_threads_for_growth. Returns the percentage growth in decimal form (e.g., 2 = 100% growth).
const float_get_growth_from_threads = function(ns, string_server_target, float_server_target_security, integer_threads) {
const object_constants = object_get_constants(ns);
let ajdGrowthRate = 1 + (object_constants.ServerBaseGrowthRate - 1) / float_server_target_security;
if (ajdGrowthRate > object_constants.ServerMaxGrowthRate) {
ajdGrowthRate = object_constants.ServerMaxGrowthRate;
}
const serverGrowthPercentage = ns.getServerGrowth(string_server_target) / 100;
const float_growth = Math.pow(ajdGrowthRate, integer_threads * object_constants.object_hacking_multipliers.growth * serverGrowthPercentage * object_constants.object_bitnode_multipliers.ServerGrowthRate);
return float_growth;
};
// returns the threads required by grow to grow string_server_target's cash to its maximum when security is at float_server_target_security and current cash is at float_server_target_cash
const integer_get_threads_required_for_grow_maximum_cash = 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 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
const integer_get_threads_grow = function(ns, float_server_used_ram_free, string_server_target, float_server_target_security, float_server_target_cash) {
const string_grow = object_get_constants(ns).array_workers[1];
const integer_threads_available = Math.trunc(float_server_used_ram_free / ns.getScriptRam(string_grow));
const integer_threads_required = integer_get_threads_required_for_grow_maximum_cash(ns, string_server_target, float_server_target_security, float_server_target_cash);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// returns the security increase from the growth threads used. Adapted from `processSingleServerGrowth` in ServerHelpers.ts and `fortify` in Server.ts
const float_get_security_increase_from_grow = function(ns, integer_threads_grow) {
return 2 * object_get_constants(ns).ServerFortifyAmount * integer_threads_grow;
};
// hack stuff
// returns the percentage of the available cash in string_server_target that is stolen when it is hacked when it has float_server_target_security. adapted from calculatePercentMoneyHacked() in https://github.com/danielyxie/bitburner/blob/master/src/Hacking.js . See also `hackDifficulty` in https://github.com/danielyxie/bitburner/blob/master/src/Server.js
const float_get_percentage_of_cash_from_available_per_hack = function(ns, string_server_target, float_server_target_security) {
const object_constants = object_get_constants(ns);
const balanceFactor = 240;
const difficultyMult = (100 - float_server_target_security) / 100;
const skillMult = (ns.getHackingLevel() - (ns.getServerRequiredHackingLevel(string_server_target) - 1)) / ns.getHackingLevel();
const percentMoneyHacked = difficultyMult * skillMult * object_constants.object_hacking_multipliers.money / balanceFactor;
if (percentMoneyHacked < 0) { return 0; }
if (percentMoneyHacked > 1) { return 1; }
return percentMoneyHacked * object_constants.object_bitnode_multipliers.ScriptHackMoney;
};
// returns the threads required to steal "float_percentage_to_steal" of available money in string_server_target
const integer_get_threads_required_to_hack_percentage = function(ns, string_server_target, float_server_target_security, float_percentage_to_steal) {
return Math.ceil(float_percentage_to_steal / float_get_percentage_of_cash_from_available_per_hack(ns, string_server_target, float_server_target_security));
};
// returns the threads required to steal "float_percentage_to_steal" of available money in string_server_target if possible, otherwise, return max threads that string_server_used can provide
const integer_get_threads_hack = function(ns, float_server_used_ram_free, string_server_target, float_server_target_security, float_percentage_to_steal) {
const string_hack = object_get_constants(ns).array_workers[2];
const integer_threads_available = Math.trunc(float_server_used_ram_free / ns.getScriptRam(string_hack));
const integer_threads_required = integer_get_threads_required_to_hack_percentage(ns, string_server_target, float_server_target_security, float_percentage_to_steal);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// returns the security increase from the hack threads. adapted from `hack` in NetscriptFunctions.js and `fortify` in Server.ts
const float_get_security_increase_from_hack = function(ns, string_server_target, float_server_target_security, float_server_target_cash, integer_threads_hack) {
let maxThreadNeeded = Math.ceil(1/float_get_percentage_of_cash_from_available_per_hack(ns, string_server_target, float_server_target_security)*(float_server_target_cash/ns.getServerMaxMoney(string_server_target)));
if (isNaN(maxThreadNeeded)) {
// Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
maxThreadNeeded = 1e6;
}
return object_get_constants(ns).ServerFortifyAmount * Math.min(integer_threads_hack, maxThreadNeeded);
};
// percentage to steal stuff
// returns the threads required by grow to grow a string_server_target's money back to its original value after stealing float_percentage_to_steal of it, and assuming security is at float_server_target_security
const integer_get_threads_required_for_cash_grow_after_percentage_stolen = function(ns, string_server_target, float_server_target_security, float_percentage_to_steal) {
return integer_get_threads_for_growth(ns, string_server_target, float_server_target_security, Math.pow(1 - float_percentage_to_steal, -1));
};
// should return true if there is enough ram to provide the threads required by weaken to weaken to minimum security, then by grow to grow string_server_target's cash back to maximum after stealing float_percentage_to_steal of the cash, then by weaken to weaken to minimum security again if possible, otherwise, returns false. assumes security is at float_server_target_security
const boolean_is_ram_enough_after_hack_percentage = function(ns, float_server_used_ram_free, string_server_target, float_server_target_cash, float_server_target_security, float_percentage_to_steal) {
const string_weaken = object_get_constants(ns).array_workers[0];
const string_grow = object_get_constants(ns).array_workers[1];
const float_server_target_security_after_hack = float_server_target_security + float_get_security_increase_from_hack(ns, string_server_target, float_server_target_security, float_server_target_cash, integer_get_threads_hack(ns, float_server_used_ram_free, string_server_target, float_server_target_security, float_percentage_to_steal));
const 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);
const 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);
const 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);
const 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);
const 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);
const float_ram_required = (integer_threads_required_for_weaken_minimum_security_after_hack * ns.getScriptRam(string_weaken)) + (integer_threads_required_for_cash_grow_after_percentage_stolen * ns.getScriptRam(string_grow)) + (integer_threads_required_for_weaken_minimum_security_after_grow * ns.getScriptRam(string_weaken));
if (float_ram_required < float_server_used_ram_free) {
return true;
}
else {
return false;
}
};
// returns the number of cycles of bisection to be done to reach a certain precision, rounded up to the nearest integer
const integer_get_cycles_for_bisection_precision = function(ns, float_precision) {
return Math.ceil(Math.log(Math.pow(float_precision, -1)) * Math.pow(Math.log(2), -1));
};
// this should return optimum percentage to steal such that cash stolen at most is as high as float_steal_cap and string_server_target's security is able to be weakened to minimum with one weaken after the hack, its cash grown to 100% after one grow after the weaken, then its security weakened again to minimum with one weaken, all with the ram it has remaining after the hack by using a binary search algorithm
const float_get_percentage_to_steal = function(ns, float_server_used_ram_free, string_server_target, float_server_target_cash, float_server_target_security, float_precision, float_steal_cap) {
const integer_cycles_for_bisection_precision = integer_get_cycles_for_bisection_precision(ns, float_precision);
let float_ceiling = 1;
let float_floor = 0;
let float_percentage_to_steal = (float_ceiling + float_floor) * 0.5;
for (let integer_indices_0 = 0; integer_indices_0 < integer_cycles_for_bisection_precision; ++integer_indices_0) {
if (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;
}
else {
float_ceiling = float_percentage_to_steal;
}
float_percentage_to_steal = (float_ceiling + float_floor) * 0.5;
if (float_percentage_to_steal > float_steal_cap) {
break;
}
}
// cap which can be used so not all money is stolen, which can be bad because it's harder to grow from 0 in most cases
if (float_percentage_to_steal > float_steal_cap) {
return float_steal_cap;
}
else {
return float_percentage_to_steal;
}
};
// scheduling
const array_get_servers_rooted_sorted_by_score = function(ns) {
let array_servers_rooted = array_get_servers_rooted(ns);
void_sort_by_server_scores(ns, array_servers_rooted);
return array_servers_rooted;
};
const string_get_server_rooted_hackable_with_score_biggest = function(ns) {
const array_servers_rooted_sorted_by_score = array_get_servers_rooted_sorted_by_score(ns);
// iterate through array in reverse
for (let integer_indices_0 = array_servers_rooted_sorted_by_score.length - 1; integer_indices_0 >= 0; --integer_indices_0) {
const string_server_target = array_servers_rooted_sorted_by_score[integer_indices_0];
if (ns.getHackingLevel() >= ns.getServerRequiredHackingLevel(string_server_target)) {
return string_server_target;
}
}
};
const string_job_decider = function(ns, string_server_target, float_server_target_security, float_server_target_cash) {
if (float_server_target_security > ns.getServerMinSecurityLevel(string_server_target)) {
return "weaken";
}
else {
if (float_server_target_cash < ns.getServerMaxMoney(string_server_target)) {
return "grow";
}
else {
return "hack";
}
}
};
// Returns time it takes to complete a hack on a server, in seconds. Adapted from `calculateHackingTime` in Hacking.js
const float_get_time_hack = function(ns, string_server_target, float_server_target_security) {
const 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-line
skillFactor /= (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.js
const float_get_time_grow = function(ns, string_server_target, float_server_target_security) {
const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2
return 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.js
const float_get_time_weaken = function(ns, string_server_target, float_server_target_security) {
const weakenTimeMultiplier = 4; // Relative to hacking time
return weakenTimeMultiplier * float_get_time_hack(ns, string_server_target, float_server_target_security);
};
// makes a schedule
const array_make_schedule = function(ns, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target, string_decider) {
const array_workers = object_get_constants(ns).array_workers;
const string_weaken = array_workers[0];
const string_grow = array_workers[1];
const string_hack = array_workers[2];
const array_servers_rooted_sorted_by_ram = array_get_servers_rooted_sorted_by_ram(ns);
const float_server_target_security_minimum = ns.getServerMinSecurityLevel(string_server_target);
const float_server_target_cash_maximum = ns.getServerMaxMoney(string_server_target);
const float_time_weaken = float_get_time_weaken(ns, string_server_target, ns.getServerSecurityLevel(string_server_target));
const float_time_grow = float_get_time_grow(ns, string_server_target, ns.getServerSecurityLevel(string_server_target));
const float_time_hack = float_get_time_hack(ns, string_server_target, ns.getServerSecurityLevel(string_server_target));
// tripwires
let boolean_end_loop_array_servers = false;
let boolean_end_loop_server = false;
let float_server_target_security_current = ns.getServerSecurityLevel(string_server_target);
let float_server_target_cash_current = ns.getServerMoneyAvailable(string_server_target);
let array_schedule = [];
let integer_array_schedule_length = 0;
let integer_time_job_finishes_seconds = Math.max(float_time_weaken, float_time_grow, float_time_hack);
// iterate through servers in reverse to use servers with the biggest rams first
for (let integer_indices_0 = array_servers_rooted_sorted_by_ram.length - 1; integer_indices_0 >= 0; --integer_indices_0) {
if (integer_array_schedule_length >= integer_job_cap ||
boolean_end_loop_array_servers) {
break;
}
const string_server_used = array_servers_rooted_sorted_by_ram[integer_indices_0];
let float_server_used_ram_free_current = float_get_server_ram_free(ns, string_server_used);
let string_job = string_decider(ns, string_server_target, float_server_target_security_current, float_server_target_cash_current);
if (boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, string_weaken, 1)) {
boolean_end_loop_server = false;
}
while (
float_server_used_ram_free_current > 0 &&
integer_array_schedule_length < integer_job_cap &&
!boolean_end_loop_array_servers &&
!boolean_end_loop_server
) {
string_job = string_decider(ns, string_server_target, float_server_target_security_current, float_server_target_cash_current);
const schedule_item = {
string_job: string_job,
string_server_used: string_server_used,
string_server_target: string_server_target,
float_server_target_security_before: float_server_target_security_current,
float_server_target_cash_before: float_server_target_cash_current
};
switch (string_job) {
case "weaken": {
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, string_weaken, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
break;
}
const integer_threads_weaken = integer_get_threads_weaken(ns, float_server_used_ram_free_current, string_server_target, float_server_target_security_current);
float_server_used_ram_free_current -= integer_threads_weaken * ns.getScriptRam(string_weaken);
const float_server_target_security_uncorrected = float_server_target_security_current - float_get_security_decrease_from_weaken(ns, integer_threads_weaken);
if (float_server_target_security_uncorrected < float_server_target_security_minimum) {
float_server_target_security_current = float_server_target_security_minimum;
}
else {
float_server_target_security_current = float_server_target_security_uncorrected;
}
schedule_item.float_server_target_security_current = float_server_target_security_current;
schedule_item.float_delay_seconds = integer_time_job_finishes_seconds - float_time_weaken + float_padding_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
schedule_item.integer_threads = integer_threads_weaken;
array_schedule.push(schedule_item);
++integer_array_schedule_length;
break;
}
case "grow": {
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, string_grow, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
break;
}
if (float_server_target_cash_current === 0) {
float_server_target_cash_current = 1; // counts 0 cash as 1 so it can still grow. taken from `grow` in NetscriptFunctions.js
}
const integer_threads_grow = integer_get_threads_grow(ns, float_server_used_ram_free_current, string_server_target, float_server_target_security_current, float_server_target_cash_current);
float_server_used_ram_free_current -= integer_threads_grow * ns.getScriptRam(string_grow);
const float_server_target_cash_current_uncorrected = float_server_target_cash_current * float_get_growth_from_threads(ns, string_server_target, float_server_target_security_current, integer_threads_grow);
if (float_server_target_cash_current_uncorrected > float_server_target_cash_maximum) {
float_server_target_cash_current = float_server_target_cash_maximum;
}
else {
float_server_target_cash_current = float_server_target_cash_current_uncorrected;
}
// the following is adapted from `processSingleServerGrowth` in ServerHelpers.ts and `fortify` in Server.ts
float_server_target_security_current += float_get_security_increase_from_grow(ns, integer_threads_grow);
schedule_item.float_server_target_security_current = float_server_target_security_current;
schedule_item.float_delay_seconds = integer_time_job_finishes_seconds - float_time_grow + float_padding_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
schedule_item.integer_threads = integer_threads_grow;
array_schedule.push(schedule_item);
++integer_array_schedule_length;
break;
}
case "hack": {
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, string_hack, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
break;
}
const integer_threads_hack = integer_get_threads_hack(ns, float_server_used_ram_free_current, string_server_target, float_server_target_security_current, float_get_percentage_to_steal(ns, float_server_used_ram_free_current, string_server_target, float_server_target_cash_current, float_server_target_security_current, float_precision, float_steal_cap));
float_server_used_ram_free_current -= integer_threads_hack * ns.getScriptRam(string_hack);
// the following is adapted from `hack` in NetscriptFunctions.js and `fortify` in Server.ts
const float_server_target_cash_before = float_server_target_cash_current;
const float_server_target_cash_current_uncorrected = float_server_target_cash_current - Math.floor(float_server_target_cash_current * float_get_percentage_of_cash_from_available_per_hack(ns, string_server_target, float_server_target_security_current)) * integer_threads_hack;
if (float_server_target_cash_current_uncorrected < 0) {
float_server_target_cash_current = 0;
}
else {
float_server_target_cash_current = float_server_target_cash_current_uncorrected;
}
float_server_target_security_current += float_get_security_increase_from_hack(ns, string_server_target, float_server_target_security_current, float_server_target_cash_before, integer_threads_hack);
schedule_item.float_server_target_security_current = float_server_target_security_current;
schedule_item.float_delay_seconds = integer_time_job_finishes_seconds - float_time_hack + float_padding_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
schedule_item.integer_threads = integer_threads_hack;
array_schedule.push(schedule_item);
++integer_array_schedule_length;
break;
}
}
}
}
// remove jobs near the end that cause security to not equal minimum. in other words, the target should have minimum security when the schedule finishes. this is to make the jobs in the next schedule run as quick as possible. TODO: make it so that we don't have to do this deleting step, instead, the array making steps above should already take into this into account and don't make more items than is needed.
let array_schedule_edited = [...array_schedule];
let boolean_have_not_seen_item_with_security_minimum = true;
let boolean_end_loop_schedule_edit = false;
while (
boolean_have_not_seen_item_with_security_minimum &&
!boolean_end_loop_schedule_edit
) {
for (let integer_indices_1 = array_schedule_edited.length - 1; integer_indices_1 >= 0; --integer_indices_1) {
if (
!boolean_have_not_seen_item_with_security_minimum ||
boolean_end_loop_schedule_edit
) {
boolean_end_loop_schedule_edit = true;
break;
}
const object_job = array_schedule_edited[integer_indices_1];
if (object_job.float_server_target_security_current === float_server_target_security_minimum) {
boolean_have_not_seen_item_with_security_minimum = false;
}
else {
array_schedule_edited.splice(integer_indices_1, 1);
if (array_schedule_edited.length === 0) {
boolean_end_loop_schedule_edit = true;
}
}
}
}
if (
boolean_have_not_seen_item_with_security_minimum ||
array_schedule_edited.length === 0
) {
return array_schedule;
}
else {
return array_schedule_edited;
}
};
const void_schedule_runner = function(ns, array_schedule) {
const array_workers = object_get_constants(ns).array_workers;
for (let integer_indices_0 = 0; integer_indices_0 < array_schedule.length; ++integer_indices_0) {
const string_job = array_schedule[integer_indices_0].string_job;
const string_server_used = array_schedule[integer_indices_0].string_server_used;
const string_server_target = array_schedule[integer_indices_0].string_server_target;
const integer_threads = array_schedule[integer_indices_0].integer_threads;
const float_delay = array_schedule[integer_indices_0].float_delay_seconds * 1000;
const identifier = integer_indices_0;
let string_script = "";
switch (string_job) {
case "weaken": {
string_script = array_workers[0];
break;
}
case "grow": {
string_script = array_workers[1];
break;
}
case "hack": {
string_script = array_workers[2];
break;
}
}
ns.exec(string_script, string_server_used, integer_threads, string_server_used, string_server_target, float_delay, identifier);
}
};
// returns the the time it'll take to finish in milliseconds.
const void_runner = function(ns, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target_argument) {
let integer_time_start = Date.now();
let string_server_target = string_server_target_argument;
if (string_server_target_argument === "") {
string_server_target = string_get_server_rooted_hackable_with_score_biggest(ns);
}
const array_schedule = array_make_schedule(ns, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target, string_job_decider);
void_schedule_runner(ns, array_schedule);
return ((array_schedule[array_schedule.length - 1].integer_time_job_finishes_seconds + float_padding_seconds) * 1000) - integer_time_start + Date.now();
};