Compare commits
3 Commits
c238e2a9c2
...
fbcd89cd7d
| Author | SHA1 | Date | |
|---|---|---|---|
| fbcd89cd7d | |||
| 48ba1c0877 | |||
| 80b3ca8873 |
@@ -1,97 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns, allServers) {
|
|
||||||
ns.tail();
|
|
||||||
await scanRecursiveWrapper(ns);
|
|
||||||
let currentHackingLevel = ns.getHackingLevel();
|
|
||||||
let currentArray = [];
|
|
||||||
let currentHop = "";
|
|
||||||
let serverRoutes = JSON.parse(ns.read("ServerRouteList.txt"));
|
|
||||||
let allPaths = getPaths(serverRoutes);
|
|
||||||
let checkAll = ns.args[0];
|
|
||||||
for (const entry of allPaths) {
|
|
||||||
for (const name of entry) {
|
|
||||||
if (ns.singularity.connect(name) === false) {
|
|
||||||
ns.tprint("Error when trying to connect to: " + currentHop);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ns.getServer(name).hostname === "CSEC" || ns.getServer(name).hostname === "avmnite-02h" || ns.getServer(name).hostname === "I.I.I.I" || ns.getServer(name).hostname === "run4theh111z" || ns.getServer(name).hostname === "The-Cave" || checkAll === true ) {
|
|
||||||
if (!ns.getServer(name).backdoorInstalled) {
|
|
||||||
if (ns.getServerRequiredHackingLevel(name) < currentHackingLevel && ns.hasRootAccess(name) === true) {
|
|
||||||
ns.print("Trying to backdoor " + name)
|
|
||||||
await ns.singularity.installBackdoor(name);
|
|
||||||
ns.print("Success on " + name)
|
|
||||||
}
|
|
||||||
} else { continue }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ns.singularity.connect("home");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPaths(obj, path = []) {
|
|
||||||
const paths = [];
|
|
||||||
for (const key in obj) {
|
|
||||||
const newPath = [...path, key];
|
|
||||||
paths.push(newPath);
|
|
||||||
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
||||||
paths.push(...getPaths(obj[key], newPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
async function scanRecursiveWrapper(ns) {
|
|
||||||
ns.rm("ServerRouteList.txt");
|
|
||||||
const home = "home";
|
|
||||||
let serverRouteList = { home: {} };
|
|
||||||
let knownServers = [];
|
|
||||||
let unscanned = [];
|
|
||||||
unscanned.push(home);
|
|
||||||
knownServers.push(home);
|
|
||||||
while (unscanned.length > 0) {
|
|
||||||
let currentServer = unscanned.pop();
|
|
||||||
let currentChildren = ns.scan(currentServer).filter(element => !knownServers.includes(element));
|
|
||||||
knownServers = knownServers.concat(currentChildren);
|
|
||||||
let keyPath = findKeyPath(serverRouteList, currentServer);
|
|
||||||
let childrenObject = currentChildren.reduce((a, v) => ({ ...a, [v]: {} }), {});
|
|
||||||
writeValueToPath(serverRouteList, keyPath, childrenObject);
|
|
||||||
for (let i = 0; i < currentChildren.length; i++) {
|
|
||||||
let child = currentChildren[i];
|
|
||||||
unscanned.push(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ns.write("ServerRouteList.txt", JSON.stringify(serverRouteList), "w");
|
|
||||||
}
|
|
||||||
|
|
||||||
function findKeyPath(json, key) {
|
|
||||||
if (typeof json !== 'object' || json === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (key in json) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
for (const property in json) {
|
|
||||||
if (json.hasOwnProperty(property)) {
|
|
||||||
const path = findKeyPath(json[property], key);
|
|
||||||
if (path !== null) {
|
|
||||||
return property + '*' + path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeValueToPath(json, path, value) {
|
|
||||||
const parts = path.split('*');
|
|
||||||
let currentObject = json;
|
|
||||||
for (let i = 0; i < parts.length - 1; i++) {
|
|
||||||
const part = parts[i];
|
|
||||||
if (currentObject[part] === undefined) {
|
|
||||||
currentObject[part] = {};
|
|
||||||
}
|
|
||||||
currentObject = currentObject[part];
|
|
||||||
}
|
|
||||||
currentObject[parts[parts.length - 1]] = value;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cities = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
|
||||||
let corpName = "AgraNeo";
|
|
||||||
//ns.tprint(ns.corporation.getConstants())
|
|
||||||
//ns.corporation.getMaterial();
|
|
||||||
//ns.corporation.buyMaterial();
|
|
||||||
for (let city of cities) {
|
|
||||||
await ns.run("/corp/Smart.js",1,corpName,city);
|
|
||||||
await ns.tprint(ns.run("/corp/UpgradeOffice.js",1,corpName,city));
|
|
||||||
await ns.sleep(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
import { getCracks, scanServerList, findBestTarget, crackingAndRooting, copyAndRunScript } from "/RamsesUtils.js";
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cracks = {};
|
|
||||||
cracks = getCracks(ns);
|
|
||||||
crackingAndRooting(ns, cracks, "", false);
|
|
||||||
}
|
|
||||||
88
local/path/home/EveryServerRun.js
Normal file
88
local/path/home/EveryServerRun.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import { getGrowThreads } from "myLibrary.js";
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//ns.tail();
|
||||||
|
const sOverrideTarget = ns.args[0]; // run on this target instead of best
|
||||||
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
|
let bestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
|
let sTarget;
|
||||||
|
|
||||||
|
if (sOverrideTarget !== undefined) {
|
||||||
|
sTarget = sOverrideTarget;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sTarget = bestTarget.serverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sScript = "batch.js";
|
||||||
|
const sShareScript = "factionboost.js";
|
||||||
|
const sWeakenScript = "RMweaken.js";
|
||||||
|
const sGrowScript = "RMgrow.js";
|
||||||
|
const sHackScript = "RMhack.js";
|
||||||
|
|
||||||
|
const nWeakenThreads = 1; //5
|
||||||
|
const nHackThreads = 1; //1
|
||||||
|
const nGrowThreads = getGrowThreads(ns, sTarget, nHackThreads);
|
||||||
|
//ns.tprint("nGrowThreads = " + nGrowThreads);
|
||||||
|
|
||||||
|
const nWeakenScriptRAM = 1.75 * nWeakenThreads;
|
||||||
|
const nHackScriptRAM = 1.75 * nHackThreads;
|
||||||
|
const nGrowScriptRAM = 1.7 * nGrowThreads;
|
||||||
|
//ns.tprint("nGrowScriptRAM = " + nGrowScriptRAM);
|
||||||
|
|
||||||
|
const nFrequency = 50;
|
||||||
|
let nScriptsRAM;
|
||||||
|
let nMaxRam;
|
||||||
|
let nScripts;
|
||||||
|
|
||||||
|
for (const [name, entry] of Object.entries(serverList)) {
|
||||||
|
//let rootAccess = ns.hasRootAccess(currentServer);
|
||||||
|
|
||||||
|
//ns.tprint(entry.serverName + " sTarget = " + sTarget);
|
||||||
|
|
||||||
|
nMaxRam = ns.getServerMaxRam(entry.serverName);
|
||||||
|
//ns.tprint(entry.serverName + " nMaxRam = " + nMaxRam);
|
||||||
|
|
||||||
|
//nScriptsRAM = ns.getScriptRam(sScript, "home") + Math.max(nWeakenScriptRAM, nGrowScriptRAM, nHackScriptRAM);
|
||||||
|
//ns.tprint("nScriptsRAM = " + nScriptsRAM);
|
||||||
|
if (entry.maxRam >= 64 && serverList[name].rootAccess === true) {
|
||||||
|
|
||||||
|
if (sOverrideTarget !== undefined) {
|
||||||
|
sTarget = sOverrideTarget;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sTarget = bestTarget.serverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ns.tprint("sTarget = " + sTarget);
|
||||||
|
//ns.tprint("entry.serverName = " + entry.serverName);
|
||||||
|
|
||||||
|
ns.scriptKill(sScript, entry.serverName);
|
||||||
|
ns.scriptKill(sShareScript, entry.serverName);
|
||||||
|
ns.scp("myLibrary.js", entry.serverName, "home");
|
||||||
|
ns.scp(sScript, entry.serverName, "home");
|
||||||
|
ns.scp(sWeakenScript, entry.serverName, "home");
|
||||||
|
ns.scp(sGrowScript, entry.serverName, "home");
|
||||||
|
ns.scp(sHackScript, entry.serverName, "home");
|
||||||
|
ns.exec(sScript, entry.serverName, 1, sTarget, nFrequency, true, false);
|
||||||
|
await ns.sleep(1);
|
||||||
|
}
|
||||||
|
else if (entry.maxRam < 64 && entry.maxRam > 0 && serverList[name].rootAccess === true) {
|
||||||
|
ns.scriptKill(sScript, entry.serverName);
|
||||||
|
ns.scriptKill(sShareScript, entry.serverName);
|
||||||
|
ns.scriptKill(sWeakenScript, entry.serverName);
|
||||||
|
ns.scriptKill(sGrowScript, entry.serverName);
|
||||||
|
ns.scriptKill(sHackScript, entry.serverName);
|
||||||
|
|
||||||
|
ns.scp(sShareScript, entry.serverName);
|
||||||
|
|
||||||
|
let nShare = Math.floor(((ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName)) / ns.getScriptRam(sShareScript)));
|
||||||
|
ns.tprint(entry.serverName + " nShare = " + nShare * ns.getScriptRam(sShareScript));
|
||||||
|
ns.exec(sShareScript, entry.serverName, nShare);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
//ns.exec("serverlister.js", "home", 1);
|
||||||
|
}
|
||||||
929
local/path/home/HackingLog.txt
Normal file
929
local/path/home/HackingLog.txt
Normal file
File diff suppressed because one or more lines are too long
29
local/path/home/Minimum_Path_Sum_in_a_Triangle.js
Normal file
29
local/path/home/Minimum_Path_Sum_in_a_Triangle.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//8,5,1,1,2,6,7,2,5,4
|
||||||
|
//const sContractData = ns.codingcontract.getData(sContract, sTarget);
|
||||||
|
const sContractData = "8,5,1,1,2,6,7,2,5,4";
|
||||||
|
/*
|
||||||
|
8
|
||||||
|
5,1
|
||||||
|
1,2,6
|
||||||
|
7,2,5,4
|
||||||
|
*/
|
||||||
|
//nArray[0[2]]
|
||||||
|
const sArray = sContractData.split(',');
|
||||||
|
ns.tprint(sArray);
|
||||||
|
let nArray = [];
|
||||||
|
//Number
|
||||||
|
for (let i = 0; i < sArray.length; i++) {
|
||||||
|
nArray[i] = Number(sArray[i]);
|
||||||
|
}
|
||||||
|
ns.tprint(nArray);
|
||||||
|
|
||||||
|
let nLayers = [];
|
||||||
|
for (let l = 0; l < nArray.length; l++) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
108
local/path/home/RMbreach.js
Normal file
108
local/path/home/RMbreach.js
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//args
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
|
||||||
|
// declare objects
|
||||||
|
const oHome = ns.getServer("home");
|
||||||
|
//const oTarget = ns.getServer(sTarget);
|
||||||
|
|
||||||
|
//declare variables
|
||||||
|
const sWeakenScript = "RMweaken.js";
|
||||||
|
const sGrowScript = "RMgrow.js";
|
||||||
|
const sBatch = "RMcontroller.js";
|
||||||
|
|
||||||
|
const nCores = oHome.cpuCores;
|
||||||
|
let nSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
const nMinSecurity = ns.getServerMinSecurityLevel(sTarget);
|
||||||
|
let nMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
const nMaxMoney = ns.getServerMaxMoney(sTarget);
|
||||||
|
|
||||||
|
const nWeakenSTR = ns.weakenAnalyze(1, nCores);
|
||||||
|
let nWeakenThreads = Math.ceil((nSecurity - nMinSecurity) / nWeakenSTR);
|
||||||
|
let nFreeRam = ns.getServerMaxRam("home") - ns.getServerUsedRam("home");
|
||||||
|
ns.tail(ns.pid, oHome.hostname, sTarget);
|
||||||
|
//ns.resizeTail(815, 395);
|
||||||
|
//ns.moveTail(1925, 0);
|
||||||
|
|
||||||
|
// crack target
|
||||||
|
//ns.run(sCrack, 1, sTarget);
|
||||||
|
const nDelay = ns.getWeakenTime(sTarget);
|
||||||
|
if (nWeakenThreads > 0 && nSecurity > nMinSecurity) {
|
||||||
|
|
||||||
|
|
||||||
|
ns.tprint("current security is: " + nSecurity);
|
||||||
|
ns.tprint("minimum security is: " + nMinSecurity);
|
||||||
|
ns.tprint("threads needed for weaken: " + nWeakenThreads);
|
||||||
|
ns.tprint(nWeakenThreads + " will reduce Security by " + ns.weakenAnalyze(nWeakenThreads, nCores));
|
||||||
|
let nScriptRAM = ns.getScriptRam(sWeakenScript, "home");
|
||||||
|
let nRequiredRAM = nScriptRAM * nWeakenThreads;
|
||||||
|
ns.tprint(nWeakenThreads + " of " + sWeakenScript + " requires " + nRequiredRAM + " GB of RAM");
|
||||||
|
ns.tprint("weakening will take " + (nDelay / 1000 / 60) + " minutes");
|
||||||
|
|
||||||
|
if (nFreeRam > nRequiredRAM) {
|
||||||
|
ns.run(sWeakenScript, nWeakenThreads, sTarget);
|
||||||
|
|
||||||
|
//await ns.sleep(Math.ceil(nDelay));
|
||||||
|
|
||||||
|
nSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
ns.tprint("Breach complete, security level is now at: " + nSecurity);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.print("not enough RAM to run all threads at once, splitting into smaller chunks...");
|
||||||
|
|
||||||
|
|
||||||
|
while (nSecurity > nMinSecurity) {
|
||||||
|
//nWeakenThreads /= (1+(nRequiredRAM / nFreeRam));
|
||||||
|
nMaxThreads = Math.min( );
|
||||||
|
ns.print(Math.ceil(nRequiredRAM / nFreeRam));
|
||||||
|
ns.print(nWeakenThreads);
|
||||||
|
ns.print(nWeakenThreads * nScriptRAM);
|
||||||
|
ns.run(sWeakenScript, Math.ceil(nWeakenThreads), sTarget);
|
||||||
|
await ns.sleep(Math.ceil(nDelay));
|
||||||
|
nSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let nGrowMulti = 1;
|
||||||
|
ns.print("nGrowMulti = " + nGrowMulti);
|
||||||
|
let nGrowth = ns.growthAnalyze(sTarget, nGrowMulti, nCores);
|
||||||
|
ns.print("nGrowth = " + nGrowth);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//ns.growthAnalyzeSecurity();
|
||||||
|
|
||||||
|
|
||||||
|
const startValue = nMoney; // First argument: starting value
|
||||||
|
const target = nMaxMoney; // Second argument: target value
|
||||||
|
let result = startValue; // Initialize result with the starting value
|
||||||
|
let n = 1;
|
||||||
|
// For loop that continues until the result exceeds or matches the target
|
||||||
|
for (; result < target; n++) {
|
||||||
|
result += 1; // Add 1 before multiplication
|
||||||
|
result *= n; // Multiply by the current step value
|
||||||
|
}
|
||||||
|
let nGrowThreadsNeeded = n * ns.growthAnalyze(sTarget, n, 1);
|
||||||
|
ns.print("nGrowThreadsNeeded = " + nGrowThreadsNeeded);
|
||||||
|
|
||||||
|
while (nMoney < nMaxMoney) {
|
||||||
|
|
||||||
|
let nFreeRam = ns.getServerMaxRam("home") - ns.getServerUsedRam("home");
|
||||||
|
let nGrowPID = ns.run(sGrowScript, Math.min([Math.ceil(nGrowThreadsNeeded)], [Math.ceil(nFreeRam / ns.getScriptRam(sGrowScript, "home"))]), sTarget);
|
||||||
|
await ns.nextPortWrite(nGrowPID);
|
||||||
|
await ns.sleep(1000);
|
||||||
|
nMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
await ns.sleep(Math.ceil(nDelay));
|
||||||
|
|
||||||
|
//run batch
|
||||||
|
const nBatchPID = ns.run(sBatch, 1, sTarget);
|
||||||
|
ns.tail(nBatchPID, "home", sBatch, 1, sTarget);
|
||||||
|
ns.resizeTail(815, 395, nBatchPID);
|
||||||
|
ns.moveTail(1925, 0, nBatchPID);
|
||||||
|
|
||||||
|
}
|
||||||
166
local/path/home/RMcontroller.js
Normal file
166
local/path/home/RMcontroller.js
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//Arguments
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
|
||||||
|
ns.tail("RMcontroller.js", "home", sTarget);
|
||||||
|
|
||||||
|
//Settings
|
||||||
|
const oHome = ns.getServer("home");
|
||||||
|
const nCores = oHome.cpuCores;
|
||||||
|
const sScript = ns.getScriptName();
|
||||||
|
const sWeaken = "RMweaken.js";
|
||||||
|
const sGrow = "RMgrow.js";
|
||||||
|
const sHack = "RMhack.js";
|
||||||
|
const nScriptRAM = ns.getScriptRam(sScript, "home");
|
||||||
|
const nWeakenRAM = ns.getScriptRam(sWeaken, "home");
|
||||||
|
const nGrowRAM = ns.getScriptRam(sGrow, "home");
|
||||||
|
const nHackRAM = ns.getScriptRam(sHack, "home");
|
||||||
|
const nHomeUsedRAM = ns.getServerUsedRam("home");
|
||||||
|
const nHomeMaxRAM = ns.getServerMaxRam("home");
|
||||||
|
let nHomeFreeRAM = nHomeMaxRAM - nHomeUsedRAM;
|
||||||
|
|
||||||
|
const nDelays = [0, 100, 200, 300];
|
||||||
|
|
||||||
|
|
||||||
|
//abort script if sTarget is undefined
|
||||||
|
if (sTarget === undefined) {
|
||||||
|
ns.tprint("1st arg sTarget is undefined");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//target server info
|
||||||
|
const nMinSecurity = ns.getServerMinSecurityLevel(sTarget);
|
||||||
|
const nMaxMoney = ns.getServerMaxMoney(sTarget);
|
||||||
|
|
||||||
|
let nWeakenTime1 = ns.getWeakenTime(sTarget);
|
||||||
|
let nWeakenTime2 = nWeakenTime1 + nDelays[3];
|
||||||
|
let nGrowTime = nWeakenTime1 * 0.8;
|
||||||
|
let nHackTime = nWeakenTime1 / 4;
|
||||||
|
|
||||||
|
//let nHackSecurityGain = ns.hackAnalyzeSecurity(1, sTarget);
|
||||||
|
//let nHackSecurityGain = 0.002;
|
||||||
|
//let nHackThreadsEstimate = Math.max(Math.floor(1 / nHackSecurityGain),1);
|
||||||
|
//let nHackThreadsEstimate = 10;
|
||||||
|
//ns.tprint("nHackSecurityGain = " + nHackSecurityGain);
|
||||||
|
//ns.tprint("nHackThreadsEstimate = " + nHackThreadsEstimate);
|
||||||
|
const nHackTotalRAM = nHackRAM * 25;
|
||||||
|
|
||||||
|
//let nGrowSecurityGain = ns.growthAnalyzeSecurity(1, sTarget, nCores);
|
||||||
|
//let nGrowSecurityGain = 0.004;
|
||||||
|
//let nGrowThreadsEstimate = Math.max(Math.floor(1 / nGrowSecurityGain),1);
|
||||||
|
//ns.tprint("nGrowSecurityGain = " + nGrowSecurityGain);
|
||||||
|
//ns.tprint("nGrowThreadsEstimate = " + nGrowThreadsEstimate);
|
||||||
|
const nGrowTotalRAM = nGrowRAM * 12.5;
|
||||||
|
|
||||||
|
//let nWeakenSecurity = ns.weakenAnalyze(1, nCores);
|
||||||
|
//let nWeakenSecurity = 0.05;
|
||||||
|
//let nWeakenThreadsEstimate = Math.max(Math.ceil(1 / nWeakenSecurity),1);
|
||||||
|
//ns.tprint("nWeakenSecurity = " + nWeakenSecurity);
|
||||||
|
//ns.tprint("nWeakenThreadsEstimate = " + nWeakenThreadsEstimate);
|
||||||
|
const nWeakenTotalRAM = nWeakenRAM * 1;
|
||||||
|
|
||||||
|
const nTotalRAM = nHackTotalRAM + nGrowTotalRAM + (nWeakenTotalRAM * 2)
|
||||||
|
const nTotalBatches = Math.floor((nHomeFreeRAM - nScriptRAM) / nTotalRAM);
|
||||||
|
|
||||||
|
let nHackThreadsEstimate = nTotalBatches * 25;
|
||||||
|
let nWeakenThreadsEstimate1 = nTotalBatches * 1;
|
||||||
|
let nGrowThreadsEstimate = nTotalBatches * 12.5;
|
||||||
|
let nWeakenThreadsEstimate2 = nTotalBatches * 1;
|
||||||
|
|
||||||
|
ns.tprint("RAM per Cycle = " + nTotalRAM);
|
||||||
|
ns.tprint("how many batches can i run at the same time? = " + nTotalBatches);
|
||||||
|
|
||||||
|
//await ns.grow(server, { additionalMsec: nMsecDelay });
|
||||||
|
let nGrowDelay = nWeakenTime1 - nGrowTime;
|
||||||
|
let nHackDelay = nWeakenTime1 - nHackTime;
|
||||||
|
|
||||||
|
|
||||||
|
const nCycleDuration = nWeakenTime2 + nDelays[3];
|
||||||
|
ns.tprint("nCycleDuration = " + nCycleDuration);
|
||||||
|
|
||||||
|
const nBatchFrequency = Math.ceil(nCycleDuration / nTotalBatches);
|
||||||
|
ns.tprint("nBatchFrequency = " + nBatchFrequency);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
//server stats
|
||||||
|
let nCurrentSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
let nCurrentMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
|
||||||
|
//timestamp
|
||||||
|
let currentDate = new Date();
|
||||||
|
let nOffset;
|
||||||
|
|
||||||
|
ns.print("Cash: " + (Math.floor(nCurrentMoney * 1000) / 1000) + " / " + nMaxMoney);
|
||||||
|
ns.print("Security: " + (Math.floor(nCurrentSecurity * 1000) / 1000) + " / " + nMinSecurity);
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
nOffset = ns.getWeakenTime(sTarget);
|
||||||
|
let nSafeTime = nOffset + nDelays[3] + 1000;
|
||||||
|
let nWeakTime = new Date(currentDate.getTime() + nSafeTime);
|
||||||
|
let sWeakTime = nWeakTime.toLocaleTimeString('sw-SV'); //swedish time
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Weakening " + sTarget + " Estimated complete at " + sWeakTime);
|
||||||
|
|
||||||
|
//hack
|
||||||
|
const nHackPID = ns.exec(sHack, "home", nHackThreadsEstimate, sTarget, false, nHackDelay + nDelays[0]);
|
||||||
|
//ns.tail(nHackPID, "home", "home", nHackThreadsEstimate, sTarget, 0, nHackDelay + nDelays[0]);
|
||||||
|
|
||||||
|
//weaken 1
|
||||||
|
const nWeakenPID1 = ns.exec(sWeaken, "home", nWeakenThreadsEstimate1, sTarget, false, nDelays[1]);
|
||||||
|
//ns.tail(nWeakenPID, "home", "home", nWeakenThreadsEstimate, sTarget, 0, nDelays[1]);
|
||||||
|
|
||||||
|
//grow
|
||||||
|
const nGrowPID = ns.exec(sGrow, "home", nGrowThreadsEstimate, sTarget, false, nGrowDelay + nDelays[2]);
|
||||||
|
//ns.tail(nGrowPID, "home", "home", nGrowThreadsEstimate, sTarget, 0, nGrowDelay + nDelays[2]);
|
||||||
|
|
||||||
|
//weaken 2
|
||||||
|
const nWeakenPID2 = ns.exec(sWeaken, "home", nWeakenThreadsEstimate2, sTarget, false, nDelays[3]);
|
||||||
|
//ns.tail(nWeakenPID2, "home", "home", nWeakenThreadsEstimate, sTarget, 0, nDelays[3]);
|
||||||
|
|
||||||
|
//await ns.sleep(nSafeTime);
|
||||||
|
|
||||||
|
/*
|
||||||
|
await ns.nextPortWrite(nHackPID);
|
||||||
|
await ns.nextPortWrite(nWeakenPID1);
|
||||||
|
await ns.nextPortWrite(nGrowPID);
|
||||||
|
await ns.nextPortWrite(nWeakenPID2);
|
||||||
|
|
||||||
|
ns.print("nHackPeek = " + nHackPeek);
|
||||||
|
ns.print("nWeaken1Peek = " + nWeaken1Peek);
|
||||||
|
ns.print("nGrowPeek = " + nGrowPeek);
|
||||||
|
ns.print("nWeaken2Peek = " + nWeaken2Peek);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
let nHackPeek = ns.peek(nHackPID);
|
||||||
|
let nWeaken1Peek = ns.peek(nWeakenPID1);
|
||||||
|
let nGrowPeek = ns.peek(nGrowPID);
|
||||||
|
let nWeaken2Peek = ns.peek(nWeakenPID2);
|
||||||
|
|
||||||
|
|
||||||
|
if (nHackPeek === true || nWeaken1Peek === true || nGrowPeek === true || nWeaken2Peek === true) {
|
||||||
|
ns.print("some of the ports are already written to...");
|
||||||
|
ns.print("nHackPeek = " + nHackPeek);
|
||||||
|
ns.print("nWeaken1Peek = " + nWeaken1Peek);
|
||||||
|
ns.print("nGrowPeek = " + nGrowPeek);
|
||||||
|
ns.print("nWeaken2Peek = " + nWeaken2Peek);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
ns.nextPortWrite(nHackPID),
|
||||||
|
ns.nextPortWrite(nWeakenPID1),
|
||||||
|
ns.nextPortWrite(nGrowPID),
|
||||||
|
ns.nextPortWrite(nWeakenPID2)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
ns.print("hack: " + nHackPID + " completed at " + ns.readPort(nHackPID));
|
||||||
|
ns.print("weaken1: " + nWeakenPID1 + " completed at " + ns.readPort(nWeakenPID1));
|
||||||
|
ns.print("grow: " + nGrowPID + " completed at " + ns.readPort(nGrowPID));
|
||||||
|
ns.print("weaken2: " + nWeakenPID2 + " completed at " + ns.readPort(nWeakenPID2));
|
||||||
|
await ns.sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
local/path/home/RMgrow.js
Normal file
15
local/path/home/RMgrow.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print(Date.now());
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
const bRepeat = ns.args[1]; // should this script loop
|
||||||
|
const nMsecDelay = ns.args[2]; // MsecDelay
|
||||||
|
|
||||||
|
while (bRepeat === true) {
|
||||||
|
await ns.grow(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ns.grow(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
ns.print(Date.now());
|
||||||
|
ns.writePort(ns.pid, Date.now());
|
||||||
|
}
|
||||||
15
local/path/home/RMhack.js
Normal file
15
local/path/home/RMhack.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print(Date.now());
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
const bRepeat = ns.args[1]; // should this script loop
|
||||||
|
const nMsecDelay = ns.args[2]; // MsecDelay
|
||||||
|
|
||||||
|
while (bRepeat === true) {
|
||||||
|
await ns.hack(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ns.hack(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
ns.print(Date.now());
|
||||||
|
ns.writePort(ns.pid, Date.now());
|
||||||
|
}
|
||||||
15
local/path/home/RMweaken.js
Normal file
15
local/path/home/RMweaken.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print(Date.now());
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
const bRepeat = ns.args[1]; // should this script loop
|
||||||
|
const nMsecDelay = ns.args[2]; // MsecDelay
|
||||||
|
|
||||||
|
while (bRepeat === true) {
|
||||||
|
await ns.weaken(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ns.weaken(sTarget, { additionalMsec: nMsecDelay });
|
||||||
|
ns.print(Date.now());
|
||||||
|
ns.writePort(ns.pid, Date.now());
|
||||||
|
}
|
||||||
@@ -1,491 +0,0 @@
|
|||||||
/*
|
|
||||||
Welcome to part 4. A continuous batcher is a major hurdle compared to everything we've done so far. The number
|
|
||||||
and complexity of the challenges increases drastically when trying to keep everything running indefinitely.
|
|
||||||
With luck, the overengineering we've done so far will have well prepared us for the challenges of a periodic
|
|
||||||
batcher.
|
|
||||||
|
|
||||||
Technically, I use quite a few JIT techniques in this batcher, but I don't consider it a true JIT batcher
|
|
||||||
as it doesn't take full advantage of the potential RAM efficiency. Instead, I favor simpler logic, while still
|
|
||||||
allowing the batcher to make certain adjustments if it needs to.
|
|
||||||
|
|
||||||
When it comes to continuous batchers, performance is king. We're going to aim for 5ms spacing as we have
|
|
||||||
throughout this guide so far, but there's a lot we need to do in those 5ms. As such, we need to make sure that
|
|
||||||
we choose which operations to do carefully, as well as when to do them and how to make sure they are as fast
|
|
||||||
as we can make them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// One new utility. A custom data structure for managing our schedule. You can see the details in utils.js
|
|
||||||
import { getServers, copyScripts, checkTarget, isPrepped, prep, Deque } from "/S4utils.js";
|
|
||||||
|
|
||||||
const TYPES = ["hack", "weaken1", "grow", "weaken2"];
|
|
||||||
const WORKERS = ["S4tHack.js", "S4tWeaken.js", "S4tGrow.js"];
|
|
||||||
const SCRIPTS = { hack: "S4tHack.js", weaken1: "S4tWeaken.js", grow: "S4tGrow.js", weaken2: "S4tWeaken.js" };
|
|
||||||
const COSTS = { hack: 1.7, weaken1: 1.75, grow: 1.75, weaken2: 1.75 };
|
|
||||||
// const OFFSETS = { hack: 0, weaken1: 1, grow: 2, weaken2: 3 };
|
|
||||||
|
|
||||||
// A new optional constant. The RamNet will attempt to reserve this much ram at home.
|
|
||||||
// You can set it to 0 if you don't want to reserve anything, and setting it too high will just reserve as much as possible.
|
|
||||||
const RESERVED_HOME_RAM = 0;
|
|
||||||
|
|
||||||
// A brand new class to help keep our increasingly complex logic organized.
|
|
||||||
class ContinuousBatcher {
|
|
||||||
#ns; // The ns object. Stored as a class variable to save me the trouble of passing it all the time.
|
|
||||||
|
|
||||||
// The usual data we've grown familiar with by now.
|
|
||||||
#metrics;
|
|
||||||
#ramNet;
|
|
||||||
#target;
|
|
||||||
#schedule;
|
|
||||||
#dataPort;
|
|
||||||
#batchCount = 0;
|
|
||||||
#desyncs = 0; // This is mostly used for logging purposes, since the batcher is self-correcting.
|
|
||||||
|
|
||||||
// A capital M Map. We'll use this to keep track of active jobs.
|
|
||||||
#running = new Map();
|
|
||||||
|
|
||||||
constructor(ns, metrics, ramNet) {
|
|
||||||
this.#ns = ns;
|
|
||||||
this.#metrics = metrics;
|
|
||||||
this.#ramNet = ramNet;
|
|
||||||
this.#target = metrics.target;
|
|
||||||
this.#dataPort = ns.getPortHandle(ns.pid);
|
|
||||||
|
|
||||||
// Seeding the first ending time.
|
|
||||||
this.#metrics.end = Date.now() + metrics.wTime - metrics.spacer;
|
|
||||||
|
|
||||||
// The new schedule I promised. It's a double-ended queue, but we'll mostly just be using it as a normal queue.
|
|
||||||
// It has a static size, so we make sure it can accomodate all of our jobs.
|
|
||||||
this.#schedule = new Deque(metrics.depth * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a function that can schedule a given number of batches.
|
|
||||||
// With no arguments, it just fills up the queue.
|
|
||||||
scheduleBatches(batches = this.#metrics.depth) {
|
|
||||||
while (this.#schedule.size < batches * 4) {
|
|
||||||
++this.#batchCount;
|
|
||||||
for (const type of TYPES) {
|
|
||||||
this.#metrics.end += this.#metrics.spacer;
|
|
||||||
const job = new Job(type, this.#metrics, this.#batchCount);
|
|
||||||
|
|
||||||
/*
|
|
||||||
We don't actually error out if a job can't be assigned anymore. Instead, we just assign as much
|
|
||||||
as we can. If it desyncs, the logic will correct it, and if a weaken2 gets cancelled then the actual
|
|
||||||
depth will naturally decrease below the target depth. Not a perfect fix, but better than breaking.
|
|
||||||
*/
|
|
||||||
if (!this.#ramNet.assign(job)) {
|
|
||||||
this.#ns.tprint(`WARN: Insufficient RAM to assign ${job.type}: ${job.batch}.`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.#schedule.push(job);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The function for deploying jobs. Very similar to the code from our shotgun batcher with some minor changes.
|
|
||||||
async deploy() {
|
|
||||||
// The for loop is replaced by a while loop, since our Deque isn't iterable.
|
|
||||||
while (!this.#schedule.isEmpty()) {
|
|
||||||
const job = this.#schedule.shift();
|
|
||||||
job.end += this.#metrics.delay;
|
|
||||||
const jobPid = this.#ns.exec(SCRIPTS[job.type], job.server, { threads: job.threads, temporary: true }, JSON.stringify(job));
|
|
||||||
if (!jobPid) throw new Error(`Unable to deploy ${job.type}`);
|
|
||||||
const tPort = this.#ns.getPortHandle(jobPid);
|
|
||||||
|
|
||||||
// We save the pid for later.
|
|
||||||
job.pid = jobPid;
|
|
||||||
await tPort.nextWrite();
|
|
||||||
|
|
||||||
// Jobs can be late as long as the delay won't cause collisions.
|
|
||||||
this.#metrics.delay += Math.max(Math.ceil(tPort.read()) - this.#metrics.spacer, 0);
|
|
||||||
this.#running.set(job.id, job);
|
|
||||||
}
|
|
||||||
|
|
||||||
// After the loop, we adjust future job ends to account for the delay, then discard it.
|
|
||||||
this.#metrics.end += this.#metrics.delay;
|
|
||||||
this.#metrics.delay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our old timeout function is now a proper function of its own. A few extra baubles in the log, but nothing exciting.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
log() {
|
|
||||||
const ns = this.#ns;
|
|
||||||
const metrics = this.#metrics;
|
|
||||||
const ramNet = this.#ramNet;
|
|
||||||
ns.clearLog();
|
|
||||||
ns.print(`Hacking ~\$${ns.formatNumber(metrics.maxMoney * metrics.greed * metrics.chance / (4 * metrics.spacer) * 1000)}/s from ${metrics.target}`);
|
|
||||||
ns.print(`Status: ${isPrepped(ns, this.#target) ? "Prepped" : "Desynced"}`);
|
|
||||||
ns.print(`Security: +${metrics.minSec - metrics.sec}`);
|
|
||||||
ns.print(`Money: \$${ns.formatNumber(metrics.money, 2)}/${ns.formatNumber(metrics.maxMoney, 2)}`);
|
|
||||||
ns.print(`Greed: ${Math.floor(metrics.greed * 1000) / 10}%`);
|
|
||||||
ns.print(`Ram available: ${ns.formatRam(ramNet.totalRam)}/${ns.formatRam(ramNet.maxRam)}`);
|
|
||||||
ns.print(`Active jobs: ${this.#running.size}/${metrics.depth * 4}`);
|
|
||||||
|
|
||||||
// You'll see what this line's about in a moment.
|
|
||||||
if (this.#desyncs) ns.print(`Hacks cancelled by desync: ${this.#desyncs}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The core loop of our batcher logic. Quite lean with everything neatly divided into functions, but there's still
|
|
||||||
// plenty going on here.
|
|
||||||
async run() {
|
|
||||||
// First we do some initial setup, this is essentially firing off a shotgun blast to get us started.
|
|
||||||
const dataPort = this.#dataPort;
|
|
||||||
this.scheduleBatches();
|
|
||||||
await this.deploy();
|
|
||||||
await this.#ns.sleep(0); // This is probably pointless. I forget why I put it here.
|
|
||||||
this.log();
|
|
||||||
while (true) {
|
|
||||||
// Wait for the nextWrite, as usual.
|
|
||||||
await dataPort.nextWrite();
|
|
||||||
|
|
||||||
// Sometimes there's a delay and more than one job writes to the port at once.
|
|
||||||
// We make sure to handle it all before we move on.
|
|
||||||
while (!dataPort.empty()) {
|
|
||||||
// Workers now report unique identifiers (type + batchnumber) used to find them on the map.
|
|
||||||
const data = dataPort.read();
|
|
||||||
|
|
||||||
// Free up the ram, them remove them from the active list.
|
|
||||||
// The check handles a corner case where a hack gets "cancelled" after it's already finished.
|
|
||||||
if (this.#running.has(data)) {
|
|
||||||
this.#ramNet.finish(this.#running.get(data));
|
|
||||||
this.#running.delete(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's a W2, we've got an opening to do some work.
|
|
||||||
if (data.startsWith("weaken2")) {
|
|
||||||
// Recalculate times. Threads too, but only if prepped (the logic is in the function itself).
|
|
||||||
this.#metrics.calculate(this.#ns);
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is probably the most JIT-like aspect of the entire batcher. If the server isn't prepped, then
|
|
||||||
we cancel the next hack to let the server fix itself. Between this and the extra 1% grow threads, level
|
|
||||||
ups are completely handled. Rapid level ups can lead to a lot of lost jobs, but eventually the program
|
|
||||||
stabilizes.
|
|
||||||
|
|
||||||
There are probably more efficient ways to do this. Heck, even this solution could be optimized better,
|
|
||||||
but for now, this is an adequate demonstration of a reasonable non-formulas solution to the level up
|
|
||||||
problem. It also lets us dip our toes into JIT logic in preparation for the final part.
|
|
||||||
*/
|
|
||||||
if (!isPrepped(this.#ns, this.#target)) {
|
|
||||||
const id = "hack" + (parseInt(data.slice(7)) + 1);
|
|
||||||
const cancel = this.#running.get(id);
|
|
||||||
// Just in case the hack was already aborted somehow.
|
|
||||||
if (cancel) {
|
|
||||||
this.#ramNet.finish(cancel);
|
|
||||||
this.#ns.kill(cancel.pid);
|
|
||||||
this.#running.delete(id);
|
|
||||||
++this.#desyncs; // Just to keep track of how much we've lost keeping things prepped.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then of course we just schedule and deploy a new batch.
|
|
||||||
this.scheduleBatches(1);
|
|
||||||
await this.deploy();
|
|
||||||
this.log();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Our poor "main" function isn't much more than a kickstart for our new batcher object. It's a bit weird having
|
|
||||||
it wedged between objects like this, but I wanted to have the new functionality up at the top since most of the
|
|
||||||
remaining code hasn't changed much. I'll comment the changes anyway.
|
|
||||||
*/
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
ns.disableLog("ALL");
|
|
||||||
ns.tail();
|
|
||||||
|
|
||||||
/*
|
|
||||||
This commented out code is for a debugging tool that centralizes logs from the worker scripts into one place.
|
|
||||||
It's main advantage is the ability to write txt logs to file, which can be perused later to track down errors.
|
|
||||||
You can uncomment it if you'd like to see a live stream of workers finishing without flooding the terminal.
|
|
||||||
|
|
||||||
If you do, make sure to search the file for -LOGGING and uncomment all relevant lines.
|
|
||||||
*/
|
|
||||||
// if (ns.isRunning("S4logHelper.js", "home")) ns.kill("S4logHelper.js", "home");
|
|
||||||
// const logPort = ns.exec("S4logHelper.js", "home");
|
|
||||||
// ns.atExit(() => ns.closeTail(logPort));
|
|
||||||
|
|
||||||
// Setup is mostly the same.
|
|
||||||
const dataPort = ns.getPortHandle(ns.pid);
|
|
||||||
dataPort.clear();
|
|
||||||
let target = ns.args[0] ? ns.args[0] : "n00dles";
|
|
||||||
while (true) {
|
|
||||||
const servers = getServers(ns, (server) => {
|
|
||||||
if (!ns.args[0]) target = checkTarget(ns, server, target, ns.fileExists("Formulas.exe", "home"));
|
|
||||||
copyScripts(ns, server, WORKERS, true);
|
|
||||||
return ns.hasRootAccess(server);
|
|
||||||
});
|
|
||||||
const ramNet = new RamNet(ns, servers);
|
|
||||||
const metrics = new Metrics(ns, target);
|
|
||||||
// metrics.log = logPort; // Uncomment for -LOGGING.
|
|
||||||
if (!isPrepped(ns, target)) await prep(ns, metrics, ramNet);
|
|
||||||
ns.clearLog();
|
|
||||||
ns.print("Optimizing. This may take a few seconds...");
|
|
||||||
|
|
||||||
// Optimizer has changed again. Back to being synchronous, since the performance is much better.
|
|
||||||
optimizePeriodic(ns, metrics, ramNet);
|
|
||||||
metrics.calculate(ns);
|
|
||||||
|
|
||||||
// Create and run our batcher.
|
|
||||||
const batcher = new ContinuousBatcher(ns, metrics, ramNet);
|
|
||||||
await batcher.run();
|
|
||||||
|
|
||||||
/*
|
|
||||||
You might be wondering why I put this in a while loop and then just return here. The simple answer is that
|
|
||||||
it's because this is meant to be run in a loop, but I didn't implement the logic for it. This version of the
|
|
||||||
batcher is completely static once created. It sticks to a single greed value, and doesn't update if more
|
|
||||||
RAM becomes available.
|
|
||||||
|
|
||||||
In a future version, you'd want some logic to allow the batcher to choose new targets, update its available RAM,
|
|
||||||
and create new batchers during runtime. For now, that's outside the scope of this guide, but consider this loop
|
|
||||||
as a sign of what could be.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Job class, lean as it is, remains mostly unchanged. I got rid of the server argument since I wasn't using it
|
|
||||||
// and added a batch number instead.
|
|
||||||
class Job {
|
|
||||||
constructor(type, metrics, batch) {
|
|
||||||
this.type = type;
|
|
||||||
// this.end = metrics.ends[type];
|
|
||||||
this.end = metrics.end;
|
|
||||||
this.time = metrics.times[type];
|
|
||||||
this.target = metrics.target;
|
|
||||||
this.threads = metrics.threads[type];
|
|
||||||
this.cost = this.threads * COSTS[type];
|
|
||||||
this.server = "none";
|
|
||||||
this.report = true;
|
|
||||||
this.port = metrics.port;
|
|
||||||
this.batch = batch;
|
|
||||||
|
|
||||||
// The future is now. The status and id are used for interacting with the Deque and Map in our batcher class.
|
|
||||||
this.status = "active";
|
|
||||||
this.id = type + batch;
|
|
||||||
// this.log = metrics.log; // -LOGGING
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The only change to the metrics class is the calculate function skipping threadcounts if the server isn't prepped.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
class Metrics {
|
|
||||||
constructor(ns, server) {
|
|
||||||
this.target = server;
|
|
||||||
this.maxMoney = ns.getServerMaxMoney(server);
|
|
||||||
this.money = Math.max(ns.getServerMoneyAvailable(server), 1);
|
|
||||||
this.minSec = ns.getServerMinSecurityLevel(server);
|
|
||||||
this.sec = ns.getServerSecurityLevel(server);
|
|
||||||
this.prepped = isPrepped(ns, server);
|
|
||||||
this.chance = 0;
|
|
||||||
this.wTime = 0;
|
|
||||||
this.delay = 0;
|
|
||||||
this.spacer = 5;
|
|
||||||
this.greed = 0.01;
|
|
||||||
this.depth = 0; // The number of concurrent batches to run. Set by the optimizer.
|
|
||||||
|
|
||||||
this.times = { hack: 0, weaken1: 0, grow: 0, weaken2: 0 };
|
|
||||||
this.end = 0; // Slight change for the new timing. The old way in commented out in case I switch back later.
|
|
||||||
// this.ends = { hack: 0, weaken1: 0, grow: 0, weaken2: 0 };
|
|
||||||
this.threads = { hack: 0, weaken1: 0, grow: 0, weaken2: 0 };
|
|
||||||
|
|
||||||
this.port = ns.pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate(ns, greed = this.greed) {
|
|
||||||
const server = this.target;
|
|
||||||
const maxMoney = this.maxMoney;
|
|
||||||
this.money = ns.getServerMoneyAvailable(server);
|
|
||||||
this.sec = ns.getServerSecurityLevel(server);
|
|
||||||
this.wTime = ns.getWeakenTime(server);
|
|
||||||
this.times.weaken1 = this.wTime;
|
|
||||||
this.times.weaken2 = this.wTime;
|
|
||||||
this.times.hack = this.wTime / 4;
|
|
||||||
this.times.grow = this.wTime * 0.8;
|
|
||||||
// this.depth = this.wTime / this.spacer * 4;
|
|
||||||
|
|
||||||
if (isPrepped(ns, server)) { // The only change.
|
|
||||||
const hPercent = ns.hackAnalyze(server);
|
|
||||||
const amount = maxMoney * greed;
|
|
||||||
const hThreads = Math.max(Math.floor(ns.hackAnalyzeThreads(server, amount)), 1);
|
|
||||||
const tGreed = hPercent * hThreads;
|
|
||||||
const gThreads = Math.ceil(ns.growthAnalyze(server, maxMoney / (maxMoney - maxMoney * tGreed)) * 1.01);
|
|
||||||
this.threads.weaken1 = Math.max(Math.ceil(hThreads * 0.002 / 0.05), 1);
|
|
||||||
this.threads.weaken2 = Math.max(Math.ceil(gThreads * 0.004 / 0.05), 1);
|
|
||||||
this.threads.hack = hThreads;
|
|
||||||
this.threads.grow = gThreads;
|
|
||||||
this.chance = ns.hackAnalyzeChance(server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A few minor edits here. An unused "simulation" mode, and reserved RAM on home.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
class RamNet {
|
|
||||||
#blocks = [];
|
|
||||||
#minBlockSize = Infinity;
|
|
||||||
#maxBlockSize = 0;
|
|
||||||
#totalRam = 0;
|
|
||||||
#prepThreads = 0;
|
|
||||||
#maxRam = 0;
|
|
||||||
#index = new Map();
|
|
||||||
|
|
||||||
// Simulate mode ignores running scripts. Can be used to make calculations while the batcher is operating.
|
|
||||||
constructor(ns, servers, simulate = false) {
|
|
||||||
for (const server of servers) {
|
|
||||||
if (ns.hasRootAccess(server)) {
|
|
||||||
const maxRam = ns.getServerMaxRam(server);
|
|
||||||
// Save some extra ram on home. Clamp used ram to maxRam to prevent negative numbers.
|
|
||||||
const reserved = (server === "home") ? RESERVED_HOME_RAM : 0;
|
|
||||||
const used = Math.min((simulate ? 0 : ns.getServerUsedRam(server)) + reserved, maxRam);
|
|
||||||
const ram = maxRam - used;
|
|
||||||
if (maxRam > 0) {
|
|
||||||
const block = { server: server, ram: ram };
|
|
||||||
this.#blocks.push(block);
|
|
||||||
if (ram < this.#minBlockSize) this.#minBlockSize = ram;
|
|
||||||
if (ram > this.#maxBlockSize) this.#maxBlockSize = ram;
|
|
||||||
this.#totalRam += ram;
|
|
||||||
this.#maxRam += maxRam;
|
|
||||||
this.#prepThreads += Math.floor(ram / 1.75);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.#sort();
|
|
||||||
this.#blocks.forEach((block, index) => this.#index.set(block.server, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
#sort() {
|
|
||||||
this.#blocks.sort((x, y) => {
|
|
||||||
if (x.server === "home") return 1;
|
|
||||||
if (y.server === "home") return -1;
|
|
||||||
|
|
||||||
return x.ram - y.ram;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get totalRam() {
|
|
||||||
return this.#totalRam;
|
|
||||||
}
|
|
||||||
|
|
||||||
get maxRam() {
|
|
||||||
return this.#maxRam;
|
|
||||||
}
|
|
||||||
|
|
||||||
get maxBlockSize() {
|
|
||||||
return this.#maxBlockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
get prepThreads() {
|
|
||||||
return this.#prepThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBlock(server) {
|
|
||||||
if (this.#index.has(server)) {
|
|
||||||
return this.#blocks[this.#index.get(server)];
|
|
||||||
} else {
|
|
||||||
throw new Error(`Server ${server} not found in RamNet.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assign(job) {
|
|
||||||
const block = this.#blocks.find(block => block.ram >= job.cost);
|
|
||||||
if (block) {
|
|
||||||
job.server = block.server;
|
|
||||||
block.ram -= job.cost;
|
|
||||||
this.#totalRam -= job.cost;
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
finish(job) {
|
|
||||||
const block = this.getBlock(job.server);
|
|
||||||
block.ram += job.cost;
|
|
||||||
this.#totalRam += job.cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
cloneBlocks() {
|
|
||||||
return this.#blocks.map(block => ({ ...block }));
|
|
||||||
}
|
|
||||||
|
|
||||||
printBlocks(ns) {
|
|
||||||
for (const block of this.#blocks) ns.print(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
testThreads(threadCosts) {
|
|
||||||
const pRam = this.cloneBlocks();
|
|
||||||
let batches = 0;
|
|
||||||
let found = true;
|
|
||||||
while (found) {
|
|
||||||
for (const cost of threadCosts) {
|
|
||||||
found = false;
|
|
||||||
const block = pRam.find(block => block.ram >= cost);
|
|
||||||
if (block) {
|
|
||||||
block.ram -= cost;
|
|
||||||
found = true;
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
if (found) batches++;
|
|
||||||
}
|
|
||||||
return batches;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quite a bit has changed in this one. It's back to being synchronous, though it can still take a while.
|
|
||||||
/**
|
|
||||||
* @param {NS} ns
|
|
||||||
* @param {Metrics} metrics
|
|
||||||
* @param {RamNet} ramNet
|
|
||||||
*/
|
|
||||||
function optimizePeriodic(ns, metrics, ramNet) {
|
|
||||||
const maxThreads = ramNet.maxBlockSize / 1.75;
|
|
||||||
const maxMoney = metrics.maxMoney;
|
|
||||||
const hPercent = ns.hackAnalyze(metrics.target);
|
|
||||||
const wTime = ns.getWeakenTime(metrics.target);
|
|
||||||
|
|
||||||
const minGreed = 0.001;
|
|
||||||
const maxSpacer = wTime; // This is more of an infinite loop safety net than anything.
|
|
||||||
const stepValue = 0.01;
|
|
||||||
let greed = 0.95; // Capping greed a bit lower. I don't have a compelling reason for this.
|
|
||||||
let spacer = metrics.spacer; // We'll be adjusting the spacer in low ram conditions to allow smaller depths.
|
|
||||||
|
|
||||||
while (greed > minGreed && spacer < maxSpacer) {
|
|
||||||
// We calculate a max depth based on the spacer, then add one as a buffer.
|
|
||||||
const depth = Math.ceil(wTime / (4 * spacer)) + 1;
|
|
||||||
const amount = maxMoney * greed;
|
|
||||||
const hThreads = Math.max(Math.floor(ns.hackAnalyzeThreads(metrics.target, amount)), 1);
|
|
||||||
const tGreed = hPercent * hThreads;
|
|
||||||
const gThreads = Math.ceil(ns.growthAnalyze(metrics.target, maxMoney / (maxMoney - maxMoney * tGreed)) * 1.01);
|
|
||||||
if (Math.max(hThreads, gThreads) <= maxThreads) {
|
|
||||||
const wThreads1 = Math.max(Math.ceil(hThreads * 0.002 / 0.05), 1);
|
|
||||||
const wThreads2 = Math.max(Math.ceil(gThreads * 0.004 / 0.05), 1);
|
|
||||||
|
|
||||||
const threadCosts = [hThreads * 1.7, wThreads1 * 1.75, gThreads * 1.75, wThreads2 * 1.75];
|
|
||||||
|
|
||||||
// Glad I kept these, they turned out to be useful after all. When trying to hit target depth,
|
|
||||||
// checking that there's actually enough theoretical ram to fit them is a massive boost to performance.
|
|
||||||
const totalCost = threadCosts.reduce((t, c) => t + c) * depth;
|
|
||||||
if (totalCost < ramNet.totalRam) {
|
|
||||||
// Double check that we can actually fit our threads into ram, then set our metrics and return.
|
|
||||||
const batchCount = ramNet.testThreads(threadCosts);
|
|
||||||
if (batchCount >= depth) {
|
|
||||||
metrics.spacer = spacer;
|
|
||||||
metrics.greed = greed;
|
|
||||||
metrics.depth = depth;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// await ns.sleep(0); // Uncomment and make the function async if you don't like the freeze on startup.
|
|
||||||
|
|
||||||
// Decrement greed until we hit the minimum, then reset and increment spacer. We'll find a valid configuration eventually.
|
|
||||||
greed -= stepValue;
|
|
||||||
if (greed < minGreed && spacer < maxSpacer) {
|
|
||||||
greed = 0.99;
|
|
||||||
++spacer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error("Not enough ram to run even a single batch. Something has gone seriously wrong.");
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
This script is completely unchanged from the last part. As a note, if you find that saves are taking a very long time
|
|
||||||
it may help to disable txt logging when you aren't actively debugging. The log files generated by this script
|
|
||||||
are quite big even when it's erasing the data on each new instance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
|
|
||||||
const logFile = "S4log.txt";
|
|
||||||
ns.clear(logFile); // Clear the previous log for each instance.
|
|
||||||
ns.disableLog("ALL");
|
|
||||||
ns.tail();
|
|
||||||
ns.moveTail(200, 200); // Move it out of the way so it doesn't cover up the controller.
|
|
||||||
const logPort = ns.getPortHandle(ns.pid);
|
|
||||||
logPort.clear();
|
|
||||||
|
|
||||||
// Pretty simple. Just wait until something writes to the log and save the info.
|
|
||||||
// Writes to its own console as well as a text file.
|
|
||||||
let max = 0;
|
|
||||||
let count = 0;
|
|
||||||
let total = 0;
|
|
||||||
let errors = 0;
|
|
||||||
while (true) {
|
|
||||||
await logPort.nextWrite();
|
|
||||||
do {
|
|
||||||
const data = logPort.read();
|
|
||||||
// if (data > max) max = data;
|
|
||||||
// if (data > 5) ++errors;
|
|
||||||
// total += data;
|
|
||||||
// ++count;
|
|
||||||
// ns.clearLog();
|
|
||||||
// ns.print(`Max desync: ${max}`);
|
|
||||||
// ns.print(`Average desync: ${total / count}`);
|
|
||||||
// ns.print(`Errors: ${errors}`);
|
|
||||||
|
|
||||||
// if (data.startsWith("WARN")) ns.print(data);
|
|
||||||
ns.print(data);
|
|
||||||
// ns.write(logFile, data); // Comment this line out to disable txt logging.
|
|
||||||
} while (!logPort.empty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
A pretty big change this time. Well, big for workers anyway. I've tightened up the delay calculations
|
|
||||||
to be as perfect as I can get them. Full comments in weaken.js as usual.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
const start = performance.now();
|
|
||||||
const port = ns.getPortHandle(ns.pid);
|
|
||||||
const job = JSON.parse(ns.args[0]);
|
|
||||||
let tDelay = 0;
|
|
||||||
let delay = job.end - job.time - Date.now();
|
|
||||||
if (delay < 0) {
|
|
||||||
ns.tprint(`WARN: Batch ${job.batch} ${job.type} was ${-delay}ms late. (${job.end})\n`);
|
|
||||||
tDelay = -delay
|
|
||||||
delay = 0;
|
|
||||||
}
|
|
||||||
const promise = ns.grow(job.target, { additionalMsec: delay });
|
|
||||||
tDelay += performance.now() - start;
|
|
||||||
port.write(tDelay);
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
ns.atExit(() => {
|
|
||||||
const end = Date.now();
|
|
||||||
if (job.report) ns.writePort(job.port, job.type + job.batch);
|
|
||||||
// Uncomment one of these if you want to log completed jobs. Make sure to uncomment the appropriate lines in the controller as well.
|
|
||||||
// ns.tprint(`Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end).toString().slice(-6)}\n`);
|
|
||||||
// ns.writePort(job.log, `Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end + tDelay).toString().slice(-6)}\n`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
A pretty big change this time. Well, big for workers anyway. I've tightened up the delay calculations
|
|
||||||
to be as perfect as I can get them. Full comments in weaken.js as usual.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
const start = performance.now();
|
|
||||||
const port = ns.getPortHandle(ns.pid);
|
|
||||||
const job = JSON.parse(ns.args[0]);
|
|
||||||
let tDelay = 0;
|
|
||||||
let delay = job.end - job.time - Date.now();
|
|
||||||
if (delay < 0) {
|
|
||||||
ns.tprint(`WARN: Batch ${job.batch} ${job.type} was ${-delay}ms late. (${job.end})\n`);
|
|
||||||
tDelay = -delay
|
|
||||||
delay = 0;
|
|
||||||
}
|
|
||||||
const promise = ns.hack(job.target, { additionalMsec: delay });
|
|
||||||
tDelay += performance.now() - start;
|
|
||||||
port.write(tDelay);
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
ns.atExit(() => {
|
|
||||||
const end = Date.now();
|
|
||||||
if (job.report) ns.writePort(job.port, job.type + job.batch);
|
|
||||||
// Uncomment one of these if you want to log completed jobs. Make sure to uncomment the appropriate lines in the controller as well.
|
|
||||||
// ns.tprint(`Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end).toString().slice(-6)}\n`);
|
|
||||||
// ns.writePort(job.log, `Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end + tDelay).toString().slice(-6)}\n`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
A pretty big change this time. Well, big for workers anyway. I've tightened up the delay calculations
|
|
||||||
to be as perfect as I can get them. Full comments in weaken.js as usual.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
const start = performance.now();
|
|
||||||
const port = ns.getPortHandle(ns.pid); // We have to define this here. You'll see why in a moment.
|
|
||||||
const job = JSON.parse(ns.args[0]);
|
|
||||||
let tDelay = 0;
|
|
||||||
let delay = job.end - job.time - Date.now();
|
|
||||||
|
|
||||||
// Don't report delay right away.
|
|
||||||
if (delay < 0) {
|
|
||||||
ns.tprint(`WARN: Batch ${job.batch} ${job.type} was ${-delay}ms late. (${job.end})\n`);
|
|
||||||
tDelay = -delay
|
|
||||||
delay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The actual function call can take some time, so instead of awaiting on it right away, we save the promise for later.
|
|
||||||
const promise = ns.weaken(job.target, { additionalMsec: delay });
|
|
||||||
|
|
||||||
// Then after calling the hack function, we calculate our final delay and report it to the controller.
|
|
||||||
tDelay += performance.now() - start;
|
|
||||||
|
|
||||||
// The ns object is tied up by the promise, so invoking it now would cause a concurrency error.
|
|
||||||
// That's why we fetched this handle earlier.
|
|
||||||
port.write(tDelay);
|
|
||||||
|
|
||||||
// Then we finally await the promise. This should give millisecond-accurate predictions for the end time of a job.
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
ns.atExit(() => {
|
|
||||||
const end = Date.now();
|
|
||||||
if (job.report) ns.writePort(job.port, job.type + job.batch);
|
|
||||||
// Uncomment one of these if you want to log completed jobs. Make sure to uncomment the appropriate lines in the controller as well.
|
|
||||||
// ns.tprint(`Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end).toString().slice(-6)}\n`);
|
|
||||||
// ns.writePort(job.log, `Batch ${job.batch}: ${job.type} finished at ${end.toString().slice(-6)}/${Math.round(job.end + tDelay).toString().slice(-6)}\n`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,420 +0,0 @@
|
|||||||
/*
|
|
||||||
We've got a brand new class to look at, but the rest of the file remains unchanged.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
ns.tprint("This is just a function library, it doesn't do anything.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is an overengineered abomination of a custom data structure. It is essentially a double-ended queue,
|
|
||||||
but also has a Map stapled to it, just in case we need to access items by id (we don't.)
|
|
||||||
|
|
||||||
The idea is that it can fetch/peek items from the front or back with O(1) timing. This gets around the issue of
|
|
||||||
dynamic arrays taking O(n) time to shift, which is terrible behavior for very long queues like the one we're using.
|
|
||||||
*/
|
|
||||||
export class Deque {
|
|
||||||
#capacity = 0; // The maximum length.
|
|
||||||
#length = 0; // The actual number of items in the queue
|
|
||||||
#front = 0; // The index of the "head" where data is read from the queue.
|
|
||||||
#deleted = 0; // The number of "dead" items in the queue. These occur when items are deleted by index. They are bad.
|
|
||||||
#elements; // An inner array to store the data.
|
|
||||||
#index = new Map(); // A hash table to track items by ID. Try not to delete items using this, it's bad.
|
|
||||||
|
|
||||||
// Create a new queue with a specific capacity.
|
|
||||||
constructor(capacity) {
|
|
||||||
this.#capacity = capacity;
|
|
||||||
this.#elements = new Array(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// You can also convert arrays.
|
|
||||||
static fromArray(array, overallocation = 0) {
|
|
||||||
const result = new Deque(array.length + overallocation);
|
|
||||||
array.forEach(item => result.push(item));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deleted items don't count towards length, but they still take up space in the array until they can be cleared.
|
|
||||||
// Seriously, don't use the delete function unless it's absolutely necessary.
|
|
||||||
get size() {
|
|
||||||
return this.#length - this.#deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty() {
|
|
||||||
return this.#length - this.#deleted === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Again, "deleted" items still count towards this. Use caution.
|
|
||||||
isFull() {
|
|
||||||
return this.#length === this.#capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The "tail" where data is typically written to.
|
|
||||||
// Unlike the front, which points at the first piece of data, this point at the first empty slot.
|
|
||||||
get #back() {
|
|
||||||
return (this.#front + this.#length) % this.#capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push a new element into the queue.
|
|
||||||
push(value) {
|
|
||||||
if (this.isFull()) {
|
|
||||||
throw new Error("The deque is full. You cannot add more items.");
|
|
||||||
}
|
|
||||||
this.#elements[this.#back] = value;
|
|
||||||
this.#index.set(value.id, this.#back);
|
|
||||||
++this.#length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop an item off the back of the queue.
|
|
||||||
pop() {
|
|
||||||
while (!this.isEmpty()) {
|
|
||||||
--this.#length;
|
|
||||||
const item = this.#elements[this.#back];
|
|
||||||
this.#elements[this.#back] = undefined; // Free up the item for garbage collection.
|
|
||||||
this.#index.delete(item.id); // Don't confuse index.delete() with this.delete()
|
|
||||||
if (item.status !== "deleted") return item; // Clear any "deleted" items we encounter.
|
|
||||||
else --this.#deleted; // If you needed another reason to avoid deleting by ID, this breaks the O(1) time complexity.
|
|
||||||
}
|
|
||||||
throw new Error("The deque is empty. You cannot delete any items.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shift an item off the front of the queue. This is the main method for accessing data.
|
|
||||||
shift() {
|
|
||||||
while (!this.isEmpty()) {
|
|
||||||
// Our pointer already knows exactly where the front of the queue is. This is much faster than the array equivalent.
|
|
||||||
const item = this.#elements[this.#front];
|
|
||||||
this.#elements[this.#front] = undefined;
|
|
||||||
this.#index.delete(item.id);
|
|
||||||
|
|
||||||
// Move the head up and wrap around if we reach the end of the array. This is essentially a circular buffer.
|
|
||||||
this.#front = (this.#front + 1) % this.#capacity;
|
|
||||||
--this.#length;
|
|
||||||
if (item.status !== "deleted") return item;
|
|
||||||
else --this.#deleted;
|
|
||||||
}
|
|
||||||
throw new Error("The deque is empty. You cannot delete any items.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Place an item at the front of the queue. Slightly slower than pushing, but still faster than doing it on an array.
|
|
||||||
unshift(value) {
|
|
||||||
if (this.isFull()) {
|
|
||||||
throw new Error("The deque is full. You cannot add more items.");
|
|
||||||
}
|
|
||||||
this.#front = (this.#front - 1 + this.#capacity) % this.#capacity;
|
|
||||||
this.#elements[this.#front] = value;
|
|
||||||
this.#index.set(value.id, this.#front);
|
|
||||||
++this.#length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peeking at the front is pretty quick, since the head is already looking at it. We just have to clear those pesky "deleted" items first.
|
|
||||||
peekFront() {
|
|
||||||
if (this.isEmpty()) {
|
|
||||||
throw new Error("The deque is empty. You cannot peek.");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (this.#elements[this.#front].status === "deleted") {
|
|
||||||
this.#index.delete(this.#elements[this.#front]?.id);
|
|
||||||
this.#elements[this.#front] = undefined;
|
|
||||||
this.#front = (this.#front + 1) % this.#capacity;
|
|
||||||
--this.#deleted;
|
|
||||||
--this.#length;
|
|
||||||
|
|
||||||
if (this.isEmpty()) {
|
|
||||||
throw new Error("The deque is empty. You cannot peek.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.#elements[this.#front];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peeking at the back is ever so slightly slower, since we need to recalculate the pointer.
|
|
||||||
// It's a tradeoff for the faster push function, and it's a very slight difference either way.
|
|
||||||
peekBack() {
|
|
||||||
if (this.isEmpty()) {
|
|
||||||
throw new Error("The deque is empty. You cannot peek.");
|
|
||||||
}
|
|
||||||
|
|
||||||
let back = (this.#front + this.#length - 1) % this.#capacity;
|
|
||||||
while (this.#elements[back].status === "deleted") {
|
|
||||||
this.#index.delete(this.#elements[back].id);
|
|
||||||
this.#elements[back] = undefined;
|
|
||||||
back = (back - 1 + this.#capacity) % this.#capacity;
|
|
||||||
--this.#deleted;
|
|
||||||
--this.#length;
|
|
||||||
|
|
||||||
if (this.isEmpty()) {
|
|
||||||
throw new Error("The deque is empty. You cannot peek.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.#elements[back];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill the queue with a single value.
|
|
||||||
fill(value) {
|
|
||||||
while (!this.isFull()) {
|
|
||||||
this.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty the whole queue.
|
|
||||||
clear() {
|
|
||||||
while (!this.isEmpty()) {
|
|
||||||
this.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if an ID exists.
|
|
||||||
exists(id) {
|
|
||||||
return this.#index.has(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch an item by ID
|
|
||||||
get(id) {
|
|
||||||
let pos = this.#index.get(id);
|
|
||||||
return pos !== undefined ? this.#elements[pos] : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DON'T
|
|
||||||
delete(id) {
|
|
||||||
let item = this.get(id);
|
|
||||||
if (item !== undefined) {
|
|
||||||
item.status = "deleted";
|
|
||||||
++this.#deleted;
|
|
||||||
return item;
|
|
||||||
} else {
|
|
||||||
throw new Error("Item not found in the deque.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The recursive server navigation algorithm. The lambda predicate determines which servers to add to the final list.
|
|
||||||
// You can also plug other functions into the lambda to perform other tasks that check all servers at the same time.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export function getServers(ns, lambdaCondition = () => true, hostname = "home", servers = [], visited = []) {
|
|
||||||
if (visited.includes(hostname)) return;
|
|
||||||
visited.push(hostname);
|
|
||||||
if (lambdaCondition(hostname)) servers.push(hostname);
|
|
||||||
const connectedNodes = ns.scan(hostname);
|
|
||||||
if (hostname !== "home") connectedNodes.shift();
|
|
||||||
for (const node of connectedNodes) getServers(ns, lambdaCondition, node, servers, visited);
|
|
||||||
return servers;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here are a couple of my own getServers modules.
|
|
||||||
// This one finds the best target for hacking. It tries to balance expected return with time taken.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export function checkTarget(ns, server, target = "n00dles", forms = false) {
|
|
||||||
if (!ns.hasRootAccess(server)) return target;
|
|
||||||
const player = ns.getPlayer();
|
|
||||||
const serverSim = ns.getServer(server);
|
|
||||||
const pSim = ns.getServer(target);
|
|
||||||
let previousScore;
|
|
||||||
let currentScore;
|
|
||||||
if (serverSim.requiredHackingSkill <= player.skills.hacking / (forms ? 1 : 2)) {
|
|
||||||
if (forms) {
|
|
||||||
serverSim.hackDifficulty = serverSim.minDifficulty;
|
|
||||||
pSim.hackDifficulty = pSim.minDifficulty;
|
|
||||||
previousScore = pSim.moneyMax / ns.formulas.hacking.weakenTime(pSim, player) * ns.formulas.hacking.hackChance(pSim, player);
|
|
||||||
currentScore = serverSim.moneyMax / ns.formulas.hacking.weakenTime(serverSim, player) * ns.formulas.hacking.hackChance(serverSim, player);
|
|
||||||
} else {
|
|
||||||
const weight = (serv) => {
|
|
||||||
// Calculate the difference between max and available money
|
|
||||||
let diff = serv.moneyMax - serv.moneyAvailable;
|
|
||||||
|
|
||||||
// Calculate the scaling factor as the ratio of the difference to the max money
|
|
||||||
// The constant here is just an adjustment to fine tune the influence of the scaling factor
|
|
||||||
let scalingFactor = diff / serv.moneyMax * 0.95;
|
|
||||||
|
|
||||||
// Adjust the weight based on the difference, applying the scaling penalty
|
|
||||||
return (serv.moneyMax / serv.minDifficulty) * (1 - scalingFactor);
|
|
||||||
}
|
|
||||||
previousScore = weight(pSim)
|
|
||||||
currentScore = weight(serverSim)
|
|
||||||
}
|
|
||||||
if (currentScore > previousScore) target = server;
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A simple function for copying a list of scripts to a server.
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export function copyScripts(ns, server, scripts, overwrite = false) {
|
|
||||||
for (const script of scripts) {
|
|
||||||
if ((!ns.fileExists(script, server) || overwrite) && ns.hasRootAccess(server)) {
|
|
||||||
ns.scp(script, server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generic function to check that a given server is prepped. Mostly just a convenience.
|
|
||||||
export function isPrepped(ns, server) {
|
|
||||||
const tolerance = 0.0001;
|
|
||||||
const maxMoney = ns.getServerMaxMoney(server);
|
|
||||||
const money = ns.getServerMoneyAvailable(server);
|
|
||||||
const minSec = ns.getServerMinSecurityLevel(server);
|
|
||||||
const sec = ns.getServerSecurityLevel(server);
|
|
||||||
const secFix = Math.abs(sec - minSec) < tolerance;
|
|
||||||
return (money === maxMoney && secFix) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This prep function isn't part of the tutorial, but the rest of the code wouldn't work without it.
|
|
||||||
I don't make any guarantees, but I've been using it and it's worked well enough. I'll comment it anyway.
|
|
||||||
The prep strategy uses a modified proto-batching technique, which will be covered in part 2.
|
|
||||||
*/
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function prep(ns, values, ramNet) {
|
|
||||||
const maxMoney = values.maxMoney;
|
|
||||||
const minSec = values.minSec;
|
|
||||||
let money = values.money;
|
|
||||||
let sec = values.sec;
|
|
||||||
while (!isPrepped(ns, values.target)) {
|
|
||||||
const wTime = ns.getWeakenTime(values.target);
|
|
||||||
const gTime = wTime * 0.8;
|
|
||||||
const dataPort = ns.getPortHandle(ns.pid);
|
|
||||||
dataPort.clear();
|
|
||||||
|
|
||||||
const pRam = ramNet.cloneBlocks();
|
|
||||||
const maxThreads = Math.floor(ramNet.maxBlockSize / 1.75);
|
|
||||||
const totalThreads = ramNet.prepThreads;
|
|
||||||
let wThreads1 = 0;
|
|
||||||
let wThreads2 = 0;
|
|
||||||
let gThreads = 0;
|
|
||||||
let batchCount = 1;
|
|
||||||
let script, mode;
|
|
||||||
/*
|
|
||||||
Modes:
|
|
||||||
0: Security only
|
|
||||||
1: Money only
|
|
||||||
2: One shot
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (money < maxMoney) {
|
|
||||||
gThreads = Math.ceil(ns.growthAnalyze(values.target, maxMoney / money));
|
|
||||||
wThreads2 = Math.ceil(ns.growthAnalyzeSecurity(gThreads) / 0.05);
|
|
||||||
}
|
|
||||||
if (sec > minSec) {
|
|
||||||
wThreads1 = Math.ceil((sec - minSec) * 20);
|
|
||||||
if (!(wThreads1 + wThreads2 + gThreads <= totalThreads && gThreads <= maxThreads)) {
|
|
||||||
gThreads = 0;
|
|
||||||
wThreads2 = 0;
|
|
||||||
batchCount = Math.ceil(wThreads1 / totalThreads);
|
|
||||||
if (batchCount > 1) wThreads1 = totalThreads;
|
|
||||||
mode = 0;
|
|
||||||
} else mode = 2;
|
|
||||||
} else if (gThreads > maxThreads || gThreads + wThreads2 > totalThreads) {
|
|
||||||
mode = 1;
|
|
||||||
const oldG = gThreads;
|
|
||||||
wThreads2 = Math.max(Math.floor(totalThreads / 13.5), 1);
|
|
||||||
gThreads = Math.floor(wThreads2 * 12.5);
|
|
||||||
batchCount = Math.ceil(oldG / gThreads);
|
|
||||||
} else mode = 2;
|
|
||||||
|
|
||||||
// Big buffer here, since all the previous calculations can take a while. One second should be more than enough.
|
|
||||||
const wEnd1 = Date.now() + wTime + 1000;
|
|
||||||
const gEnd = wEnd1 + values.spacer;
|
|
||||||
const wEnd2 = gEnd + values.spacer;
|
|
||||||
|
|
||||||
// "metrics" here is basically a mock Job object. Again, this is just an artifact of repurposed old code.
|
|
||||||
const metrics = {
|
|
||||||
batch: "prep",
|
|
||||||
target: values.target,
|
|
||||||
type: "none",
|
|
||||||
time: 0,
|
|
||||||
end: 0,
|
|
||||||
port: ns.pid,
|
|
||||||
log: values.log,
|
|
||||||
report: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// Actually assigning threads. We actually allow grow threads to be spread out in mode 1.
|
|
||||||
// This is because we don't mind if the effect is a bit reduced from higher security unlike a normal batcher.
|
|
||||||
// We're not trying to grow a specific amount, we're trying to grow as much as possible.
|
|
||||||
for (const block of pRam) {
|
|
||||||
while (block.ram >= 1.75) {
|
|
||||||
const bMax = Math.floor(block.ram / 1.75)
|
|
||||||
let threads = 0;
|
|
||||||
if (wThreads1 > 0) {
|
|
||||||
script = "S4tWeaken.js";
|
|
||||||
metrics.type = "pWeaken1";
|
|
||||||
metrics.time = wTime;
|
|
||||||
metrics.end = wEnd1;
|
|
||||||
threads = Math.min(wThreads1, bMax);
|
|
||||||
if (wThreads2 === 0 && wThreads1 - threads <= 0) metrics.report = true;
|
|
||||||
wThreads1 -= threads;
|
|
||||||
} else if (wThreads2 > 0) {
|
|
||||||
script = "S4tWeaken.js";
|
|
||||||
metrics.type = "pWeaken2";
|
|
||||||
metrics.time = wTime;
|
|
||||||
metrics.end = wEnd2;
|
|
||||||
threads = Math.min(wThreads2, bMax);
|
|
||||||
if (wThreads2 - threads === 0) metrics.report = true;
|
|
||||||
wThreads2 -= threads;
|
|
||||||
} else if (gThreads > 0 && mode === 1) {
|
|
||||||
script = "S4tGrow.js";
|
|
||||||
metrics.type = "pGrow";
|
|
||||||
metrics.time = gTime;
|
|
||||||
metrics.end = gEnd;
|
|
||||||
threads = Math.min(gThreads, bMax);
|
|
||||||
metrics.report = false;
|
|
||||||
gThreads -= threads;
|
|
||||||
} else if (gThreads > 0 && bMax >= gThreads) {
|
|
||||||
script = "S4tGrow.js";
|
|
||||||
metrics.type = "pGrow";
|
|
||||||
metrics.time = gTime;
|
|
||||||
metrics.end = gEnd;
|
|
||||||
threads = gThreads;
|
|
||||||
metrics.report = false;
|
|
||||||
gThreads = 0;
|
|
||||||
} else break;
|
|
||||||
metrics.server = block.server;
|
|
||||||
const pid = ns.exec(script, block.server, { threads: threads, temporary: true }, JSON.stringify(metrics));
|
|
||||||
if (!pid) throw new Error("Unable to assign all jobs.");
|
|
||||||
block.ram -= 1.75 * threads;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fancy UI stuff to update you on progress.
|
|
||||||
const tEnd = ((mode === 0 ? wEnd1 : wEnd2) - Date.now()) * batchCount + Date.now();
|
|
||||||
const timer = setInterval(() => {
|
|
||||||
ns.clearLog();
|
|
||||||
switch (mode) {
|
|
||||||
case 0:
|
|
||||||
ns.print(`Weakening security on ${values.target}...`);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ns.print(`Maximizing money on ${values.target}...`);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ns.print(`Finalizing preparation on ${values.target}...`);
|
|
||||||
}
|
|
||||||
ns.print(`Security: +${ns.formatNumber(sec - minSec, 3)}`);
|
|
||||||
ns.print(`Money: \$${ns.formatNumber(money, 2)}/${ns.formatNumber(maxMoney, 2)}`);
|
|
||||||
const time = tEnd - Date.now();
|
|
||||||
ns.print(`Estimated time remaining: ${ns.tFormat(time)}`);
|
|
||||||
ns.print(`~${batchCount} ${(batchCount === 1) ? "batch" : "batches"}.`);
|
|
||||||
}, 200);
|
|
||||||
ns.atExit(() => clearInterval(timer));
|
|
||||||
|
|
||||||
// Wait for the last weaken to finish.
|
|
||||||
do await dataPort.nextWrite(); while (!dataPort.read().startsWith("pWeaken"));
|
|
||||||
clearInterval(timer);
|
|
||||||
await ns.sleep(100);
|
|
||||||
|
|
||||||
money = ns.getServerMoneyAvailable(values.target);
|
|
||||||
sec = ns.getServerSecurityLevel(values.target);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// I don't actually use this anywhere it the code. It's a debugging tool that I use to test the runtimes of functions.
|
|
||||||
export function benchmark(lambda) {
|
|
||||||
let result = 0;
|
|
||||||
for (let i = 0; i <= 1000; ++i) {
|
|
||||||
const start = performance.now();
|
|
||||||
lambda(i);
|
|
||||||
result += performance.now() - start;
|
|
||||||
}
|
|
||||||
return result / 1000;
|
|
||||||
}
|
|
||||||
1
local/path/home/ServerRouteList.txt
Normal file
1
local/path/home/ServerRouteList.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"home":{"n00dles":{"nectar-net":{"neo-net":{"computek":{"summit-uni":{}}}}},"foodnstuff":{"zer0":{"silver-helix":{"the-hub":{"rothman-uni":{"millenium-fitness":{}}},"netlink":{"zb-institute":{"alpha-ent":{"galactic-cyber":{}}}},"johnson-ortho":{},"crush-fitness":{}}},"max-hardware":{"phantasy":{},"omega-net":{"avmnite-02h":{"syscore":{"rho-construction":{},"aevum-police":{"global-pharm":{"omnia":{"defcomm":{},"solaris":{}}}}},"catalyst":{},"I.I.I.I":{"lexo-corp":{"aerocorp":{"deltaone":{"icarus":{"infocomm":{"run4theh111z":{"helios":{}}},"taiyang-digital":{"titan-labs":{"vitalife":{"omnitek":{"nwo":{},"powerhouse-fitness":{"fulcrumassets":{},"The-Cave":{}}}}}},"zb-def":{"microdyne":{}}},"zeus-med":{}},"unitalife":{"univ-energy":{"nova-med":{"applied-energetics":{"fulcrumtech":{"4sigma":{},".":{"b-and-a":{"ecorp":{}}}},"stormtech":{"kuai-gong":{"blade":{},"clarkinc":{"megacorp":{}}}}}}}}},"snap-fitness":{}}}}}}},"sigma-cosmetics":{"CSEC":{}},"joesguns":{},"hong-fang-tea":{},"harakiri-sushi":{},"iron-gym":{},"darkweb":{},"pserv-01":{},"pserv-02":{},"pserv-03":{},"pserv-04":{},"pserv-05":{},"pserv-06":{},"pserv-07":{},"pserv-08":{},"pserv-09":{},"pserv-10":{},"pserv-11":{},"pserv-12":{},"pserv-13":{},"pserv-14":{},"pserv-15":{},"pserv-16":{},"pserv-17":{},"pserv-18":{},"pserv-19":{},"pserv-20":{},"pserv-21":{},"pserv-22":{},"pserv-23":{},"pserv-24":{},"pserv-25":{}}}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { getCracks, scanServerList, findBestTarget, crackingAndRooting, copyAndRunScript, purchaseAndUpgradeServers } from "/RamsesUtils.js";
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
const funnyScript = ["batch.js", "Ramses-grow.js", "Ramses-weaken.js", "Ramses-hack.js"];
|
|
||||||
//write function to purchase scripts from tor network and rerun getCracks() then recrack and reroot
|
|
||||||
let cracks = {};
|
|
||||||
cracks = getCracks(ns);
|
|
||||||
let maxPorts = Object.keys(cracks).length;
|
|
||||||
scanServerList(ns);
|
|
||||||
let manualTargetOverride = "";
|
|
||||||
if (ns.getHackingLevel() < 200) {
|
|
||||||
manualTargetOverride = "n00dles";
|
|
||||||
};
|
|
||||||
|
|
||||||
findBestTarget(ns, 999, maxPorts, ns.getHackingLevel(), manualTargetOverride);
|
|
||||||
let bestTarget = ns.read("bestTarget.txt")
|
|
||||||
|
|
||||||
ns.tprint("Best Target: " + bestTarget);
|
|
||||||
ns.tprint(Object.keys(JSON.parse(ns.read("serverList.txt"))).length);
|
|
||||||
crackingAndRooting(ns, cracks, funnyScript, true);
|
|
||||||
ns.exec(funnyScript[0], "home", 1, JSON.parse(bestTarget).serverName, 500, true);
|
|
||||||
let reset = ns.args[0];
|
|
||||||
ns.print(reset);
|
|
||||||
if (reset === true) {
|
|
||||||
ns.tprint("reset === true")
|
|
||||||
findBestTarget(ns, 999, maxPorts, ns.getHackingLevel(), manualTargetOverride);
|
|
||||||
let serverList = JSON.parse(ns.read("serverList.txt"));
|
|
||||||
for (const [name, entry] of Object.entries(serverList)) {
|
|
||||||
|
|
||||||
copyAndRunScript(ns, funnyScript, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*let serverListForFiles = JSON.parse(ns.read("serverList.txt"));
|
|
||||||
for (const [name2, entry2] of Object.entries(serverListForFiles)) {
|
|
||||||
ns.tprint(name2 + " Files: " + entry2.serverFiles)
|
|
||||||
}*/
|
|
||||||
//await ns.sleep(500000);
|
|
||||||
await purchaseAndUpgradeServers(ns);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
72
local/path/home/algorithm.js
Normal file
72
local/path/home/algorithm.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
const sNode = ns.args[0]; // target server
|
||||||
|
|
||||||
|
//logs
|
||||||
|
ns.disableLog("getServerSecurityLevel");
|
||||||
|
ns.disableLog("getServerMoneyAvailable");
|
||||||
|
|
||||||
|
//server info
|
||||||
|
const nMinSec = ns.getServerMinSecurityLevel(sNode);
|
||||||
|
const nMaxCash = ns.getServerMaxMoney(sNode);
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
//timestamp
|
||||||
|
let currentDate = new Date();
|
||||||
|
let ntimeStamp = currentDate.toLocaleTimeString('sw-SV') + " -";
|
||||||
|
|
||||||
|
const nCurrSec = ns.getServerSecurityLevel(sNode);
|
||||||
|
const nCurrCash = ns.getServerMoneyAvailable(sNode);
|
||||||
|
|
||||||
|
ns.print(ntimeStamp + "---------------------------------------------------------------");
|
||||||
|
ns.print("Cash: " + (Math.floor(nCurrCash * 1000) / 1000) + " / " + nMaxCash);
|
||||||
|
ns.print("Security: " + (Math.floor(nCurrSec * 1000) / 1000) + " / " + nMinSec);
|
||||||
|
|
||||||
|
if (nCurrSec > (nMinSec + 1)) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getWeakenTime(sNode);
|
||||||
|
let nWeakTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sWeakTime = nWeakTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Weakening " + sNode + " Estimated complete at " + sWeakTime);
|
||||||
|
|
||||||
|
//run weaken
|
||||||
|
await ns.weaken(sNode);
|
||||||
|
//ns.spawn(sWeakenScript, {threads: 1, spawnDelay: 0});
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
else if (nCurrCash < (nMaxCash * 0.9)) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getGrowTime(sNode);
|
||||||
|
let nGrowTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sGrowTime = nGrowTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Growing " + sNode + " Estimated complete at " + sGrowTime);
|
||||||
|
|
||||||
|
//run grow
|
||||||
|
await ns.grow(sNode);
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getHackTime(sNode);
|
||||||
|
let nHackTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sHackTime = nHackTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Hacking " + sNode + " Estimated complete at " + sHackTime);
|
||||||
|
|
||||||
|
//run hack
|
||||||
|
await ns.hack(sNode);
|
||||||
|
//await ns.singularity.manualHack();
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
82
local/path/home/ascii/detective.txt
Normal file
82
local/path/home/ascii/detective.txt
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$XX$$XXXXXXX$XXXXXXxxxxXXXXXxxxxXxXXXXXxxxxxXX$XXXXXXXXXXXXXX$$$$$$$$$$$XX$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$X$$$$$
|
||||||
|
$$$$$$$$$$$$$$$$$$$$XXXXX$$XX$XXXXXXXXX$$XXXXXX$XXXXXXXxxxxXXxXXxxxxxxxxxXXxxxxxxXXXXXXXXXXXXXXXXXXXX$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXX$$$$$$$$xx$$$$$
|
||||||
|
$$$XXXX$XX$$X$$$$$$$$$$XX$XXX$$XXXXXXXXX$XXXXXXXXXXXXXXXxxxXXxXXxxxxxxxxxXXxxxx+xxxXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXXX$XX$$$$$X$$XXX$$$XX$$$$$$$$$xxX$$$$
|
||||||
|
XXX..;xX$XX$XX$$$$$$$$$XXXXXX$$XX$XXXXXXXXXXXXXXXXXXXxXxxxxxxxXXxxxxxxxxXXXxxxx+xxxxXXXXxXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$X$XXX$$XXX$$$$$$$$$$$$$$xXX$$$$
|
||||||
|
X$X:..xXXXX$XX$XX$$$$$$XXXXXX$$XXXXXXXXXXXXXXXXXXXXXXXXxxxxxx+xxxxxxxxxxxxxxxxx;x+xXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$XXXXXXXXXX$$$XXXXX$$$$$$XxX$$$$
|
||||||
|
$$XX$XXXXXXXXXXXXX$$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxx++xxxxxxxxxxxxxxxxx;x+++XXXXxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$$XXXXXXXX$$$$$$XXX$X$$
|
||||||
|
$$$X$XX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxx;x;++XXXXxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXX+XXXXXX$$$$$$xXX$X$$
|
||||||
|
XX$X$$X$XXX$XXX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxx+xxxxxXxxxxx;x+;;XXXXxXXXXXXXXXxXXXX+;++xXXXXXXXXXXXxXXXXXXXXXX+xxxXXX$$X$$XXxXXxX$
|
||||||
|
$$$$$$X$XXX$$XX$XXXX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxXXxxx+xx+XXXXXx+x++;;;XXxxxXXXXXXXXXxXXXXx++++XxXXXXXXXXXxXXXXXXXXXXx;xxXXX$$XX$$X+xxXxX
|
||||||
|
$X$X$$X$XXX$$XX$XXXXXXXXXXXXXXXXXXXXXXXXXXX+;:xXXXXXXXXxxxxxxxxXx+++xx+XXXXXx++++;;+XXxxxXXXXxXXxX+xXXX+;;;+xxxxXXXxxXXxXXXxXXXXXXx;xxXXXX$XX$$XxxXXxX
|
||||||
|
$$$$$$$$$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxX$x;+++++xxxxxxxxxx++++x++xXXXX++++++;xXxxxxXXxxXxxxxxxXXX+;;;;xxxxxxxXxXXxxxxxXXXxXXx+xxxxXX$XX$$XxxXXxX
|
||||||
|
$$$$$$$$$XXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXxX$$$$$$xxx++;+;;;;xxx++++xx+xXXXXx++++;;;xxxx+XXxxxxxxxxxXXXx;;:;xx+xxxxxxXXxxxxxXXXxXXxxxxXXXX$XX$XxxxxxXX
|
||||||
|
$$$$$$$$$XXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXxXX$$$$$$$$Xxx;:..:X+xx+xxxxx;+XXXXx+++;;::+xxx+XXxxxxxxxxxxxxxxx;xxx++xxxx+xxx+xxxXXXxXX+;+xxxXX$XXXXXxxxXXx
|
||||||
|
X$XXXX$$$XXXXXXXXXXXXXXXXXXXXXXXXxXxxXXX+xX$$$$$$$$$$$$Xx;;X+xxx+++xxx;xXXXxx+++;;;;+xxxxxxxxxxxx+xxxxx+++;xx++;++xx+xxx+xxxxXXxXX+:xxxXxX$XXx++xXXXX+
|
||||||
|
XXXXXX$$$XXXXXXXXXXXXXXXXXXXXXXXXxxxxXXxXXX$$$$$$$$$$$$$$XX+$xxx+x+xxx+xxXxxx++++++++xxxxxxxxxx++x+xxx+++;;+++;;+++x+xxx+xxxxXX+Xxx+Xxxxxxx+++xXXXxxx+
|
||||||
|
$$$$$$$$$XXXXXXXXXXXXXXXXXXXXxX++xxxxxxXxX$$$$$$$$$$$$$$$$XX$xxxxxxxxx+xxxxxxxxx+xxx+xxx+xxxxxx+++++x+++;;::;++:;;++++xxx+xxxXXx+x+XXXxx+;+xxXXx++;++;
|
||||||
|
$$$$$$$$$$XXXXXXXXXXXXXXXXXXXxXX+xx+++xxX$$$$$$$$$$$$$$$$$$xXxXxxxxxxxxxxxxxxxxx+xxx+xxx+xxx+++++++++++: :;+++xxx+xxxXXxxx+Xx+++xxXXx+;;;;;++x
|
||||||
|
$$$$$$$$$$$$XXXXXXXXXXXXXXXXXxXXXXx++;;;XX$$$$$$$$$$$$$$$$$XXxxxxxxxxxxxxxxxx+x++xx++xx+;++++++;;;;+++;: .;+++x+x+xxxxXx+++XxxXXXx+;;:;::;xXx+
|
||||||
|
$$$$XX$$XXX$XXXXXXXXXXXXXXXXXxXXXXxXX+++x+xX$$$$$$$$$$$$$$$$x+xxxxxxxxx+xxxxx+++++++;+++;+++++;;;;;;+;;; ..;;+;x++++xxxxxxXx+XXx++;;;::+Xx+x$x+
|
||||||
|
$$$$$X$$X$$$XXXXXXXXXXXXXXXXXxXXXXXXXX$xxx+xxX$$$$$$$$$$$$$$xXxx++xxxxx+xxxxx+++++++;+++;+;+++;;;;;;;;;:: ::;++;x++++xxxxxxxx;xX+;;;+xXXXX+;x$xx
|
||||||
|
XXX$$XX$X$$$XXXXxxXXXXXXXXXXXXXXXXXXXX$X$XxxxxxX$$$$$$$$$$$$$$$Xxx+;x+x+xxxxx;++; :+++;;;;;;;;::;;;;;;;. :::;++;+++xxxxxxx+;x+xX+xXXXXXXXXXxxXx+
|
||||||
|
XXXX$XXXX$$XXXXXxxXXXXXXXXXXXXXXXx;$$X$$$$$$XXxXxX$$$$$$$$$$$$$$XXXxx+x+xxxxx;+++. :;+;:;;;;:::::;;;;;;;;;;+;:;;:++++xxxxx++;xX+;Xxx+;+xXXXXXx++x++X;
|
||||||
|
XXXXXXXXXXXXXXXXXxxXXXXxXXXXXXXXx;xXX$X$$$XXXX$$$XxXXX$$$$$$$$$$Xxx+x+x+xxxxx++++ .;;;:::::...::;;;;;;;;:+++;;+;++++x+;;;+x++xxXxx:;++xxXXXx+;;x:;X;
|
||||||
|
XXXXXXx+XXXXXXXXXx+XXXxxXXXXXxx;+:++$X$XXX$XXXXX$$$$$$$$$$$$$XXxxxx+xxx+xxxxx++;; :;:..:.. ..::;;;;;;++++x++++;++++++++++xXXxxXXx;+xxxxxXXx;+XX;:X:
|
||||||
|
XXXXX+;::;xXXXXXXxxXXXxxXXXXX:;++:x+$X$XXXXXXXXXXX$XX$$$Xxxxxxxxxxxxxxxxx++++++;;;;:::::.. ..:;;;;;;++++xx+++;+++++xxxxxxxXxxxXX;+x+;.:xXxx++X+;X;
|
||||||
|
XXXXXx+x;+xXXXXXXX+XXXXxXXx+:;++x;x$$X$XXXXXXXXXXXXXXX$xx+x+xxxxxxxxx+xxx++++++;;;;:;:. ..::;;;+;+;++xx++x;++xxxxxxxxxxXXXXXX;.;+; :x+. .;X;
|
||||||
|
XXXXXXX+xxxXXXXXXX+XXxx;;x+ ;+x+X$X$$$XXXXXXXXXXXXXX$Xx+xxxxx+x++++;+xx++;.++;;;;::.. ..::;;;;+++++Xx++x;xxxxxxxxXxXXXXXXXx;.:+: ;:: :X+
|
||||||
|
$XXXXxx;+xxXXXXXXx+;+++;++;++;+xXxX$$X$$$$XXXXXXX$XXX$$$Xx+xxx+++++++;+xx++++++;;;:::::. .::;;;;++++++Xx++++xxxxxxxxXXXXXXXXXx;..+; . ;Xx
|
||||||
|
XXXXXxx;++xXXXx++++:;::;:++xxxxxXXX$$XX$$$$$XXXXXXXX$$$$$XXx+xxx+++++++xx++++;::;;;;;:::. .. ..::;;;+;+;++++XXx++xxxxxxxxxXXXXxXx;;:::.+; .;: :+Xx
|
||||||
|
XXXXXxx+++xX+;++;;::::;;xxxXxXXXXXX$$$XXXX$$$XXXXXXX$$$$$$XxX+x+++++xxxxx+;;;;++;;;;;:;:::::.:::;;;;;;;+++++XXx++xxxxxxxxxx+;::++:;++: ++ ;++xXXx+XX
|
||||||
|
xxXXXxXXXXxxXx++x+xx+++xXxXXXxx++;x$$$$XXXXX$$$$$$XX$$$$$$$$xX+++++++xxxx+;;+++++;;;;;;;;;;;:;:;;+;+++++++++XXx++xxxxxx;. ++:+xXxxxxx;;++ ;XXXXXXxXX
|
||||||
|
;+:;++XXXxxXXXXxxXxXxXXXXxxx;;+xX$$$$$$$XXXXXX$$$XXX$$$$$$$$XX$Xx;+++xxx++;+++++++;+;;;+;;;+;;;;;++++;+;++++XXxx+xxxxx+;++xx+xXXXxxxx+;xx; +XXXXxxxXX
|
||||||
|
:; +XXxXXXXXXxXXXXXXXXXX+x$$$X$XxX$X$$XXXXXX$$$$XX$$$$$$$$$xxXxX+++++++++++++x+;;;;;+;++++;+++;;+++;++++;;xXxxxxxxxxxxXXxX+++xx+++x++xx+.:+XXXXXXxXX
|
||||||
|
:;+++;xXXXXXX$$XXX$$$$XXX$XX$$Xx;;xX$$$$$XXXX$$$$X$X$$$$$$$$$X$xXxx++++++x++++xx+;;;;;+;+++x;;;+;+++++++++;;xx+:;xxxxXxxxxXx+++xx++++x+xxx;;xXXXXXXXXX
|
||||||
|
:+x+xxxxXXXXXX$XXX$$$$$XXX$$$$XXxXxXX$$$$$XX$$$$$$X$$$$$$$$$$$$X$xX++++++x++++++;;;;;;+++++x+++++++x++++:: .X;.;xxxXXxxxxXxx++xx++;+xxXxx;;xXXXXXXXXX
|
||||||
|
:+xx++xXXX$XX$$$XX$$$$$XXx$$$X$$$Xx+x$$$$$$XX$$$$$X$$$$$$$$$$$$XXXX+++++++++++;;;;;;;;+++++x++++++xxxxx; . :X+.;xxxXXxxxxxx+++xx;;;+xxXXX++xXXXXXXXXX
|
||||||
|
xxXxx+XXX$$$$$$$$X$$$$$$$X$$$$$XXX$$XX$$$$$$XX$$$$XX$$$$$$$$$$XXXXX;;+;;;+x+xx;;;;;;;;;++++xx++++xxxxxXX+;: ;X+:;xxxxXxxxxxxx++xx;;;+xxXXXx+xXXXXXXXXX
|
||||||
|
xxxxxxXX$$$$$$$$$X$$$$$$$$$$$$$XX$X$$$$$$$$$$$$$$$$X$$$$$$$$$$XXX$$;:;;;;+x+xx;:::::;;;;;;+xx+++++xxxxXXXx+:+Xx:;xxxxXXxxxx+;::;x;;;;+xXXXxxxXXXXXXXXX
|
||||||
|
xxXxxXXXXX$$$$$$$XX$$$$$$$$$$$$XXXX$$$$$$$$$$$$$$$$X$$$$$$$$$XXXXXXX;;;;;+xxxx;..::::;;::;+xx++++++x+xXXx++;xXX;+xxxxXXxxxxx+; :x;;x++xXXXXxXXXXXXXXXX
|
||||||
|
xxXXXXXXXX$$$$$$$X$$$$$$$$$$$$$$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$XXxXXX$+;:::;xxxx;.. ..:;;;;:;xx++++++xXXXXXXx+XXXx+xxxxxXxxxxx;; ;x+xxxxXXXXXxXXXXXXXXX$
|
||||||
|
.$XXXxX$XXX$$$$$$X$$$$$$X$$$$X$XXX$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$X$XX+ :::;xxxx;....:;: ::xx+;;+xXXXXXXXXXXXXXxxxxxXXXxxxxx++++xxxxx+xxXXXxXX$XXXXXXX
|
||||||
|
xX$XXXXXXXxX$$$$$X$$$$$$$$$$$$X$XXX$$$$$$$$$$$$$$$$$$$$$$$$$$XXXX$XXx .: +xxx; ++::. ;;xx+;;+xXXXXXXXXXXXXXXXXxxXXXXx+xx++++xxxx++xXXXXXXX$$XXXXXX
|
||||||
|
:XXXXXX$XxX$$$$$XX$$$$$X$$$$$$$XX$X$$$$$$$$$$$$$$$$$$$$$$$$$$$XXX$XXx: +xxx+. +x;:: ;;xx++:xXXXXXXXXXXXXXXXxxXXXXXxxxxXxxxxxx++++xXXXXXXX$$XXXXXX
|
||||||
|
;:XXXX$X$$XxX$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$X$XXXXXXX. +xxx+;+xxx+:. +xxxx+;xXXXXXXXXXXXXXXXxxxxxXxxxxxXxxxXxxxxxxxXXXXXXX$$XXXXXX
|
||||||
|
$+XXX$$$$$$XxX$$$$$$$$$$$$$$$$$$$XXX$$$$$$$$$$$$$$$$$$$$$$$$$$$XXX$$X$;...+xxx+;xxx+x;: ;+xxx+;XXxXXXXXXXXXXXXXXxxxxxx+;+xX$XXXXXXXXXxXXXXXX$XX$X$$X$
|
||||||
|
$XXX$$$$$$$XXXX$$$$$$$$$$$$$$$$$$X$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$XX$$XX+:..+xxx+;xxx+x+. ;+xxx+;XXxXXXXXXXXXXXXXXxxXXXXXX$XXXXXXXXXXXXxXXXXXX$XXXXXX$X
|
||||||
|
$$X$$XXXXxXX$$X$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$XX$$$$$$$$$$$$$$X$X$$$$$Xx;.+xxxx+xxxxxx;;;++xxx+;XxxXXXXXXXXXXXXXXXXXXXxxXXX$X$XXXXXXXXxXXXXXXxXX+xxxxX
|
||||||
|
$xXXxxxxXX$$$X$X$$$$$$$$$$$$$$$$$$$$$X$$$$X$$$X;X$$$$$$$$$$$$$$$X$$$$$$X$+;xxxx+xxxxxx+;++xxxx++xxXXXXXXXXXXXXXXXXXXXXXXXX$XXX$$$$X$XXxxxxxxXXXXxX$$$$
|
||||||
|
$XxxXX$$x++xXX++xxx+X$$$$$$$$$$$$XX$$XX$$$XX$$$$x$$$$$$$$$$$$$$$X$$$XXXxxX+xxxxx+xx+xxx+++xxxxxxxxxXXXXXXXXXXXXXX$X$$XXXXX$$$$$XXXXXX$xXXXXXXX$$$$$$$$
|
||||||
|
$XxX$X+++;;xXXXXx++xXX;xxXX;+;;:+;x++x+++X$::;:;;;;::x$$$$$$$$$$$$$XX$X+$X+xxxxxxxx;+xx+;+xxxxxxxxxXXXXX$XXXXXXXXX$$$XXXXXx$$$$$$$$$XXxXXXX$$XXXXX$$$$
|
||||||
|
XX$$$Xx+X$X$XXx+xXXXxx++xX+x+.:::;;;::;+x. :xxXXXx+$$$$$$$$$$$$Xxx+XXXXxxxxxxx+;;+x+;;xXxXx++xxXXXXX$$XXXXXX$$$$$$$XXXX$$$$$$$X$xXxXXXXXXXXXXX$$$$
|
||||||
|
X$$$$$$$$$XxxxXXXX$xXXXXx+xx+;:;;+;;;;x;:+;++xxXxx+++XXx$$$$$$x+++xxXXxxXXx+x+++xx++xxxxxxxXXXXxxxxXXXXXX$XXXXXXXX$$$$$$$$$$$$$$$XXXXXxXXXX$$XXXXX$$$$
|
||||||
|
$$$$X$$$$$XX$$$$$XxX$$XXxxxxxxxX$XxxxXx+;;x+;;;++++XXxXx$$$$Xx++;:::::::+xxXXXXXxxxxxXXXx;+xxxXXXXXXXXXXX$XXXXXXX$$$$$$$XXX$$$$$$XXXXXXX$$$$$$$$$X$$$$
|
||||||
|
$$XX$$$$$$$$$$$$xx$$$$XXXXXxXXX$XXXXXXXxxx;++xXXXXXX$$XXXx+;;;:.. :xXXXXxxxxx+xxxxxxXXXXXXXx++: ;XX+xX$XXXXXXXXXXXXXXXXX$$$$$$$XxxXXXxxXXXX$$$$$$$$$
|
||||||
|
$X$$$$$$$$$$$$$XX$X$$$$$$$$XXXX$$XXXXX$XXXXxxxxxxXXx+:...::;;++xxxxXXXXXXX++xxxxxxXxXxxxx++++++xxXXXXXXXXXx+..:;;xxXX+:.+++XX$$$$XXxxxxXXxxXXXxXXXXXXX
|
||||||
|
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XX$XXXXx+;;;+xxxXXXXXXX$XXXXXXxXXXXXXxxxxxxxx++;:... .:;+xXX++XXXXXXX$$XXXxx++:+xxXxXXXXXXXXXXxXXxxxXxxXXXXXX
|
||||||
|
$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$X$$X+xXXX$$$$$$$$$$$$$$$XxXXxXXXXXXx::::;;:;;;;. . :xXXXxxx+xx++xXxXX$$$$$$$$XxxXX$$XXX$$$$$$$$$$$$$
|
||||||
|
$$$$X$$$$$$$$$$$$$$$$$$$$X$$$$XX$$$$$X$$$$X$$$$$$X$$$$$$$$$$$$$XxXXXXX$$xxxxXxx+x;+++xxx;x +:: ... ;XXXXXX$$XXxXXXXXXXxxXXXX$$XXXX$$XX$$$$$$$$$$XX
|
||||||
|
$$$$xxXXXX:xXX$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$X$xx+.:. ;;;;;;::. . .. :;::xxxx;++XXX$X$$$$$$$$XX+xX+xXXXX$$$$$$$$$$$Xx$X$x$
|
||||||
|
$$$$xXXXXX;+XXX$$$$$$$$$$$$$$$$$$$$$$$$$$$XX$$X$$$$X$$$$$$$$$$$$$Xx;;+;:::;;+xXXXxXXXXxxxxXXXXXX+x;+x+;+;;;;;..+xxxxXXXXXXXX$$$XXXXxXXXXX$X$$$$$$X+x+:
|
||||||
|
$$$$XXXXXXXXXXX$$$$$$$$$$$$$$$$$$$$$$$$$$$XX$$$$$$X$$$$$$$$$$$$$$X$x+++xx+++++; +;xxx+:xx;:::..xxxxxxXXXXXXXX$X$$$$$$$$$$$xxXXXXXXXXXXxX$XX$$$$$$$$$XX
|
||||||
|
$$$$$$XXXXXXXXX$$$$$$$$$$$$$$$$$$$X$$$$$$$XX$$$$$$$$$$$$$$$$$$$$$X$::::;++xxXX; ;+XxXXxXx; .+xxxx;xxXXXXXXXXXXxXXXxxxx++xXXxXXXXX$XXX$$$$$$$$$$Xxx+::
|
||||||
|
$X$$$XXXXXXXXXX$$$$$$$$$$$$$$$$$$XX$$$$$$$XX$$$$$$$$$$$$$$$$$$$$$XX+;;:...:;:xx:+xxxXXXXXXXXxxxxxXXxXXXXXXXXXx::;x;.::;x+xXXXXXX$XxxXXXXXX$$X$$$XX+;xX
|
||||||
|
$XXXxXxXX$$$xxX$$$$$$$$$$$$$$$$$$$X$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$X$xxxXXxx;;;XXXxxXXXXXXXXXXXXXXXXXXXXXXXXXX$$$$XXx+:+++xXXX:XXXXXXX;xXX$$$$$$XX$$$xxX
|
||||||
|
$$$$X$XXxxX$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$X$XXXXXXXxxXXxXXXXx+;+XXXXXXXXXXXXXXXXXXXXX$$$$$$$$$$X: +XXXX$x.+X$$$X$xx$$$$$$$x;;xx
|
||||||
|
XXxxX$x+++Xxxx$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$X$XXXXxxXXXXxxXxxXxxxxx+:.;xXxXXXXXXXXXXXXXX$$$$$$$$$$$$$xX$$XXX$X$Xx$$$$$$$$$$$+Xx;x
|
||||||
|
Xx+;X$$XX$XxxX$$$$$$$$$$$$$$$$$$$$$$$XXX$$$XXX$$$$$$$$$$$$$$$$$$$XXXXXXXXXXXXXxxxXXxxXX : .x+XXXXXXXXXXX$X$X$$$$$$$$$$$$$XX$$$$$$$$$$$$$$$$$$$$$x
|
||||||
|
XXxx$$XXXX$XxX$$$$$X$$$$$$$$$$$$$$$X$XXXX$$XXXX$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXX;:+xxxx+++++++ ; .:;+ :x;;;+xXX$$$$$$$$$$$$$$$$$$$$X+$$$$$$$$$$$$$$$$$$
|
||||||
|
Xxx$$XXXXXX$xX$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXx+XX++:..:::;;:. . ..:. ..+ :.;xXX$$$$$$X$$$$$$$$$XXX$$$$$$$$$$$$$$$$$$
|
||||||
|
$X$$Xx++xXXXXX$$$$$$$$$$$$$$$$$$$$$$$$$XXX$$X$X$$$$$$$$$$$$$$$$$$$$$XxXXxxXXXXx;X+;Xx++: ;+:: ::;;::;;::.:++xXXXX+X$$$$$XXXXXX$$XXX$XXX$$XX$XX$XXX
|
||||||
|
xx$$$X$X$X$XX$$$$$$$X$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXxxxxxxxXXXxXXX+;xx+: ;+xx+.;:++;+++;;;;:;X;.;::.++;+XXX+xX$$$$XXXXxxxxxxxx
|
||||||
|
X$X$XXXxX$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$X$$$$$$$$$$$$$$$$$$$$$$$$xxxxxXxXXxXxXXXXxxxx . .:::++ ++xX:;XX+ ;;;;;;;x$x++X$XxxXXXXXxxxxxxxxXxXXX
|
||||||
|
$$xx++;+x$X$X$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXxxXXxXXxXXXXXXXx;:: .;$XxXXXXXx;;:::.:::::::::;;;++++xxXXXXX$$$$$$$$$$$$$
|
||||||
|
$XXXXXxxX$$x$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$XxXXXXxXXXXXXXxx+x:+. : . . :..;Xx;::;++xx+ ::. ...:;x$$$$$$$$$$$$$$$$$$$
|
||||||
|
$$$$$XxX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$xXXxxxxxXXx.XXXXx++x ;x++xx:xXXxX+. :+xX$XX$$$$$$$$$$$$$$$X$XXXXxXX$$$$$$$$
|
||||||
|
$$$$XXXX$$$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$X$$$$$$$$$$$$$$$$$$$$$$$$$xXxXxxx:++ +XXXXXXXX+. .+XXXXXXXX$$$$X:x+++;xxXx +;xxXXX$$x+XxX$X$$$$$$$$$$$X
|
||||||
|
$$$$$xX$X$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XX$X$$$$$$$$$$$$$$$$$$$$$$$$X$$$X$$XXXXXXXXXXXXX: . .+XXXXX$XXXXXX$X$$X;;;+XXxXXXXXXXXXXx++xXXXXXXXXXXXXX$
|
||||||
|
$$X$XXXXX$XXX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXX$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXXXXXXXXXX+: .+xXXX$XXx+++;;+;x::+ . .+:X;+xXXX$$$$$$$XXXXXX$$
|
||||||
|
$$$$$$$$X$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXXXXX$$XXXXx: ;xXxXX$$X+;: ;;;;+. .:+xXXxXXX$$$XXXXX$XXXXXXXXX
|
||||||
|
XXXX$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$$$$$$$XXXXX$$$X$$XX$$$$$$X$+:.:;. ;xx+XX$$Xx++;; .;:x++.+x .+xXXXXXXXX$$$$$$$$$$$$$$
|
||||||
|
$$$$$$$$XXXXX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXxXX$XXxx+;:+.;; +Xxx:.:+$$$$X+. .;+xXxXXXxXX$$$XXXXxxxxXXXXXXXXXXX$
|
||||||
|
XXXX$X$$X$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXxx; XXXxXXXxx..++XX$$+;x .x+XXX$$X+. ..:;;+;.; .;;++xX$X$$$$$$$$$$XX
|
||||||
55
local/path/home/ascii/detective2.txt
Normal file
55
local/path/home/ascii/detective2.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
$$$$$$$$$$$$$$$$$$$$X$$X$X$XXXXXXXXXXxxXXXXxxxxXXXxxxxXXXXXXXXXXXXX$$$$$XX$$$$$$$$$$$$$$$X$$$$$$X$$$
|
||||||
|
$$X$X$$$$$$$$$$XXXXXXXXXXXXXXXXXXXXxXxxXXXxxxxxxxXxxxxxXXXXXXXXXXXXXXXXXXXXXXX$$$$$$$X$$XX$$$$$xx$$$
|
||||||
|
Xx..xXXXX$$$$$$XXXX$$XXXXXXXXXXXXXXxXxxxxxxxxxxxxXxx+xxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$$$X$$$$$XX$$$
|
||||||
|
$XXXXXX$XXXX$XXXXXXXXXXXXXXXXXXXXXXXXxxx+xxxxxxxxxxx+x+xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$$$$XXX$$
|
||||||
|
$$$$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxx++++XXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXxXXX$$$$XXX$$
|
||||||
|
$$$$$$X$XXXXX$XXXXXXXXXXXXXXXXXXXXXXXxxxXXxxxx+xXXXx++;+XxxXXXXXXxXXX+++XXXXXXXXXXXXXXX+xxXX$X$XxxxX
|
||||||
|
$X$$$$XX$XXXXXXXXXXXXXXXXXXXx++xXXXXXxxxxxx++x+xXXX+++;+xxxXXXxXxxxXX;;;xxxXxxXXxXxXXXX+xxXX$X$XxXXX
|
||||||
|
$$$$$$XXXXXXXXXXXXXXXXXXXXXXxX$$Xx+++;;++xx++x+xXXX++;++xxxxxxxxxxxXx;::x+xxxxXxxxxXXXXxxxXX$XXXxxxX
|
||||||
|
$$$$$$XXXXXXXXXXXXXXXXXXXXXxX$$$$$$Xx;::x++xxx++XXx++;;:xxxxxxxxxxxxxx++x++xxxxxxxxXXXx++xxX$XXXxxXx
|
||||||
|
XXXX$$XXXXXXXXXXXXXXXXxXxXxxX$$$$$$$$Xxxxx+x+xx+xxxx+;++xxxxxxx+xxxxx+;++;;+++xxxxxXxXx+xxxXx++xXXX+
|
||||||
|
$$$$$$XXXXXXXXXXXXXXx+xxxxxX$$$$$$$$$$$XXxxxxxxxxxxxx+xx+xxxxxx++++++;;:::;;++xxxxxxx++xXx++xxxx++++
|
||||||
|
$$$$$$$XXXXXXXXXXXXXXXx;;;xX$$$$$$$$$$$XXxxxxxxxxxxxx+xx+x+++++;;+++; :;++x+xxxX++xxxxxx;;;;;xx
|
||||||
|
$$XX$$X$XXXXXXXXXXXXXXXXXx++XX$$$$$$$$$$xxxxxxx+xxx++++++++++++;;;+;;. :;+++++xxxxxxXx+;;;+x+xX+
|
||||||
|
XX$XX$$$XXXxXXXXXXXXXXXXX$$XxxxX$$$$$$$$XXx+++x+xxx+++..;++;;+;;;;;;;: .:;++++xxxx++xx++xXXXXxxX+
|
||||||
|
XXX$XX$XXXXxXXXXXXXXXX+x$X$$$XXXxX$$$$$$$$$XXx++xxx+++ :;;;;;:::;;;;;;;+;;;+++xxx++x++x+++XXXX+x+x+
|
||||||
|
XXXXXXXXXXXxXXXxXXXXx+;xX$$$XXXX$XX$$$$$$XXxx++xxxx++; .;:::...:;;;;;;++++++++++;+xxxxx;+xxxX+;x+++
|
||||||
|
XXXx+;+XXXXxXXXxXXX+++;xX$XXXXXXXXXX$Xxxxxxxxxxxx++++;;;::. ..:;;;+++x++++++xxxxxxxXx+++:;x+:;x+;
|
||||||
|
XXXXXXxXXXXXxXXx+;..;x+X$$XXXXXXXXXXXxxxxxxxxx+xx++++;;;:. .:;;;+++x+++xxxxxxxXXXXX:.+ ;;. ++
|
||||||
|
XXXx+;xxXXXx+++++++++xXX$$$$XXXXXXX$$Xxx++++++;xx++++;;::: .::;;++++xx+xxxxxxxXXXXXx;.+ . +x
|
||||||
|
XXXx+++xXx++;::;+xxxXXXX$XXX$XXXXXX$$$Xxx+x+++xxx+;;;;;;;::.:..:;;;;;+++Xx+xxxxxxxxxx+::;.; .;.;xxx
|
||||||
|
xxxxXXxxX+xxx++xXXXxx++X$$XXXX$$$XX$$$$$Xx++++xxx;;+++;;;;;;;:;;;;++++++Xxxxxxx;:+;;xXxx+;+: :XXXxxX
|
||||||
|
: .+XXxXXXxXXXXXx++xX$XX$$$XXXX$$XX$$$$$XXxx+++x++++++;;;+;;+;;;;++;++++xxxxxxxxxxxxxXxx++x+ ;XXXXxX
|
||||||
|
:;;+xXXXX$XXX$$XX$X$x++XX$$XXX$$$X$$$$$$$XXX++++++++x+;;;+;+++;++++;++;.++;xxxxxxxx+xx++x+xx:+XXXXXX
|
||||||
|
:++xXXXX$$$X$$$$XX$$$XxxX$$$$X$$$X$$$$$$$XXXx+++++++;;;;;++++++++xxx+. :+:xxXXxxxx++x;;+xXx+xXXXXXX
|
||||||
|
xxx+XX$$$$$X$$$$X$$$XX$$X$$$$$$$$$$$$$$$$$XXx;+;+x++;;;;;;++xx++xxxxX+;.++:xxxXxxxx++x;;+xXXxxXXXXXX
|
||||||
|
xxxxXX$$$$$XX$$$$$$$$XX$$$$$$$$$$$$$$$$$$$XXX+;;;xx+;:::;;::+x++++xxXXx;xx;xxxXxxx+;:x;;+xXXxxXXXXXX
|
||||||
|
xXXXXXX$$$$$X$$$$$$$$XX$$$$$$$$$$$$$$$$$$XXXX+:::+xx;. .:;;:;x++++xXXXX+XXxxxxXXxx+;.x+xxxXXxXXXXXXX
|
||||||
|
;XXXXXxX$$$XX$$$$$$$$XX$$$$$$$$$$$$$$$$$$XXXXx ::+xx:.::: .;x+;+XXXXXXXXXxxxxXXxxx++xx+++XXXXX$XXXX
|
||||||
|
:+XXX$Xx$$$$X$$$$$$$$$X$$$$$$$$$$$$$$$$$$$XXXX; ;xx;.++:. :+x+;xXXXXXXXXXXxxXXxxxXxxxx+++XXXXX$XXXX
|
||||||
|
x+XX$$$XX$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$$$XX$Xx..;xx+xxx+. :xxx;XXXXXXXXXXXxxxx++xXXXXXXXxXXXXX$XXXX
|
||||||
|
$XX$$$$XXX$$$$$$$$$$$$XXX$$$$$$$$$$$$$$$$$XX$$X;.;xx+xxxx:.;xxx;XxXXXXXXXXXxxXXXXXXXXXXXXxXXXXXXXxXX
|
||||||
|
$XXxxxXX$X$$$$$$$$$$$$$$$$$$$$X+$$$$$$$$$X$X$$$X+;xxxxxxx+;+xxx+XxXXXXXXXXXXXXxXXX$$$XXX$X++++xxxXXX
|
||||||
|
XXxXXXxxXXxxxXX$$$$XX$$$$X$$XXXX+XX$$$$$$$$$$XXxx+xxx+xxxx;+xxxxxxXXXXXXXXXX$XXXXXX$$X$$XXXXXXX$X$$$
|
||||||
|
XX$Xx+xXXXxxxXx++x+;::;+;;+x:.:+xx+xX$$$$$$$XXxxXXxxxxx++x+;xxx++xXXX$XXXXXX$$XXXX$$$$$$XXXXX$XXX$$$
|
||||||
|
X$$$$$$XxxXXXXXXx+x;:;+;;+;;;;+xx++xXX$$$x++xXxxxx+x+xx++xxxxxXxxXXXX$$XXXXX$$$$$X$$$$XXXXXXXXX$$$$$
|
||||||
|
$$$$$$$$$$$XX$$XXxxX$$XXXxxxx+xx++XXXX$X+;:::::;XXXXxxxxxXX++x++xxXXXXXXXXXX$$$$XX$$$$XXXXX$$$$$$$$$
|
||||||
|
$X$$$$$$$$XX$$$$$$XX$XXXXXXXx+xx+x++;;;;;;++xXXXXx+xxxxxxxxxxxxxxXXxxXXx++++xx++x+xXX$XxxxxxXXXXXXXX
|
||||||
|
$$$$$$$$$$$$$$$$$$$$$$$$X$XXxxxxxXXXX$$$XXXXXXXXx+++++;;;. ::;;;+xxXX+x+xXXXXXXXXxXXXX$X+xXXXXXXXX
|
||||||
|
$$$$$$$$$$$$$$$$$$$XX$$$X$$$X$$$$$$$$$$$$XXXXXXXxxxx;;:;;;++ ;; .. :xXXX$XXXXXXXxXX$$XXX$XX$$$$$$XX
|
||||||
|
$$XxXXx:XX$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$Xxx;;:;+++;;:;:..:. ::;;+;+xxXXXXXXXX+XxXXXXX$$$$$XXXxx
|
||||||
|
$$XXXXXXXX$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$XX++x+++x;;+xx:+;:::+xxxXXXXXXXXXXX$$$XxXXXXXXxX$$$$$$$$X
|
||||||
|
$$$XXXXXXX$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$Xx::.:;+x:.+xXXXx++xxxxxXXXXXxxxx;+XXxxxXXXX$X$$$$$$$x;x;
|
||||||
|
$XXXXX$XXX$$$$$$$$$$$$X$$$$$XX$$$$$$$$$$$$$XX++xx+;xxxxxXXXXXXXXXXXXXXXX$Xxxx++++XxxXXXXxXX$$$$$$X;;
|
||||||
|
$XXXXxx$XX$$$$$$$$$$$$$$$$$$XX$$$$$$$$$$$$$XXXXXXXxXxXX+::x+:+XXXXXXXXXX$$$$$$$xxX$$XxxXXXXX$$$$x++.
|
||||||
|
Xxx$$$$xX$$$$$$$$$$$$$$$$X$$XXX$$$$$$$$$$$$$XXXXXXXXxxXxXX::.. :xXXXXXXXXX$$$$$$$$$$X$$$$$$$$$$$$$$X
|
||||||
|
XXXXXXXXX$$$$$$$$$$$$$$$XXX$$XX$$$$$$$$$$$$$$XXXXXXX++xxx++++: :::;;;+xX$$$$$$$$$$$XXXX$$$$$$$$$$$
|
||||||
|
$$$X+xXXX$$$$$$$$$$$$$$$$$XX$XX$$$$$$$$$$$$$$XxXxXXXxxx++:. +;: .:;::::.;+XX$x$$$$$XXXXXX$$$$$$X$XX
|
||||||
|
XXX+xxX$X$$$$$$$$$$$$$$$$$XX$$$$$$$$$$$$$$$$$$xXXXXxXXxXXxx+: +x+ :+:;;.:..x+++;xXXXXX$$$XXXxxxxx
|
||||||
|
XXX++x$$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXxx+;: :++:;;;+;.;:;;;;;;+++xxxxxxXXXX$$$$$
|
||||||
|
$XXXXX$X$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXXx+;::. ::;;++++++xx+xx++xxxxX$$$$$$$$$$$$$
|
||||||
|
$$XXXX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXxXxx+xXXXXx; .xXXXXXXXx+;;;+X;+;xXX$XXXX$XX$$$$XX
|
||||||
|
$$$XXX$$$$$$$$$$$$$$$$$$$$$$$X$$$$$$$$$$$$$$$$$X$XXXXXXXXXXX:. :xXXXXXXXXXX+;:xxxxxXXxXxxXXXXXXXXXX
|
||||||
|
$$$$$$XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXXXXXXX$XXx: ;xXX$x;. .:;::. :+xxxXXXXX$$$XX$$X
|
||||||
|
XX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXXXX$$XX$$$$Xx;.: :+;X$$X+; :;;+++: :xXX$$XX$$$$$$$$
|
||||||
|
$XXX$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$XXxxXX++XXXXx;.xxx;::.xxX$Xx;::;:x+;::;+xXXXXX$$$$XX
|
||||||
54
local/path/home/ascii/detective3.txt
Normal file
54
local/path/home/ascii/detective3.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▒▓▓▓▒▒▒▒▒▒▒▓▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓
|
||||||
|
▓▒ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▒▒▒▒▒▒▓▓▓▒▒▒░░▓▒▒▓▓▓▓▓▓▒▓▓▓▒░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▒▒▒▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒░░░▒▒▒▓▓▓▒▓▒▒▒▓▓░░░▒▒▒▓▒▒▓▓▒▓▒▓▓▓▓▒▒▒▓▓▓▓▓▓▒▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▒▒░░░░░▒▒▒▒▒▒▒▒▓▓▓▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▒░ ▒▒▒▒▒▒▓▒▒▒▒▓▓▓▓▒▒▒▓▓▓▓▓▓▒▒▒▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▒░ ▒▒▒▒▒▒▒░▓▓▒▒▒░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒░▒▒▒▓▓▓▓▓▒▒▓▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▒▒▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒░░░▒▒▒▒▒▒▒▓▒▓▒░▒▒▒▓▒▒▒▒▓▓▓▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░ ░░░░▒▒▒▒▒▒▒▒▒▒▓▒▒░▒▒▒▒░░▒░
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░ ░░▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒░░░░░▒▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▒░▒░░░░░░░░░░░ ░░░▒▒▒▒▒▒▒▒▒▓▒▒░░░░▒▒▒▓▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒░▒▒▒▒▒▒▒░░ ░▒░░░░░░░░░░░ ░░░▒▒▒▒▒▒▒▒▒▒▒░▒▓▓▓▓▒▒▓▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░ ░░░░░ ░░░░░░░░░░░░░░▒▒▒▒░▒▒░▒▒░▒▓▓▓▓▒▒▒▒░
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▒▓▓▓▓▒░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒░░ ░ ░░░░░░░▒░░░▒▒▒░░░░▒▒▒▒▒░▒▒▒▒▓▒░▒▒░░
|
||||||
|
▓▓▓▒░░░▓▓▓▓▒▓▓▓▒▓▓▓░░▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░ ░░░░░░▒▒░░▒░▒▒▒▒▒▒▒▒▓▒░▒▒ ░▒░ ░▒▒░
|
||||||
|
▓▓▓▓▓▓▒▓▓▓▓▓▒▓▓▒▒░ ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒░▒▒░░░░░░░ ░░░░░▒▒▒▒░▒▒▒▒▒▒▒▓▓▓▓▓ ░ ░░ ░▒
|
||||||
|
▓▓▓▒▒░▒▒▓▓▓▒▒░░░░░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒░▒▒▒░░░░░ ░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▒░ ░ ░▒
|
||||||
|
▓▓▓▒▒░▒▒▓▒▒░░ ░░▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒░░░░░░░░ ░░░░░░▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒ ░ ░ ░ ░▒▒▒
|
||||||
|
▒▒▒▒▓▓▒▒▓▒▒▒▒▒▒▒▓▓▓▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒░▒▒▒▒░░░▒▒░░░░░░░ ░░░░░░░▒▒▒▓▒▒▒▒▒▒░ ░░░▒▓▒▒▒░▒ ▓▓▓▒▒▓
|
||||||
|
░▓▓▒▓▓▓▒▓▓▓▓▓▒░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒░▒▒▒░░▒▒▒░░░░░░░░░░░░░░░▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒░▒░ ░▓▓▓▓▒▓
|
||||||
|
░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░▒▒▒▒▒▒░░░░░░▒░░░░░▒░░▒░ ▒▒░▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒ ▒▓▓▓▓▓▓
|
||||||
|
▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░░▒▒░░░░░░░░░▒▒░▒▒▒▒▒▒ ░ ▒▒▓▓▒▒▒▒░▒▒░░▒▒▓▒░▒▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░░▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▓▒░ ░▒ ▒▒▒▓▒▒▒▒▒▒▒░░▒▒▓▓▒▒▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░▒▒▒░ ░░ ▒▒▒▒▒▒▒▒▓▓▒░▒▒░▒▒▒▓▒▒▒▒░ ▒░░░▒▓▓▒▒▓▓▓▓▓▓
|
||||||
|
▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒▒░ ░░ ░▒▒▒▒▒▒▓▓▓▓▒▓▓▒▒▒▒▓▓▒▒▒░ ▒░▒▒▒▓▓▒▓▓▓▓▓▓▓
|
||||||
|
░▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒ ░▒░░▒▓▓▓▓▓▓▓▓▓▒▒▒▒▓▓▒▒▒▒░▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ░▒▒░ ░░ ▒▒▒░▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▒▒▒▓▒▒▒▒▒▒░▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒░▒▒▒▒ ▒▒▒░▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ░▒▒░▒▒▒▒ ░▒▒▒░▓▒▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓
|
||||||
|
▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒▒▒▒▒▒▒░░░▒▒▒░▓▒▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓
|
||||||
|
▓▓▒▓▓▓▒▒▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒░▒▒▒▒░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▒▒▒▓▓▓▒▒▒▓▒▒▒▒▒░ ░░░░▒▒ ░▒▒▒▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▒▒▒▒▒░░▒░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▒▒▒░ ░░░░▒░░░░▒▒▒░▒▒▓▓▓▓▓▒▒▒▒▓▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▒▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒░▓▓▓▓▓▓▒░ ░▓▓▓▓▒▒▒▒▒▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░░░░░░░▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒░░░▒▒▒▒░▒▒▒▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░▒░░░░░ ░░░▒▒▒▓▓▒▒▒▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒░░ ░░░░░ ░░ ▒▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▒▓▓▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ░░▒▒░░ ░ ░░░░░▒▒▓▓▓▓▓▓▓▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░░▒▒ ░░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒ ▒▒▓▓▓▒░░▒▒▒▒▒▓▓▓▓▓▒▒▒▒░░▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒░
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒░▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒░░░▓▒▒▓▓▓▓▒▓▓▓▓▓▓▓▓▓░░
|
||||||
|
▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▓▒ ▒░ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▒▒░
|
||||||
|
▓▒▒▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▒▓▓ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒ ░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓
|
||||||
|
▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▓▓▒▒▒▒░ ░░ ░ ░▒▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▒▓▓▒▓▓▒▒▒ ▒▒░ ░ ░░ ▒░▒▒░▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒
|
||||||
|
▓▓▓▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ░▒ ░░░▒░ ░ ░░░░░░▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓█
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░ ░░░░▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▓▓█▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▒▓▒▒░▒▓▓▓▓▒░ ▒▓▓▓▓▓▓▓▒░░░░▒▓░░░▒▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▒░ ▒▒▒▒▒▓▓▒▓▒▒▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▓▓▓▒░ ░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▓█▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░ ░░▓▓▓▓▒░ ░░▒░░ ▒▓▓▓▓▓▓██████▓▓
|
||||||
|
▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓█▓███▓▓▓▓███▓▓▓▓▓▓▓▒▒▓▓▒░▓▓▓▓▒░ ▒▒▒░ ▒▒▓▓▓▒░ ░ ▒▒░ ░▒▒▓▓▓▓▓▓▓▓▓▓▓
|
||||||
33
local/path/home/ascii/hacker.txt
Normal file
33
local/path/home/ascii/hacker.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*-%@%: :%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ *@@@= *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ %@@@@@: =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# #@@@@#- =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.-@@#: *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ =#%*+=-. #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%. +%@@@@@@@%. :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# *@@@@@@@@@@@@@@@* %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% @@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@ .%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% :@@@@@@@@@@@@@@@+ =%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ @@@@@@@@@@@@% :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@= #@* #@@@@@@@@@% -+-. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- @@@@@@@*:#@@@@@@@@=+@@@@@+ * .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# @%@@@@@@@@@@@@@@@@@@@@@@@@@=%@@ =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@% -@@@@@+====-----::::.... %@@% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ :==@@@@ =##%%%%%%%%%%%%%%%%%%%%* %@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@= -@@@@@@ *@@@@@@@@@@@@@@@@@@@@@@# %@@@@@* @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@:*@@@@@@@@@@@@@@@@@@@@@@#.%@@@@@== *@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@*:=#%#-. :*%*+@@@@@@@@*: :#@@@@@@@@#=@@@=. ...:%@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#%@@@@@@+@@@@@@@@*. .*@@@@@@@@##%*+=. %@@#@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@%##@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
21
local/path/home/ascii/judge.txt
Normal file
21
local/path/home/ascii/judge.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
______
|
||||||
|
,-~ _ ^^~-.,
|
||||||
|
,^ -,____ ^, ,/\/\/\,
|
||||||
|
/ (____) | S~ ~7
|
||||||
|
; .---._ | | || _| S I AM THE Z
|
||||||
|
| | ~-.,\ | |!/ | /_ LAW! _\
|
||||||
|
( | ~<-.,_^\|_7^ ,| _//_ _\
|
||||||
|
| | ", 77> (T/| _/' \/\/\/
|
||||||
|
| \_ )/<,/^\)i(|
|
||||||
|
( ^~-, |________||
|
||||||
|
^!,_ / /, ,'^~^',!!_,..---.
|
||||||
|
\_ "-./ / (-~^~-))' =,__,..>-,
|
||||||
|
^-,__/#w,_ '^' /~-,_/^\ )
|
||||||
|
/\ ( <_ ^~~--T^ ~=, \ \_,-=~^\
|
||||||
|
.-==, _,=^_,.-"_ ^~*.(_ /_) \ \,=\ )
|
||||||
|
/-~; \,-~ .-~ _,/ \ ___[8]_ \ T_),--~^^)
|
||||||
|
_/ \,,..==~^_,.=,\ _.-~O ~ \_\_\_,.-=}
|
||||||
|
,{ _,.-<~^\ \ \\ () .=~^^~=. \_\_,./
|
||||||
|
,{ ^T^ _ / \ \ \ \ \) [| \oDREDD >
|
||||||
|
^T~ ^ { \ \ _\.-|=-T~\\ () ()\<||>,' )
|
||||||
|
+ \ |=~T ! Y [|() \ ,' / -naughty
|
||||||
58
local/path/home/ascii/noir.txt
Normal file
58
local/path/home/ascii/noir.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
@@@@@@@@@@@@@%@@%%@%###(>{=*<[{%@@%@@@@%{#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@%%#%@%#(^ ~ :<}@@@@@@@@@%@##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@%#{#%%@@@% (#%%@@@@@@@@@@{{%%@@%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@%{{%%#@@@@@( . <}@@@@@@@@@%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@%%}#%#@@@@@@@@. {@@@@@@@%%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@%%#{##%@@@@@@@%{ -] [%@@@@@@@%%%###%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@%###@@@@@@@@@@@%%{ + @%%@@@@@@%%##############%%%%%%%@%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@%#{#%@@@@@@@@@@@@%{({[~+@%%@@@@@%################%%%%%%%@%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@%#{%@@@@@@@@@@@@@@@@%}%#(#%@@@@@@%%##{{{#{{{{{{{{#######%%%%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@
|
||||||
|
@@%#{{%@@@@@@@@@@@@@@@@@@%%%#[%@@@@%%%##{{{{{{{{{{{{{#############%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@
|
||||||
|
@%#}[%@@@@@@@@@@@@@@@@@@@@@@#%%@@@@%%##{{}}}{{{{{{{{{{{{#######%##%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@
|
||||||
|
%#{}#@@@@@@@@@@@@@@@@@@@@@%%#%%@@@%%%{{{}[[}}{{{{{{{{{{{{{########[#%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@
|
||||||
|
{{}%@@@@@@@@@@@@@@@@@@@@@@@%%%%%@@%%#{}}[]][[[[[[[}}{{{{{{{{{{{{{}*}#%%%%%######%%%%%%%%%@@@@@@@@@@@
|
||||||
|
][%%%@@@@@@@@@@@@@@@@@@@@@@%%%@@%%%##}}[[]]][[[[[[[[}}{{{{{{{{{{{{###############%%%%%%%%@@@@@@@@@@@
|
||||||
|
#%%%%%%@@@@@@@@@@@@@@@@@@@@%##%%%##{{[[]]((]]]]][]]][}}}}}}{{{{{{{{{{{{{{{########%%%%%%%%%%@@@@@@@@
|
||||||
|
@%%%%#%%%@@@@@@@@@@@@@@@@@@%##%###{{}]]]())((]]] (][[[[}}}}}{{{{{{{{{{{########%%%%%%%%%%@@@@@@@@
|
||||||
|
#######%%%%%%%%%%%@@@@@@@@%#%{##%#{[])))))<)))((( ([[][[[[}}}}}}}{{{{{{{{{{{{{{##%%%%%%%%%@@@@@@@@
|
||||||
|
{{{#{######%%%%%%%%@@@@%@(##)}{###{[(<<<<<><))))])><]]]]]]][[[[[[[}}}}{}}[{{{{{{{##%%%%%%%%%@@@@@@@@
|
||||||
|
{{{{{{#############%%%%@@@@%{}{{{#}])>>>>>>>><<<))((((( >]]]]]]][[[}}}}}{{{{{####%%%%%%%%@@%%%@@@@
|
||||||
|
{{{{{{{{{{{{{{{}{{####%%%@@%{}{{{}])>^^^^^^^><<<<))))))* =(((]]]][[[[}}}{{{{{####%%%%%%%%@@%%%@@@@
|
||||||
|
{{{{{{{{{{}}}[[[[][}}}}{%%@%}[[[[[(>*++++***^>>>>>>><<<<)( >)([[[[[} >( [[{{{{######%%%%%%%@@@@
|
||||||
|
}}}}}}}}}[[]]]]((((]]()]{%@%[]((](>+~=++++++**^^^^>>>>>><> =->- ))[]][[}]>]{}}{{}{{######%%%%%%%@@@@
|
||||||
|
[[[}[[[[[]]]((()<>^<>+~^({%#<)(())*----~====+++++***^^^>><<<<<)))((]]][[[}}}}{{{{{{######%%%%%%%%%@@
|
||||||
|
]]]]]]]]]]]()>^*+*^*~~=.*[%#- ]( :..:----~====+++**^^>>>><<<))(((]]][[[}}}}}{{{{######%%%%%%%%%@@
|
||||||
|
)(]((((](<<<<<>==+=~-~+ >#{=%@@@. .::::--~~=+++**^^>>><<)))(((]]]][[[}}}{{{{{#####%%%%%%%%%@@
|
||||||
|
)))(((()<>>=--=~~ .*%@%%@%}- .:-~=+++**^^>>><<)))(((]((]][[}}}{{{{{#####%%%%%%%%%@@
|
||||||
|
)<<<)))<<>*+*=- ..~}#%@@{+ ==++**^^^>><<)))(((]]]]][[}}}{{{{######%%%%%%%%%%%
|
||||||
|
))<>><<<>*-. . : #%%%@@# -~=+++*^^^>><<)))(((]]]]][[}}}{{{{######%%%%%%%%%%%
|
||||||
|
)>>>>>>>>>*+~=~:: : }@@@%%@%= *] -++**^^^>><<))((((]][[[[[}}}{{{{{#####%%%%%%%%%@@
|
||||||
|
)^^><<<>>>^~++~ . }@@@@@@%%{{# .**^^^>><<))((((][[[[[[}}}{{{{{#####%%%%%%%%%@@
|
||||||
|
)>>>>><>^^*++*~: . . }%@@@@@@@@@% +*^^>>><<))(((]]][[[[[}}}{{{{{{####%%%%%%%%%%%
|
||||||
|
)<>>>>>>^^**=**++~::-. {#){%%%%%%%* ~+***^^>>><<))(((]]][[[[[}}}{{{{{{####%%%%%%%%%%%
|
||||||
|
()<)<<<>>^^^^^^*+~ ~- . #[ <@@@@@%) =++*^^^>>><<))((]]]][[[[[}}}{{{{{{{{{#%%%%%%%%%%@
|
||||||
|
(((()<<<>>^*^^^^*++~ -:-::{[ (@@@@@@# :---~~==++*^^^>>><<))((((]][[[[[}}}{{{{{{{{{#%%%%%%%%%%@
|
||||||
|
((]))>^>>>^**><^+*+++--=>^%%)]@@@@@@( - .:-~~===+++**^^>><<<))((]]]][[[[[}}}{{{{{{{{{####%%%%%%%%
|
||||||
|
](>^><)>++*+*^^^+=+++=~++)@%(<%@@@@@@]+:::----~=++**+**^^>><<<)))((]]]][[[[}}}}{{{{{{{{{####%%%%%%%%
|
||||||
|
{()^==***-==^~ - :-=**^*}%%(*)}#%@@@@@(-~~~-~===+++*^^^>><<)))))((]]][[[[}}}}{{{{{{{{{{####%%%%%%%%
|
||||||
|
([[(][)^+-: ::~.:=^>>*=[%%(++*)}{{#%%@#[+=++++++**^>>>><<<)))((((]]][[[[}}}}{{{{{{{{###%%%%%%%%%@@
|
||||||
|
<][}[[]((^ -.=++~+*^>><><{@%[^*+>[##%%@@@#(*++****^^>><<<<)))))((((]]][[[}}}}}}{{{{{{{###%%%%%%%%%@@
|
||||||
|
(]{}][})<>=-^)^>)<<<*^<)({@%[^**>[##%%%#}])>***^^^>>><<<)))))((((]]]]][[}}}{{{{{{{{{{{###%%%%%%%%@@@
|
||||||
|
[-}{{}}]*=>)>++]]())<<^)]#@%[+>}{%%#[<<.(())<^*^>>><<<<<)))((((]][[[[}}}}}{{{{{{{##{{{#%%%%%%%%%%%%%
|
||||||
|
<+(^[{[}[>^<^([])(]]]((][#%#()}%##%%{))>(]]((<>*><<<<<<)))))(((]][[[[[[[[}}}}}}}}}}[(]][}}}}}}}}{{{{
|
||||||
|
)*){])}[](+^^]]]>]}[[}]}[#%{)([]]{%%<=><>*+=~. ----~==++++***^>><<<))((((]]]][[[}}]**^><<<))(((]]][
|
||||||
|
+~](})>[[(~*(>)())[[}}[[[#%}<^+~.^#%( >+++++**^^^^***^^^>>^^^>>>>>>>>^^^^+*= -~+*******^>>>
|
||||||
|
+[~<]}]<(]*^*^>>>*<>**+*=]{[>. ]%^ .:---= ....::-:-~~
|
||||||
|
(^*=+==**+:- ~: =}(+ *%> *]]]])<<<<<<<)((((((]]]]](][[][[}[]][}}]]
|
||||||
|
===~- . [(~ (%%
|
||||||
|
=::. [): >} .-~=+*><)((]}}}[}}}}{{{{{{##{{#{#%>
|
||||||
|
. ])= }^ ))[#{#{{{}}}}[[[[]((<<<<<>^^>>><<))<))<<>^^*~:
|
||||||
|
<[] [{(
|
||||||
|
=[]= ]{}
|
||||||
|
^###[ +{{{] .-=*^<<)))(][}}}{%#%%%%%@%%%%%%%@%)
|
||||||
|
[{{}~ <#%%# %%%@@@@@@@@@@@%%%%%%##%%%%%%%%%%%#@%@%%%%%%%%%%%%%#{(
|
||||||
|
~++*+ + -^^*^*- =^^^^^^^^^^*===~~~~~--. :-:::--~:..
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
56
local/path/home/ascii/sonic.js
Normal file
56
local/path/home/ascii/sonic.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.tprint(" ...,?77??!~~~~!???77?<~.... ");
|
||||||
|
ns.tprint(" ..?7` `7!.. ");
|
||||||
|
ns.tprint(" .,=` ..~7^` I ?1. ");
|
||||||
|
ns.tprint(" ........ ..^ ?` ..?7!1 . ...??7 ");
|
||||||
|
ns.tprint(" . .7` .,777.. .I. . .! .,7! ");
|
||||||
|
ns.tprint(" .. .? .^ .l ?i. . .` .,^ ");
|
||||||
|
ns.tprint(" b .! .= .?7???7~. .>r . .= ");
|
||||||
|
ns.tprint(" .,.?4 , .^ 1 ` 4... ");
|
||||||
|
ns.tprint(" J ^ , 5 ` ?<. ");
|
||||||
|
ns.tprint(" .%.7; .` ., .; .=. ");
|
||||||
|
ns.tprint(" .+^ ., .% MML F ., ?, ");
|
||||||
|
ns.tprint(" P ,, J .MMN F 6 4. ");
|
||||||
|
ns.tprint(" l d, , .MMM! .t .. ,, ");
|
||||||
|
ns.tprint(" , JMa..` MMM` . .! .; ");
|
||||||
|
ns.tprint(" r .M# .M# .% . .~ ., ");
|
||||||
|
ns.tprint(" dMMMNJ..! .P7! .> . . ,, ");
|
||||||
|
ns.tprint(" .WMMMMMm ?^.. ..,?! .. .. , Z7` `?^.. ,, ");
|
||||||
|
ns.tprint(" ?THB3 ?77?! .Yr . .! ?, ?^C ");
|
||||||
|
ns.tprint(" ?, .,^.` .% .^ 5. ");
|
||||||
|
ns.tprint(" 7, .....?7 .^ ,` ?. ");
|
||||||
|
ns.tprint(" `<. .= .`' 1 ");
|
||||||
|
ns.tprint(" ....dn... ... ...,7..J=!7, ., ");
|
||||||
|
ns.tprint(" ..= G.,7 ..,o.. .? J. F ");
|
||||||
|
ns.tprint(" .J. .^ ,,,t ,^ ?^. .^ `?~. F ");
|
||||||
|
ns.tprint(" r %J. $ 5r J ,r.1 .=. .% ");
|
||||||
|
ns.tprint(" r .77=?4. ``, l ., 1 .. <. 4., ");
|
||||||
|
ns.tprint(" .$.. .X.. .n.. ., J. r .` J. `' ");
|
||||||
|
ns.tprint(" .?` .5 `` .% .% .' L.' t ");
|
||||||
|
ns.tprint(" ,. ..1JL ., J .$.?` . ");
|
||||||
|
ns.tprint(" 1. .=` ` .J7??7<.. .; ");
|
||||||
|
ns.tprint(" JS.. ..^ L 7.: ");
|
||||||
|
ns.tprint(" `> .. J. 4. ");
|
||||||
|
ns.tprint(" + r `t r ~=..G. ");
|
||||||
|
ns.tprint(" = $ ,. J ");
|
||||||
|
ns.tprint(" 2 r t .; ");
|
||||||
|
ns.tprint(" .,7! r t`7~.. j.. ");
|
||||||
|
ns.tprint(" j 7~L...$=.?7r r ;?1. ");
|
||||||
|
ns.tprint(" 8. .= j ..,^ .. ");
|
||||||
|
ns.tprint(" r G . ");
|
||||||
|
ns.tprint(" .,7, j, .>=. ");
|
||||||
|
ns.tprint(" .J??, `T....... % .. ");
|
||||||
|
ns.tprint(" ..^ <. ~. ,. .D ");
|
||||||
|
ns.tprint(" .?` 1 L .7.........?Ti..l ");
|
||||||
|
ns.tprint(" ,` L . .% .`! `j, ");
|
||||||
|
ns.tprint(" .^ . .. .` .^ .?7!?7+. 1 ");
|
||||||
|
ns.tprint(".` . .`..`7. .^ ,` .i.; ");
|
||||||
|
ns.tprint(".7<..........~<<3?7!` 4. r ` G% ");
|
||||||
|
ns.tprint(" J.` .! % ");
|
||||||
|
ns.tprint(" JiJ .` ");
|
||||||
|
ns.tprint(" .1. J ");
|
||||||
|
ns.tprint(" ?1. .' ");
|
||||||
|
ns.tprint(" 7<..% ");
|
||||||
|
|
||||||
|
}
|
||||||
298
local/path/home/autoexec.js
Normal file
298
local/path/home/autoexec.js
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
|
||||||
|
import { purchaseServers, listPurchasedServers, getSetting } from "myLibrary.js";
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
|
||||||
|
ns.disableLog("ALL");
|
||||||
|
|
||||||
|
//host and script info
|
||||||
|
const sThisRunner = ns.getHostname();
|
||||||
|
const sThisScript = ns.getScriptName();
|
||||||
|
const nThisPID = ns.pid;
|
||||||
|
|
||||||
|
// Custom color coding.
|
||||||
|
const cCyan = "\u001b[36m";
|
||||||
|
const cGreen = "\u001b[32m";
|
||||||
|
const cRed = "\u001b[31m";
|
||||||
|
const cReset = "\u001b[0m";
|
||||||
|
|
||||||
|
//open log for this script
|
||||||
|
ns.tail(nThisPID, sThisRunner, ns.args);
|
||||||
|
|
||||||
|
//scripts
|
||||||
|
const sGangScript = "gang/auto-gang2.js";
|
||||||
|
const sServerLister = "serverlister.js";
|
||||||
|
const sServerListFile = "serverList.txt";
|
||||||
|
const sBestServerFile = "bestTarget.txt";
|
||||||
|
const sBackdoorScript = "backdoor.js";
|
||||||
|
|
||||||
|
//settings
|
||||||
|
const nRefreshFrequency = 1000; //time in ms
|
||||||
|
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
|
||||||
|
await ns.sleep(100);
|
||||||
|
let oBestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
|
let sBestTarget;
|
||||||
|
while (true) {
|
||||||
|
ns.clearLog();
|
||||||
|
|
||||||
|
//Home Computer
|
||||||
|
let nHomeMaxRAM = ns.getServerMaxRam("home");
|
||||||
|
let nHomeUsedRAM = ns.getServerUsedRam("home");
|
||||||
|
let nHomeFreeRAM = nHomeMaxRAM - nHomeUsedRAM;
|
||||||
|
ns.print("Home Free RAM = " + cCyan + Math.floor(nHomeFreeRAM).toLocaleString() + cReset + " / " + cCyan + nHomeMaxRAM.toLocaleString() + cReset + " GB");
|
||||||
|
let oHome = ns.getServer("home");
|
||||||
|
let nCores = oHome.cpuCores;
|
||||||
|
ns.print("Home Cores = " + cCyan + Math.floor(nCores).toLocaleString() + cReset);
|
||||||
|
|
||||||
|
|
||||||
|
//Gang
|
||||||
|
ns.print("Karma = " + cCyan + Math.round(ns.heart.break()).toLocaleString() + cReset);
|
||||||
|
if (ns.gang.inGang()) {
|
||||||
|
if (!ns.getRunningScript(sGangScript)) {
|
||||||
|
ns.print("Gang found... running " + sGangScript);
|
||||||
|
ns.exec(sGangScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.print("Gang: " + cRed + "none" + cReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Best Target
|
||||||
|
|
||||||
|
oBestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
|
sBestTarget = oBestTarget.serverName;
|
||||||
|
ns.print("Best Target: " + cCyan + sBestTarget + cReset);
|
||||||
|
ns.print("Target Weakness: " + cCyan + Math.floor((ns.getServerMinSecurityLevel(sBestTarget) / ns.getServerSecurityLevel(sBestTarget)) * 100) + "%" + cReset);
|
||||||
|
ns.print("Target Money: " + cCyan + Math.floor((ns.getServerMoneyAvailable(sBestTarget) / ns.getServerMaxMoney(sBestTarget)) * 100) + "%" + cReset);
|
||||||
|
|
||||||
|
let nPServs = listPurchasedServers(ns).length;
|
||||||
|
let aPserv;
|
||||||
|
|
||||||
|
const oEXE = {
|
||||||
|
ssh: { name: "BruteSSH.exe", nHackingLevel: 50, cost: 500000 },
|
||||||
|
ftp: { name: "FTPCrack.exe", nHackingLevel: 100, cost: 1500000 },
|
||||||
|
smtp: { name: "relaySMTP.exe", nHackingLevel: 250, cost: 5000000 },
|
||||||
|
http: { name: "HTTPWorm.exe", nHackingLevel: 500, cost: 30000000 },
|
||||||
|
sql: { name: "SQLInject.exe", nHackingLevel: 750, cost: 250000000 },
|
||||||
|
ds1: { name: "DeepscanV1.exe", nHackingLevel: 75, cost: 500000 },
|
||||||
|
ds2: { name: "DeepscanV2.exe", nHackingLevel: 400, cost: 25000000 },
|
||||||
|
sp: { name: "ServerProfiler.exe", nHackingLevel: 75, cost: 500000 },
|
||||||
|
al: { name: "AutoLink.exe", nHackingLevel: 25, cost: 1000000 },
|
||||||
|
form: { name: "Formulas.exe", nHackingLevel: 25, cost: 1000000000 }
|
||||||
|
};
|
||||||
|
|
||||||
|
let bBusy = ns.singularity.isBusy();
|
||||||
|
let bBruteSSH = ns.fileExists(oEXE.ssh.name, "home");
|
||||||
|
let bFTPCrack = ns.fileExists(oEXE.ftp.name, "home");
|
||||||
|
let bRelaySMTP = ns.fileExists(oEXE.smtp.name, "home");
|
||||||
|
let bHttpWorm = ns.fileExists(oEXE.http.name, "home");
|
||||||
|
let bSqlInject = ns.fileExists(oEXE.sql.name, "home");
|
||||||
|
|
||||||
|
let bDeepscanV1 = ns.fileExists(oEXE.ds1.name, "home");
|
||||||
|
let bDeepscanV2 = ns.fileExists(oEXE.ds2.name, "home");
|
||||||
|
let bServerProfiler = ns.fileExists(oEXE.sp.name, "home");
|
||||||
|
let bAutoLink = ns.fileExists(oEXE.al.name, "home");
|
||||||
|
let bFormulas = ns.fileExists(oEXE.form.name, "home");
|
||||||
|
|
||||||
|
let nHackingLevel = ns.getHackingLevel();
|
||||||
|
let nMoney = ns.getPlayer().money;
|
||||||
|
|
||||||
|
//Home Upgrades
|
||||||
|
if (nMoney > ns.singularity.getUpgradeHomeRamCost()) {
|
||||||
|
ns.singularity.upgradeHomeRam();
|
||||||
|
ns.tprint(cCyan + "Upgraded home RAM" + cReset);
|
||||||
|
}
|
||||||
|
else if (nCores < 8 && nMoney > ns.singularity.getUpgradeHomeCoresCost()) {
|
||||||
|
ns.singularity.upgradeHomeCores();
|
||||||
|
ns.tprint(cCyan + "Upgraded home Cores" + cReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ns.print("Number of pservers = " + cCyan + nPServs + cReset);
|
||||||
|
|
||||||
|
let sLowestPserv;
|
||||||
|
aPserv = listPurchasedServers(ns);
|
||||||
|
let nLowestRAM = 2 ** 21;
|
||||||
|
let nCurrentRAM = 0;
|
||||||
|
for (let i = 0; i < aPserv.length; i++) {
|
||||||
|
nCurrentRAM = ns.getServerMaxRam(aPserv[i]);
|
||||||
|
if (nCurrentRAM < nLowestRAM) {
|
||||||
|
nLowestRAM = nCurrentRAM
|
||||||
|
sLowestPserv = aPserv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nLowestRAM < 2 ** 21) {
|
||||||
|
ns.print("Smallest psserv = " + cCyan + sLowestPserv + " " + nLowestRAM.toLocaleString() + " GB" + cReset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.print("Smallest psserv = " + cRed + "none" + cReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TOR
|
||||||
|
let bHasTOR = ns.hasTorRouter();
|
||||||
|
if (bHasTOR === false && nMoney >= 2e+5) {
|
||||||
|
ns.singularity.purchaseTor();
|
||||||
|
ns.tprint(cCyan + "Purchased TOR" + cReset);
|
||||||
|
ns.toast("Purchased " + "TOR Router", "info", 10000);
|
||||||
|
}
|
||||||
|
await ns.sleep(1);
|
||||||
|
if (bBruteSSH === false && bHasTOR && nMoney >= oEXE.ssh.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.ssh.name);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.ssh.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.ssh.name, "info", 10000);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
ns.exec(sBackdoorScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
else if (bAutoLink === false && bHasTOR && nMoney >= oEXE.al.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.al.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.al.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.al.name, "info", 10000);
|
||||||
|
}
|
||||||
|
else if (bFTPCrack === false && bHasTOR && nMoney >= oEXE.ftp.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.ftp.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.ftp.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.ftp.name, "info", 10000);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
ns.exec(sBackdoorScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
else if (bDeepscanV1 === false && bHasTOR && nMoney >= oEXE.ds1.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.ds1.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.ds1.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.ds1.name, "info", 10000);
|
||||||
|
}
|
||||||
|
else if (bRelaySMTP === false && bHasTOR && nMoney >= oEXE.smtp.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.smtp.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.smtp.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.smtp.name, "info", 10000);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
ns.exec(sBackdoorScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
else if (bHttpWorm === false && bHasTOR && nMoney >= oEXE.http.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.http.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.http.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.http.name, "info", 10000);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
ns.exec(sBackdoorScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
else if (bSqlInject === false && bHasTOR && nMoney >= oEXE.sql.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.sql.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.sql.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.sql.name, "info", 10000);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
ns.exec(sBackdoorScript, sThisRunner, 1);
|
||||||
|
}
|
||||||
|
else if (bDeepscanV2 === false && bHasTOR && nMoney >= oEXE.ds2.cost) {
|
||||||
|
ns.singularity.purchaseProgram(oEXE.ds2.name, false);
|
||||||
|
ns.tprint(cCyan + "Purchased " + oEXE.ds2.name + cReset);
|
||||||
|
ns.toast("Purchased " + oEXE.ds2.name, "info", 10000);
|
||||||
|
}
|
||||||
|
else if (getSetting(ns, "autoPurchaseServers") && nPServs < 25 && nMoney >= 5e+6) { //Purchased Servers
|
||||||
|
ns.tprint("purchasing servers ");
|
||||||
|
await purchaseServers(ns);
|
||||||
|
ns.exec(sServerLister, sThisRunner, 1, false, true);
|
||||||
|
}
|
||||||
|
else if (getSetting(ns, "autoUpgrades") && nLowestRAM < (2 ** 20) && !ns.scriptRunning("upgrade.js", sThisRunner) && nPServs >= 25 && nMoney >= 1e+6) {
|
||||||
|
ns.tprint("upgrading servers ");
|
||||||
|
ns.exec("upgrade.js", sThisRunner, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//ns.tprint("autoPurchaseServers = " + getSetting(ns, "autoPurchaseServers"));
|
||||||
|
//ns.tprint("autoUpgrades = " + getSetting(ns, "autoUpgrades"));
|
||||||
|
|
||||||
|
|
||||||
|
//work on something
|
||||||
|
if (bBusy === false) {
|
||||||
|
if (bHasTOR === false) {
|
||||||
|
if (bBruteSSH === false && nHackingLevel >= 50) {
|
||||||
|
ns.singularity.createProgram("BruteSSH.exe", false);
|
||||||
|
}
|
||||||
|
else if (bFTPCrack === false && nHackingLevel >= 100) {
|
||||||
|
ns.singularity.createProgram("FTPCrack.exe", false);
|
||||||
|
}
|
||||||
|
else if (bRelaySMTP === false && nHackingLevel >= 250) {
|
||||||
|
ns.singularity.createProgram("relaySMTP.exe", false);
|
||||||
|
}
|
||||||
|
else if (bDeepscanV1 === false && nHackingLevel >= 75) {
|
||||||
|
ns.singularity.createProgram("DeepscanV1.exe", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nHackingLevel < 500) {
|
||||||
|
ns.singularity.universityCourse("rothman university", "study computer science", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let nSharePower = Math.floor(ns.getSharePower() * 10000) / 100;
|
||||||
|
ns.print("Faction Reputation = " + cCyan + nSharePower + " %" + cReset);
|
||||||
|
|
||||||
|
|
||||||
|
if (bBusy) {
|
||||||
|
let oCurrentWork = ns.singularity.getCurrentWork();
|
||||||
|
//ns.print("oCurrentWork = " + JSON.stringify(oCurrentWork));
|
||||||
|
let bCanResume = false;
|
||||||
|
let nWorkCycles;
|
||||||
|
switch (oCurrentWork.type) {
|
||||||
|
case "CLASS": //Task = StudyTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Working at: " + cCyan + oCurrentWork.location + cReset);
|
||||||
|
ns.print("Working with: " + cCyan + oCurrentWork.classType + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = true;
|
||||||
|
break;
|
||||||
|
case "CREATE_PROGRAM": //Task = CreateProgramWorkTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Creating Program: " + cCyan + oCurrentWork.programName + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = true;
|
||||||
|
break;
|
||||||
|
case "FACTION": //Task = FactionWorkTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Working at: " + cCyan + oCurrentWork.factionName + cReset);
|
||||||
|
ns.print("Working with: " + cCyan + oCurrentWork.factionWorkType + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = true;
|
||||||
|
break;
|
||||||
|
case "CRIME": //Task = CrimeTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Comitting crime: " + cCyan + oCurrentWork.crimeType + cReset);
|
||||||
|
ns.print("Crime Chance: " + cCyan + Math.floor(10000 * ns.singularity.getCrimeChance(oCurrentWork.crimeType)) / 100 + "%" + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = true;
|
||||||
|
break;
|
||||||
|
case "COMPANY": //Task = CompanyWorkTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Working at: " + cCyan + oCurrentWork.companyName + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = true;
|
||||||
|
break;
|
||||||
|
case "GRAFTING": //Task = GraftingTask
|
||||||
|
nWorkCycles = oCurrentWork.cyclesWorked;
|
||||||
|
ns.print("Grafting: " + cCyan + oCurrentWork.augmentation + cReset);
|
||||||
|
ns.print("Task Cycle: " + cCyan + nWorkCycles.toLocaleString() + cReset)
|
||||||
|
bCanResume = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (bBusy && bCanResume === true && nWorkCycles >= 100) {
|
||||||
|
ns.singularity.stopAction();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
await ns.sleep(nRefreshFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
120
local/path/home/backup/batch2.js
Normal file
120
local/path/home/backup/batch2.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//Arguments
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
|
||||||
|
const oRunner = ns.getServer();
|
||||||
|
const sRunner = oRunner.hostname;
|
||||||
|
|
||||||
|
ns.tail("batch2.js", sRunner, sTarget);
|
||||||
|
|
||||||
|
//Settings
|
||||||
|
//const oHome = ns.getServer("home");
|
||||||
|
//const nCores = oHome.cpuCores;
|
||||||
|
|
||||||
|
const sScript = ns.getScriptName();
|
||||||
|
const sWeaken = "RMweaken.js";
|
||||||
|
const sGrow = "RMgrow.js";
|
||||||
|
const sHack = "RMhack.js";
|
||||||
|
const nScriptRAM = ns.getScriptRam(sScript, sRunner);
|
||||||
|
const nWeakenRAM = ns.getScriptRam(sWeaken, sRunner);
|
||||||
|
const nGrowRAM = ns.getScriptRam(sGrow, sRunner);
|
||||||
|
const nHackRAM = ns.getScriptRam(sHack, sRunner);
|
||||||
|
const nHomeUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
const nHomeMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
let nHomeFreeRAM = nHomeMaxRAM - nHomeUsedRAM;
|
||||||
|
|
||||||
|
const nDelays = [0, 20, 40, 60];
|
||||||
|
|
||||||
|
|
||||||
|
//abort script if sTarget is undefined
|
||||||
|
if (sTarget === undefined) {
|
||||||
|
ns.tprint("1st arg sTarget is undefined");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//target server info
|
||||||
|
const nMinSecurity = ns.getServerMinSecurityLevel(sTarget);
|
||||||
|
const nMaxMoney = ns.getServerMaxMoney(sTarget);
|
||||||
|
|
||||||
|
let nWeakenTime1 = ns.getWeakenTime(sTarget);
|
||||||
|
let nWeakenTime2 = nWeakenTime1;
|
||||||
|
let nGrowTime = nWeakenTime1 * 0.8;
|
||||||
|
let nHackTime = nWeakenTime1 / 4;
|
||||||
|
|
||||||
|
//let nHackSecurityGain = ns.hackAnalyzeSecurity(1, sTarget);
|
||||||
|
let nHackSecurityGain = 0.002;
|
||||||
|
//let nHackThreadsEstimate = Math.floor(1 / nHackSecurityGain);
|
||||||
|
let nHackThreadsEstimate = 10;
|
||||||
|
ns.tprint("nHackSecurityGain = " + nHackSecurityGain);
|
||||||
|
ns.tprint("nHackThreadsEstimate = " + nHackThreadsEstimate);
|
||||||
|
const nHackTotalRAM = nHackRAM * nHackThreadsEstimate;
|
||||||
|
|
||||||
|
//let nGrowSecurityGain = ns.growthAnalyzeSecurity(1, sTarget, nCores);
|
||||||
|
let nGrowSecurityGain = 0.004;
|
||||||
|
let nGrowThreadsEstimate = Math.floor(1 / nGrowSecurityGain);
|
||||||
|
ns.tprint("nGrowSecurityGain = " + nGrowSecurityGain);
|
||||||
|
ns.tprint("nGrowThreadsEstimate = " + nGrowThreadsEstimate);
|
||||||
|
const nGrowTotalRAM = nGrowRAM * nGrowThreadsEstimate;
|
||||||
|
|
||||||
|
//let nWeakenSecurity = ns.weakenAnalyze(1, nCores);
|
||||||
|
let nWeakenSecurity = 0.05;
|
||||||
|
let nWeakenThreadsEstimate = Math.ceil(1 / nWeakenSecurity);
|
||||||
|
ns.tprint("nWeakenSecurity = " + nWeakenSecurity);
|
||||||
|
ns.tprint("nWeakenThreadsEstimate = " + nWeakenThreadsEstimate);
|
||||||
|
const nWeakenTotalRAM = nWeakenRAM * nWeakenThreadsEstimate;
|
||||||
|
|
||||||
|
const nTotalRAM = nHackTotalRAM + nGrowTotalRAM + (nWeakenTotalRAM * 2)
|
||||||
|
const nTotalBatches = Math.floor(nHomeFreeRAM / (nTotalRAM - nScriptRAM));
|
||||||
|
ns.tprint("RAM per Cycle = " + nTotalRAM);
|
||||||
|
ns.tprint("how many batches can i run at the same time? = " + nTotalBatches);
|
||||||
|
|
||||||
|
let nGrowDelay = nWeakenTime1 - nGrowTime;
|
||||||
|
let nHackDelay = nWeakenTime1 - nHackTime;
|
||||||
|
|
||||||
|
const nCycleDuration = nWeakenTime2 + nDelays[3];
|
||||||
|
ns.tprint("nCycleDuration = " + nCycleDuration);
|
||||||
|
|
||||||
|
const nBatchFrequency = Math.ceil(nCycleDuration / nTotalBatches);
|
||||||
|
ns.tprint("nBatchFrequency = " + nBatchFrequency);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
//server stats
|
||||||
|
let nCurrentSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
let nCurrentMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
|
||||||
|
//timestamp
|
||||||
|
let currentDate = new Date();
|
||||||
|
let nOffset;
|
||||||
|
|
||||||
|
ns.print("Cash: " + (Math.floor(nCurrentMoney * 1000) / 1000) + " / " + nMaxMoney);
|
||||||
|
ns.print("Security: " + (Math.floor(nCurrentSecurity * 1000) / 1000) + " / " + nMinSecurity);
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
nOffset = ns.getWeakenTime(sTarget);
|
||||||
|
let nWeakTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sWeakTime = nWeakTime.toLocaleTimeString('sw-SV'); //swedish time
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Weakening " + sTarget + " Estimated complete at " + sWeakTime);
|
||||||
|
|
||||||
|
//hack
|
||||||
|
const nHackPID = ns.exec(sHack, sRunner, 10, sTarget, false, nHackDelay + nDelays[0]);
|
||||||
|
//ns.tail(nHackPID, "home", "home", nHackThreadsEstimate, sTarget, 0, nHackDelay + nDelays[0]);
|
||||||
|
|
||||||
|
//weaken 1
|
||||||
|
const nWeakenPID = ns.exec(sWeaken, sRunner, nWeakenThreadsEstimate, sTarget, false, nDelays[1]);
|
||||||
|
//ns.tail(nWeakenPID, "home", "home", nWeakenThreadsEstimate, sTarget, 0, nDelays[1]);
|
||||||
|
|
||||||
|
//grow
|
||||||
|
const nGrowPID = ns.exec(sGrow, sRunner, nGrowThreadsEstimate, sTarget, false, nGrowDelay + nDelays[2]);
|
||||||
|
//ns.tail(nGrowPID, "home", "home", nGrowThreadsEstimate, sTarget, 0, nGrowDelay + nDelays[2]);
|
||||||
|
|
||||||
|
//weaken 2
|
||||||
|
const nWeakenPID2 = ns.exec(sWeaken, sRunner, nWeakenThreadsEstimate, sTarget, false, nDelays[3]);
|
||||||
|
//ns.tail(nWeakenPID2, "home", "home", nWeakenThreadsEstimate, sTarget, 0, nDelays[3]);
|
||||||
|
|
||||||
|
await ns.sleep(nBatchFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
local/path/home/backup/bitnodeStart.js
Normal file
18
local/path/home/backup/bitnodeStart.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
goals
|
||||||
|
get money
|
||||||
|
upgrade home ram
|
||||||
|
/*
|
||||||
|
|
||||||
|
let nPID = ns.run("serverlister.js");
|
||||||
|
while (ns.getRunningScript(nPID)){
|
||||||
|
ns.tprint("waiting for script to finish");
|
||||||
|
await ns.sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
5
local/path/home/backup/growrepeater.js
Normal file
5
local/path/home/backup/growrepeater.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
while (true) { await ns.grow(sTarget); }
|
||||||
|
}
|
||||||
28
local/path/home/backup/maxGrow.js
Normal file
28
local/path/home/backup/maxGrow.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//args
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
|
||||||
|
ns.tail(ns.pid,"home",ns.args);
|
||||||
|
let nMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
const nMaxMoney = ns.getServerMaxMoney(sTarget);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const startValue = nMoney; // First argument: starting value
|
||||||
|
const target = nMaxMoney; // Second argument: target value
|
||||||
|
let result = startValue; // Initialize result with the starting value
|
||||||
|
let n = 1;
|
||||||
|
// For loop that continues until the result exceeds or matches the target
|
||||||
|
for (; result < target; n++) {
|
||||||
|
result += 1; // Add 1 before multiplication
|
||||||
|
result *= n; // Multiply by the current step value
|
||||||
|
ns.print("result = "+result.toLocaleString() + " / "+ nMaxMoney.toLocaleString());
|
||||||
|
ns.print("n = "+n);
|
||||||
|
}
|
||||||
|
let nGrowThreadsNeeded = n;
|
||||||
|
// * ns.growthAnalyze(sTarget, n, 1);
|
||||||
|
ns.print("nGrowThreadsNeeded = " + nGrowThreadsNeeded);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
205
local/path/home/batch.js
Normal file
205
local/path/home/batch.js
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
import { getGrowThreads } from "myLibrary.js";
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//Arguments
|
||||||
|
const nArgs = ns.args.length
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
let nFrequency = ns.args[1]; // frequency to run the Hack / Grow / Weaken
|
||||||
|
const bIgnoreRAM = ns.args[2]; //if true the script will run even if estimated RAM is too low
|
||||||
|
const bTail = ns.args[3]; //if true the script will run even if estimated RAM is too low
|
||||||
|
|
||||||
|
//host and script info
|
||||||
|
//const sThisRunner = ns.getHostname();
|
||||||
|
//const sThisScript = ns.getScriptName();
|
||||||
|
if (bTail === true) { ns.tail(); }
|
||||||
|
|
||||||
|
//logs
|
||||||
|
ns.disableLog("ALL");
|
||||||
|
|
||||||
|
//Settings
|
||||||
|
const sHackScript = "RMhack.js";
|
||||||
|
const sGrowScript = "RMgrow.js";
|
||||||
|
const sWeakenScript = "RMweaken.js";
|
||||||
|
|
||||||
|
const nHackThreads = 5; //1
|
||||||
|
|
||||||
|
const nHackScriptRAM = 1.75;
|
||||||
|
const nGrowScriptRAM = 1.7;
|
||||||
|
const nWeakenScriptRAM = 1.75;
|
||||||
|
|
||||||
|
|
||||||
|
//abort script if sTarget is undefined
|
||||||
|
if (sTarget === undefined) { ns.tprint("1st arg sTarget is undefined"); return false; }
|
||||||
|
|
||||||
|
//how often do we run script in milliseconds
|
||||||
|
if (nFrequency === undefined) { nFrequency = 1000; }
|
||||||
|
|
||||||
|
//target server info
|
||||||
|
const nMinSecurity = ns.getServerMinSecurityLevel(sTarget);
|
||||||
|
const nMaxMoney = ns.getServerMaxMoney(sTarget);
|
||||||
|
|
||||||
|
//abort script if sTarget cant have money
|
||||||
|
if (nMaxMoney <= 0) { ns.tprint("sTarget (" + sTarget + ") has no nMaxMoney"); return false; }
|
||||||
|
|
||||||
|
let nCurrentSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
let nCurrentMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
|
||||||
|
let nBonusWeaken = 0;
|
||||||
|
let nBonusGrow = 0;
|
||||||
|
|
||||||
|
/*if (nCurrentSecurity > nMinSecurity + 3) {
|
||||||
|
nBonusWeaken = 4;
|
||||||
|
}
|
||||||
|
if (nCurrentMoney <= nMaxMoney * 0.8) {
|
||||||
|
nBonusGrow = 9;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
let nGrowThreads = Math.max(12 + nBonusGrow, getGrowThreads(ns, sTarget, nHackThreads));
|
||||||
|
let nGrowThreadsINT = Math.ceil(nGrowThreads);
|
||||||
|
|
||||||
|
//25 hacks or 12.5 grows
|
||||||
|
let nWeakenThreads = Math.max(1 + nBonusWeaken, (nHackThreads / 25) + (nGrowThreads / 12.5));
|
||||||
|
let nWeakenThreadsINT = Math.ceil(nWeakenThreads);
|
||||||
|
|
||||||
|
//main variables
|
||||||
|
const oRunner = ns.getServer(); //which server object is running this script
|
||||||
|
const sRunner = oRunner.hostname; //hostname string of the server running the script
|
||||||
|
const nCores = oRunner.cpuCores;
|
||||||
|
|
||||||
|
//const sRunner = ns.getHostname(); //hostname string of the server running the script
|
||||||
|
let nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
let nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
let nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
//const sScriptName = ns.getScriptName();
|
||||||
|
//const nScriptSize = ns.getScriptRam(sScriptName, sRunner);
|
||||||
|
//let nMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
let nHomeServerReserve = Math.min(nMaxRAM / 8, 64);
|
||||||
|
|
||||||
|
if (sRunner !== "home") {
|
||||||
|
nHomeServerReserve = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let nWeakenPower = ns.weakenAnalyze(1, nCores); // default 0.05 (always?)
|
||||||
|
ns.tprint("nWeakenPower = " + nWeakenPower + " with " + nCores + " nCores");
|
||||||
|
|
||||||
|
let nHackSecurity = ns.hackAnalyzeSecurity(1, sTarget); // default 0.002
|
||||||
|
ns.tprint("nHackSecurity = " + nHackSecurity + " on " + sTarget + " sTarget");
|
||||||
|
|
||||||
|
let nGrowSecurity = ns.growthAnalyzeSecurity(1, "", nCores);// default 0.004 (always?)
|
||||||
|
ns.tprint("nGrowSecurity = " + nGrowSecurity + " on " + "_" + " sTarget" + " with " + nCores + " nCores");
|
||||||
|
*/
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
//server stats
|
||||||
|
nCurrentSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
nCurrentMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
|
||||||
|
nBonusWeaken = 0;
|
||||||
|
if (nCurrentSecurity > nMinSecurity + 3) {
|
||||||
|
nBonusWeaken = 4;
|
||||||
|
}
|
||||||
|
nBonusGrow = 0;
|
||||||
|
if (nCurrentMoney <= nMaxMoney * 0.8) {
|
||||||
|
nBonusGrow = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nGrowThreads = Math.max(1 + nBonusGrow, getGrowThreads(ns, sTarget, nHackThreads));
|
||||||
|
nGrowThreadsINT = Math.ceil(nGrowThreads);
|
||||||
|
|
||||||
|
//25 hacks or 12.5 grows
|
||||||
|
nWeakenThreads = Math.max(1 + nBonusWeaken, (nHackThreads / 25) + (nGrowThreads / 12.5));
|
||||||
|
nWeakenThreadsINT = Math.ceil(nWeakenThreads);
|
||||||
|
|
||||||
|
//timestamp
|
||||||
|
let currentDate = new Date();
|
||||||
|
let nOffset;
|
||||||
|
|
||||||
|
ns.print("Cash: " + (Math.floor(nCurrentMoney * 1000) / 1000) + " / " + nMaxMoney);
|
||||||
|
ns.print("Security: " + (Math.floor(nCurrentSecurity * 1000) / 1000) + " / " + nMinSecurity);
|
||||||
|
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
|
||||||
|
while (nFreeRam <= (nWeakenScriptRAM * nWeakenThreads) + nHomeServerReserve + 6) {
|
||||||
|
await ns.sleep(100);
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nFreeRam > (nWeakenScriptRAM * nWeakenThreads) + nHomeServerReserve + 6) {
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
nOffset = ns.getWeakenTime(sTarget);
|
||||||
|
let nWeakTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sWeakTime = nWeakTime.toLocaleTimeString('sw-SV'); //swedish time
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Weakening " + sTarget + " Estimated complete at " + sWeakTime);
|
||||||
|
ns.print("Weakening with " + nWeakenThreadsINT + " threads on " + sTarget);
|
||||||
|
let nWeakenPID = ns.run(sWeakenScript, nWeakenThreadsINT, sTarget);
|
||||||
|
if (nWeakenPID === 0) { ns.print("Weaken Failed..."); }
|
||||||
|
}
|
||||||
|
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
|
||||||
|
while (nFreeRam <= (nGrowScriptRAM * nGrowThreads) + nHomeServerReserve + 6) {
|
||||||
|
await ns.sleep(100);
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCurrentSecurity <= (nMinSecurity + 1) && nFreeRam > (nGrowScriptRAM * nGrowThreads) + nHomeServerReserve + 6) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
nOffset = ns.getGrowTime(sTarget);
|
||||||
|
let nGrowTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sGrowTime = nGrowTime.toLocaleTimeString('sw-SV'); //swedish time
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Growing " + sTarget + " Estimated complete at " + sGrowTime);
|
||||||
|
ns.print("Growing with " + nGrowThreadsINT + " threads on " + sTarget);
|
||||||
|
let nGrowPID = ns.run(sGrowScript, nGrowThreadsINT, sTarget);
|
||||||
|
if (nGrowPID === 0) { ns.print("Grow Failed..."); }
|
||||||
|
|
||||||
|
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
|
||||||
|
while (nFreeRam <= (nHackScriptRAM * nHackThreads) + nHomeServerReserve + 6) {
|
||||||
|
await ns.sleep(100);
|
||||||
|
nMaxRAM = ns.getServerMaxRam(sRunner);
|
||||||
|
nUsedRAM = ns.getServerUsedRam(sRunner);
|
||||||
|
nFreeRam = nMaxRAM - nUsedRAM;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCurrentMoney >= nMaxMoney * 0.8 && nFreeRam > (nHackScriptRAM * nHackThreads) + nHomeServerReserve + 6) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
nOffset = ns.getHackTime(sTarget);
|
||||||
|
let nHackTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sHackTime = nHackTime.toLocaleTimeString('sw-SV'); //swedish time
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Hacking " + sTarget + " Estimated complete at " + sHackTime);
|
||||||
|
ns.print("Hacking with " + nHackThreads + " threads on " + sTarget);
|
||||||
|
let mHackPID = ns.run(sHackScript, nHackThreads, sTarget);
|
||||||
|
if (mHackPID === 0) { ns.print("Hack Failed..."); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
await ns.sleep(nFrequency);
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
local/path/home/bestTarget.txt
Normal file
1
local/path/home/bestTarget.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"serverName":"the-hub","maxRam":32,"maxMoney":483168296.25,"minSec":13,"minPorts":2,"minHackLvl":318,"rootAccess":true,"factorMoneyPerTime":0.1841702873569451,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":0.40919188586028893}
|
||||||
63
local/path/home/breach.js
Normal file
63
local/path/home/breach.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
//args
|
||||||
|
const sTarget = ns.args[0]; // target server
|
||||||
|
|
||||||
|
// declare objects
|
||||||
|
const oHome = ns.getServer("home");
|
||||||
|
//const oTarget = ns.getServer(sTarget);
|
||||||
|
|
||||||
|
//declare variables
|
||||||
|
const sScriptName = ns.getScriptName();
|
||||||
|
const sWeakenScript = "RMweaken.js";
|
||||||
|
const nScriptRAM = ns.getScriptRam(sScriptName);
|
||||||
|
const sBatch = "EveryServerRun.js";
|
||||||
|
const nCores = oHome.cpuCores;
|
||||||
|
let nSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
const nMinSecurity = ns.getServerMinSecurityLevel(sTarget);
|
||||||
|
const nWeakenSTR = ns.weakenAnalyze(1, nCores);
|
||||||
|
const nThreads = Math.ceil((nSecurity - nMinSecurity) / nWeakenSTR);
|
||||||
|
ns.tprint("nThreads = " + nThreads);
|
||||||
|
|
||||||
|
|
||||||
|
ns.tail(ns.pid, oHome.hostname, sTarget);
|
||||||
|
//ns.resizeTail(815, 395);
|
||||||
|
//ns.moveTail(1925, 0);
|
||||||
|
|
||||||
|
if (nThreads > 0) {
|
||||||
|
const nDelay = ns.getWeakenTime(sTarget);
|
||||||
|
|
||||||
|
ns.tprint("current security is: " + nSecurity);
|
||||||
|
ns.tprint("minimum security is: " + nMinSecurity);
|
||||||
|
ns.tprint("threads needed for weaken: " + nThreads);
|
||||||
|
ns.tprint(nThreads + " will reduce Security by " + ns.weakenAnalyze(nThreads, nCores));
|
||||||
|
ns.tprint(nThreads + " of " + sWeakenScript + " requires " + (ns.getScriptRam(sWeakenScript, "home") * nThreads) + " GB of RAM");
|
||||||
|
ns.tprint("weakening will take " + (nDelay / 1000 / 60) + " minutes");
|
||||||
|
|
||||||
|
if ((ns.getServerMaxRam(oHome.hostname) - ns.getServerUsedRam(oHome.hostname)) >= (ns.getScriptRam(sWeakenScript, "home") * nThreads)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ns.run(sWeakenScript, nThreads, sTarget);
|
||||||
|
await ns.sleep(Math.ceil(nDelay));
|
||||||
|
nSecurity = ns.getServerSecurityLevel(sTarget);
|
||||||
|
ns.tprint("Breach complete, security level is now at: " + nSecurity);
|
||||||
|
|
||||||
|
//run batch
|
||||||
|
const nBatchPID = ns.run(sBatch, 1, sTarget);
|
||||||
|
ns.tail(nBatchPID, "home", sBatch, 1, sTarget);
|
||||||
|
ns.resizeTail(815, 395, nBatchPID);
|
||||||
|
ns.moveTail(1925, 0, nBatchPID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.tprint("try to loop untill finished");
|
||||||
|
let nScripts = Math.ceil((ns.getServerMaxRam("home") - ns.getServerUsedRam("home")) / ns.getScriptRam(sWeakenScript, "home")-nScriptRAM);
|
||||||
|
ns.tprint("nScripts = " + nScripts);
|
||||||
|
ns.run(sWeakenScript, nScripts, sTarget);
|
||||||
|
await ns.sleep(Math.ceil(nDelay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cities = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
|
||||||
let corpName = "AgraNeo";
|
|
||||||
ns.tprint(ns.corporation.getMaterial(corpName,cities[0],"Plants"))
|
|
||||||
ns.corporation.sellMaterial()
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cities = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
|
||||||
let corpName = "ChemNeo";
|
|
||||||
let currentSize = 0;
|
|
||||||
for (let city of cities) {
|
|
||||||
|
|
||||||
let currentOffice=(ns.corporation.getOffice(corpName, city));
|
|
||||||
if (currentOffice.numEmployees < currentOffice.size) {
|
|
||||||
(currentOffice.employeeJobs.Operations < 1) ? ns.corporation.hireEmployee(corpName, city,"Operations") : "";
|
|
||||||
(currentOffice.employeeJobs.Engineer < 1) ? ns.corporation.hireEmployee(corpName, city,"Engineer") : "";
|
|
||||||
(currentOffice.employeeJobs.Business < 1) ? ns.corporation.hireEmployee(corpName, city,"Business") : "";
|
|
||||||
(currentOffice.employeeJobs.Management < 1) ? ns.corporation.hireEmployee(corpName, city,"Management") : "";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cities = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
|
||||||
let corpName1 = ["AgraNeo","Plants"];
|
|
||||||
let corpName2 = ["ChemNeo","Chemicals"];
|
|
||||||
let exportString = "IPROD*-1"
|
|
||||||
for (let city of cities) {
|
|
||||||
ns.corporation.cancelExportMaterial(corpName1[0],city,corpName2[0],city,corpName1[1]);
|
|
||||||
ns.corporation.cancelExportMaterial(corpName2[0],city,corpName1[0],city,corpName2[1]);
|
|
||||||
ns.corporation.exportMaterial(corpName1[0],city,corpName2[0],city,corpName1[1],exportString);
|
|
||||||
ns.corporation.exportMaterial(corpName2[0],city,corpName1[0],city,corpName2[1],exportString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let [corpName, city] = ns.args;
|
|
||||||
//ns.corporation.setSmartSupply(corpName, city, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
let cities = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
|
||||||
let corpName = "ChemNeo";
|
|
||||||
let currentSize = 0;
|
|
||||||
for (let city of cities) {
|
|
||||||
currentSize = ns.corporation.getOffice(corpName, city).size;
|
|
||||||
if (currentSize < 4) {
|
|
||||||
ns.corporation.upgradeOfficeSize(corpName, city, 4 - currentSize);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
46
local/path/home/fixpserv.js
Normal file
46
local/path/home/fixpserv.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
/*
|
||||||
|
ns.renamePurchasedServer("pserv-23", "pserv-24");
|
||||||
|
ns.renamePurchasedServer("pserv-22", "pserv-23");
|
||||||
|
ns.renamePurchasedServer("pserv-21", "pserv-22");
|
||||||
|
ns.renamePurchasedServer("pserv-20", "pserv-21");
|
||||||
|
ns.renamePurchasedServer("pserv-19", "pserv-20");
|
||||||
|
ns.renamePurchasedServer("pserv-18", "pserv-19");
|
||||||
|
ns.renamePurchasedServer("pserv-17", "pserv-18");
|
||||||
|
ns.renamePurchasedServer("pserv-16", "pserv-17");
|
||||||
|
ns.renamePurchasedServer("pserv-15", "pserv-16");
|
||||||
|
ns.renamePurchasedServer("pserv-14", "pserv-15");
|
||||||
|
ns.renamePurchasedServer("pserv-13", "pserv-14");
|
||||||
|
ns.renamePurchasedServer("pserv-12", "pserv-13");
|
||||||
|
ns.renamePurchasedServer("pserv-11", "pserv-12");
|
||||||
|
ns.renamePurchasedServer("pserv-10", "pserv-11");
|
||||||
|
ns.renamePurchasedServer("pserv-9", "pserv-10");
|
||||||
|
ns.renamePurchasedServer("pserv-8", "pserv-9");
|
||||||
|
ns.renamePurchasedServer("pserv-7", "pserv-8");
|
||||||
|
ns.renamePurchasedServer("pserv-6", "pserv-7");
|
||||||
|
ns.renamePurchasedServer("pserv-5", "pserv-6");
|
||||||
|
ns.renamePurchasedServer("pserv-4", "pserv-5");
|
||||||
|
ns.renamePurchasedServer("pserv-3", "pserv-4");
|
||||||
|
ns.renamePurchasedServer("pserv-2", "pserv-3");
|
||||||
|
ns.renamePurchasedServer("pserv-1-0", "pserv-2");
|
||||||
|
*/
|
||||||
|
ns.renamePurchasedServer("pserv-1", "pserv-01");
|
||||||
|
ns.renamePurchasedServer("pserv-2", "pserv-02");
|
||||||
|
ns.renamePurchasedServer("pserv-3", "pserv-03");
|
||||||
|
ns.renamePurchasedServer("pserv-4", "pserv-04");
|
||||||
|
ns.renamePurchasedServer("pserv-5", "pserv-05");
|
||||||
|
ns.renamePurchasedServer("pserv-6", "pserv-06");
|
||||||
|
ns.renamePurchasedServer("pserv-7", "pserv-07");
|
||||||
|
ns.renamePurchasedServer("pserv-8", "pserv-08");
|
||||||
|
ns.renamePurchasedServer("pserv-9", "pserv-09");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//const nServers = ns.getPurchasedServers();
|
||||||
|
|
||||||
|
//for (let i = 0; i < nServers; i++)
|
||||||
|
//let hostname = ns.purchaseServer("pserv-" + i, ram);
|
||||||
|
// ns.renamePurchasedServer(([i]), "pserv-" + i);
|
||||||
|
|
||||||
|
}
|
||||||
30
local/path/home/gang/argFunctions.js
Normal file
30
local/path/home/gang/argFunctions.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export function GetFlag(ns, flag)
|
||||||
|
{
|
||||||
|
return ns.args.includes(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetArg(ns, arg, def = null)
|
||||||
|
{
|
||||||
|
for(var i = 0; i < ns.args.length - 1; i++)
|
||||||
|
{
|
||||||
|
if(ns.args[i] == arg)
|
||||||
|
{
|
||||||
|
return ns.args[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetIndex(ns, arg)
|
||||||
|
{
|
||||||
|
for(var i = 0; i < ns.args.length; i++)
|
||||||
|
{
|
||||||
|
if(ns.args[i] == arg)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
114
local/path/home/gang/auto-gang.js
Normal file
114
local/path/home/gang/auto-gang.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
A 'cycle' lasts 5 minutes and the current task for any given member on a cycle
|
||||||
|
is set by taking the cycle and their member index and modding by the number
|
||||||
|
of tasks in your list, so it should spread out tasks evenly among your members,
|
||||||
|
and each one should progress through the list of tasks, although when you start
|
||||||
|
only the first member will start on task 0.
|
||||||
|
|
||||||
|
Set 'upgradeEquipmentNames' to a list of the gear you want to purchase,
|
||||||
|
currently it gets a list of all equipment by type and includes all types.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Jobs are:
|
||||||
|
[
|
||||||
|
"Unassigned",
|
||||||
|
"Mug People",
|
||||||
|
"Deal Drugs",
|
||||||
|
"Strongarm Civilians",
|
||||||
|
"Run a Con",
|
||||||
|
"Armed Robbery",
|
||||||
|
"Traffick Illegal Arms",
|
||||||
|
"Threaten & Blackmail",
|
||||||
|
"Human Trafficking",
|
||||||
|
"Terrorism",
|
||||||
|
"Vigilante Justice",
|
||||||
|
"Train Combat",
|
||||||
|
"Train Hacking",
|
||||||
|
"Train Charisma",
|
||||||
|
"Territory Warfare"
|
||||||
|
]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const DURATION = 5 * 60 * 1000 // 5 minutes
|
||||||
|
|
||||||
|
const newMemberNames = ('General Kenobi,General Zod,Admiral Akbar,Admiral Thrawn' +
|
||||||
|
',Colonel Duke,Colonel Nick Fury,Major Tom,Major Paine' +
|
||||||
|
',Corporal Klinger,Corporal Barnes,Sergeant Slaughter,Sergeant Smith').split(',')
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
// // show list of job names
|
||||||
|
// ns.tprint(JSON.stringify(ns.gang.getTaskNames(), null, 2))
|
||||||
|
// return
|
||||||
|
|
||||||
|
ns.disableLog('ALL')
|
||||||
|
|
||||||
|
// what gear will we buy after ascension?
|
||||||
|
let equipmentNames = ns.gang.getEquipmentNames()
|
||||||
|
let upgradeEquipmentNames = equipmentNames.filter(x => ['Weapon', 'Armor', 'Vehicle', 'Rootkit', 'Augmentation'].find(y => ns.gang.getEquipmentType(x) === y))
|
||||||
|
|
||||||
|
let cycle = 0
|
||||||
|
|
||||||
|
// with 6 jobs and 12 members, we should have two members on each
|
||||||
|
let cycleTasks = ['Train Combat', 'Train Combat',
|
||||||
|
'Vigilante Justice', 'Terrorism',
|
||||||
|
'Human Trafficking', 'Territory Warfare']
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
let memberNames = ns.gang.getMemberNames()
|
||||||
|
ns.print(`Cycle ${cycle} activating for ${memberNames.length} gang members`)
|
||||||
|
memberNames.forEach((name, index) => {
|
||||||
|
let taskIndex = (cycle + index) % cycleTasks.length
|
||||||
|
if (taskIndex === 0) {
|
||||||
|
let result = ns.gang.ascendMember(name)
|
||||||
|
if (result) ns.print(`INFO: Ascended gang member ${name}:\n Hack:${sf(result.hack)}, Str:${sf(result.str)}, Def:${sf(result.def)}, Dex:${sf(result.dex)}, Agi:${sf(result.agi)}`)
|
||||||
|
// if (result) ns.print(`INFO: Ascended gang member ${name}:\n ${JSON.stringify(result)}`)
|
||||||
|
purchaseEquipment(name)
|
||||||
|
}
|
||||||
|
ns.gang.setMemberTask(name, cycleTasks[taskIndex])
|
||||||
|
})
|
||||||
|
|
||||||
|
// hire new members if possible and set them to first job for this cycle,
|
||||||
|
// should be training probably
|
||||||
|
if (ns.gang.canRecruitMember()) {
|
||||||
|
newMemberNames.forEach(name => {
|
||||||
|
if (ns.gang.recruitMember(name)) {
|
||||||
|
ns.print(`INFO: Recruited new gang member '${name}`)
|
||||||
|
ns.gang.setMemberTask(name, cycleTasks[0])
|
||||||
|
purchaseEquipment()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let cycleEnd = new Date(new Date().valueOf() + DURATION).toLocaleTimeString()
|
||||||
|
ns.print(`Next cycle at ${cycleEnd}`)
|
||||||
|
await ns.sleep(DURATION) // wait 5 minutes
|
||||||
|
cycle++
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purchase equipment for a gang member if we have the money
|
||||||
|
*
|
||||||
|
* @param {string} memberName Name of the gang member to purchase equipment for
|
||||||
|
*/
|
||||||
|
function purchaseEquipment(memberName) {
|
||||||
|
let { money } = ns.getPlayer()
|
||||||
|
upgradeEquipmentNames.forEach(equipName => {
|
||||||
|
let cost = ns.gang.getEquipmentCost(equipName)
|
||||||
|
if (money >= cost && ns.gang.purchaseEquipment(memberName, equipName)) money -= cost
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple format for stats
|
||||||
|
*
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
function sf(value) {
|
||||||
|
if (typeof(value) !== 'number') return '???'
|
||||||
|
return Math.trunc(value * 1000) / 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
144
local/path/home/gang/auto-gang2.js
Normal file
144
local/path/home/gang/auto-gang2.js
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
const TASK_TRAIN = "Train Combat";
|
||||||
|
const TASK_VIGI = "Vigilante Justice";
|
||||||
|
const TASK_NOOB = String.fromCharCode(77) + "ug People";
|
||||||
|
const TASK_RESPECT = String.fromCharCode(84) + "errorism";
|
||||||
|
const TASK_MONEY = "Human " + String.fromCharCode(84) + "rafficking";
|
||||||
|
const TASK_WARFARE = "Territory Warfare";
|
||||||
|
const TASK_NULL = "Unassigned";
|
||||||
|
const TASK_MANUAL = "Manual/NotReallyTaskName";
|
||||||
|
|
||||||
|
const ASCEND_ON_MPL = 10;
|
||||||
|
const EQUIP_AFFORD_COEFF = 100;
|
||||||
|
|
||||||
|
const STATS_TRESHOLD = 0.7;
|
||||||
|
const STATS_MIN = 4000;
|
||||||
|
const STATS_HARD_MIN = 200;
|
||||||
|
const TRAIN_CHANCE = 0.2;
|
||||||
|
const RESPECT_MIN = 2e+7;
|
||||||
|
|
||||||
|
const WANTED_PENALTY_TRESHOLD = 0.99;
|
||||||
|
const WARFARE_TRESHOLD = 2;
|
||||||
|
|
||||||
|
const MEMBERS_MIN = 6;
|
||||||
|
const MEMBERS_MAX = 12;
|
||||||
|
|
||||||
|
const SLEEP_TIME = 10000;
|
||||||
|
|
||||||
|
/** @param {NS} ns **/
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.tail();
|
||||||
|
const gang = ns.gang;
|
||||||
|
// Get weighted stats sum (at this moment, sum of combat stats in eq proportions)
|
||||||
|
function getStatsSum(member) {
|
||||||
|
const info = gang.getMemberInformation(member);
|
||||||
|
return info.str + info.def + info.dex + info.agi;
|
||||||
|
}
|
||||||
|
// Find the best gang power except our gang
|
||||||
|
function maxEnemyPower(myGang) {
|
||||||
|
const others = ns.gang.getOtherGangInformation();
|
||||||
|
let maxPower = 0;
|
||||||
|
for (let name in others) {
|
||||||
|
if (name === myGang.faction) continue;
|
||||||
|
maxPower = Math.max(maxPower, others[name].power);
|
||||||
|
}
|
||||||
|
return maxPower;
|
||||||
|
}
|
||||||
|
// Set a task or not to set (if manually overridden)
|
||||||
|
const autoTasks = {}
|
||||||
|
function setAutoTask(member, task) {
|
||||||
|
const info = gang.getMemberInformation(member);
|
||||||
|
const lastTask = info.task;
|
||||||
|
// Manual task: stored task mismatches real task and not unassigned
|
||||||
|
if (lastTask !== TASK_NULL && autoTasks.hasOwnProperty(member) && autoTasks[member] !== lastTask) {
|
||||||
|
autoTasks[member] = TASK_MANUAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Automatic task: set it if differs from real one
|
||||||
|
autoTasks[member] = task;
|
||||||
|
if (lastTask !== task) {
|
||||||
|
gang.setMemberTask(member, task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The script accepts argument for default task override (optional)
|
||||||
|
let defaultTask = null;
|
||||||
|
if (ns.args[0] && gang.getTaskNames().includes(ns.args[0])) {
|
||||||
|
defaultTask = ns.args[0];
|
||||||
|
}
|
||||||
|
// Main loop
|
||||||
|
for (; ;) {
|
||||||
|
// Recruit any member possible
|
||||||
|
while (gang.canRecruitMember()) {
|
||||||
|
gang.recruitMember('member' + Math.random().toString().substr(2, 3));
|
||||||
|
}
|
||||||
|
let bestStats = STATS_MIN / STATS_TRESHOLD; // minimum
|
||||||
|
const members = gang.getMemberNames();
|
||||||
|
const info = gang.getGangInformation();
|
||||||
|
// Ascend if good enough
|
||||||
|
for (let member of members) {
|
||||||
|
const r = gang.getAscensionResult(member);
|
||||||
|
if (!r) continue;
|
||||||
|
const mpl = r.agi * r.def * r.dex * r.str;
|
||||||
|
if (mpl > ASCEND_ON_MPL) {
|
||||||
|
gang.ascendMember(member);
|
||||||
|
ns.tprint(`Member ${member} ascended!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Purchase equipment
|
||||||
|
const allEquip = gang.getEquipmentNames();
|
||||||
|
let money = ns.getServerMoneyAvailable('home');
|
||||||
|
for (let equip of allEquip) {
|
||||||
|
const cost = gang.getEquipmentCost(equip);
|
||||||
|
const amount = money / cost;
|
||||||
|
if (amount < EQUIP_AFFORD_COEFF) continue;
|
||||||
|
for (let member of members) {
|
||||||
|
const info = gang.getMemberInformation(member);
|
||||||
|
if (info.upgrades.includes(equip) || info.augmentations.includes(equip)) continue;
|
||||||
|
if (gang.purchaseEquipment(member, equip)) {
|
||||||
|
money -= cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Find best stats
|
||||||
|
for (let member of members) {
|
||||||
|
let sum = getStatsSum(member);
|
||||||
|
if (sum > bestStats) bestStats = sum;
|
||||||
|
}
|
||||||
|
// Check if we are powerful enough
|
||||||
|
let powerfulEnough = info.power >= maxEnemyPower(info) * WARFARE_TRESHOLD;
|
||||||
|
gang.setTerritoryWarfare(powerfulEnough);
|
||||||
|
// Choose the default task for members
|
||||||
|
let task = defaultTask;
|
||||||
|
if (!defaultTask) {
|
||||||
|
// If gang isn't full - gain respect
|
||||||
|
if (members.length < MEMBERS_MAX) {
|
||||||
|
task = (members.length < MEMBERS_MIN) ? TASK_NOOB : TASK_RESPECT;
|
||||||
|
} else {
|
||||||
|
// if respect too low - gain it first, power second, money last
|
||||||
|
if (info.respect < RESPECT_MIN) {
|
||||||
|
task = TASK_RESPECT;
|
||||||
|
} else if (!powerfulEnough) {
|
||||||
|
task = TASK_WARFARE;
|
||||||
|
} else {
|
||||||
|
task = TASK_MONEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Assign tasks
|
||||||
|
for (let member of members) {
|
||||||
|
let sum = getStatsSum(member);
|
||||||
|
// Train members, not acceptable in 'noob mode'
|
||||||
|
if (sum < STATS_HARD_MIN || (members.length >= MEMBERS_MIN && sum < bestStats * STATS_TRESHOLD)) {
|
||||||
|
setAutoTask(member, TASK_TRAIN);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Vigi if wanted penalty too large
|
||||||
|
if (info.wantedLevel > 2 && info.wantedPenalty < WANTED_PENALTY_TRESHOLD) {
|
||||||
|
setAutoTask(member, TASK_VIGI);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Do the default task (autoselected or called with args[0])
|
||||||
|
setAutoTask(member, Math.random() < TRAIN_CHANCE ? TASK_TRAIN : task);
|
||||||
|
}
|
||||||
|
await ns.sleep(SLEEP_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
219
local/path/home/gang/gangManager.js
Normal file
219
local/path/home/gang/gangManager.js
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
import { GetFlag, GetArg } from "gang/argFunctions.js";
|
||||||
|
|
||||||
|
function getRandomInt(max) {
|
||||||
|
return Math.floor(Math.random() * Math.floor(max));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 30 possible gang members
|
||||||
|
// create list of names
|
||||||
|
let memberNamePool = [
|
||||||
|
"Thor", // 1
|
||||||
|
"Iron Man", // 2
|
||||||
|
"Starlord", // 3
|
||||||
|
"Thanos", // 4
|
||||||
|
"Groot", // 5
|
||||||
|
"Ant-Man", // 6
|
||||||
|
"Wasp", // 7
|
||||||
|
"Spiderman", // 8
|
||||||
|
"Loki", // 9
|
||||||
|
"Gamora", // 10
|
||||||
|
"Rocket Raccoon", // 11
|
||||||
|
"T'Challa", // 12
|
||||||
|
"Vision", // 13
|
||||||
|
"Scarlet Witch", // 14
|
||||||
|
"Winter Soldier", // 15
|
||||||
|
"Black Widow", // 16
|
||||||
|
"Hulk", // 17
|
||||||
|
"Bruce Banner", // 18
|
||||||
|
"Hawkeye", // 19
|
||||||
|
"Captain Marvel", // 20
|
||||||
|
"War Machine", // 21
|
||||||
|
"Nick Fury", // 22
|
||||||
|
"Nebula", // 23
|
||||||
|
"Drax", // 24
|
||||||
|
"Deadpool", // 25
|
||||||
|
"Cable", // 26
|
||||||
|
"Quicksilver", // 27
|
||||||
|
"Wolverine", // 28
|
||||||
|
"Adam Warlock", // 29
|
||||||
|
"Yondu", // 30
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
var buyAll = GetFlag(ns, "--buyAll");
|
||||||
|
|
||||||
|
var buyEquip = buyAll || GetFlag(ns, "--buyEquip");
|
||||||
|
|
||||||
|
var buyWeapon = buyAll || buyEquip || GetFlag(ns, "--buyWeapon");
|
||||||
|
var buyArmor = buyAll || buyEquip || GetFlag(ns, "--buyArmor");
|
||||||
|
var buyVehicle = buyAll || buyEquip || GetFlag(ns, "--buyVehicle");
|
||||||
|
var buyRoot = buyAll || buyEquip || GetFlag(ns, "--buyRoot");
|
||||||
|
|
||||||
|
var buyAug = buyAll || GetFlag(ns, "--buyAug");
|
||||||
|
|
||||||
|
var myGang = ns.gang.getGangInformation();
|
||||||
|
var possibleTasks = ns.gang.getTaskNames();
|
||||||
|
var unassignedTask = possibleTasks.shift();
|
||||||
|
|
||||||
|
var territoryTask = possibleTasks.pop();
|
||||||
|
var trainingTasks = possibleTasks.splice(possibleTasks.length - 3, 3);
|
||||||
|
var wantedLevelLowerTask = possibleTasks.pop();
|
||||||
|
|
||||||
|
var desirableAugs = [];
|
||||||
|
|
||||||
|
if (myGang.isHacking) {
|
||||||
|
wantedLevelLowerTask = possibleTasks.pop();
|
||||||
|
|
||||||
|
// replace combat with hacking
|
||||||
|
trainingTasks.splice(0, 1, trainingTasks[1]);
|
||||||
|
|
||||||
|
desirableAugs.push("BitWire");
|
||||||
|
desirableAugs.push("Neuralstimulator");
|
||||||
|
desirableAugs.push("DataJack");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// replace hacking with combat
|
||||||
|
trainingTasks.splice(1, 1, trainingTasks[0]);
|
||||||
|
|
||||||
|
desirableAugs.push("Bionic Arms");
|
||||||
|
desirableAugs.push("Bionic Legs");
|
||||||
|
desirableAugs.push("Bionic Spine");
|
||||||
|
desirableAugs.push("BrachiBlades");
|
||||||
|
desirableAugs.push("Nanofiber Weave");
|
||||||
|
desirableAugs.push("Synthetic Heart");
|
||||||
|
desirableAugs.push("Synfibril Muscle");
|
||||||
|
desirableAugs.push("Graphene Bone Lacings");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ascensionCycles = GetArg(ns, "--asc", 600000);
|
||||||
|
var nextAscensionAttempt = 0;
|
||||||
|
var cycleMs = 1100;
|
||||||
|
var ascensionMultLimit = GetArg(ns, "--alim", 2);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
myGang = ns.gang.getGangInformation();
|
||||||
|
var otherGangs = ns.gang.getOtherGangInformation();
|
||||||
|
var buyableEquipment = ns.gang.getEquipmentNames().filter(e => {
|
||||||
|
return ns.gang.getEquipmentType(e) != "Augmentation" || desirableAugs.includes(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
var members = ns.gang.getMemberNames();
|
||||||
|
|
||||||
|
while (ns.gang.canRecruitMember()) {
|
||||||
|
var possibleNames = memberNamePool.filter(name => !members.includes(name));
|
||||||
|
var toRecruit = possibleNames[getRandomInt(possibleNames.length)];
|
||||||
|
|
||||||
|
ns.gang.recruitMember(toRecruit);
|
||||||
|
await ns.sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
members = ns.gang.getMemberNames();
|
||||||
|
var memInfo = null;
|
||||||
|
|
||||||
|
members.sort((a, b) => { return Math.random() * 2 - 1; });
|
||||||
|
members.forEach((m) => {
|
||||||
|
var didBuy = false;
|
||||||
|
var hadAll = true;
|
||||||
|
|
||||||
|
memInfo = ns.gang.getMemberInformation(m);
|
||||||
|
|
||||||
|
ns.gang.setMemberTask(m, unassignedTask);
|
||||||
|
|
||||||
|
buyableEquipment.forEach((e) => {
|
||||||
|
if (memInfo.equipment.includes(e)) return;
|
||||||
|
if (memInfo.augmentations.includes(e)) return;
|
||||||
|
|
||||||
|
hadAll = false;
|
||||||
|
|
||||||
|
var type = ns.gang.getEquipmentType(e);
|
||||||
|
switch (type) {
|
||||||
|
case "Weapon":
|
||||||
|
if (buyWeapon) {
|
||||||
|
didBuy |= ns.gang.purchaseEquipment(m, e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Armor":
|
||||||
|
if (buyArmor) {
|
||||||
|
didBuy |= ns.gang.purchaseEquipment(m, e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Vehicle":
|
||||||
|
if (buyVehicle) {
|
||||||
|
didBuy |= ns.gang.purchaseEquipment(m, e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Rootkit":
|
||||||
|
if (buyRoot) {
|
||||||
|
didBuy |= ns.gang.purchaseEquipment(m, e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Augmentation":
|
||||||
|
if (buyAug) {
|
||||||
|
didBuy |= ns.gang.purchaseEquipment(m, e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var wantsToAscend = hadAll;
|
||||||
|
|
||||||
|
if (myGang.isHacking) {
|
||||||
|
wantsToAscend &= memInfo.hackingAscensionMult < ascensionMultLimit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wantsToAscend &= memInfo.hackingAscensionMult < ascensionMultLimit;
|
||||||
|
wantsToAscend &= memInfo.strengthAscensionMult < ascensionMultLimit;
|
||||||
|
wantsToAscend &= memInfo.agilityAscensionMult < ascensionMultLimit;
|
||||||
|
wantsToAscend &= memInfo.dexterityAscensionMult < ascensionMultLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantsToAscend && nextAscensionAttempt <= 0) {
|
||||||
|
ns.gang.ascendMember(m);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nextAscensionAttempt <= 0) {
|
||||||
|
nextAscensionAttempt = ascensionCycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
var member = "";
|
||||||
|
if (!myGang.isHacking) {
|
||||||
|
var memCount = members.length;
|
||||||
|
|
||||||
|
while (members.length > (memCount / 2)) {
|
||||||
|
member = members.pop();
|
||||||
|
ns.gang.setMemberTask(member, territoryTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (members.length > 0) {
|
||||||
|
var task = "";
|
||||||
|
member = members.pop();
|
||||||
|
memInfo = ns.gang.getMemberInformation(member);
|
||||||
|
|
||||||
|
var statsTarget = 50;
|
||||||
|
|
||||||
|
if ((myGang.isHacking && memInfo.hacking < statsTarget) ||
|
||||||
|
(!myGang.isHacking && memInfo.strength < statsTarget && memInfo.agility < statsTarget && memInfo.charisma < statsTarget && memInfo.defense < statsTarget)) {
|
||||||
|
task = trainingTasks[getRandomInt(trainingTasks.length)];
|
||||||
|
}
|
||||||
|
else if (myGang.wantedLevel > 1) {
|
||||||
|
task = wantedLevelLowerTask;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Math.random() > 0.25) {
|
||||||
|
task = possibleTasks[possibleTasks.length - getRandomInt(2) - 1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task = trainingTasks[getRandomInt(trainingTasks.length)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ns.gang.setMemberTask(member, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
await ns.sleep(cycleMs);
|
||||||
|
nextAscensionAttempt -= cycleMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
local/path/home/hacknetmanager.js
Normal file
41
local/path/home/hacknetmanager.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/** @param {NS} ns **/
|
||||||
|
export async function main(ns) {
|
||||||
|
function myMoney() {
|
||||||
|
return ns.getServerMoneyAvailable("home");
|
||||||
|
}
|
||||||
|
//this script is designed to manage the hacknet nodes
|
||||||
|
//to prevent excess spending i've limited it from spending
|
||||||
|
//more than half the players money
|
||||||
|
var nodes = 0;
|
||||||
|
var ref = 0;
|
||||||
|
ns.disableLog("ALL");
|
||||||
|
while (true) {
|
||||||
|
//sleep for second to prevent the loop from crashing the game
|
||||||
|
await ns.sleep(50);
|
||||||
|
//buy a node if we have more than twice the money needed
|
||||||
|
if (ns.hacknet.getPurchaseNodeCost() < myMoney() / 10) {
|
||||||
|
ref = ns.hacknet.purchaseNode();
|
||||||
|
ns.print("bought node hn-" + ref);
|
||||||
|
}
|
||||||
|
nodes = ns.hacknet.numNodes()
|
||||||
|
for (var i = 0; i < nodes; i++) {
|
||||||
|
//check if nodes level is a multiple of 10
|
||||||
|
var mod = ns.hacknet.getNodeStats(i).level % 10;
|
||||||
|
//buy level node to the nearest multiple of 10 if we have double the money needed
|
||||||
|
if (ns.hacknet.getLevelUpgradeCost(i, 10 - mod) < myMoney() / 10) {
|
||||||
|
ns.hacknet.upgradeLevel(i, 10 - mod);
|
||||||
|
ns.print("node hn-" + i + " leveled up");
|
||||||
|
}
|
||||||
|
//same for ram
|
||||||
|
if (ns.hacknet.getRamUpgradeCost(i) < myMoney() / 10) {
|
||||||
|
ns.hacknet.upgradeRam(i);
|
||||||
|
ns.print("node hn-" + i + " ram upgraded");
|
||||||
|
}
|
||||||
|
//and cores
|
||||||
|
if (ns.hacknet.getCoreUpgradeCost(i) < myMoney() / 10) {
|
||||||
|
ns.hacknet.upgradeCore(i);
|
||||||
|
ns.print("node hn-" + i + " core upgraded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
local/path/home/myLibrary.js
Normal file
77
local/path/home/myLibrary.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Custom color coding.
|
||||||
|
const cCyan = "\u001b[36m";
|
||||||
|
const cGreen = "\u001b[32m";
|
||||||
|
const cRed = "\u001b[31m";
|
||||||
|
const cReset = "\u001b[0m";
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.print("This script does nothing on its own, it contains functions for other scripts to use");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function purchaseServers(ns) {
|
||||||
|
|
||||||
|
const ram = 64;
|
||||||
|
|
||||||
|
let aServers = listPurchasedServers(ns);
|
||||||
|
let nServers = aServers.length;
|
||||||
|
if (nServers >= ns.getPurchasedServerLimit()) {
|
||||||
|
return nServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns.getServerMoneyAvailable("home") > ns.getPurchasedServerCost(ram)) {
|
||||||
|
let sFrontZero = "0";
|
||||||
|
if (nServers >= 9) {
|
||||||
|
sFrontZero = "";
|
||||||
|
}
|
||||||
|
let hostname = ns.purchaseServer("pserv-" + sFrontZero + (aServers.length + 1), ram);
|
||||||
|
|
||||||
|
ns.tprint("Purchased " + cCyan + hostname + cReset);
|
||||||
|
ns.toast("Purchased " + hostname, "info", 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
aServers = listPurchasedServers(ns);
|
||||||
|
return aServers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export function listPurchasedServers(ns) {
|
||||||
|
return ns.getPurchasedServers();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export function getSetting(ns, sSetting) {
|
||||||
|
let oSettings = JSON.parse(ns.read("settings.txt"));
|
||||||
|
let settingEntry = oSettings.setting[sSetting];
|
||||||
|
//ns.tprint(oSettings.setting[sSetting])
|
||||||
|
//ns.tprint("settingEntry = "+settingEntry);
|
||||||
|
return settingEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export function getGrowThreads(ns, sTarget, nHackThreads, nCores) {
|
||||||
|
let nHackAmountPercent = ns.hackAnalyze(sTarget) * nHackThreads;
|
||||||
|
let nGrowthThreads = ns.growthAnalyze(sTarget, 1 + nHackAmountPercent, nCores);
|
||||||
|
return nGrowthThreads;
|
||||||
|
}
|
||||||
23
local/path/home/notes.txt
Normal file
23
local/path/home/notes.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Karma loss per second by crime:
|
||||||
|
0.0500 Shoplifting
|
||||||
|
0.0083 Robbery
|
||||||
|
0.0625 Mugging
|
||||||
|
0.0167 Larceny
|
||||||
|
0.0500 Drug dealing
|
||||||
|
0.0003 Bond forgery
|
||||||
|
0.0250 Trafficking arms
|
||||||
|
1.0000 Homicide
|
||||||
|
0.0625 Grand theft auto
|
||||||
|
0.0500 Kidnapping
|
||||||
|
0.0333 Assassination
|
||||||
|
0.0250 The ultimate heist
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cool functions
|
||||||
|
ns.singularity.getOwnedSourceFiles();
|
||||||
|
ns.asleep();
|
||||||
|
ns.atExit();
|
||||||
|
ns.spawn();
|
||||||
|
ns.toast();
|
||||||
39
local/path/home/progress.js
Normal file
39
local/path/home/progress.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
const sMessage = ns.args[0]; //
|
||||||
|
const nCurrentProgress = ns.args[1]; //
|
||||||
|
const stest = ns.args[2];
|
||||||
|
|
||||||
|
const nPID = ns.pid;
|
||||||
|
const sFileName = "progress_" + nPID;
|
||||||
|
|
||||||
|
|
||||||
|
//ns.print("nPID = "+nPID);
|
||||||
|
const sProgress = [
|
||||||
|
"░░░░░░░░░░",
|
||||||
|
"█░░░░░░░░░",
|
||||||
|
"██░░░░░░░░",
|
||||||
|
"███░░░░░░░",
|
||||||
|
"████░░░░░░",
|
||||||
|
"█████░░░░░",
|
||||||
|
"██████░░░░",
|
||||||
|
"███████░░░",
|
||||||
|
"████████░░",
|
||||||
|
"█████████░",
|
||||||
|
"██████████"
|
||||||
|
];
|
||||||
|
ns.tail(nPID);
|
||||||
|
|
||||||
|
|
||||||
|
while (nCurrentProgress < 100) {
|
||||||
|
ns.read(""filename"");
|
||||||
|
ns.print(sProgress[Math.floor(nCurrentProgress / (sProgress.length - 1))]);
|
||||||
|
|
||||||
|
ns.write("filename", "text", "w");
|
||||||
|
|
||||||
|
}
|
||||||
|
if (nCurrentProgress >= 100)
|
||||||
|
ns.rm(sFileName);
|
||||||
|
return nPID;
|
||||||
|
|
||||||
|
}
|
||||||
52
local/path/home/pserv.js
Normal file
52
local/path/home/pserv.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
|
||||||
|
let aPservers = ns.getPurchasedServers();
|
||||||
|
ns.tprint("aPservers = " + aPservers);
|
||||||
|
let nPservers = aPservers.length;
|
||||||
|
ns.tprint("nPservers = " + nPservers);
|
||||||
|
|
||||||
|
let nCurrentRAM;
|
||||||
|
let nLowestRAM = 2 ** 21;
|
||||||
|
let nHighestRAM = 0;
|
||||||
|
let sLowestPserv;
|
||||||
|
let sHighestPserv;
|
||||||
|
let nTotalPServRAM = 0;
|
||||||
|
|
||||||
|
|
||||||
|
const oPservers = new Object();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const oPservers = {
|
||||||
|
pserv-01 : { name: "pserv-01" , ram: nRAM}
|
||||||
|
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (let i = 0; i < nPservers; i++) {
|
||||||
|
nCurrentRAM = ns.getServerMaxRam(aPservers[i]);
|
||||||
|
//ns.tprint("nTotalPServRAM = " + nTotalPServRAM + " + " + "nCurrentRAM = " + nCurrentRAM);
|
||||||
|
nTotalPServRAM += nCurrentRAM;
|
||||||
|
if (nCurrentRAM < nLowestRAM) {
|
||||||
|
nLowestRAM = nCurrentRAM
|
||||||
|
sLowestPserv = aPservers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCurrentRAM > nHighestRAM) {
|
||||||
|
nHighestRAM = nCurrentRAM
|
||||||
|
sHighestPserv = aPservers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns.tprint("sLowestPserv = " + sLowestPserv);
|
||||||
|
ns.tprint("nLowestRAM = " + nLowestRAM);
|
||||||
|
|
||||||
|
ns.tprint("sHighestPserv = " + sHighestPserv);
|
||||||
|
ns.tprint("nHighestRAM = " + nHighestRAM);
|
||||||
|
|
||||||
|
ns.tprint("nTotalPServRAM = " + nTotalPServRAM);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { getCracks, scanServerList, findBestTarget, crackingAndRooting, copyAndRunScript, purchaseAndUpgradeServers } from "/RamsesUtils.js";
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
await purchaseAndUpgradeServers(ns);
|
|
||||||
}
|
|
||||||
24
local/path/home/scanFactionAugments.js
Normal file
24
local/path/home/scanFactionAugments.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
|
||||||
|
let aFactions = ns.getPlayer().factions;
|
||||||
|
ns.tprint("aFactions = " + aFactions);
|
||||||
|
let aAugmentations;
|
||||||
|
let sStats;
|
||||||
|
|
||||||
|
for (let f = 0; f < aFactions.length; f++) {
|
||||||
|
//ns.tprint("f = " + f);
|
||||||
|
//sFaction = ns.singularity.faction
|
||||||
|
aAugmentations = ns.singularity.getAugmentationsFromFaction(aFactions[f]);
|
||||||
|
ns.tprint("aAugmentations = " + aAugmentations);
|
||||||
|
ns.tprint("----------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||||
|
for (let a = 0; a < aFactions.length; a++) {
|
||||||
|
sStats = JSON.stringify(ns.singularity.getAugmentationStats(aAugmentations[a]));
|
||||||
|
ns.tprint(aAugmentations[f] + "sStats = " + sStats);
|
||||||
|
ns.tprint("----------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
1
local/path/home/serverList.txt
Normal file
1
local/path/home/serverList.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -1,97 +1,83 @@
|
|||||||
|
|
||||||
|
|
||||||
|
// Custom color coding.
|
||||||
|
const cCyan = "\u001b[36m";
|
||||||
|
const cGreen = "\u001b[32m";
|
||||||
|
const cRed = "\u001b[31m";
|
||||||
|
const cReset = "\u001b[0m";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
/** @param {NS} ns */
|
||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
ns.tprint("This is just a function library, it doesn't do anything.");
|
let reset = ns.args[0];
|
||||||
}
|
const bSilent = ns.args[1] === true ? true : false; // if true supress feedback
|
||||||
|
//ns.tprint("bSilent = " + bSilent);
|
||||||
|
//host and script info
|
||||||
|
const sThisRunner = ns.getHostname();
|
||||||
|
const sThisScript = ns.getScriptName();
|
||||||
|
const nThisPID = ns.pid;
|
||||||
|
|
||||||
/** @param {NS} ns */
|
//open log for this script
|
||||||
export function getCracks(ns) {
|
if (!bSilent) ns.tail(nThisPID, sThisRunner, ns.args);
|
||||||
|
|
||||||
|
const funnyScript = ["breach.js", "batch.js", "grow.js", "weaken.js", "hack.js"];
|
||||||
|
const sScript = "breach.js";
|
||||||
|
//write function to purchase scripts from tor network and rerun getCracks() then recrack and reroot
|
||||||
let cracks = {};
|
let cracks = {};
|
||||||
if (ns.fileExists("BruteSSH.exe", "home")) {
|
cracks = getCracks(ns);
|
||||||
cracks["BruteSSH.exe"] = ns.brutessh;
|
let maxPorts = Object.keys(cracks).length;
|
||||||
};
|
scanServerList(ns, bSilent);
|
||||||
if (ns.fileExists("FTPCrack.exe", "home")) {
|
let manualTargetOverride = "";
|
||||||
cracks["FTPCrack.exe"] = ns.ftpcrack;
|
let nHackingLevel = ns.getHackingLevel();
|
||||||
};
|
let nServerMaxSecurity = 100;
|
||||||
if (ns.fileExists("relaySMTP.exe", "home")) {
|
|
||||||
cracks["relaySMTP.exe"] = ns.relaysmtp;
|
|
||||||
};
|
|
||||||
if (ns.fileExists("HTTPWorm.exe", "home")) {
|
|
||||||
cracks["HTTPWorm.exe"] = ns.httpworm;
|
|
||||||
};
|
|
||||||
if (ns.fileExists("SQLInject.exe", "home")) {
|
|
||||||
cracks["SQLInject.exe"] = ns.sqlinject;
|
|
||||||
};
|
|
||||||
return cracks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export function scanServerList(ns) {
|
|
||||||
const home = "home";
|
|
||||||
let serverList = {};
|
|
||||||
let unscanned = [];
|
|
||||||
unscanned.push(home);
|
|
||||||
while (unscanned.length > 0) {
|
|
||||||
let currentServer = unscanned.pop();
|
|
||||||
if (!serverList[currentServer]) {
|
|
||||||
let maxRam = ns.getServerMaxRam(currentServer);
|
|
||||||
let minPorts = ns.getServerNumPortsRequired(currentServer);
|
|
||||||
let minSecLevel = ns.getServerMinSecurityLevel(currentServer);
|
|
||||||
let minHackLevel = ns.getServerRequiredHackingLevel(currentServer);
|
|
||||||
let rootAccess = ns.hasRootAccess(currentServer);
|
|
||||||
let serverMoney = ns.getServerMaxMoney(currentServer);
|
|
||||||
let serverFiles = ns.ls(currentServer);
|
|
||||||
let skillFactor = (2.5 * minHackLevel * minSecLevel + 500) / (ns.getHackingLevel() + 50);
|
|
||||||
let compareTimeFactor = serverMoney / skillFactor / 10e7;
|
|
||||||
serverList[currentServer] =
|
|
||||||
{
|
|
||||||
serverName: currentServer,
|
|
||||||
maxRam: maxRam,
|
|
||||||
maxMoney: serverMoney,
|
|
||||||
minSec: minSecLevel,
|
|
||||||
minPorts: minPorts,
|
|
||||||
minHackLvl: minHackLevel,
|
|
||||||
rootAccess: rootAccess,
|
|
||||||
factorMoneyPerTime: compareTimeFactor,
|
|
||||||
openPorts: 0,
|
|
||||||
serverFiles: serverFiles,
|
|
||||||
};
|
|
||||||
let neighbours = ns.scan(currentServer);
|
|
||||||
for (let i = 0; i < neighbours.length; i++) {
|
|
||||||
let neighbour = neighbours[i];
|
|
||||||
if (serverList[neighbour]) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
unscanned.push(neighbour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
if (nHackingLevel < 10) {
|
||||||
export function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTargetOverride) {
|
manualTargetOverride = "n00dles";
|
||||||
if (!ns.fileExists("serverList.txt", "home")) scanServerList();
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//ns.tprint("find best target");
|
||||||
|
findBestTarget(ns, nServerMaxSecurity, maxPorts, ns.getHackingLevel(), manualTargetOverride);
|
||||||
|
//ns.tprint("Best Target found? ");
|
||||||
|
//let bestTarget = ns.read("bestTarget.txt");
|
||||||
|
//ns.tprint("Best Target: " + bestTarget);
|
||||||
|
//ns.tprint(Object.keys(JSON.parse(ns.read("serverList.txt"))).length);
|
||||||
|
crackingAndRooting(ns, cracks, funnyScript);
|
||||||
|
//ns.exec(funnyScript[0], "home", 1, JSON.parse(bestTarget).serverName);
|
||||||
|
//ns.print(reset);
|
||||||
|
if (reset === true) {
|
||||||
|
//ns.tprint("reset === true")
|
||||||
|
findBestTarget(ns, nServerMaxSecurity, maxPorts, ns.getHackingLevel(), manualTargetOverride);
|
||||||
let serverList = JSON.parse(ns.read("serverList.txt"));
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
let bestEntry = null;
|
|
||||||
let compareTime = 0;
|
|
||||||
for (const [name, entry] of Object.entries(serverList)) {
|
for (const [name, entry] of Object.entries(serverList)) {
|
||||||
if (entry.minSec <= maxSec && entry.minPorts <= maxPorts && entry.minHackLvl < currentHackLevel) {
|
//copyAndRunSript(ns, funnyScript, name);
|
||||||
if (entry.factorMoneyPerTime > compareTime) {
|
|
||||||
compareTime = entry.factorMoneyPerTime;
|
|
||||||
bestEntry = name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*let serverListForFiles = JSON.parse(ns.read("serverList.txt"));
|
||||||
|
for (const [name2, entry2] of Object.entries(serverListForFiles)) {
|
||||||
|
ns.tprint(name2 + " Files: " + entry2.serverFiles)
|
||||||
|
}*/
|
||||||
|
//await ns.sleep(500000);
|
||||||
|
//await purchaseAndUpgradeServers(ns, funnyScript);
|
||||||
|
//await runScriptsFromServers(ns, sScript, JSON.parse(bestTarget).serverName);
|
||||||
|
let oBestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
|
let sBestTarget = oBestTarget.serverName;
|
||||||
|
//ns.exec(sScript, "home", 1, sBestTarget);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(){
|
||||||
|
ns.exec(sScript,"home",1);
|
||||||
}
|
}
|
||||||
if (manualTargetOverride.length > 0) {
|
*/
|
||||||
bestEntry = manualTargetOverride;
|
|
||||||
}
|
|
||||||
ns.write("bestTarget.txt", JSON.stringify(serverList[bestEntry]), "w");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
/** @param {NS} ns */
|
||||||
export function crackingAndRooting(ns, cracks, funnyScript, copy) {
|
function crackingAndRooting(ns, cracks, funnyScript) {
|
||||||
if (!ns.fileExists("serverList.txt", "home")) scanServerList();
|
|
||||||
let serverList = JSON.parse(ns.read("serverList.txt"));
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
for (const [name, entry] of Object.entries(serverList)) {
|
for (const [name, entry] of Object.entries(serverList)) {
|
||||||
let cracked = false;
|
let cracked = false;
|
||||||
@@ -107,8 +93,8 @@ export function crackingAndRooting(ns, cracks, funnyScript, copy) {
|
|||||||
ns.nuke(name);
|
ns.nuke(name);
|
||||||
if (ns.hasRootAccess(name)) {
|
if (ns.hasRootAccess(name)) {
|
||||||
serverList[name].rootAccess = true;
|
serverList[name].rootAccess = true;
|
||||||
if (serverList[name].maxRam > 0 && copy === true) {
|
if (serverList[name].maxRam > 0) {
|
||||||
copyAndRunScript(ns, funnyScript, name);
|
copyAndRunSript(ns, funnyScript, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,13 +103,73 @@ export function crackingAndRooting(ns, cracks, funnyScript, copy) {
|
|||||||
ns.tprint("Cracking and rooting done");
|
ns.tprint("Cracking and rooting done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
async function purchaseAndUpgradeServers(ns, funnyScript) {
|
||||||
|
let maxPurchasedServers = ns.getPurchasedServerLimit();
|
||||||
|
let purchasedServers = [];
|
||||||
|
let count = listPurchasedServers(ns).length;
|
||||||
|
let currentMoney = 0;
|
||||||
|
let serverList = {};
|
||||||
|
while (count < maxPurchasedServers) {
|
||||||
|
purchasedServers = listPurchasedServers(ns);
|
||||||
|
currentMoney = ns.getServerMoneyAvailable("home");
|
||||||
|
let targetRamInitial = 16;
|
||||||
|
if (ns.getPurchasedServerCost(targetRamInitial) < currentMoney) {
|
||||||
|
let hostname = ns.purchaseServer("pserv-" + purchasedServers.length, 16);
|
||||||
|
count = listPurchasedServers(ns).length;
|
||||||
|
serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
|
serverList[hostname] = {
|
||||||
|
serverName: hostname,
|
||||||
|
maxRam: 16,
|
||||||
|
maxMoney: 0,
|
||||||
|
minSec: 0,
|
||||||
|
minPorts: 5,
|
||||||
|
minHackLvl: 1,
|
||||||
|
rootAccess: true,
|
||||||
|
factorMoneyPerTime: 99999999,
|
||||||
|
openPorts: 0,
|
||||||
|
};
|
||||||
|
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
||||||
|
copyAndRunSript(ns, funnyScript, hostname);
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
await ns.sleep(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let i = 5;
|
||||||
|
while (i < 21) {
|
||||||
|
let targetRam = 2 ** i;
|
||||||
|
purchasedServers = listPurchasedServers(ns);
|
||||||
|
for (let currentServer of purchasedServers) {
|
||||||
|
currentMoney = ns.getServerMoneyAvailable("home");
|
||||||
|
if (ns.getPurchasedServerUpgradeCost(currentServer, targetRam) < currentMoney) {
|
||||||
|
if (ns.upgradePurchasedServer(currentServer, targetRam)) {
|
||||||
|
ns.print(currentServer + " upgraded to " + targetRam + " GB RAM");
|
||||||
|
copyAndRunSript(ns, funnyScript, currentServer);
|
||||||
|
serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
|
serverList[currentServer].maxRam = targetRam;
|
||||||
|
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await ns.sleep(5000);
|
||||||
|
continue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
ns.tprint("Extiting purchaseServers script!")
|
||||||
|
}
|
||||||
|
|
||||||
/** @param {NS} ns */
|
/** @param {NS} ns */
|
||||||
export function copyAndRunScript(ns, funnyScript, currentServer) {
|
function listPurchasedServers(ns) {
|
||||||
|
return ns.getPurchasedServers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
function copyAndRunSript(ns, funnyScript, currentServer) {
|
||||||
// change to run for one specific server with bestTarget from file
|
// change to run for one specific server with bestTarget from file
|
||||||
//let minRam = ns.getScriptRam(funnyScript);
|
//let minRam = ns.getScriptRam(funnyScript);
|
||||||
let bestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
let bestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
|
|
||||||
let name = currentServer;
|
let name = currentServer;
|
||||||
let serverList = JSON.parse(ns.read("serverList.txt"));
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
ns.print(name);
|
ns.print(name);
|
||||||
@@ -137,16 +183,15 @@ export function copyAndRunScript(ns, funnyScript, currentServer) {
|
|||||||
if (serverList[name].maxRam > 0) {
|
if (serverList[name].maxRam > 0) {
|
||||||
ns.scp(funnyScript, name, "home");
|
ns.scp(funnyScript, name, "home");
|
||||||
let maxProcesses = 1;
|
let maxProcesses = 1;
|
||||||
if (serverList[name].maxRam >= 8) {
|
if (serverList[name].maxRam - 64 > 512) {
|
||||||
maxProcesses = Math.max(Math.floor((serverList[name].maxRam) / 8), 1);
|
|
||||||
|
maxProcesses = Math.max(Math.floor((serverList[name].maxRam - 64) / 512), 1);
|
||||||
} else {
|
} else {
|
||||||
maxProcesses = 1
|
maxProcesses = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let n = 1; n <= maxProcesses; n++) {
|
for (let n = 1; n <= maxProcesses; n++) {
|
||||||
ns.exec(funnyScript[0], name, 1, bestTarget.serverName);
|
ns.exec(funnyScript[0], name, 1, bestTarget.serverName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*let maxThreads = 0;
|
/*let maxThreads = 0;
|
||||||
if (name === "home") {
|
if (name === "home") {
|
||||||
maxThreads = Math.floor((serverList[name].maxRam - ns.getServerUsedRam(name) - 32) / minRam);
|
maxThreads = Math.floor((serverList[name].maxRam - ns.getServerUsedRam(name) - 32) / minRam);
|
||||||
@@ -171,108 +216,156 @@ export function copyAndRunScript(ns, funnyScript, currentServer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @param {NS} ns */
|
/** @param {NS} ns */
|
||||||
export async function purchaseAndUpgradeServers(ns) {
|
function getCracks(ns) {
|
||||||
ns.disableLog("sleep");
|
let cracks = {};
|
||||||
ns.disableLog("getServerMoneyAvailable");
|
if (ns.fileExists("BruteSSH.exe", "home")) {
|
||||||
ns.disableLog("getServerMaxRam");
|
cracks["BruteSSH.exe"] = ns.brutessh;
|
||||||
let maxPurchasedServers = ns.getPurchasedServerLimit();
|
};
|
||||||
let purchasedServers = [];
|
if (ns.fileExists("FTPCrack.exe", "home")) {
|
||||||
let count = listPurchasedServers(ns).length;
|
cracks["FTPCrack.exe"] = ns.ftpcrack;
|
||||||
let currentMoney = 0;
|
};
|
||||||
|
if (ns.fileExists("relaySMTP.exe", "home")) {
|
||||||
|
cracks["relaySMTP.exe"] = ns.relaysmtp;
|
||||||
|
};
|
||||||
|
if (ns.fileExists("HTTPWorm.exe", "home")) {
|
||||||
|
cracks["HTTPWorm.exe"] = ns.httpworm;
|
||||||
|
};
|
||||||
|
if (ns.fileExists("SQLInject.exe", "home")) {
|
||||||
|
cracks["SQLInject.exe"] = ns.sqlinject;
|
||||||
|
};
|
||||||
|
return cracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
function scanServerList(ns, bSilent) {
|
||||||
|
const home = "home";
|
||||||
let serverList = {};
|
let serverList = {};
|
||||||
while (count < maxPurchasedServers) {
|
let unscanned = [];
|
||||||
purchasedServers = listPurchasedServers(ns);
|
let nHackingLevel = ns.getHackingLevel();
|
||||||
currentMoney = ns.getServerMoneyAvailable("home");
|
let oServer;
|
||||||
let targetRamInitial = 16;
|
unscanned.push(home);
|
||||||
if (ns.getPurchasedServerCost(targetRamInitial) < currentMoney) {
|
while (unscanned.length > 0) {
|
||||||
let hostname = ns.purchaseServer("pserv-" + purchasedServers.length, 16);
|
let currentServer = unscanned.pop();
|
||||||
|
if (!serverList[currentServer]) {
|
||||||
count = listPurchasedServers(ns).length;
|
let maxRam = ns.getServerMaxRam(currentServer);
|
||||||
serverList = JSON.parse(ns.read("serverList.txt"));
|
let minPorts = ns.getServerNumPortsRequired(currentServer);
|
||||||
serverList[hostname] = {
|
let minSecLevel = ns.getServerMinSecurityLevel(currentServer);
|
||||||
serverName: hostname,
|
let minHackLevel = ns.getServerRequiredHackingLevel(currentServer);
|
||||||
maxRam: 16,
|
let rootAccess = ns.hasRootAccess(currentServer);
|
||||||
maxMoney: 0,
|
let serverMoney = ns.getServerMaxMoney(currentServer);
|
||||||
minSec: 0,
|
let serverFiles = ns.ls(currentServer);
|
||||||
minPorts: 5,
|
let skillFactor = (2.5 * minHackLevel * minSecLevel + 500) / (nHackingLevel + 50);
|
||||||
minHackLvl: 1,
|
let compareTimeFactor = serverMoney / skillFactor / 10e7;
|
||||||
rootAccess: true,
|
let nHackingChance = ns.hackAnalyzeChance(currentServer);
|
||||||
factorMoneyPerTime: 99999999,
|
oServer = ns.getServer(currentServer);
|
||||||
|
let sOrg = oServer.organizationName;
|
||||||
|
let nCores = oServer.cpuCores;
|
||||||
|
if (minHackLevel <= nHackingLevel && !currentServer.includes("home") && !currentServer.includes("pserv") && serverMoney > 0 && !bSilent) {
|
||||||
|
//if (!currentServer.includes("home") && !currentServer.includes("pserv") && !bSilent) {
|
||||||
|
ns.tprint("Server : " + currentServer);
|
||||||
|
ns.tprint("sOrg : " + sOrg);
|
||||||
|
ns.tprint("Hacking : " + minHackLevel);
|
||||||
|
ns.tprint("RAM : " + maxRam);
|
||||||
|
ns.tprint("Cores : " + nCores);
|
||||||
|
ns.tprint("Money : " + Math.floor(serverMoney).toLocaleString());
|
||||||
|
ns.tprint("Hack chance : " + Math.floor(nHackingChance * 10000) / 100 + " %");
|
||||||
|
ns.tprint("Security : " + minSecLevel);
|
||||||
|
ns.tprint("--------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
serverList[currentServer] =
|
||||||
|
{
|
||||||
|
serverName: currentServer,
|
||||||
|
maxRam: maxRam,
|
||||||
|
maxMoney: serverMoney,
|
||||||
|
minSec: minSecLevel,
|
||||||
|
minPorts: minPorts,
|
||||||
|
minHackLvl: minHackLevel,
|
||||||
|
rootAccess: rootAccess,
|
||||||
|
factorMoneyPerTime: compareTimeFactor,
|
||||||
openPorts: 0,
|
openPorts: 0,
|
||||||
|
serverFiles: serverFiles,
|
||||||
|
hackingChance: nHackingChance
|
||||||
};
|
};
|
||||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
let neighbours = ns.scan(currentServer);
|
||||||
|
for (let i = 0; i < neighbours.length; i++) {
|
||||||
|
let neighbour = neighbours[i];
|
||||||
|
if (serverList[neighbour]) {
|
||||||
continue
|
continue
|
||||||
} else {
|
}
|
||||||
await ns.sleep(5000);
|
unscanned.push(neighbour);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = 5;
|
|
||||||
while (i < 21) {
|
|
||||||
let targetRam = 2 ** i;
|
|
||||||
purchasedServers = listPurchasedServers(ns);
|
|
||||||
for (let currentServer of purchasedServers) {
|
|
||||||
currentMoney = ns.getServerMoneyAvailable("home");
|
|
||||||
|
|
||||||
if (ns.getServerMaxRam(currentServer) < targetRam && ns.getPurchasedServerUpgradeCost(currentServer, targetRam) < currentMoney) {
|
|
||||||
if (ns.upgradePurchasedServer(currentServer, targetRam)) {
|
|
||||||
ns.print(currentServer + " upgraded to " + targetRam + " GB RAM");
|
|
||||||
serverList = JSON.parse(ns.read("serverList.txt"));
|
|
||||||
serverList[currentServer].maxRam = targetRam;
|
|
||||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await ns.sleep(5000);
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
ns.tprint("Extiting purchaseServers script!")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {NS} ns */
|
/** @param {NS} ns */
|
||||||
function listPurchasedServers(ns) {
|
function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTargetOverride) {
|
||||||
return ns.getPurchasedServers();
|
//ns.tprint("start of findBestTarget ");
|
||||||
}
|
const bSilent = ns.args[1] === true ? true : false; // if true supress feedback
|
||||||
|
//ns.tprint("bSilent = " +bSilent);
|
||||||
/** @param {NS} ns */
|
let sCurrentBestTarget = JSON.parse(ns.read("bestTarget.txt"));
|
||||||
export async function runControllerOnPserv(ns) {
|
//let sCurrentBestTarget = "n00dles";
|
||||||
let purchasedServers = listPurchasedServers(ns);
|
//ns.tprint("sCurrentBestTarget = " +JSON.stringify(sCurrentBestTarget));
|
||||||
let nPID = 0;
|
//if (!bSilent) ns.tprint("sCurrentBestTarget = " + sCurrentBestTarget.serverName);
|
||||||
nPID = ns.exec("S2controller.js", "home");
|
|
||||||
ns.tprint("Started S2controller.js on " + "home" + " with PID " + nPID)
|
|
||||||
for (let currentServer of purchasedServers) {
|
|
||||||
ns.scp(["S2tGrow.js", "S2tWeaken.js", "S2tHack.js", "S2controller.js", "S2utils.js"], currentServer, "home");
|
|
||||||
nPID = ns.exec("S2controller.js", currentServer);
|
|
||||||
if (nPID > 0) {
|
|
||||||
ns.tprint("Started S2controller.js on " + currentServer + " with PID " + nPID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {NS} ns */
|
|
||||||
export async function backdoor(ns) {
|
|
||||||
let serverList = JSON.parse(ns.read("serverList.txt"));
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
let lasthackingLevel = 0;
|
let bestEntry = null;
|
||||||
let currentHackingLevel = 0;
|
let compareTime = 0;
|
||||||
while (true) {
|
let nMaxMoneyPerChance = 0;
|
||||||
currentHackingLevel = ns.getHackingLevel();
|
let nBestMoneyPerChance = 0;
|
||||||
if (currentHackingLevel > lasthackingLevel) {
|
//ns.tprint("before for loop ");
|
||||||
lasthackingLevel = currentHackingLevel;
|
|
||||||
for (const [name, entry] of Object.entries(serverList)) {
|
for (const [name, entry] of Object.entries(serverList)) {
|
||||||
if (entry.minHackLvl <= lasthackingLevel && entry.hasBackdoor !== true) {
|
if (entry.minSec <= maxSec && entry.minPorts <= maxPorts && entry.minHackLvl < currentHackLevel) {
|
||||||
ns.singularity.connect(name);
|
nMaxMoneyPerChance = (entry.maxMoney * entry.hackingChance) / entry.minSec;
|
||||||
await ns.singularity.installBackdoor();
|
//ns.tprint("nMaxMoneyPerChance " + nMaxMoneyPerChance);
|
||||||
ns.singularity.connect("home");
|
/*
|
||||||
serverList[name].hasBackdoor = true;
|
if (entry.factorMoneyPerTime > compareTime) {
|
||||||
ns.tprint("Backdoor on: " + name);
|
compareTime = entry.factorMoneyPerTime;
|
||||||
|
bestEntry = name;
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
if (nMaxMoneyPerChance > nBestMoneyPerChance) {
|
||||||
} else {
|
nBestMoneyPerChance = nMaxMoneyPerChance;
|
||||||
await ns.sleep(30000)
|
bestEntry = name;
|
||||||
};
|
if (!bSilent) ns.tprint("bestEntry " + bestEntry);
|
||||||
|
if (!bSilent) ns.tprint("╚ value = " + Math.floor(nMaxMoneyPerChance));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manualTargetOverride.length > 0) {
|
||||||
|
bestEntry = manualTargetOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sCurrentBestTarget.serverName === bestEntry) {
|
||||||
|
if (!bSilent) ns.tprint("Same target = " + bestEntry);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.tprint("New best target = " + cCyan + bestEntry + cReset);
|
||||||
|
}
|
||||||
|
ns.write("bestTarget.txt", JSON.stringify(serverList[bestEntry]), "w");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
async function runScriptsFromServers(ns, sScript, sTarget) {
|
||||||
|
let serverList = JSON.parse(ns.read("serverList.txt"));
|
||||||
|
let nScripts;
|
||||||
|
let nMaxRam = 0;
|
||||||
|
const nScriptRAM = ns.getScriptRam(sScript);
|
||||||
|
for (const [name, entry] of Object.entries(serverList)) {
|
||||||
|
//let rootAccess = ns.hasRootAccess(currentServer);
|
||||||
|
nMaxRam = ns.getServerMaxRam(entry.serverName);
|
||||||
|
nScripts = Math.floor(nMaxRam / nScriptRAM);
|
||||||
|
if (entry.maxRam >= 8 && serverList[name].rootAccess === true && !entry.serverName.includes("home") && !entry.serverName.includes("pserv")) {
|
||||||
|
//ns.killall(entry.serverName);
|
||||||
|
ns.scriptKill(sScript, entry.serverName);
|
||||||
|
ns.scp(sScript, entry.serverName);
|
||||||
|
while (nScripts > 0) {
|
||||||
|
ns.exec(sScript, entry.serverName, 1, sTarget);
|
||||||
|
nScripts--;
|
||||||
|
await ns.sleep(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
4
local/path/home/settings.txt
Normal file
4
local/path/home/settings.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"setting":{
|
||||||
|
"autoUpgrades":true,
|
||||||
|
"autoPurchaseServers":true
|
||||||
|
}}
|
||||||
34
local/path/home/sharePserv.js
Normal file
34
local/path/home/sharePserv.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
const bKill = ns.args[0]; // if true kill all existing processess
|
||||||
|
|
||||||
|
//host and script info
|
||||||
|
const sThisRunner = ns.getHostname();
|
||||||
|
//const sThisScript = ns.getScriptName();
|
||||||
|
const nThisPID = ns.pid;
|
||||||
|
|
||||||
|
//open log for this script
|
||||||
|
ns.tail(nThisPID, sThisRunner, ns.args);
|
||||||
|
|
||||||
|
|
||||||
|
//my servers
|
||||||
|
const nServ = ns.getPurchasedServers();
|
||||||
|
|
||||||
|
const sShareScript = "factionboost.js";
|
||||||
|
let nScripts = 0;
|
||||||
|
|
||||||
|
//kill all scripts
|
||||||
|
for (let i = 0; i < nServ.length; i++) {
|
||||||
|
|
||||||
|
nScripts = Math.floor(ns.getServerMaxRam(nServ[i]) / ns.getScriptRam(sShareScript));
|
||||||
|
|
||||||
|
if (bKill) { ns.killall(nServ[i]); }
|
||||||
|
else { ns.scriptKill(sShareScript, nServ[i]); }
|
||||||
|
ns.scp(sShareScript, nServ[i], "home");
|
||||||
|
|
||||||
|
let nShare = Math.floor(((ns.getServerMaxRam(nServ[i]) - ns.getServerUsedRam(nServ[i])) / ns.getScriptRam(sShareScript)));
|
||||||
|
if (nShare > 0) {
|
||||||
|
ns.exec(sShareScript, nServ[i], nShare);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
local/path/home/singularity/RMroutelist.js
Normal file
52
local/path/home/singularity/RMroutelist.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.tail();
|
||||||
|
let serverRoutes = await scanRecursiveWrapper(ns);
|
||||||
|
let currentHackingLevel = ns.getHackingLevel();
|
||||||
|
let currentArray = [];
|
||||||
|
let currentHop = "";
|
||||||
|
|
||||||
|
for (const [name, entry] of Object.entries(serverRoutes)) {
|
||||||
|
if (ns.getServerRequiredHackingLevel(name) < currentHackingLevel && ns.hasRootAccess(name) === true) {
|
||||||
|
currentArray = entry;
|
||||||
|
if (entry.length > 0) {
|
||||||
|
while (currentArray.length > 0) {
|
||||||
|
currentHop = currentArray.shift();
|
||||||
|
if (ns.singularity.connect(currentHop) === false) ns.tprint("Error when trying to connect to: " + currentHop);
|
||||||
|
}
|
||||||
|
ns.tprint("Trying to backdoor " + currentHop)
|
||||||
|
await ns.singularity.installBackdoor(currentHop);
|
||||||
|
ns.tprint("Success on " + currentHop)
|
||||||
|
ns.singularity.connect("home");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
async function scanRecursiveWrapper(ns) {
|
||||||
|
let startTime = Date.now();
|
||||||
|
ns.rm("ServerRouteList.txt");
|
||||||
|
await scanRecursive(ns, [], "home", startTime);
|
||||||
|
let result = JSON.parse("[" + ns.read("ServerRouteList.txt") + "{}]").reduce((acc, obj) => ({ ...acc, ...obj }), {});
|
||||||
|
ns.write("ServerRouteList.txt", JSON.stringify(result, "w"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
async function scanRecursive(ns, parents, currentServer, startTime) {
|
||||||
|
let currentTime = Date.now();
|
||||||
|
if (currentTime > startTime + 5) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
let currentChildren = ns.scan(currentServer);
|
||||||
|
let parentsSet = new Set(parents);
|
||||||
|
let cleanedChildren = currentChildren.filter(element => !parentsSet.has(element));
|
||||||
|
let tempServername = String(currentServer);
|
||||||
|
ns.write("ServerRouteList.txt", JSON.stringify({ [tempServername]: parents }) + ",", "a");
|
||||||
|
parents.push(currentServer);
|
||||||
|
for (let child in cleanedChildren) {
|
||||||
|
await scanRecursive(ns, parents, cleanedChildren[child], startTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
71
local/path/home/singularity/manualalgo.js
Normal file
71
local/path/home/singularity/manualalgo.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
const sNode = ns.args[0]; // target server
|
||||||
|
|
||||||
|
//logs
|
||||||
|
ns.disableLog("getServerSecurityLevel");
|
||||||
|
ns.disableLog("getServerMoneyAvailable");
|
||||||
|
|
||||||
|
//server info
|
||||||
|
const nMinSec = ns.getServerMinSecurityLevel(sNode);
|
||||||
|
const nMaxCash = ns.getServerMaxMoney(sNode);
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
//timestamp
|
||||||
|
let currentDate = new Date();
|
||||||
|
let ntimeStamp = currentDate.toLocaleTimeString('sw-SV') + " -";
|
||||||
|
|
||||||
|
const nCurrSec = ns.getServerSecurityLevel(sNode);
|
||||||
|
const nCurrCash = ns.getServerMoneyAvailable(sNode);
|
||||||
|
|
||||||
|
ns.print(ntimeStamp + "---------------------------------------------------------------");
|
||||||
|
ns.print("Cash: " + (Math.floor(nCurrCash * 1000) / 1000) + " / " + nMaxCash);
|
||||||
|
ns.print("Security: " + (Math.floor(nCurrSec * 1000) / 1000) + " / " + nMinSec);
|
||||||
|
|
||||||
|
if (nCurrSec > (nMinSec + 1)) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getWeakenTime(sNode);
|
||||||
|
let nWeakTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sWeakTime = nWeakTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Weakening " + sNode + " Estimated complete at " + sWeakTime);
|
||||||
|
|
||||||
|
//run weaken
|
||||||
|
await ns.weaken(sNode);
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
else if (nCurrCash < (nMaxCash * 0.9)) {
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getGrowTime(sNode);
|
||||||
|
let nGrowTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sGrowTime = nGrowTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Growing " + sNode + " Estimated complete at " + sGrowTime);
|
||||||
|
|
||||||
|
//run grow
|
||||||
|
await ns.grow(sNode);
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
//Calculate estimate time of completion
|
||||||
|
let nOffset = ns.getHackTime(sNode);
|
||||||
|
let nHackTime = new Date(currentDate.getTime() + nOffset);
|
||||||
|
let sHackTime = nHackTime.toLocaleTimeString('sw-SV');
|
||||||
|
|
||||||
|
|
||||||
|
//Print estimated time of completion
|
||||||
|
ns.print("Hacking " + sNode + " Estimated complete at " + sHackTime);
|
||||||
|
|
||||||
|
//run hack
|
||||||
|
//await ns.hack(sNode);
|
||||||
|
await ns.singularity.manualHack();
|
||||||
|
ns.print("-------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
local/path/home/test.js
Normal file
16
local/path/home/test.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
|
||||||
|
let oSettings = JSON.parse(ns.read("settings.txt"));
|
||||||
|
// let variable = someJSON.missingKey || ""
|
||||||
|
//let tempVar = oSettings.settings.missingKey || "";
|
||||||
|
//ns.tprint(tempVar)
|
||||||
|
|
||||||
|
ns.tprint(oSettings);
|
||||||
|
ns.tprint(JSON.stringify(oSettings));
|
||||||
|
ns.tprint(oSettings.setting.autoUpgrades);
|
||||||
|
|
||||||
|
//let tempVar = oSettings.settings.missingKey || "";
|
||||||
|
//ns.tprint(tempVar)
|
||||||
|
|
||||||
|
}
|
||||||
41
local/path/home/testhackgrow.js
Normal file
41
local/path/home/testhackgrow.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.tail();
|
||||||
|
const sTarget = ns.args[0]; // run on this target instead of best
|
||||||
|
const nHackThreads = ns.args[1] ? ns.args[1] : 1;
|
||||||
|
|
||||||
|
ns.disableLog("sleep");
|
||||||
|
|
||||||
|
ns.print("nHackThreads = " + nHackThreads);
|
||||||
|
|
||||||
|
//ns.tprint(ns.getHackingMultipliers());
|
||||||
|
|
||||||
|
let nHackAmountPercent = ns.hackAnalyze(sTarget) * nHackThreads;
|
||||||
|
let nTargetMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
let nHackAmount = nTargetMoney * nHackAmountPercent;
|
||||||
|
ns.print("nHackAmountPercent = " + nHackAmountPercent);
|
||||||
|
ns.print("nTargetMoney = " + nTargetMoney);
|
||||||
|
ns.print("nHackAmount = " + nHackAmount);
|
||||||
|
|
||||||
|
let nGrowthThreads = ns.growthAnalyze(sTarget, 1 + nHackAmountPercent, 1);
|
||||||
|
ns.print("nGrowthThreads = " + nGrowthThreads);
|
||||||
|
let nGrowThreadsINT = Math.ceil(nGrowthThreads);
|
||||||
|
ns.print("Hack() : Grow() Ratio = " + nHackThreads + ":" + nGrowThreadsINT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//test hack() and grow()
|
||||||
|
/*
|
||||||
|
let nHackPID = ns.exec("RMhack.js", "home", nHackThreads, sTarget);
|
||||||
|
ns.tail(nHackPID);
|
||||||
|
let nGrowPID = ns.exec("RMgrow.js", "home", nGrowThreadsINT, sTarget);
|
||||||
|
ns.tail(nGrowPID);
|
||||||
|
ns.print("Wait for Hack and Grow...");
|
||||||
|
while (ns.isRunning(nHackPID) || ns.isRunning(nGrowPID)) {
|
||||||
|
await ns.sleep(1000);
|
||||||
|
}
|
||||||
|
ns.print("Wait complete");
|
||||||
|
nTargetMoney = ns.getServerMoneyAvailable(sTarget);
|
||||||
|
ns.print("nTargetMoney = " + nTargetMoney);
|
||||||
|
*/
|
||||||
|
}
|
||||||
66
local/path/home/upgrade.js
Normal file
66
local/path/home/upgrade.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { listPurchasedServers, getSetting } from "myLibrary.js";
|
||||||
|
|
||||||
|
// Custom color coding.
|
||||||
|
const cCyan = "\u001b[36m";
|
||||||
|
const cGreen = "\u001b[32m";
|
||||||
|
const cRed = "\u001b[31m";
|
||||||
|
const cReset = "\u001b[0m";
|
||||||
|
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
ns.disableLog("ALL");
|
||||||
|
|
||||||
|
//host and script info
|
||||||
|
const sThisRunner = ns.getHostname();
|
||||||
|
|
||||||
|
//open log for this script
|
||||||
|
ns.tail(ns.pid, sThisRunner);
|
||||||
|
|
||||||
|
//const npServ = ["pserv-0", "pserv-1", "pserv-2", "pserv-3", "pserv-4", "pserv-5", "pserv-6", "pserv-7", "pserv-8", "pserv-9", "pserv-10", "pserv-11", "pserv-12", "pserv-13", "pserv-14", "pserv-15", "pserv-16", "pserv-17", "pserv-18", "pserv-19", "pserv-20", "pserv-21", "pserv-22", "pserv-23", "pserv-24"];
|
||||||
|
const npServ = listPurchasedServers(ns);
|
||||||
|
let nCurrentRAM = 4;
|
||||||
|
let nMyMoney = ns.getServerMoneyAvailable("home");
|
||||||
|
let bAutoUpgrade = getSetting(ns, "autoUpgrades");
|
||||||
|
while (bAutoUpgrade && nCurrentRAM < 2 ** 20) {
|
||||||
|
|
||||||
|
//for (let i = 0; i < npServ.length; i++) {
|
||||||
|
for (let i = 0; i < npServ.length && bAutoUpgrade; i++) {
|
||||||
|
ns.print("----------------------------------------------------------------------");
|
||||||
|
nMyMoney = ns.getServerMoneyAvailable("home");
|
||||||
|
|
||||||
|
let nNextRAM = nCurrentRAM * 2;
|
||||||
|
let nUpgradeCost = ns.getPurchasedServerUpgradeCost(npServ[i], nNextRAM);
|
||||||
|
|
||||||
|
ns.print("npServ = " + npServ[i]);
|
||||||
|
ns.print("nMyMoney = " + Math.ceil(nMyMoney).toLocaleString());
|
||||||
|
ns.print("nCurrentRAM = " + nCurrentRAM.toLocaleString());
|
||||||
|
ns.print("nNextRAM = " + nNextRAM);
|
||||||
|
ns.print("nUpgradeCost = " + Math.ceil(nUpgradeCost).toLocaleString());
|
||||||
|
|
||||||
|
while (bAutoUpgrade && nMyMoney < nUpgradeCost) {
|
||||||
|
ns.print("Money Treshold = " + Math.ceil(nMyMoney).toLocaleString() + " / " + Math.ceil(nUpgradeCost).toLocaleString());
|
||||||
|
await ns.sleep(1000);
|
||||||
|
bAutoUpgrade = getSetting(ns, "autoUpgrades");
|
||||||
|
if (bAutoUpgrade === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nMyMoney = ns.getServerMoneyAvailable("home");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns.upgradePurchasedServer(npServ[i], nNextRAM)) {
|
||||||
|
ns.print("Server: " + npServ[i] + " upgraded to: " + nNextRAM + "GB");
|
||||||
|
ns.tprint(cCyan + "Server: " + npServ[i] + " upgraded to: " + nNextRAM.toLocaleString() + " GB" + cReset);
|
||||||
|
ns.toast("Server: " + npServ[i] + " upgraded to: " + nNextRAM.toLocaleString() + " GB", "info", 10000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ns.print("Server: " + npServ[i] + " could not be upgraded to : " + nNextRAM + "GB it is currently at: " + ns.getServerMaxRam(npServ[i]) + "GB");
|
||||||
|
}
|
||||||
|
bAutoUpgrade = getSetting(ns, "autoUpgrades");
|
||||||
|
if (bAutoUpgrade === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nCurrentRAM *= 2;
|
||||||
|
}
|
||||||
|
ns.print("----------------------------------------------------------------------");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user