const object_get_constants = function(ns) {
const object_get_bitnode_multipliers = function(ns) {
// try {
// return ns.getBitNodeMultipliers();
// }
// catch (error) {
// return {
// 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,
// };
// }
return {
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,
};
};
const object_get_stats = function(ns) {
// try {
// return ns.getStats();
// }
// catch (error) {
// return {
// hacking: ns.getHackingLevel(),
// strength: 1,
// defense: 1,
// dexterity: 1,
// agility: 1,
// charisma: 1,
// intelligence: 1
// };
// }
return {
hacking: ns.getHackingLevel(),
strength: 1,
defense: 1,
dexterity: 1,
agility: 1,
charisma: 1,
intelligence: 1
};
};
const object_constants = {
// cost of server per 1 GB of RAM
BaseCostFor1GBOfRamServer: 55000,
// maximum amount of purchased servers allowed
PurchasedServerLimit: 25,
// minimum ram of purchased servers possible
integer_server_ram_min: 2,
// maximum ram of purchased servers possible. 2^20
PurchasedServerMaxRam: 1048576,
// filenames and related functions of exploits
object_exploits: {
brutessh: {
file: "BruteSSH.exe",
function: "brutessh"
},
ftpcrack: {
file: "FTPCrack.exe",
function: "ftpcrack"
},
relaysmtp: {
file: "relaySMTP.exe",
function: "relaysmtp"
},
httpworm: {
file: "HTTPWorm.exe",
function: "httpworm"
},
sqlinject: {
file: "SQLInject.exe",
function: "sqlinject"
}
},
// factor used in determining the amount security increases by from a grow or hack
ServerFortifyAmount: 0.002,
// amount security decreases by from a weaken
ServerWeakenAmount: 0.05,
// base percentage cash increases by from a grow
ServerBaseGrowthRate: 1.03,
// max percentage cash increases by from a grow (accounts for server security)
ServerMaxGrowthRate: 1.0035,
// hacking multipliers
object_hacking_multipliers: ns.getHackingMultipliers(),
// bitnode multipliers
object_bitnode_multipliers: object_get_bitnode_multipliers(ns),
// player stats
object_stats: object_get_stats(ns),
// filenames and ram cost of helper object_scripts
object_scripts: {
weaken: {
file: "weaken.js",
ram: 1.75 // or ns.getScriptRam(object_get_constants(ns).object_scripts.weaken.file);
},
grow: {
file: "grow.js",
ram: 1.75 // or ns.getScriptRam(object_get_constants(ns).object_scripts.grow.file);
},
hack: {
file: "hack.js",
ram: 1.7 // or ns.getScriptRam(object_get_constants(ns).object_scripts.hack.file);
}
},
string_host: "home" // or ns.getHostname()
};
return object_constants;
};
// returns an array of all servers in the game
const array_get_servers = function(ns) {
const string_host = object_get_constants(ns).string_host;
const array_servers = [string_host];
for (let integer_indices_0 = 0; integer_indices_0 < array_servers.length; ++integer_indices_0) {
const array_scan_results = ns.scan(array_servers[integer_indices_0]);
for (let integer_indices_1 = 0; integer_indices_1 < array_scan_results.length; ++integer_indices_1) {
if (array_servers.indexOf(array_scan_results[integer_indices_1]) === -1) {
array_servers.push(array_scan_results[integer_indices_1]);
}
}
}
return array_servers;
};
// returns the total ram of a server
const integer_get_server_ram_total = function(ns, string_server) {
return (ns.getServerRam(string_server))[0];
};
// returns the used ram of a server
const float_get_server_ram_used = function(ns, string_server) {
return (ns.getServerRam(string_server))[1];
};
// returns the amount of free ram of a server
const float_get_server_ram_free = function(ns, string_server) {
return integer_get_server_ram_total(ns, string_server) - float_get_server_ram_used(ns, string_server);
};
// buy/upgrade servers
// true if all bought servers have ram == PurchasedServerMaxRam
const boolean_servers_bought_all_max = function(ns) {
const array_servers_bought = ns.getPurchasedServers();
if (array_servers_bought.length > 0) {
let boolean_tripwire = true;
for (let integer_indices_0 = 0; integer_indices_0 < array_servers_bought.length; ++integer_indices_0) {
if (integer_get_server_ram_total(ns, array_servers_bought[integer_indices_0]) < object_get_constants(ns).PurchasedServerMaxRam) {
boolean_tripwire = false;
}
}
return boolean_tripwire;
}
};
// returns bought server with smallest RAM
const string_get_server_bought_smallest = function(ns) {
const array_servers_bought = ns.getPurchasedServers();
if (array_servers_bought.length > 0) {
let string_server_smallest;
let integer_size_smallest = object_get_constants(ns).PurchasedServerMaxRam;
for (let integer_indices_0 = 0; integer_indices_0 < array_servers_bought.length; ++integer_indices_0) {
let integer_server_ram_total = integer_get_server_ram_total(ns, array_servers_bought[integer_indices_0]);
if (integer_server_ram_total < integer_size_smallest) {
string_server_smallest = array_servers_bought[integer_indices_0];
integer_size_smallest = integer_server_ram_total;
}
}
return string_server_smallest;
}
};
// returns bought server with biggest RAM
const string_get_server_bought_biggest = function(ns) {
const array_servers_bought = ns.getPurchasedServers();
if (array_servers_bought.length > 0) {
let string_server_biggest;
let integer_size_biggest = object_get_constants(ns).integer_server_ram_min;
for (let integer_indices_0 = 0; integer_indices_0 < array_servers_bought.length; ++integer_indices_0) {
let integer_server_ram_total = integer_get_server_ram_total(ns, array_servers_bought[integer_indices_0]);
if (integer_server_ram_total > integer_size_biggest) {
string_server_biggest = array_servers_bought[integer_indices_0];
integer_size_biggest = integer_server_ram_total;
}
}
return string_server_biggest;
}
};
// return the RAM of the server with the biggest RAM that you can afford
const integer_get_server_ram_biggest_afforded = function(ns) {
const object_constants = object_get_constants(ns);
if (integer_server_ram_biggest_afforded > object_constants.PurchasedServerMaxRam) {
integer_server_ram_biggest_afforded = object_constants.PurchasedServerMaxRam;
}
return integer_server_ram_biggest_afforded;
};
const void_server_buy_or_upgrade = function(ns, string_name) {
}
// 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.
}
}
};
// root servers
// returns an array of all servers that are yet to be rooted
const array_get_servers_unrooted = function(ns) {
const array_servers = array_get_servers(ns);
const array_servers_unrooted = [];
for (let integer_indices_0 = 0; integer_indices_0 < array_servers.length; ++integer_indices_0) {
if (!ns.hasRootAccess(array_servers[integer_indices_0])) {
array_servers_unrooted.push(array_servers[integer_indices_0]);
}
}
return array_servers_unrooted;
};
// tries to open ports of server
const void_open_ports_try = function(ns, string_server_target) {
const object_exploits = object_get_constants(ns).object_exploits;
for (const exploit in object_exploits) {
try {
eval("ns." + object_exploits[exploit].function + "(\"" + string_server_target + "\")");
}
catch (error) {
}
}
};
// 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 present
const void_open_ports_nuke_try = function(ns) {
const array_servers_unrooted = array_get_servers_unrooted(ns);
for (let integer_indices_0 = 0; integer_indices_0 < array_servers_unrooted.length; ++integer_indices_0) {
const string_server_unrooted = array_servers_unrooted[integer_indices_0];
void_open_ports_try(ns, string_server_unrooted);
try {
ns.nuke(string_server_unrooted);
} catch (error) {
}
}
};
// targetting
// sort an array of servers by their amounts of RAM, from lowest to highest
const void_sort_by_server_ram = function(ns, array_servers) {
return array_servers.sort((string_element_0, string_element_1) => (integer_get_server_ram_total(ns, string_element_0) - integer_get_server_ram_total(ns, string_element_1)));
};
};
const void_sort_by_server_scores = function(ns, array_servers) {
};
// weaken, grow, hack
// returns an array of all rooted servers
const array_get_servers_rooted = function(ns) {
const array_servers = array_get_servers(ns);
const array_servers_rooted = [];
for (let integer_indices_0 = 0; integer_indices_0 < array_servers.length; ++integer_indices_0) {
if (ns.hasRootAccess(array_servers[integer_indices_0])) {
array_servers_rooted.push(array_servers[integer_indices_0]);
}
}
return array_servers_rooted;
};
// 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
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 integer_threads_available = Math.trunc(float_server_used_ram_free / object_get_constants(ns).object_scripts.weaken.ram);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// 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
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 integer_threads_available = Math.trunc(float_server_used_ram_free / object_get_constants(ns).object_scripts.grow.ram);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// 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;
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
};
// 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 integer_threads_available = Math.trunc(float_server_used_ram_free / object_get_constants(ns).object_scripts.hack.ram);
return integer_get_corrected_threads(ns, integer_threads_required, integer_threads_available);
};
// 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));
};
}
else {
}
};
// returns the number of cycles of bisection to be done to reach a certain precision, rounded up to the nearest integer
return Math.ceil(Math.log(Math.pow(float_precision, -1)) * Math.pow(Math.log(2), -1));
};
let float_ceiling = 1;
let float_floor = 0;
let float_percentage_to_steal = (float_ceiling + float_floor) * 0.5;
float_floor = float_percentage_to_steal;
}
else {
float_ceiling = float_percentage_to_steal;
}
float_percentage_to_steal = (float_ceiling + float_floor) * 0.5;
}
// 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
}
else {
return float_percentage_to_steal;
}
};
// copies files to all rooted servers
const void_copy_files_to_string_servers_rooted = function(ns, array_files, string_source) {
const array_servers_rooted = array_get_servers_rooted(ns);
for (let integer_indices_0 = 0; integer_indices_0 < array_servers_rooted.length; ++integer_indices_0) {
for (let integer_indices_1 = 0; integer_indices_1 < array_files.length; ++integer_indices_1) {
}
}
};
// scheduling
const array_get_servers_rooted_sorted_by_ram = function(ns) {
let array_servers_rooted = array_get_servers_rooted(ns);
void_sort_by_server_ram(ns, array_servers_rooted);
return array_servers_rooted;
};
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;
}
}
};
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";
}
}
};
if (float_script_ram * integer_threads > float_server_used_ram_free) {
return false;
}
else {
return true;
}
};
// Returns time it takes to complete a hack on a server, in seconds. Adapted from `calculateHackingTime` in Hacking.js
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;
var skillFactor = (diffFactor * difficultyMult + baseDiff);
// tslint:disable-next-line
skillFactor /= (hack + 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 growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2
};
// Returns time it takes to complete a weaken operation on a server, in seconds. Adapted from `calculateHackingTime` in Hacking.js
const weakenTimeMultiplier = 4; // Relative to hacking time
};
const object_constants = object_get_constants(ns);
const object_scripts = object_constants.object_scripts;
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));
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 = [];
// assumes weaken takes longest
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);
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
};
case "weaken": {
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 * object_scripts.weaken.ram;
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.integer_threads = integer_threads_weaken;
array_schedule.push(schedule_item);
break;
}
case "grow": {
break;
}
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 * object_scripts.grow.ram;
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
schedule_item.integer_threads = integer_threads_grow;
array_schedule.push(schedule_item);
break;
}
case "hack": {
break;
}
// the following is adapted from `hack` in NetscriptFunctions.js and `fortify` in Server.ts
}
schedule_item.integer_threads = integer_threads_hack;
array_schedule.push(schedule_item);
break;
}
}
}
}
};
// script executors
// execute the "weaken.js" script
const void_exec_script_weaken = async function(ns, string_server_used, string_server_target, threads, delay, identifier) {
await ns.exec(object_get_constants(ns).object_scripts.weaken.file, string_server_used, threads, string_server_used, string_server_target, delay, identifier);
};
// execute the "grow.js" script
const void_exec_script_grow = async function(ns, string_server_used, string_server_target, threads, delay, identifier) {
await ns.exec(object_get_constants(ns).object_scripts.grow.file, string_server_used, threads, string_server_used, string_server_target, delay, identifier);
};
// execute the "hack.js" script
const void_exec_script_hack = async function(ns, string_server_used, string_server_target, threads, delay, identifier) {
await ns.exec(object_get_constants(ns).object_scripts.hack.file, string_server_used, threads, string_server_used, string_server_target, delay, identifier);
};
const object_constants = object_get_constants(ns);
const object_scripts = object_constants.object_scripts;
void_server_buy_or_upgrade(ns, string_servers_bought_name);
// 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 present
void_open_ports_nuke_try(ns);
// copy object_scripts to rooted servers
void_copy_files_to_string_servers_rooted(ns, [
object_scripts.weaken.file,
object_scripts.grow.file,
object_scripts.hack.file
}
}
};
// make and run actual hacking schedule
const array_schedule = array_make_schedule(ns, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target, string_job_decider);
await void_schedule_runner(ns, array_schedule);
return array_schedule[array_schedule.length - 1].integer_time_job_finishes_seconds * 1000;
], object_constants.string_host);
break;
}
const array_schedule_prepare = array_make_schedule(ns, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target, string_job_decider_prepare);
if (array_schedule_prepare.length > 0) {
await void_schedule_runner(ns, array_schedule_prepare);
await ns.sleep(array_schedule_prepare[array_schedule_prepare.length - 1].integer_time_job_finishes_seconds * 1000);
// prepare the target if necessary
while (true) {
if (
ns.getServerSecurityLevel(string_server_target) === ns.getServerMinSecurityLevel(string_server_target) &&
ns.getServerMoneyAvailable(string_server_target) === ns.getServerMaxMoney(string_server_target)
) {
void_buy_home_ram(ns);
let string_server_target = string_server_target_argument;
if (string_server_target_argument === null) {
string_server_target = string_get_server_rooted_hackable_with_score_biggest(ns);
}
// returns the the time it'll take to finish in milliseconds.
export const void_runner = async function(ns, string_servers_bought_name, integer_job_cap, float_precision, float_steal_cap, float_padding_seconds, string_server_target_argument) {
const void_schedule_runner = async function(ns, array_schedule) {
for (let integer_indices_0 = 0; integer_indices_0 < array_schedule.length; ++integer_indices_0) {
switch (array_schedule[integer_indices_0].string_job) {
case "weaken": {
await void_exec_script_weaken(ns, array_schedule[integer_indices_0].string_server_used, array_schedule[integer_indices_0].string_server_target, array_schedule[integer_indices_0].integer_threads, array_schedule[integer_indices_0].float_delay_seconds * 1000, integer_indices_0);
break;
}
case "grow": {
await void_exec_script_grow(ns, array_schedule[integer_indices_0].string_server_used, array_schedule[integer_indices_0].string_server_target, array_schedule[integer_indices_0].integer_threads, array_schedule[integer_indices_0].float_delay_seconds * 1000, integer_indices_0);
break;
}
case "hack": {
await void_exec_script_hack(ns, array_schedule[integer_indices_0].string_server_used, array_schedule[integer_indices_0].string_server_target, array_schedule[integer_indices_0].integer_threads, array_schedule[integer_indices_0].float_delay_seconds * 1000, integer_indices_0);
break;
}
}
}
};
// remove schedule items near the end that cause security to not equal minimum. in other words, the target should have minimum security when the cycle finishes. this is to make the next cycle of jobs 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 boolean_have_not_seen_item_with_security_minimum = true;
while (boolean_have_not_seen_item_with_security_minimum) {
break;
}
boolean_have_not_seen_item_with_security_minimum = false;
break;
}
else {
}
}
}
if (boolean_have_not_seen_item_with_security_minimum) {
return array_schedule;
}
else {
return array_schedule_edited;
}
array_schedule_edited.splice(integer_indices_1, 1);
const object_job = array_schedule_edited[integer_indices_1];
if (object_job.float_server_target_security_current === float_server_target_security_minimum) {
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) {
let array_schedule_edited = array_schedule;
++integer_array_schedule_length;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
schedule_item.float_delay_seconds = integer_time_job_finishes_seconds - float_time_hack + float_padding_seconds;
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;
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;
float_server_used_ram_free_current -= integer_threads_hack * object_scripts.hack.ram;
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));
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, object_scripts.hack.ram, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
++integer_array_schedule_length;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
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;
float_server_target_security_current += float_get_security_increase_from_grow(ns, integer_threads_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 === 0) {
float_server_target_cash_current = 1; // counts 0 cash as 1 so it can still grow. taken from `grow` in NetscriptFunctions.js
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, object_scripts.grow.ram, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
++integer_array_schedule_length;
schedule_item.integer_time_job_finishes_seconds = integer_time_job_finishes_seconds;
integer_time_job_finishes_seconds += float_padding_seconds;
schedule_item.float_delay_seconds = integer_time_job_finishes_seconds - float_time_weaken + float_padding_seconds;
schedule_item.float_server_target_security_current = float_server_target_security_current;
const float_server_target_security_uncorrected = float_server_target_security_current - float_get_security_decrease_from_weaken(ns, integer_threads_weaken);
if (!boolean_can_server_run_script_threads(ns, float_server_used_ram_free_current, object_scripts.weaken.ram, 1)) {
// start using a server with more ram
boolean_end_loop_server = true;
switch (string_job) {
case "": {
boolean_end_loop_array_servers = true;
break;
}
string_job: string_job,
while (
float_server_used_ram_free_current > 0 &&
) {
const string_job = string_decider(ns, string_server_target, float_server_target_security_current, float_server_target_cash_current);
const schedule_item = {
integer_array_schedule_length < integer_job_cap &&
!boolean_end_loop_array_servers &&
!boolean_end_loop_server
// 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) {
break;
}
if (integer_array_schedule_length >= integer_job_cap ||
boolean_end_loop_array_servers) {
let integer_time_job_finishes_seconds = float_time_weaken;
let integer_array_schedule_length = 0;
// tripwires
let boolean_end_loop_array_servers = false;
let boolean_end_loop_server = false;
const array_servers_rooted_sorted_by_ram = array_get_servers_rooted_sorted_by_ram(ns);
// 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) {
return weakenTimeMultiplier * float_get_time_hack(ns, string_server_target, float_server_target_security);
const float_get_time_weaken = function(ns, string_server_target, float_server_target_security) {
return growTimeMultiplier * float_get_time_hack(ns, string_server_target, float_server_target_security);
const float_get_time_grow = function(ns, string_server_target, float_server_target_security) {
const hack = object_constants.object_stats.hacking;
const int = object_constants.object_stats.intelligence;
const float_get_time_hack = function(ns, string_server_target, float_server_target_security) {
const boolean_can_server_run_script_threads = function(ns, float_server_used_ram_free, float_script_ram, integer_threads) {
const string_job_decider_prepare = 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";
}
if (float_server_target_cash < ns.getServerMaxMoney(string_server_target)) {
return "grow";
}
return "";
};
const string_job_decider = function(ns, string_server_target, float_server_target_security, float_server_target_cash) {
ns.scp(array_files[integer_indices_1], string_source, array_servers_rooted[integer_indices_0]);
if (float_percentage_to_steal > float_steal_cap) {
return float_steal_cap;
if (float_percentage_to_steal > float_steal_cap) {
break;
}
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)) {
const integer_cycles_for_bisection_precision = integer_get_cycles_for_bisection_precision(ns, float_precision);
// 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_get_cycles_for_bisection_precision = function(ns, float_precision) {
return false;
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);
if (float_ram_required < float_server_used_ram_free) {
return true;
const float_ram_required = (integer_threads_required_for_weaken_minimum_security_after_hack * object_scripts.weaken.ram) + (integer_threads_required_for_cash_grow_after_percentage_stolen * object_scripts.grow.ram) + (integer_threads_required_for_weaken_minimum_security_after_grow * object_scripts.weaken.ram);
const object_scripts = object_get_constants(ns).object_scripts;
// 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) {
};
// 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);
const integer_threads_required = integer_get_threads_required_to_hack_percentage(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));
const integer_get_threads_required_to_hack_percentage = function(ns, string_server_target, float_server_target_security, float_percentage_to_steal) {
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; }
};
// 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;
const integer_threads_required = integer_get_threads_required_for_grow_maximum_cash(ns, string_server_target, float_server_target_security, 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) {
};
// 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;
const integer_threads_required = integer_get_threads_required_for_weaken_minimum_security(ns, string_server_target, float_server_target_security);
const integer_get_threads_required_for_weaken_minimum_security = function(ns, string_server_target, float_server_target_security) {
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));
// sort an array of servers by their score, from lowest to highest
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));
// 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) {
ns.tprint(JSON.stringify(error));
ns.tprint(JSON.stringify(error));
};
while (boolean_conditions_server_delete_purchase(ns)) {
ns.deleteServer(string_get_server_bought_smallest(ns));
ns.purchaseServer(string_name, integer_get_server_ram_biggest_afforded(ns));
}
while (
boolean_conditions_server_purchase_3(ns) ||
boolean_conditions_server_purchase_2(ns) ||
boolean_conditions_server_purchase_1(ns)
) {
ns.purchaseServer(string_name, integer_get_server_ram_biggest_afforded(ns));
(ns.getServerMoneyAvailable("home") >= 3 * object_constants.BaseCostFor1GBOfRamServer * integer_get_server_ram_total(ns, string_get_server_bought_smallest(ns)))
) {
return true;
}
else {
return false;
!(boolean_servers_bought_all_max(ns, object_constants.PurchasedServerMaxRam)) &&
};
const boolean_conditions_server_delete_purchase = function(ns) {
const object_constants = object_get_constants(ns);
if (// you currently own the maximum amount of purchased servers allowed
(ns.getPurchasedServers().length == object_constants.PurchasedServerLimit) &&
) {
if (// you already bought a server with max ram, buy another server the max possible ram
(integer_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)
) {
return true;
}
) {
}
};
const boolean_conditions_server_purchase_3 = function(ns) {
const integer_servers_bought_amount = ns.getPurchasedServers().length;
const object_constants = object_get_constants(ns);
const float_ram_server_bought_maximum = object_constants.PurchasedServerMaxRam;
if (// you have one or more servers already
(integer_servers_bought_amount > 0) &&
// you currently own less than the maximum amount of purchased servers allowed
(integer_servers_bought_amount < object_constants.PurchasedServerLimit)
const float_ram_server_bought_biggest = integer_get_server_ram_total(ns, string_get_server_bought_biggest(ns));
if (
// you dont own a server with max ram yet, buy a server with ram greater than the ram of your biggest bought server
(float_ram_server_bought_biggest != object_constants.PurchasedServerMaxRam) &&
(float_ram_server_bought_biggest < integer_get_server_ram_biggest_afforded(ns))
) {
return true;
}
const boolean_conditions_server_purchase_1 = function(ns) {
const integer_server_ram_biggest_afforded = integer_get_server_ram_biggest_afforded(ns);
const object_constants = object_get_constants(ns);
(integer_server_ram_biggest_afforded >= object_constants.integer_server_ram_min) &&
) {
return true;
}
};
const boolean_conditions_server_purchase_2 = function(ns) {
const integer_servers_bought_amount = ns.getPurchasedServers().length;
if (// you have one or more servers already
(integer_servers_bought_amount > 0) &&
// you currently own less than the maximum amount of purchased servers allowed
(integer_servers_bought_amount < object_constants.PurchasedServerLimit)
const object_constants = object_get_constants(ns);
// 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.
(integer_server_ram_biggest_afforded >= integer_get_server_ram_total(ns, "home") ||
integer_server_ram_biggest_afforded >= object_constants.PurchasedServerMaxRam)
if (// you have no bought servers yet
(ns.getPurchasedServers().length === 0) &&
// ram is at least equal to the minimum ram possible for purchased servers
// continually buys the best server with cash available, unless there are 25 servers already, in which case deletes the worst server, unless all 25 have ram == PurchasedServerMaxRam
let integer_server_ram_biggest_afforded = Math.pow(2, Math.trunc(Math.log2(ns.getServerMoneyAvailable("home") / object_constants.BaseCostFor1GBOfRamServer) / Math.log2(2)));
};
// tries to continually buy ram as long as you have sufficient cash
const void_buy_home_ram = function(ns) {
// let float_cash_current = getServerMoneyAvailable("home");
// try {
// while (float_cash_current >= getUpgradeHomeRamCost()) {
// ns.upgradeHomeRam();
// float_cash_current = getServerMoneyAvailable("home");
// }
// }
// }
// catch (error) {
// ns.tprint(JSON.stringify(error));
// name of current host (usually "home")
// object_constants are from https://github.com/danielyxie/bitburner/blob/master/src/Constants.js
// ns.tprint(JSON.stringify(error));
// ns.tprint(JSON.stringify(error));
// from BitNode/BitNodeMultipliers