diff --git a/.gitignore b/.gitignore index e3b4457..83875d3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,11 @@ lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +# Non Clashing Bitburner Override +config.mjs* +*serverList.txt* +*bestTarget.txt* + # Runtime data pids *.pid diff --git a/Ramses/home/ContractSolverRamses.js b/Ramses/home/ContractSolverRamses.js new file mode 100644 index 0000000..75087d4 --- /dev/null +++ b/Ramses/home/ContractSolverRamses.js @@ -0,0 +1,161 @@ +/** @param {NS} ns */ +export async function main(ns) { + ns.tprint(ns.codingcontract.getContractTypes()) + let testcontract = ns.codingcontract.createDummyContract("Total Ways to Sum") + let contractType = ns.codingcontract.getContractType(testcontract); + ns.tprint(ns.codingcontract.getDescription(testcontract)) + let n = ns.codingcontract.getData(testcontract); + ns.tprint("Data: " + n); + let answer = ""; + if (contractType === "Find Largest Prime Factor") { + answer = largestPrimeFactor(n); + } + if (contractType === "Subarray with Maximum Sum") { + answer = SubarrayWithMaximumSum(ns, n) + } + if (contractType === "Total Ways to Sum") { + answer = TotalWaysToSum(ns, n) + } + + + ns.tprint(answer); + + ns.tprint(ns.codingcontract.attempt(answer, testcontract)); +} +/* +5: +4 1 +3 2 +3 1 1 +2 2 1 +2 1 1 1 +1 1 1 1 1 + +6: +5 1 +4 2 +4 1 1 +3 3 +3 2 1 +3 1 1 1 +2 2 2 +2 2 1 1 +2 1 1 1 1 +1 1 1 1 1 1 + +# Start with one position m filling it with the integers between 1 and target +# For each m, fill the next position n with integers between 1 and m +# Repeat as long as the sum is smaller than target. +# append all iterations to the Array and count +*/ + +function TotalWaysToSum(ns, target) { + let sumArray = []; + let inputArray = []; + let unfinishedArray = []; + let rollingSum = 0; + for (let i = 1; i < target; i++) { + inputArray.push([i]); + } + let z = 1 + while (inputArray.length > 0) { + z++ + inputArray.forEach((element) => { + rollingSum = element.reduce((a, b) => a + b, 0); + if (rollingSum === target) { + sumArray.push(element) + } else { + + for (let k = 1; k <= element[element.length-1] && k <= target - rollingSum; k++) { + + unfinishedArray.push(element.concat([k])) + } + } + } + ) + inputArray = unfinishedArray; + } + ns.tprint("Target: " +target) + ns.tprint("Length: " + sumArray.length) + return sumArray.length +} + + + + + + + + +function SubarrayWithMaximumSum(ns, givenArray) { + let arrayLength = givenArray.length; + let maxSum = -10000; + let runningSum = 0; + for (let i = 1; i <= arrayLength; i++) { + for (let j = 0; j <= arrayLength - i; j++) { + runningSum = eval(givenArray.slice(j, i + j).join('+')); + //ns.tprint("i: "+i+ " j: "+ j + " Array: "+givenArray.slice(j,i+j)+ " eval: "+ givenArray.slice(j,i+j).join('+')+"runningSum: "+runningSum); + if (maxSum < runningSum) { maxSum = runningSum }; + } + } + return maxSum +} + + +function FindLargestPrimeFactor(number) { + + let factor = 2; + while (factor * factor <= number) { + if (number % factor === 0) { + number /= factor; + } else { + factor++ + } + } + return number; +} + +/* +function FindLargestPrimeFactor(n) { + let x = Math.ceil(Math.random()*10); + let y = x; + let d = 1; + + while (d === 1) { + x = g(x, n); + y = g(g(y, n), n) + d = gcd(n, Math.abs(x - y)) + //ns.tprint("x:" + x + " y: " + y + " d: " + d) + } + if (d === n) { + return ("failure") + } + else { + return (d) + } +} + +function g(x, n) { + return (x * x) % n +} + +function gcd(a,b) { + a = Math.abs(a); + b = Math.abs(b); + if (b > a) {var temp = a; a = b; b = temp;} + while (true) { + if (b == 0) return a; + a %= b; + if (a == 0) return b; + b %= a; + } +} + + +function gcd(a, b) { + if (!b) { + return a; + } + return gcd(b, a % b); +} +*/ \ No newline at end of file diff --git a/Ramses/home/EveryServerRun.js b/Ramses/home/EveryServerRun.js new file mode 100644 index 0000000..143ab09 --- /dev/null +++ b/Ramses/home/EveryServerRun.js @@ -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); +} diff --git a/Ramses/home/HackingLog.txt b/Ramses/home/HackingLog.txt new file mode 100644 index 0000000..5570ebe --- /dev/null +++ b/Ramses/home/HackingLog.txt @@ -0,0 +1,929 @@ +39474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439475.7339705693439474.13899141901539474.13899141901539474.13899141901539475.7339705693436820.8084699284839474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901538937.5362797892339474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539471.74652269352439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439475.7339705693439474.13899141901539474.13899141901539474.13899141901537371.2852343816939475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539475.7339705693439474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.13899141901539474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36856.42175232096 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +36820.81372704521 +39474.138991419015 +39474.138991419015 +38941.46976158333 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37371.28523438169 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +38408.25982314148 +39474.138991419015 +39474.138991419015 +38400.9983274575 +38941.46976158333 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37371.28523438169 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +36820.80846992848 +39474.138991419015 +39475.73397056934 +37374.790437726195 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38407.20555259731 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39471.746522693524 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +37338.67713462529 +39474.138991419015 +38937.53627978923 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +38937.53627978923 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36869.083861930114 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +38408.25982314148 +39474.138991419015 +39475.73397056934 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39475.73397056934 +38937.53627978923 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +37371.28523438169 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36857.81038796931 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38400.9983274575 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +37328.116700688224 +39474.138991419015 +38407.20555259731 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +36820.80846992848 +39474.138991419015 +39474.138991419015 +37374.790437726195 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36857.80868272481 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37381.85788105512 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +37338.67713462529 +39474.138991419015 +38941.46976158333 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +38937.53627978923 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +38396.93835470901 +39474.138991419015 +39475.73397056934 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39474.138991419015 +38941.46976158333 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +38407.162377987515 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +37371.28523438169 +39475.73397056934 +38937.53627978923 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +38400.9983274575 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39471.746522693524 +39475.73397056934 +39474.138991419015 +37328.116700688224 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37381.85788105512 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +36833.45834451145 +39474.138991419015 +39474.138991419015 +37374.790437726195 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37374.79216692549 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +37338.67713462529 +39474.138991419015 +38937.53627978923 +38937.53627978923 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +37374.79130235312 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36820.81372704521 +38408.25982314148 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38941.46976158333 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39464.56911651706 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +38407.162377987515 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37371.28523438169 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +38400.9983274575 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +35392.824515811844 +39472.544012268685 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37364.22151863585 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38414.46822204606 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +37338.67713462529 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +37338.67713462529 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37371.28523438169 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39475.73397056934 +39475.73397056934 +39474.138991419015 +36820.80846992848 +39474.138991419015 +36833.46360343427 +36355.55335347026 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39471.746522693524 +38937.53627978923 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39471.746522693524 +39474.138991419015 +38941.46976158333 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39472.64369846559 +39474.138991419015 +39474.138991419015 +38400.9983274575 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +38407.20555259731 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38941.71801558968 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +37338.67713462529 +39474.138991419015 +39474.138991419015 +36355.55335347026 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38937.53627978923 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +36820.80846992848 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39475.73397056934 +39474.138991419015 +38937.53627978923 +38937.53627978923 +39474.138991419015 +38941.46976158333 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37328.116700688224 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +35861.52213272931 +39472.544012268685 +39474.138991419015 +37371.28523438169 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +36820.81372704521 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39471.746522693524 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38941.44817427843 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +36370.248403330195 +39474.138991419015 +39474.138991419015 +39474.138991419015 +38400.9983274575 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39475.73397056934 +38937.53627978923 +38407.20555259731 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39475.73397056934 +39474.138991419015 +39474.138991419015 +39474.138991419015 +39474.138991419015 +37360.65483616802 +39475.73397056934 +39475.73397056934 +39474.138991419015 +39474.138991419015 diff --git a/Ramses/home/Minimum_Path_Sum_in_a_Triangle.js b/Ramses/home/Minimum_Path_Sum_in_a_Triangle.js new file mode 100644 index 0000000..78b9bea --- /dev/null +++ b/Ramses/home/Minimum_Path_Sum_in_a_Triangle.js @@ -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++) { + + + } + + +} \ No newline at end of file diff --git a/Ramses/home/RMbreach.js b/Ramses/home/RMbreach.js new file mode 100644 index 0000000..5cd5ced --- /dev/null +++ b/Ramses/home/RMbreach.js @@ -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); + +} \ No newline at end of file diff --git a/Ramses/home/RMcontroller.js b/Ramses/home/RMcontroller.js new file mode 100644 index 0000000..2d1bd36 --- /dev/null +++ b/Ramses/home/RMcontroller.js @@ -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); + } +} \ No newline at end of file diff --git a/Ramses/home/RMgrow.js b/Ramses/home/RMgrow.js new file mode 100644 index 0000000..af66c8d --- /dev/null +++ b/Ramses/home/RMgrow.js @@ -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()); +} \ No newline at end of file diff --git a/Ramses/home/RMhack.js b/Ramses/home/RMhack.js new file mode 100644 index 0000000..bf297c9 --- /dev/null +++ b/Ramses/home/RMhack.js @@ -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()); +} \ No newline at end of file diff --git a/Ramses/home/RMweaken.js b/Ramses/home/RMweaken.js new file mode 100644 index 0000000..fe6e819 --- /dev/null +++ b/Ramses/home/RMweaken.js @@ -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()); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/Backdoor.js b/Ramses/home/Ramses/Backdoor.js new file mode 100644 index 0000000..77ff641 --- /dev/null +++ b/Ramses/home/Ramses/Backdoor.js @@ -0,0 +1,97 @@ +/** @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; +} diff --git a/Ramses/home/Ramses/ContractSolver.js b/Ramses/home/Ramses/ContractSolver.js new file mode 100644 index 0000000..75087d4 --- /dev/null +++ b/Ramses/home/Ramses/ContractSolver.js @@ -0,0 +1,161 @@ +/** @param {NS} ns */ +export async function main(ns) { + ns.tprint(ns.codingcontract.getContractTypes()) + let testcontract = ns.codingcontract.createDummyContract("Total Ways to Sum") + let contractType = ns.codingcontract.getContractType(testcontract); + ns.tprint(ns.codingcontract.getDescription(testcontract)) + let n = ns.codingcontract.getData(testcontract); + ns.tprint("Data: " + n); + let answer = ""; + if (contractType === "Find Largest Prime Factor") { + answer = largestPrimeFactor(n); + } + if (contractType === "Subarray with Maximum Sum") { + answer = SubarrayWithMaximumSum(ns, n) + } + if (contractType === "Total Ways to Sum") { + answer = TotalWaysToSum(ns, n) + } + + + ns.tprint(answer); + + ns.tprint(ns.codingcontract.attempt(answer, testcontract)); +} +/* +5: +4 1 +3 2 +3 1 1 +2 2 1 +2 1 1 1 +1 1 1 1 1 + +6: +5 1 +4 2 +4 1 1 +3 3 +3 2 1 +3 1 1 1 +2 2 2 +2 2 1 1 +2 1 1 1 1 +1 1 1 1 1 1 + +# Start with one position m filling it with the integers between 1 and target +# For each m, fill the next position n with integers between 1 and m +# Repeat as long as the sum is smaller than target. +# append all iterations to the Array and count +*/ + +function TotalWaysToSum(ns, target) { + let sumArray = []; + let inputArray = []; + let unfinishedArray = []; + let rollingSum = 0; + for (let i = 1; i < target; i++) { + inputArray.push([i]); + } + let z = 1 + while (inputArray.length > 0) { + z++ + inputArray.forEach((element) => { + rollingSum = element.reduce((a, b) => a + b, 0); + if (rollingSum === target) { + sumArray.push(element) + } else { + + for (let k = 1; k <= element[element.length-1] && k <= target - rollingSum; k++) { + + unfinishedArray.push(element.concat([k])) + } + } + } + ) + inputArray = unfinishedArray; + } + ns.tprint("Target: " +target) + ns.tprint("Length: " + sumArray.length) + return sumArray.length +} + + + + + + + + +function SubarrayWithMaximumSum(ns, givenArray) { + let arrayLength = givenArray.length; + let maxSum = -10000; + let runningSum = 0; + for (let i = 1; i <= arrayLength; i++) { + for (let j = 0; j <= arrayLength - i; j++) { + runningSum = eval(givenArray.slice(j, i + j).join('+')); + //ns.tprint("i: "+i+ " j: "+ j + " Array: "+givenArray.slice(j,i+j)+ " eval: "+ givenArray.slice(j,i+j).join('+')+"runningSum: "+runningSum); + if (maxSum < runningSum) { maxSum = runningSum }; + } + } + return maxSum +} + + +function FindLargestPrimeFactor(number) { + + let factor = 2; + while (factor * factor <= number) { + if (number % factor === 0) { + number /= factor; + } else { + factor++ + } + } + return number; +} + +/* +function FindLargestPrimeFactor(n) { + let x = Math.ceil(Math.random()*10); + let y = x; + let d = 1; + + while (d === 1) { + x = g(x, n); + y = g(g(y, n), n) + d = gcd(n, Math.abs(x - y)) + //ns.tprint("x:" + x + " y: " + y + " d: " + d) + } + if (d === n) { + return ("failure") + } + else { + return (d) + } +} + +function g(x, n) { + return (x * x) % n +} + +function gcd(a,b) { + a = Math.abs(a); + b = Math.abs(b); + if (b > a) {var temp = a; a = b; b = temp;} + while (true) { + if (b == 0) return a; + a %= b; + if (a == 0) return b; + b %= a; + } +} + + +function gcd(a, b) { + if (!b) { + return a; + } + return gcd(b, a % b); +} +*/ \ No newline at end of file diff --git a/Ramses/home/Ramses/CorpControl.js b/Ramses/home/Ramses/CorpControl.js new file mode 100644 index 0000000..4ed2131 --- /dev/null +++ b/Ramses/home/Ramses/CorpControl.js @@ -0,0 +1,14 @@ +/** @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) + } + +} \ No newline at end of file diff --git a/Ramses/home/Ramses/CrackAndRootAll.js b/Ramses/home/Ramses/CrackAndRootAll.js new file mode 100644 index 0000000..719803d --- /dev/null +++ b/Ramses/home/Ramses/CrackAndRootAll.js @@ -0,0 +1,8 @@ + +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); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/RamsesUtils.js b/Ramses/home/Ramses/RamsesUtils.js new file mode 100644 index 0000000..24d0ef4 --- /dev/null +++ b/Ramses/home/Ramses/RamsesUtils.js @@ -0,0 +1,278 @@ +/** @param {NS} ns */ +export async function main(ns) { + ns.tprint("This is just a function library, it doesn't do anything."); +} + +/** @param {NS} ns */ +export function getCracks(ns) { + let cracks = {}; + if (ns.fileExists("BruteSSH.exe", "home")) { + cracks["BruteSSH.exe"] = ns.brutessh; + }; + if (ns.fileExists("FTPCrack.exe", "home")) { + cracks["FTPCrack.exe"] = ns.ftpcrack; + }; + 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 */ +export function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTargetOverride) { + if (!ns.fileExists("serverList.txt", "home")) scanServerList(); + let serverList = JSON.parse(ns.read("serverList.txt")); + let bestEntry = null; + let compareTime = 0; + for (const [name, entry] of Object.entries(serverList)) { + if (entry.minSec <= maxSec && entry.minPorts <= maxPorts && entry.minHackLvl < currentHackLevel) { + if (entry.factorMoneyPerTime > compareTime) { + compareTime = entry.factorMoneyPerTime; + bestEntry = name; + } + } + } + if (manualTargetOverride.length > 0) { + bestEntry = manualTargetOverride; + } + ns.write("bestTarget.txt", JSON.stringify(serverList[bestEntry]), "w"); +} + + +/** @param {NS} ns */ +export function crackingAndRooting(ns, cracks, funnyScript, copy) { + if (!ns.fileExists("serverList.txt", "home")) scanServerList(); + let serverList = JSON.parse(ns.read("serverList.txt")); + for (const [name, entry] of Object.entries(serverList)) { + let cracked = false; + let openPorts = serverList[name].openPorts || 0; + if (entry.minPorts === 0 || (entry.minPorts > openPorts && entry.minPorts <= Object.keys(cracks).length)) { + for (let k = 0; k < entry.minPorts; k++) { + cracks[Object.keys(cracks)[k]](name); + serverList[name].openPorts = k; + } + cracked = true; + } + if (!ns.hasRootAccess(name) && cracked === true) { + ns.nuke(name); + if (ns.hasRootAccess(name)) { + serverList[name].rootAccess = true; + if (serverList[name].maxRam > 0 && copy === true) { + copyAndRunScript(ns, funnyScript, name); + } + } + } + ns.write("serverList.txt", JSON.stringify(serverList), "w"); + } + ns.tprint("Cracking and rooting done"); +} + + +/** @param {NS} ns */ +export function copyAndRunScript(ns, funnyScript, currentServer) { + // change to run for one specific server with bestTarget from file + //let minRam = ns.getScriptRam(funnyScript); + let bestTarget = JSON.parse(ns.read("bestTarget.txt")); + + let name = currentServer; + let serverList = JSON.parse(ns.read("serverList.txt")); + ns.print(name); + if (serverList[name].rootAccess === true && serverList[bestTarget.serverName].rootAccess === true) { + if (name !== "home") { + ns.print("killed threads on: " + name + ns.killall(name, true)); + } else { + ns.print("killed threads on: " + name + ns.scriptKill(funnyScript[0], name)); + }; + //move script and run + if (serverList[name].maxRam > 0) { + ns.scp(funnyScript, name, "home"); + let maxProcesses = 1; + if (serverList[name].maxRam >= 8) { + maxProcesses = Math.max(Math.floor((serverList[name].maxRam) / 8), 1); + } else { + maxProcesses = 1 + }; + + for (let n = 1; n <= maxProcesses; n++) { + ns.exec(funnyScript[0], name, 1, bestTarget.serverName); + } + + /*let maxThreads = 0; + if (name === "home") { + maxThreads = Math.floor((serverList[name].maxRam - ns.getServerUsedRam(name) - 32) / minRam); + ns.print(name + " " + maxThreads); + } else { + ns.print(name); + maxThreads = Math.floor(serverList[name].maxRam / minRam); + ns.print(name + " " + maxThreads); + }; + while (maxThreads > 0) { + let threadsToAssign = maxThreads < 500 ? maxThreads : 500; + if (ns.exec(funnyScript, name, threadsToAssign, bestTarget.serverName, serverList[bestTarget.serverName].minSec, serverList[bestTarget.serverName].maxMoney, JSON.stringify(serverList[bestTarget.serverName])) !== 0) { + ns.print("Executing script on: " + name + " with: " + threadsToAssign + " threads out of " + maxThreads + " total threads"); + maxThreads = maxThreads - threadsToAssign; + } else { + ns.tprint("Error running script on: " + name); + maxThreads = -1; + }; + }*/ + } + } +} + +/** @param {NS} ns */ +export async function purchaseAndUpgradeServers(ns) { + ns.disableLog("sleep"); + ns.disableLog("getServerMoneyAvailable"); + ns.disableLog("getServerMaxRam"); + 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"); + 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.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"); + } + } else { + await ns.sleep(5000); + continue + }; + } + ++i; + } + ns.tprint("Extiting purchaseServers script!") +} + +/** @param {NS} ns */ +function listPurchasedServers(ns) { + return ns.getPurchasedServers(); +} + +/** @param {NS} ns */ +export async function runControllerOnPserv(ns) { + let purchasedServers = listPurchasedServers(ns); + let nPID = 0; + 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 lasthackingLevel = 0; + let currentHackingLevel = 0; + while (true) { + currentHackingLevel = ns.getHackingLevel(); + if (currentHackingLevel > lasthackingLevel) { + lasthackingLevel = currentHackingLevel; + for (const [name, entry] of Object.entries(serverList)) { + if (entry.minHackLvl <= lasthackingLevel && entry.hasBackdoor !== true) { + ns.singularity.connect(name); + await ns.singularity.installBackdoor(); + ns.singularity.connect("home"); + serverList[name].hasBackdoor = true; + ns.tprint("Backdoor on: " + name); + } + } + ns.write("serverList.txt", JSON.stringify(serverList), "w"); + } else { + await ns.sleep(30000) + }; + + } +} diff --git a/Ramses/home/Ramses/S4controller.js b/Ramses/home/Ramses/S4controller.js new file mode 100644 index 0000000..46bd6ae --- /dev/null +++ b/Ramses/home/Ramses/S4controller.js @@ -0,0 +1,491 @@ +/* +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."); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/S4logHelper.js b/Ramses/home/Ramses/S4logHelper.js new file mode 100644 index 0000000..e1e8bdc --- /dev/null +++ b/Ramses/home/Ramses/S4logHelper.js @@ -0,0 +1,42 @@ +/* + 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()); + } +} \ No newline at end of file diff --git a/Ramses/home/Ramses/S4tGrow.js b/Ramses/home/Ramses/S4tGrow.js new file mode 100644 index 0000000..ad26af7 --- /dev/null +++ b/Ramses/home/Ramses/S4tGrow.js @@ -0,0 +1,30 @@ +/* + 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`); + }); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/S4tHack.js b/Ramses/home/Ramses/S4tHack.js new file mode 100644 index 0000000..a5ad51e --- /dev/null +++ b/Ramses/home/Ramses/S4tHack.js @@ -0,0 +1,30 @@ +/* + 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`); + }); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/S4tWeaken.js b/Ramses/home/Ramses/S4tWeaken.js new file mode 100644 index 0000000..b81ac60 --- /dev/null +++ b/Ramses/home/Ramses/S4tWeaken.js @@ -0,0 +1,41 @@ +/* + 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`); + }); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/S4utils.js b/Ramses/home/Ramses/S4utils.js new file mode 100644 index 0000000..e465b19 --- /dev/null +++ b/Ramses/home/Ramses/S4utils.js @@ -0,0 +1,420 @@ +/* + 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; +} \ No newline at end of file diff --git a/Ramses/home/Ramses/Serverlist.js b/Ramses/home/Ramses/Serverlist.js new file mode 100644 index 0000000..8b94568 --- /dev/null +++ b/Ramses/home/Ramses/Serverlist.js @@ -0,0 +1,42 @@ +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); + +} + diff --git a/Ramses/home/Ramses/analyzeContract.js b/Ramses/home/Ramses/analyzeContract.js new file mode 100644 index 0000000..2d2b025 --- /dev/null +++ b/Ramses/home/Ramses/analyzeContract.js @@ -0,0 +1,21 @@ +/** @param {NS} ns */ +export async function main(ns) { + const sTarget = ns.args[0]; // target server which has the contract + const sContract = ns.args[1]; // target contract file + + //ns.tprint(ns.codingcontract.getContractTypes()); + //ns.codingcontract.createDummyContract(); + + const sContractType = ns.codingcontract.getContractType(sContract, sTarget); + const sContractData = ns.codingcontract.getData(sContract, sTarget); + const sContractDescription = ns.codingcontract.getDescription(sContract, sTarget); + const sContractTries = ns.codingcontract.getNumTriesRemaining(sContract, sTarget); + + + ns.tprint("sContractType = " + sContractType); + ns.tprint("sContractData = " + sContractData); + ns.tprint("sContractDescription = " + sContractDescription); + ns.tprint("sContractTries = " + sContractTries); + + JSON.stringify(sContractType,sContractType, true); +} \ No newline at end of file diff --git a/Ramses/home/Ramses/corp/Autosell.js b/Ramses/home/Ramses/corp/Autosell.js new file mode 100644 index 0000000..ae30880 --- /dev/null +++ b/Ramses/home/Ramses/corp/Autosell.js @@ -0,0 +1,7 @@ +/** @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() +} \ No newline at end of file diff --git a/Ramses/home/Ramses/corp/HireWorkers.js b/Ramses/home/Ramses/corp/HireWorkers.js new file mode 100644 index 0000000..22fefa0 --- /dev/null +++ b/Ramses/home/Ramses/corp/HireWorkers.js @@ -0,0 +1,16 @@ +/** @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") : ""; + }; + } +} \ No newline at end of file diff --git a/Ramses/home/Ramses/corp/SetupExport.js b/Ramses/home/Ramses/corp/SetupExport.js new file mode 100644 index 0000000..69c0dd4 --- /dev/null +++ b/Ramses/home/Ramses/corp/SetupExport.js @@ -0,0 +1,13 @@ +/** @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); + } +} \ No newline at end of file diff --git a/Ramses/home/Ramses/corp/Smart.js b/Ramses/home/Ramses/corp/Smart.js new file mode 100644 index 0000000..e733958 --- /dev/null +++ b/Ramses/home/Ramses/corp/Smart.js @@ -0,0 +1,6 @@ +/** @param {NS} ns */ +export async function main(ns) { + let [corpName, city] = ns.args; + //ns.corporation.setSmartSupply(corpName, city, true); + return true; +} \ No newline at end of file diff --git a/Ramses/home/Ramses/corp/UpgradeOffice.js b/Ramses/home/Ramses/corp/UpgradeOffice.js new file mode 100644 index 0000000..e811f44 --- /dev/null +++ b/Ramses/home/Ramses/corp/UpgradeOffice.js @@ -0,0 +1,12 @@ +/** @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); + }; + } +} \ No newline at end of file diff --git a/Ramses/home/Ramses/killAllScript.js b/Ramses/home/Ramses/killAllScript.js new file mode 100644 index 0000000..cc54271 --- /dev/null +++ b/Ramses/home/Ramses/killAllScript.js @@ -0,0 +1,8 @@ +/** @param {NS} ns */ +export async function main(ns) { + let serverList = JSON.parse(ns.read("serverList.txt")); + for (const [name, entry] of Object.entries(serverList)) { + + ns.killall(name, true) + } +} diff --git a/Ramses/home/Ramses/purchaseServers.js b/Ramses/home/Ramses/purchaseServers.js new file mode 100644 index 0000000..e79b9cb --- /dev/null +++ b/Ramses/home/Ramses/purchaseServers.js @@ -0,0 +1,5 @@ +import { getCracks, scanServerList, findBestTarget, crackingAndRooting, copyAndRunScript, purchaseAndUpgradeServers } from "/RamsesUtils.js"; +/** @param {NS} ns */ +export async function main(ns) { + await purchaseAndUpgradeServers(ns); +} \ No newline at end of file diff --git a/Ramses/home/ServerRouteList.txt b/Ramses/home/ServerRouteList.txt new file mode 100644 index 0000000..8a0de16 --- /dev/null +++ b/Ramses/home/ServerRouteList.txt @@ -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":{}}} \ No newline at end of file diff --git a/Ramses/home/algorithm.js b/Ramses/home/algorithm.js new file mode 100644 index 0000000..bd1002e --- /dev/null +++ b/Ramses/home/algorithm.js @@ -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("-------------------------------------------------------------------------"); + } + } +} \ No newline at end of file diff --git a/Ramses/home/ascii/detective.txt b/Ramses/home/ascii/detective.txt new file mode 100644 index 0000000..bd744a5 --- /dev/null +++ b/Ramses/home/ascii/detective.txt @@ -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 \ No newline at end of file diff --git a/Ramses/home/ascii/detective2.txt b/Ramses/home/ascii/detective2.txt new file mode 100644 index 0000000..a4f152d --- /dev/null +++ b/Ramses/home/ascii/detective2.txt @@ -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 \ No newline at end of file diff --git a/Ramses/home/ascii/detective3.txt b/Ramses/home/ascii/detective3.txt new file mode 100644 index 0000000..9f6d021 --- /dev/null +++ b/Ramses/home/ascii/detective3.txt @@ -0,0 +1,54 @@ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▒▓▓▓▒▒▒▒▒▒▒▓▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓ +▓▒ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▒▒▒▒▒▒▓▓▓▒▒▒░░▓▒▒▓▓▓▓▓▓▒▓▓▓▒░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▒▒▒▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒░░░▒▒▒▓▓▓▒▓▒▒▒▓▓░░░▒▒▒▓▒▒▓▓▒▓▒▓▓▓▓▒▒▒▓▓▓▓▓▓▒▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▒▒░░░░░▒▒▒▒▒▒▒▒▓▓▓▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▒░ ▒▒▒▒▒▒▓▒▒▒▒▓▓▓▓▒▒▒▓▓▓▓▓▓▒▒▒▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▒░ ▒▒▒▒▒▒▒░▓▓▒▒▒░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒░▒▒▒▓▓▓▓▓▒▒▓▒ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▒▒▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒░░░▒▒▒▒▒▒▒▓▒▓▒░▒▒▒▓▒▒▒▒▓▓▓▒ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░ ░░░░▒▒▒▒▒▒▒▒▒▒▓▒▒░▒▒▒▒░░▒░ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░ ░░▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒░░░░░▒▒ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▒░▒░░░░░░░░░░░ ░░░▒▒▒▒▒▒▒▒▒▓▒▒░░░░▒▒▒▓▒ +▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒░▒▒▒▒▒▒▒░░ ░▒░░░░░░░░░░░ ░░░▒▒▒▒▒▒▒▒▒▒▒░▒▓▓▓▓▒▒▓▒ +▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░ ░░░░░ ░░░░░░░░░░░░░░▒▒▒▒░▒▒░▒▒░▒▓▓▓▓▒▒▒▒░ +▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▒▓▓▓▓▒░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒░░ ░ ░░░░░░░▒░░░▒▒▒░░░░▒▒▒▒▒░▒▒▒▒▓▒░▒▒░░ +▓▓▓▒░░░▓▓▓▓▒▓▓▓▒▓▓▓░░▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░ ░░░░░░▒▒░░▒░▒▒▒▒▒▒▒▒▓▒░▒▒ ░▒░ ░▒▒░ +▓▓▓▓▓▓▒▓▓▓▓▓▒▓▓▒▒░ ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒░▒▒░░░░░░░ ░░░░░▒▒▒▒░▒▒▒▒▒▒▒▓▓▓▓▓ ░ ░░ ░▒ +▓▓▓▒▒░▒▒▓▓▓▒▒░░░░░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒░▒▒▒░░░░░ ░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▒░ ░ ░▒ +▓▓▓▒▒░▒▒▓▒▒░░ ░░▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒░░░░░░░░ ░░░░░░▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒ ░ ░ ░ ░▒▒▒ +▒▒▒▒▓▓▒▒▓▒▒▒▒▒▒▒▓▓▓▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒░▒▒▒▒░░░▒▒░░░░░░░ ░░░░░░░▒▒▒▓▒▒▒▒▒▒░ ░░░▒▓▒▒▒░▒ ▓▓▓▒▒▓ + ░▓▓▒▓▓▓▒▓▓▓▓▓▒░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒░▒▒▒░░▒▒▒░░░░░░░░░░░░░░░▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒░▒░ ░▓▓▓▓▒▓ + ░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░▒▒▒▒▒▒░░░░░░▒░░░░░▒░░▒░ ▒▒░▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒ ▒▓▓▓▓▓▓ + ▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░░▒▒░░░░░░░░░▒▒░▒▒▒▒▒▒ ░ ▒▒▓▓▒▒▒▒░▒▒░░▒▒▓▒░▒▓▓▓▓▓▓ +▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░░░▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▓▒░ ░▒ ▒▒▒▓▒▒▒▒▒▒▒░░▒▒▓▓▒▒▓▓▓▓▓▓ +▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░▒▒▒░ ░░ ▒▒▒▒▒▒▒▒▓▓▒░▒▒░▒▒▒▓▒▒▒▒░ ▒░░░▒▓▓▒▒▓▓▓▓▓▓ +▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒▒░ ░░ ░▒▒▒▒▒▒▓▓▓▓▒▓▓▒▒▒▒▓▓▒▒▒░ ▒░▒▒▒▓▓▒▓▓▓▓▓▓▓ +░▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒ ░▒░░▒▓▓▓▓▓▓▓▓▓▒▒▒▒▓▓▒▒▒▒░▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓ + ▒▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ░▒▒░ ░░ ▒▒▒░▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▒▒▒▓▒▒▒▒▒▒░▓▓▓▓▓▓▓▓▓▓ +▒░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒░▒▒▒▒ ▒▒▒░▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ░▒▒░▒▒▒▒ ░▒▒▒░▓▒▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓ +▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒▒▒▒▒▒▒░░░▒▒▒░▓▒▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓ +▓▓▒▓▓▓▒▒▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒░▒▒▒▒░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▒▒▒▓▓▓▒▒▒▓▒▒▒▒▒░ ░░░░▒▒ ░▒▒▒▒▓▓▓▓▓▓▓▓▓▓▒▒▓▓▒▒▒▒▒░░▒░░▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▒▒▒░ ░░░░▒░░░░▒▒▒░▒▒▓▓▓▓▓▒▒▒▒▓▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▒▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒░▓▓▓▓▓▓▒░ ░▓▓▓▓▒▒▒▒▒▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░░░░░░░▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒░░░▒▒▒▒░▒▒▒▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░▒░░░░░ ░░░▒▒▒▓▓▒▒▒▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒░░ ░░░░░ ░░ ▒▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▒▓▓▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ░░▒▒░░ ░ ░░░░░▒▒▓▓▓▓▓▓▓▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░░▒▒ ░░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▒ ▒▒▓▓▓▒░░▒▒▒▒▒▓▓▓▓▓▒▒▒▒░░▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒░ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒░▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒░░░▓▒▒▓▓▓▓▒▓▓▓▓▓▓▓▓▓░░ +▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▓▒ ▒░ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▒▒░ +▓▒▒▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▒▓▓ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒ ░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓ +▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▓▓▒▒▒▒░ ░░ ░ ░▒▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▒▓▓▒▓▓▒▒▒ ▒▒░ ░ ░░ ▒░▒▒░▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒ +▓▓▓▒░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ░▒ ░░░▒░ ░ ░░░░░░▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓█ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░ ░░░░▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▓▓█▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▒▓▒▒░▒▓▓▓▓▒░ ▒▓▓▓▓▓▓▓▒░░░░▒▓░░░▒▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓ +▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▒░ ▒▒▒▒▒▓▓▒▓▒▒▓▓▓▓▓▓▓▓▓▓ +▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░▒▓▓▓▒░ ░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓ +▓▓▓█▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░ ░░▓▓▓▓▒░ ░░▒░░ ▒▓▓▓▓▓▓██████▓▓ +▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓█▓███▓▓▓▓███▓▓▓▓▓▓▓▒▒▓▓▒░▓▓▓▓▒░ ▒▒▒░ ▒▒▓▓▓▒░ ░ ▒▒░ ░▒▒▓▓▓▓▓▓▓▓▓▓▓ \ No newline at end of file diff --git a/Ramses/home/ascii/hacker.txt b/Ramses/home/ascii/hacker.txt new file mode 100644 index 0000000..91e5102 --- /dev/null +++ b/Ramses/home/ascii/hacker.txt @@ -0,0 +1,33 @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*-%@%: :%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ *@@@= *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ %@@@@@: =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# #@@@@#- =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%.-@@#: *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ =#%*+=-. #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%. +%@@@@@@@%. :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# *@@@@@@@@@@@@@@@* %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% @@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@ .%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% :@@@@@@@@@@@@@@@+ =%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ @@@@@@@@@@@@% :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@= #@* #@@@@@@@@@% -+-. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- @@@@@@@*:#@@@@@@@@=+@@@@@+ * .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# @%@@@@@@@@@@@@@@@@@@@@@@@@@=%@@ =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@% -@@@@@+====-----::::.... %@@% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ :==@@@@ =##%%%%%%%%%%%%%%%%%%%%* %@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@= -@@@@@@ *@@@@@@@@@@@@@@@@@@@@@@# %@@@@@* @@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@:*@@@@@@@@@@@@@@@@@@@@@@#.%@@@@@== *@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@*:=#%#-. :*%*+@@@@@@@@*: :#@@@@@@@@#=@@@=. ...:%@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#%@@@@@@+@@@@@@@@*. .*@@@@@@@@##%*+=. %@@#@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@%##@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ No newline at end of file diff --git a/Ramses/home/ascii/judge.txt b/Ramses/home/ascii/judge.txt new file mode 100644 index 0000000..b960409 --- /dev/null +++ b/Ramses/home/ascii/judge.txt @@ -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 \ No newline at end of file diff --git a/Ramses/home/ascii/noir.txt b/Ramses/home/ascii/noir.txt new file mode 100644 index 0000000..713a536 --- /dev/null +++ b/Ramses/home/ascii/noir.txt @@ -0,0 +1,58 @@ +@@@@@@@@@@@@@%@@%%@%###(>{=*<[{%@@%@@@@%{#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@%%#%@%#(^ ~ :<}@@@@@@@@@%@##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@%#{#%%@@@% (#%%@@@@@@@@@@{{%%@@%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@%{{%%#@@@@@( . <}@@@@@@@@@%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@%%}#%#@@@@@@@@. {@@@@@@@%%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@%%#{##%@@@@@@@%{ -] [%@@@@@@@%%%###%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@%###@@@@@@@@@@@%%{ + @%%@@@@@@%%##############%%%%%%%@%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@%#{#%@@@@@@@@@@@@%{({[~+@%%@@@@@%################%%%%%%%@%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@%#{%@@@@@@@@@@@@@@@@%}%#(#%@@@@@@%%##{{{#{{{{{{{{#######%%%%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@ +@@%#{{%@@@@@@@@@@@@@@@@@@%%%#[%@@@@%%%##{{{{{{{{{{{{{#############%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@@@@@ +@%#}[%@@@@@@@@@@@@@@@@@@@@@@#%%@@@@%%##{{}}}{{{{{{{{{{{{#######%##%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@ +%#{}#@@@@@@@@@@@@@@@@@@@@@%%#%%@@@%%%{{{}[[}}{{{{{{{{{{{{{########[#%%%%%%%%%%%%%%%%%@@@@@@@@@@@@@@@ +{{}%@@@@@@@@@@@@@@@@@@@@@@@%%%%%@@%%#{}}[]][[[[[[[}}{{{{{{{{{{{{{}*}#%%%%%######%%%%%%%%%@@@@@@@@@@@ +][%%%@@@@@@@@@@@@@@@@@@@@@@%%%@@%%%##}}[[]]][[[[[[[[}}{{{{{{{{{{{{###############%%%%%%%%@@@@@@@@@@@ +#%%%%%%@@@@@@@@@@@@@@@@@@@@%##%%%##{{[[]]((]]]]][]]][}}}}}}{{{{{{{{{{{{{{{########%%%%%%%%%%@@@@@@@@ +@%%%%#%%%@@@@@@@@@@@@@@@@@@%##%###{{}]]]())((]]] (][[[[}}}}}{{{{{{{{{{{########%%%%%%%%%%@@@@@@@@ +#######%%%%%%%%%%%@@@@@@@@%#%{##%#{[])))))<)))((( ([[][[[[}}}}}}}{{{{{{{{{{{{{{##%%%%%%%%%@@@@@@@@ +{{{#{######%%%%%%%%@@@@%@(##)}{###{[(<<<<<><))))])><]]]]]]][[[[[[[}}}}{}}[{{{{{{{##%%%%%%%%%@@@@@@@@ +{{{{{{#############%%%%@@@@%{}{{{#}])>>>>>>>><<<))((((( >]]]]]]][[[}}}}}{{{{{####%%%%%%%%@@%%%@@@@ +{{{{{{{{{{{{{{{}{{####%%%@@%{}{{{}])>^^^^^^^><<<<))))))* =(((]]]][[[[}}}{{{{{####%%%%%%%%@@%%%@@@@ +{{{{{{{{{{}}}[[[[][}}}}{%%@%}[[[[[(>*++++***^>>>>>>><<<<)( >)([[[[[} >( [[{{{{######%%%%%%%@@@@ +}}}}}}}}}[[]]]]((((]]()]{%@%[]((](>+~=++++++**^^^^>>>>>><> =->- ))[]][[}]>]{}}{{}{{######%%%%%%%@@@@ +[[[}[[[[[]]]((()<>^<>+~^({%#<)(())*----~====+++++***^^^>><<<<<)))((]]][[[}}}}{{{{{{######%%%%%%%%%@@ +]]]]]]]]]]]()>^*+*^*~~=.*[%#- ]( :..:----~====+++**^^>>>><<<))(((]]][[[}}}}}{{{{######%%%%%%%%%@@ +)(]((((](<<<<<>==+=~-~+ >#{=%@@@. .::::--~~=+++**^^>>><<)))(((]]]][[[}}}{{{{{#####%%%%%%%%%@@ +)))(((()<>>=--=~~ .*%@%%@%}- .:-~=+++**^^>>><<)))(((]((]][[}}}{{{{{#####%%%%%%%%%@@ +)<<<)))<<>*+*=- ..~}#%@@{+ ==++**^^^>><<)))(((]]]]][[}}}{{{{######%%%%%%%%%%% +))<>><<<>*-. . : #%%%@@# -~=+++*^^^>><<)))(((]]]]][[}}}{{{{######%%%%%%%%%%% +)>>>>>>>>>*+~=~:: : }@@@%%@%= *] -++**^^^>><<))((((]][[[[[}}}{{{{{#####%%%%%%%%%@@ +)^^><<<>>>^~++~ . }@@@@@@%%{{# .**^^^>><<))((((][[[[[[}}}{{{{{#####%%%%%%%%%@@ +)>>>>><>^^*++*~: . . }%@@@@@@@@@% +*^^>>><<))(((]]][[[[[}}}{{{{{{####%%%%%%%%%%% +)<>>>>>>^^**=**++~::-. {#){%%%%%%%* ~+***^^>>><<))(((]]][[[[[}}}{{{{{{####%%%%%%%%%%% +()<)<<<>>^^^^^^*+~ ~- . #[ <@@@@@%) =++*^^^>>><<))((]]]][[[[[}}}{{{{{{{{{#%%%%%%%%%%@ +(((()<<<>>^*^^^^*++~ -:-::{[ (@@@@@@# :---~~==++*^^^>>><<))((((]][[[[[}}}{{{{{{{{{#%%%%%%%%%%@ +((]))>^>>>^**><^+*+++--=>^%%)]@@@@@@( - .:-~~===+++**^^>><<<))((]]]][[[[[}}}{{{{{{{{{####%%%%%%%% +](>^><)>++*+*^^^+=+++=~++)@%(<%@@@@@@]+:::----~=++**+**^^>><<<)))((]]]][[[[}}}}{{{{{{{{{####%%%%%%%% +{()^==***-==^~ - :-=**^*}%%(*)}#%@@@@@(-~~~-~===+++*^^^>><<)))))((]]][[[[}}}}{{{{{{{{{{####%%%%%%%% +([[(][)^+-: ::~.:=^>>*=[%%(++*)}{{#%%@#[+=++++++**^>>>><<<)))((((]]][[[[}}}}{{{{{{{{###%%%%%%%%%@@ +<][}[[]((^ -.=++~+*^>><><{@%[^*+>[##%%@@@#(*++****^^>><<<<)))))((((]]][[[}}}}}}{{{{{{{###%%%%%%%%%@@ +(]{}][})<>=-^)^>)<<<*^<)({@%[^**>[##%%%#}])>***^^^>>><<<)))))((((]]]]][[}}}{{{{{{{{{{{###%%%%%%%%@@@ +[-}{{}}]*=>)>++]]())<<^)]#@%[+>}{%%#[<<.(())<^*^>>><<<<<)))((((]][[[[}}}}}{{{{{{{##{{{#%%%%%%%%%%%%% +<+(^[{[}[>^<^([])(]]]((][#%#()}%##%%{))>(]]((<>*><<<<<<)))))(((]][[[[[[[[}}}}}}}}}}[(]][}}}}}}}}{{{{ +)*){])}[](+^^]]]>]}[[}]}[#%{)([]]{%%<=><>*+=~. ----~==++++***^>><<<))((((]]]][[[}}]**^><<<))(((]]][ ++~](})>[[(~*(>)())[[}}[[[#%}<^+~.^#%( >+++++**^^^^***^^^>>^^^>>>>>>>>^^^^+*= -~+*******^>>> ++[~<]}]<(]*^*^>>>*<>**+*=]{[>. ]%^ .:---= ....::-:-~~ +(^*=+==**+:- ~: =}(+ *%> *]]]])<<<<<<<)((((((]]]]](][[][[}[]][}}]] +===~- . [(~ (%% +=::. [): >} .-~=+*><)((]}}}[}}}}{{{{{{##{{#{#%> + . ])= }^ ))[#{#{{{}}}}[[[[]((<<<<<>^^>>><<))<))<<>^^*~: + <[] [{( + =[]= ]{} + ^###[ +{{{] .-=*^<<)))(][}}}{%#%%%%%@%%%%%%%@%) + [{{}~ <#%%# %%%@@@@@@@@@@@%%%%%%##%%%%%%%%%%%#@%@%%%%%%%%%%%%%#{( + ~++*+ + -^^*^*- =^^^^^^^^^^*===~~~~~--. :-:::--~:.. + + + + \ No newline at end of file diff --git a/Ramses/home/ascii/sonic.js b/Ramses/home/ascii/sonic.js new file mode 100644 index 0000000..5138053 --- /dev/null +++ b/Ramses/home/ascii/sonic.js @@ -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<..% "); + +} \ No newline at end of file diff --git a/Ramses/home/autoexec.js b/Ramses/home/autoexec.js new file mode 100644 index 0000000..580f6a1 --- /dev/null +++ b/Ramses/home/autoexec.js @@ -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); + } +} \ No newline at end of file diff --git a/Ramses/home/backup/batch2.js b/Ramses/home/backup/batch2.js new file mode 100644 index 0000000..ac7041c --- /dev/null +++ b/Ramses/home/backup/batch2.js @@ -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); + } +} \ No newline at end of file diff --git a/Ramses/home/backup/bitnodeStart.js b/Ramses/home/backup/bitnodeStart.js new file mode 100644 index 0000000..ebe7daf --- /dev/null +++ b/Ramses/home/backup/bitnodeStart.js @@ -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); + } + + + +} \ No newline at end of file diff --git a/Ramses/home/backup/growrepeater.js b/Ramses/home/backup/growrepeater.js new file mode 100644 index 0000000..7674063 --- /dev/null +++ b/Ramses/home/backup/growrepeater.js @@ -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); } +} \ No newline at end of file diff --git a/Ramses/home/backup/maxGrow.js b/Ramses/home/backup/maxGrow.js new file mode 100644 index 0000000..e9447bf --- /dev/null +++ b/Ramses/home/backup/maxGrow.js @@ -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); + + +} \ No newline at end of file diff --git a/Ramses/home/batch.js b/Ramses/home/batch.js new file mode 100644 index 0000000..1c4a9b0 --- /dev/null +++ b/Ramses/home/batch.js @@ -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("-------------------------------------------------------------------------"); + } + +} \ No newline at end of file diff --git a/Ramses/home/bestTarget.txt b/Ramses/home/bestTarget.txt new file mode 100644 index 0000000..55ddf0d --- /dev/null +++ b/Ramses/home/bestTarget.txt @@ -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} \ No newline at end of file diff --git a/Ramses/home/breach.js b/Ramses/home/breach.js new file mode 100644 index 0000000..32fc888 --- /dev/null +++ b/Ramses/home/breach.js @@ -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)); + } + } + + + +} \ No newline at end of file diff --git a/Ramses/home/contract.js b/Ramses/home/contract.js new file mode 100644 index 0000000..2d2b025 --- /dev/null +++ b/Ramses/home/contract.js @@ -0,0 +1,21 @@ +/** @param {NS} ns */ +export async function main(ns) { + const sTarget = ns.args[0]; // target server which has the contract + const sContract = ns.args[1]; // target contract file + + //ns.tprint(ns.codingcontract.getContractTypes()); + //ns.codingcontract.createDummyContract(); + + const sContractType = ns.codingcontract.getContractType(sContract, sTarget); + const sContractData = ns.codingcontract.getData(sContract, sTarget); + const sContractDescription = ns.codingcontract.getDescription(sContract, sTarget); + const sContractTries = ns.codingcontract.getNumTriesRemaining(sContract, sTarget); + + + ns.tprint("sContractType = " + sContractType); + ns.tprint("sContractData = " + sContractData); + ns.tprint("sContractDescription = " + sContractDescription); + ns.tprint("sContractTries = " + sContractTries); + + JSON.stringify(sContractType,sContractType, true); +} \ No newline at end of file diff --git a/Ramses/home/fixpserv.js b/Ramses/home/fixpserv.js new file mode 100644 index 0000000..6e11d95 --- /dev/null +++ b/Ramses/home/fixpserv.js @@ -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); + +} \ No newline at end of file diff --git a/Ramses/home/gang/argFunctions.js b/Ramses/home/gang/argFunctions.js new file mode 100644 index 0000000..928a340 --- /dev/null +++ b/Ramses/home/gang/argFunctions.js @@ -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; +} \ No newline at end of file diff --git a/Ramses/home/gang/auto-gang.js b/Ramses/home/gang/auto-gang.js new file mode 100644 index 0000000..30be000 --- /dev/null +++ b/Ramses/home/gang/auto-gang.js @@ -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 + } +} \ No newline at end of file diff --git a/Ramses/home/gang/auto-gang2.js b/Ramses/home/gang/auto-gang2.js new file mode 100644 index 0000000..d35977e --- /dev/null +++ b/Ramses/home/gang/auto-gang2.js @@ -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); + } +} \ No newline at end of file diff --git a/Ramses/home/gang/gangManager.js b/Ramses/home/gang/gangManager.js new file mode 100644 index 0000000..36323aa --- /dev/null +++ b/Ramses/home/gang/gangManager.js @@ -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; + } +} \ No newline at end of file diff --git a/Ramses/home/hacknetmanager.js b/Ramses/home/hacknetmanager.js new file mode 100644 index 0000000..24db287 --- /dev/null +++ b/Ramses/home/hacknetmanager.js @@ -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"); + } + } + } +} \ No newline at end of file diff --git a/Ramses/home/killallall.js b/Ramses/home/killallall.js new file mode 100644 index 0000000..601ae5b --- /dev/null +++ b/Ramses/home/killallall.js @@ -0,0 +1,8 @@ +/** @param {NS} ns */ +export async function main(ns) { + let serverList = JSON.parse(ns.read("serverList.txt")); + for (const [name, entry] of Object.entries(serverList)) { + + ns.killall(name, true) + } +} \ No newline at end of file diff --git a/Ramses/home/myLibrary.js b/Ramses/home/myLibrary.js new file mode 100644 index 0000000..3374fe3 --- /dev/null +++ b/Ramses/home/myLibrary.js @@ -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; +} \ No newline at end of file diff --git a/Ramses/home/notes.txt b/Ramses/home/notes.txt new file mode 100644 index 0000000..264a786 --- /dev/null +++ b/Ramses/home/notes.txt @@ -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(); \ No newline at end of file diff --git a/Ramses/home/progress.js b/Ramses/home/progress.js new file mode 100644 index 0000000..5f32724 --- /dev/null +++ b/Ramses/home/progress.js @@ -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; + +} \ No newline at end of file diff --git a/Ramses/home/pserv.js b/Ramses/home/pserv.js new file mode 100644 index 0000000..cbe2626 --- /dev/null +++ b/Ramses/home/pserv.js @@ -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); + +} \ No newline at end of file diff --git a/Ramses/home/scanFactionAugments.js b/Ramses/home/scanFactionAugments.js new file mode 100644 index 0000000..ebbc94a --- /dev/null +++ b/Ramses/home/scanFactionAugments.js @@ -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("----------------------------------------------------------------------------------------------------------------------------------------------------------"); + } + + } + + +} \ No newline at end of file diff --git a/Ramses/home/serverList.txt b/Ramses/home/serverList.txt new file mode 100644 index 0000000..eed3882 --- /dev/null +++ b/Ramses/home/serverList.txt @@ -0,0 +1 @@ +{"home":{"serverName":"home","maxRam":32768,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["AutoLink.exe","BruteSSH.exe","ContractSolverRamses.js","DeepscanV1.exe","DeepscanV2.exe","EveryServerRun.js","FTPCrack.exe","HTTPWorm.exe","HackingLog.txt","Minimum_Path_Sum_in_a_Triangle.js","NUKE.exe","RMbreach.js","RMcontroller.js","RMgrow.js","RMhack.js","RMweaken.js","SQLInject.exe","ServerRouteList.txt","algorithm.js","ascii/detective.txt","ascii/detective2.txt","ascii/detective3.txt","ascii/hacker.txt","ascii/judge.txt","ascii/noir.txt","ascii/sonic.js","autoexec.js","b1t_flum3.exe","backdoor.js","backup/batch2.js","backup/bitnodeStart.js","backup/growrepeater.js","backup/maxGrow.js","batch.js","bestTarget.txt","breach.js","contract.js","csec-test.msg","factionboost.js","fixpserv.js","fl1ght.exe","gang/argFunctions.js","gang/auto-gang.js","gang/auto-gang2.js","gang/gangManager.js","hackers-starting-handbook.lit","hacknetmanager.js","j0.msg","j1.msg","j2.msg","j3.msg","killallall.js","myLibrary.js","nitesec-test.msg","notes.txt","progress.js","pserv.js","relaySMTP.exe","scanFactionAugments.js","serverList.txt","serverlister.js","settings.txt","sharePserv.js","singularity/RMroutelist.js","singularity/manualalgo.js","test.js","testhackgrow.js","upgrade.js"],"hackingChance":1},"pserv-25":{"serverName":"pserv-25","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-24":{"serverName":"pserv-24","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-23":{"serverName":"pserv-23","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-22":{"serverName":"pserv-22","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-21":{"serverName":"pserv-21","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-20":{"serverName":"pserv-20","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-19":{"serverName":"pserv-19","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-18":{"serverName":"pserv-18","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-17":{"serverName":"pserv-17","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-16":{"serverName":"pserv-16","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-15":{"serverName":"pserv-15","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-14":{"serverName":"pserv-14","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-13":{"serverName":"pserv-13","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-12":{"serverName":"pserv-12","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-11":{"serverName":"pserv-11","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-10":{"serverName":"pserv-10","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-09":{"serverName":"pserv-09","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-08":{"serverName":"pserv-08","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-07":{"serverName":"pserv-07","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-06":{"serverName":"pserv-06","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-05":{"serverName":"pserv-05","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-04":{"serverName":"pserv-04","maxRam":1024,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-03":{"serverName":"pserv-03","maxRam":2048,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-02":{"serverName":"pserv-02","maxRam":2048,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"pserv-01":{"serverName":"pserv-01","maxRam":2048,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":1},"darkweb":{"serverName":"darkweb","maxRam":0,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":[],"hackingChance":1},"iron-gym":{"serverName":"iron-gym","maxRam":32,"maxMoney":56250000,"minSec":10,"minPorts":1,"minHackLvl":100,"rootAccess":true,"factorMoneyPerTime":0.0774375,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":0.7794502647993277},"harakiri-sushi":{"serverName":"harakiri-sushi","maxRam":16,"maxMoney":11250000,"minSec":5,"minPorts":0,"minHackLvl":40,"rootAccess":true,"factorMoneyPerTime":0.0464625,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":1},"hong-fang-tea":{"serverName":"hong-fang-tea","maxRam":16,"maxMoney":8437500,"minSec":5,"minPorts":0,"minHackLvl":30,"rootAccess":true,"factorMoneyPerTime":0.03982499999999999,"openPorts":0,"serverFiles":["brighter-than-the-sun.lit","factionboost.js"],"hackingChance":1},"joesguns":{"serverName":"joesguns","maxRam":16,"maxMoney":7031250,"minSec":5,"minPorts":0,"minHackLvl":10,"rootAccess":true,"factorMoneyPerTime":0.0464625,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":1},"sigma-cosmetics":{"serverName":"sigma-cosmetics","maxRam":16,"maxMoney":6468750,"minSec":3,"minPorts":0,"minHackLvl":5,"rootAccess":true,"factorMoneyPerTime":0.049704069767441864,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":1},"CSEC":{"serverName":"CSEC","maxRam":8,"maxMoney":0,"minSec":1,"minPorts":1,"minHackLvl":57,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":0,"serverFiles":["democracy-is-dead.lit","factionboost.js"],"hackingChance":1},"foodnstuff":{"serverName":"foodnstuff","maxRam":16,"maxMoney":5625000,"minSec":3,"minPorts":0,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0.04577586206896552,"openPorts":0,"serverFiles":["factionboost.js","sector-12-crime.lit"],"hackingChance":1},"max-hardware":{"serverName":"max-hardware","maxRam":32,"maxMoney":28125000,"minSec":5,"minPorts":1,"minHackLvl":80,"rootAccess":true,"factorMoneyPerTime":0.0774375,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":0.9818410505113837},"omega-net":{"serverName":"omega-net","maxRam":32,"maxMoney":196514330.625,"minSec":11,"minPorts":2,"minHackLvl":210,"rootAccess":true,"factorMoneyPerTime":0.12933931242729083,"openPorts":1,"serverFiles":["factionboost.js","the-new-god.lit"],"hackingChance":0.7872795714853008},"avmnite-02h":{"serverName":"avmnite-02h","maxRam":32,"maxMoney":0,"minSec":1,"minPorts":2,"minHackLvl":208,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":1,"serverFiles":["democracy-is-dead.lit","factionboost.js"],"hackingChance":0.8799357426547211},"I.I.I.I":{"serverName":"I.I.I.I","maxRam":128,"maxMoney":0,"minSec":1,"minPorts":3,"minHackLvl":363,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":2,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","democracy-is-dead.lit","myLibrary.js"],"hackingChance":0.560708030281446},"lexo-corp":{"serverName":"lexo-corp","maxRam":16,"maxMoney":2069915557.5,"minSec":21,"minPorts":4,"minHackLvl":674,"rootAccess":true,"factorMoneyPerTime":0.23822631329176533,"openPorts":3,"serverFiles":[],"hackingChance":0},"snap-fitness":{"serverName":"snap-fitness","maxRam":0,"maxMoney":1265625000,"minSec":17,"minPorts":4,"minHackLvl":720,"rootAccess":true,"factorMoneyPerTime":0.16807174437299036,"openPorts":3,"serverFiles":[],"hackingChance":0},"aerocorp":{"serverName":"aerocorp","maxRam":0,"maxMoney":2964352080.9375,"minSec":28,"minPorts":5,"minHackLvl":915,"rootAccess":true,"factorMoneyPerTime":0.1896634251630035,"openPorts":4,"serverFiles":["man-and-machine.lit"],"hackingChance":0},"unitalife":{"serverName":"unitalife","maxRam":64,"maxMoney":2954374959.375,"minSec":23,"minPorts":4,"minHackLvl":799,"rootAccess":true,"factorMoneyPerTime":0.262724198357512,"openPorts":3,"serverFiles":[],"hackingChance":0},"univ-energy":{"serverName":"univ-energy","maxRam":16,"maxMoney":3187267405.3125,"minSec":27,"minPorts":4,"minHackLvl":815,"rootAccess":true,"factorMoneyPerTime":0.2371252309649291,"openPorts":3,"serverFiles":[],"hackingChance":0},"nova-med":{"serverName":"nova-med","maxRam":0,"maxMoney":3119127378.75,"minSec":24,"minPorts":4,"minHackLvl":849,"rootAccess":true,"factorMoneyPerTime":0.25042760641985806,"openPorts":3,"serverFiles":[],"hackingChance":0},"applied-energetics":{"serverName":"applied-energetics","maxRam":0,"maxMoney":2018441970,"minSec":25,"minPorts":4,"minHackLvl":838,"rootAccess":true,"factorMoneyPerTime":0.15765797325957448,"openPorts":3,"serverFiles":[],"hackingChance":0},"stormtech":{"serverName":"stormtech","maxRam":0,"maxMoney":2971835586.5625,"minSec":31,"minPorts":5,"minHackLvl":1032,"rootAccess":true,"factorMoneyPerTime":0.15250597629849807,"openPorts":4,"serverFiles":[],"hackingChance":0},"kuai-gong":{"serverName":"kuai-gong","maxRam":0,"maxMoney":60301613368.125,"minSec":32,"minPorts":5,"minHackLvl":1106,"rootAccess":true,"factorMoneyPerTime":2.798894843901509,"openPorts":4,"serverFiles":[],"hackingChance":0},"clarkinc":{"serverName":"clarkinc","maxRam":0,"maxMoney":45937777148.4375,"minSec":18,"minPorts":5,"minHackLvl":1153,"rootAccess":true,"factorMoneyPerTime":3.6217050610489046,"openPorts":4,"serverFiles":["beyond-man.lit","cost-of-immortality.lit"],"hackingChance":0},"megacorp":{"serverName":"megacorp","maxRam":0,"maxMoney":155265627000.9375,"minSec":33,"minPorts":5,"minHackLvl":1130,"rootAccess":true,"factorMoneyPerTime":6.8417928995878565,"openPorts":4,"serverFiles":[],"hackingChance":0},"blade":{"serverName":"blade","maxRam":64,"maxMoney":107670895371.5625,"minSec":30,"minPorts":5,"minHackLvl":1177,"rootAccess":true,"factorMoneyPerTime":5.009076855922873,"openPorts":4,"serverFiles":["beyond-man.lit"],"hackingChance":0},"fulcrumtech":{"serverName":"fulcrumtech","maxRam":512,"maxMoney":4090821741.5625,"minSec":29,"minPorts":5,"minHackLvl":977,"rootAccess":true,"factorMoneyPerTime":0.23684987618060668,"openPorts":4,"serverFiles":["simulated-reality.lit"],"hackingChance":0},".":{"serverName":".","maxRam":16,"maxMoney":0,"minSec":1,"minPorts":4,"minHackLvl":514,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":3,"serverFiles":[],"hackingChance":0.2497184524210297},"b-and-a":{"serverName":"b-and-a","maxRam":0,"maxMoney":79095950848.125,"minSec":27,"minPorts":5,"minHackLvl":1149,"rootAccess":true,"factorMoneyPerTime":4.184944137369968,"openPorts":4,"serverFiles":[],"hackingChance":0},"ecorp":{"serverName":"ecorp","maxRam":0,"maxMoney":167282154509.0625,"minSec":33,"minPorts":5,"minHackLvl":1193,"rootAccess":true,"factorMoneyPerTime":6.984005642017015,"openPorts":4,"serverFiles":[],"hackingChance":0},"4sigma":{"serverName":"4sigma","maxRam":0,"maxMoney":67097355693.75,"minSec":23,"minPorts":5,"minHackLvl":1093,"rootAccess":true,"factorMoneyPerTime":4.374475378115751,"openPorts":4,"serverFiles":[],"hackingChance":0},"deltaone":{"serverName":"deltaone","maxRam":0,"maxMoney":4563772689.375,"minSec":28,"minPorts":5,"minHackLvl":857,"rootAccess":true,"factorMoneyPerTime":0.3115949943316044,"openPorts":4,"serverFiles":[],"hackingChance":0},"zeus-med":{"serverName":"zeus-med","maxRam":0,"maxMoney":3656464233.75,"minSec":29,"minPorts":5,"minHackLvl":818,"rootAccess":true,"factorMoneyPerTime":0.2525072700507901,"openPorts":4,"serverFiles":[],"hackingChance":0},"icarus":{"serverName":"icarus","maxRam":0,"maxMoney":2728379078.4375,"minSec":30,"minPorts":5,"minHackLvl":883,"rootAccess":true,"factorMoneyPerTime":0.1688753180059479,"openPorts":4,"serverFiles":[],"hackingChance":0},"zb-def":{"serverName":"zb-def","maxRam":0,"maxMoney":2635448774.0625,"minSec":20,"minPorts":4,"minHackLvl":794,"rootAccess":true,"factorMoneyPerTime":0.27075630439995335,"openPorts":3,"serverFiles":["contract-817042-CyberSec.cct","synthetic-muscles.lit"],"hackingChance":0},"microdyne":{"serverName":"microdyne","maxRam":16,"maxMoney":1828178758.125,"minSec":23,"minPorts":5,"minHackLvl":814,"rootAccess":true,"factorMoneyPerTime":0.15961057543718954,"openPorts":4,"serverFiles":["synthetic-muscles.lit"],"hackingChance":0},"taiyang-digital":{"serverName":"taiyang-digital","maxRam":0,"maxMoney":2281447456.875,"minSec":24,"minPorts":5,"minHackLvl":880,"rootAccess":true,"factorMoneyPerTime":0.1767800749886257,"openPorts":4,"serverFiles":["A-Green-Tomorrow.lit","brighter-than-the-sun.lit"],"hackingChance":0},"titan-labs":{"serverName":"titan-labs","maxRam":16,"maxMoney":2374794447.1875,"minSec":25,"minPorts":5,"minHackLvl":812,"rootAccess":true,"factorMoneyPerTime":0.19137367935384147,"openPorts":4,"serverFiles":["coded-intelligence.lit"],"hackingChance":0},"vitalife":{"serverName":"vitalife","maxRam":32,"maxMoney":2137470136.875,"minSec":29,"minPorts":5,"minHackLvl":824,"rootAccess":true,"factorMoneyPerTime":0.14654302233223357,"openPorts":4,"serverFiles":["A-Green-Tomorrow.lit","contract-993088-CyberSec.cct"],"hackingChance":0},"omnitek":{"serverName":"omnitek","maxRam":512,"maxMoney":54581820887.8125,"minSec":30,"minPorts":5,"minHackLvl":929,"rootAccess":true,"factorMoneyPerTime":3.2122966906543016,"openPorts":4,"serverFiles":["coded-intelligence.lit","history-of-synthoids.lit"],"hackingChance":0},"powerhouse-fitness":{"serverName":"powerhouse-fitness","maxRam":16,"maxMoney":2531250000,"minSec":21,"minPorts":5,"minHackLvl":1041,"rootAccess":true,"factorMoneyPerTime":0.18954829790127375,"openPorts":4,"serverFiles":[],"hackingChance":0},"The-Cave":{"serverName":"The-Cave","maxRam":0,"maxMoney":0,"minSec":1,"minPorts":5,"minHackLvl":925,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":4,"serverFiles":["alpha-omega.lit"],"hackingChance":0},"fulcrumassets":{"serverName":"fulcrumassets","maxRam":0,"maxMoney":2812500,"minSec":33,"minPorts":5,"minHackLvl":1498,"rootAccess":true,"factorMoneyPerTime":0.00009361022686061973,"openPorts":4,"serverFiles":[],"hackingChance":0},"nwo":{"serverName":"nwo","maxRam":0,"maxMoney":102925863644.0625,"minSec":33,"minPorts":5,"minHackLvl":950,"rootAccess":true,"factorMoneyPerTime":5.389335237400673,"openPorts":4,"serverFiles":["the-hidden-world.lit"],"hackingChance":0},"infocomm":{"serverName":"infocomm","maxRam":0,"maxMoney":1815631956.5625,"minSec":29,"minPorts":5,"minHackLvl":902,"rootAccess":true,"factorMoneyPerTime":0.11379558358909059,"openPorts":4,"serverFiles":[],"hackingChance":0},"run4theh111z":{"serverName":"run4theh111z","maxRam":64,"maxMoney":0,"minSec":1,"minPorts":4,"minHackLvl":518,"rootAccess":true,"factorMoneyPerTime":0,"openPorts":3,"serverFiles":["simulated-reality.lit","the-new-god.lit"],"hackingChance":0.24148031790817098},"helios":{"serverName":"helios","maxRam":64,"maxMoney":1752766000.3125,"minSec":29,"minPorts":5,"minHackLvl":871,"rootAccess":true,"factorMoneyPerTime":0.11373460986355513,"openPorts":4,"serverFiles":["beyond-man.lit"],"hackingChance":0},"catalyst":{"serverName":"catalyst","maxRam":16,"maxMoney":1409611246.875,"minSec":21,"minPorts":3,"minHackLvl":419,"rootAccess":true,"factorMoneyPerTime":0.2587707278405934,"openPorts":2,"serverFiles":["factionboost.js","tensions-in-tech-race.lit"],"hackingChance":0.16645296406820898},"syscore":{"serverName":"syscore","maxRam":0,"maxMoney":1311487849.6875,"minSec":22,"minPorts":4,"minHackLvl":630,"rootAccess":true,"factorMoneyPerTime":0.154095158441234,"openPorts":3,"serverFiles":[],"hackingChance":0.0038226192341863337},"aevum-police":{"serverName":"aevum-police","maxRam":64,"maxMoney":906136543.125,"minSec":27,"minPorts":4,"minHackLvl":414,"rootAccess":true,"factorMoneyPerTime":0.13156420893324838,"openPorts":3,"serverFiles":[],"hackingChance":0.09205491217020151},"global-pharm":{"serverName":"global-pharm","maxRam":64,"maxMoney":4779752239.6875,"minSec":27,"minPorts":4,"minHackLvl":832,"rootAccess":true,"factorMoneyPerTime":0.3484005780075781,"openPorts":3,"serverFiles":["A-Green-Tomorrow.lit"],"hackingChance":0},"omnia":{"serverName":"omnia","maxRam":16,"maxMoney":2634518927.8125,"minSec":31,"minPorts":5,"minHackLvl":912,"rootAccess":true,"factorMoneyPerTime":0.15285983663761768,"openPorts":4,"serverFiles":["history-of-synthoids.lit"],"hackingChance":0},"solaris":{"serverName":"solaris","maxRam":32,"maxMoney":2214169056.5625,"minSec":24,"minPorts":5,"minHackLvl":772,"rootAccess":true,"factorMoneyPerTime":0.19531222134991724,"openPorts":4,"serverFiles":["A-Green-Tomorrow.lit","the-failed-frontier.lit"],"hackingChance":0},"defcomm":{"serverName":"defcomm","maxRam":0,"maxMoney":2563498515.9375,"minSec":32,"minPorts":5,"minHackLvl":1032,"rootAccess":true,"factorMoneyPerTime":0.12746507188564743,"openPorts":4,"serverFiles":[],"hackingChance":0},"rho-construction":{"serverName":"rho-construction","maxRam":32,"maxMoney":1749766941.5625,"minSec":13,"minPorts":3,"minHackLvl":516,"rootAccess":true,"factorMoneyPerTime":0.4184445552202157,"openPorts":2,"serverFiles":["factionboost.js"],"hackingChance":0.14884811222096989},"phantasy":{"serverName":"phantasy","maxRam":32,"maxMoney":67500000,"minSec":7,"minPorts":2,"minHackLvl":100,"rootAccess":true,"factorMoneyPerTime":0.12390000000000002,"openPorts":1,"serverFiles":["factionboost.js"],"hackingChance":0.8908003026278031},"zer0":{"serverName":"zer0","maxRam":32,"maxMoney":21093750,"minSec":8,"minPorts":1,"minHackLvl":75,"rootAccess":true,"factorMoneyPerTime":0.04355859375,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":0.8741316024297525},"silver-helix":{"serverName":"silver-helix","maxRam":64,"maxMoney":126562500,"minSec":10,"minPorts":2,"minHackLvl":150,"rootAccess":true,"factorMoneyPerTime":0.1229889705882353,"openPorts":1,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js","new-triads.lit"],"hackingChance":0.706638469862445},"crush-fitness":{"serverName":"crush-fitness","maxRam":0,"maxMoney":126678588.75,"minSec":13,"minPorts":2,"minHackLvl":266,"rootAccess":true,"factorMoneyPerTime":0.05720968524193549,"openPorts":1,"serverFiles":[],"hackingChance":0.4762619506821487},"johnson-ortho":{"serverName":"johnson-ortho","maxRam":0,"maxMoney":206727837.1875,"minSec":21,"minPorts":2,"minHackLvl":279,"rootAccess":true,"factorMoneyPerTime":0.05636481053536062,"openPorts":1,"serverFiles":[],"hackingChance":0.26680322001871964},"netlink":{"serverName":"netlink","maxRam":32,"maxMoney":773437500,"minSec":20,"minPorts":3,"minHackLvl":401,"rootAccess":true,"factorMoneyPerTime":0.15544023722627737,"openPorts":2,"serverFiles":["factionboost.js","simulated-reality.lit"],"hackingChance":0.19005438731274993},"zb-institute":{"serverName":"zb-institute","maxRam":64,"maxMoney":2995904390.625,"minSec":28,"minPorts":5,"minHackLvl":768,"rootAccess":true,"factorMoneyPerTime":0.22803326821380854,"openPorts":4,"serverFiles":[],"hackingChance":0},"alpha-ent":{"serverName":"alpha-ent","maxRam":128,"maxMoney":1837465740,"minSec":19,"minPorts":4,"minHackLvl":505,"rootAccess":true,"factorMoneyPerTime":0.3099023381807044,"openPorts":3,"serverFiles":["sector-12-crime.lit"],"hackingChance":0.11922411336664969},"galactic-cyber":{"serverName":"galactic-cyber","maxRam":0,"maxMoney":2278745147.8125,"minSec":19,"minPorts":5,"minHackLvl":854,"rootAccess":true,"factorMoneyPerTime":0.22917855742032445,"openPorts":4,"serverFiles":[],"hackingChance":0},"the-hub":{"serverName":"the-hub","maxRam":32,"maxMoney":483168296.25,"minSec":13,"minPorts":2,"minHackLvl":318,"rootAccess":true,"factorMoneyPerTime":0.1841702873569451,"openPorts":1,"serverFiles":["factionboost.js"],"hackingChance":0.40919188586028893},"rothman-uni":{"serverName":"rothman-uni","maxRam":128,"maxMoney":601140065.625,"minSec":16,"minPorts":3,"minHackLvl":371,"rootAccess":true,"factorMoneyPerTime":0.16184540228365385,"openPorts":2,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js","secret-societies.lit","tensions-in-tech-race.lit","the-failed-frontier.lit"],"hackingChance":0.2858591069222009},"millenium-fitness":{"serverName":"millenium-fitness","maxRam":128,"maxMoney":703125000,"minSec":16,"minPorts":3,"minHackLvl":486,"rootAccess":true,"factorMoneyPerTime":0.14563220912738215,"openPorts":2,"serverFiles":["RMgrow.js","RMhack.js","RMweaken.js","batch.js","myLibrary.js"],"hackingChance":0.16455985739985005},"n00dles":{"serverName":"n00dles","maxRam":4,"maxMoney":196875,"minSec":1,"minPorts":0,"minHackLvl":1,"rootAccess":true,"factorMoneyPerTime":0.0016180970149253734,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":1},"nectar-net":{"serverName":"nectar-net","maxRam":16,"maxMoney":7734375,"minSec":7,"minPorts":0,"minHackLvl":20,"rootAccess":true,"factorMoneyPerTime":0.03757996323529412,"openPorts":0,"serverFiles":["factionboost.js"],"hackingChance":1},"neo-net":{"serverName":"neo-net","maxRam":32,"maxMoney":14062500,"minSec":8,"minPorts":1,"minHackLvl":50,"rootAccess":true,"factorMoneyPerTime":0.03871875,"openPorts":0,"serverFiles":["factionboost.js","the-hidden-world.lit"],"hackingChance":0.9131379211459395},"computek":{"serverName":"computek","maxRam":0,"maxMoney":678530463.75,"minSec":19,"minPorts":3,"minHackLvl":311,"rootAccess":true,"factorMoneyPerTime":0.18348867672532332,"openPorts":2,"serverFiles":["contract-545076.cct","man-and-machine.lit"],"hackingChance":0.2968016795327152},"summit-uni":{"serverName":"summit-uni","maxRam":32,"maxMoney":684528077.8125,"minSec":20,"minPorts":3,"minHackLvl":439,"rootAccess":true,"factorMoneyPerTime":0.1259287733347717,"openPorts":2,"serverFiles":["factionboost.js","secret-societies.lit","synthetic-muscles.lit","the-failed-frontier.lit"],"hackingChance":0.1633064543584366}} \ No newline at end of file diff --git a/Ramses/home/serverlister.js b/Ramses/home/serverlister.js new file mode 100644 index 0000000..7194340 --- /dev/null +++ b/Ramses/home/serverlister.js @@ -0,0 +1,371 @@ + + +// 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) { + 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; + + //open log for this script + 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 = {}; + cracks = getCracks(ns); + let maxPorts = Object.keys(cracks).length; + scanServerList(ns, bSilent); + let manualTargetOverride = ""; + let nHackingLevel = ns.getHackingLevel(); + let nServerMaxSecurity = 100; + + + if (nHackingLevel < 10) { + manualTargetOverride = "n00dles"; + } + + + + //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")); + for (const [name, entry] of Object.entries(serverList)) { + //copyAndRunSript(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, 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); + } + */ +} + +/** @param {NS} ns */ +function crackingAndRooting(ns, cracks, funnyScript) { + let serverList = JSON.parse(ns.read("serverList.txt")); + for (const [name, entry] of Object.entries(serverList)) { + let cracked = false; + let openPorts = serverList[name].openPorts || 0; + if (entry.minPorts === 0 || (entry.minPorts > openPorts && entry.minPorts <= Object.keys(cracks).length)) { + for (let k = 0; k < entry.minPorts; k++) { + cracks[Object.keys(cracks)[k]](name); + serverList[name].openPorts = k; + } + cracked = true; + } + if (!ns.hasRootAccess(name) && cracked === true) { + ns.nuke(name); + if (ns.hasRootAccess(name)) { + serverList[name].rootAccess = true; + if (serverList[name].maxRam > 0) { + copyAndRunSript(ns, funnyScript, name); + } + } + } + ns.write("serverList.txt", JSON.stringify(serverList), "w"); + } + 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 */ +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 + //let minRam = ns.getScriptRam(funnyScript); + let bestTarget = JSON.parse(ns.read("bestTarget.txt")); + let name = currentServer; + let serverList = JSON.parse(ns.read("serverList.txt")); + ns.print(name); + if (serverList[name].rootAccess === true && serverList[bestTarget.serverName].rootAccess === true) { + if (name !== "home") { + ns.print("killed threads on: " + name + ns.killall(name, true)); + } else { + ns.print("killed threads on: " + name + ns.scriptKill(funnyScript[0], name)); + }; + //move script and run + if (serverList[name].maxRam > 0) { + ns.scp(funnyScript, name, "home"); + let maxProcesses = 1; + if (serverList[name].maxRam - 64 > 512) { + + maxProcesses = Math.max(Math.floor((serverList[name].maxRam - 64) / 512), 1); + } else { + maxProcesses = 1 + }; + for (let n = 1; n <= maxProcesses; n++) { + ns.exec(funnyScript[0], name, 1, bestTarget.serverName); + } + /*let maxThreads = 0; + if (name === "home") { + maxThreads = Math.floor((serverList[name].maxRam - ns.getServerUsedRam(name) - 32) / minRam); + ns.print(name + " " + maxThreads); + } else { + ns.print(name); + maxThreads = Math.floor(serverList[name].maxRam / minRam); + ns.print(name + " " + maxThreads); + }; + while (maxThreads > 0) { + let threadsToAssign = maxThreads < 500 ? maxThreads : 500; + if (ns.exec(funnyScript, name, threadsToAssign, bestTarget.serverName, serverList[bestTarget.serverName].minSec, serverList[bestTarget.serverName].maxMoney, JSON.stringify(serverList[bestTarget.serverName])) !== 0) { + ns.print("Executing script on: " + name + " with: " + threadsToAssign + " threads out of " + maxThreads + " total threads"); + maxThreads = maxThreads - threadsToAssign; + } else { + ns.tprint("Error running script on: " + name); + maxThreads = -1; + }; + }*/ + } + } +} + +/** @param {NS} ns */ +function getCracks(ns) { + let cracks = {}; + if (ns.fileExists("BruteSSH.exe", "home")) { + cracks["BruteSSH.exe"] = ns.brutessh; + }; + if (ns.fileExists("FTPCrack.exe", "home")) { + cracks["FTPCrack.exe"] = ns.ftpcrack; + }; + 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 unscanned = []; + let nHackingLevel = ns.getHackingLevel(); + let oServer; + 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) / (nHackingLevel + 50); + let compareTimeFactor = serverMoney / skillFactor / 10e7; + let nHackingChance = ns.hackAnalyzeChance(currentServer); + 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, + serverFiles: serverFiles, + hackingChance: nHackingChance + }; + 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 */ +function findBestTarget(ns, maxSec, maxPorts, currentHackLevel, manualTargetOverride) { + //ns.tprint("start of findBestTarget "); + const bSilent = ns.args[1] === true ? true : false; // if true supress feedback + //ns.tprint("bSilent = " +bSilent); + let sCurrentBestTarget = JSON.parse(ns.read("bestTarget.txt")); + //let sCurrentBestTarget = "n00dles"; + //ns.tprint("sCurrentBestTarget = " +JSON.stringify(sCurrentBestTarget)); + //if (!bSilent) ns.tprint("sCurrentBestTarget = " + sCurrentBestTarget.serverName); + let serverList = JSON.parse(ns.read("serverList.txt")); + let bestEntry = null; + let compareTime = 0; + let nMaxMoneyPerChance = 0; + let nBestMoneyPerChance = 0; + //ns.tprint("before for loop "); + for (const [name, entry] of Object.entries(serverList)) { + if (entry.minSec <= maxSec && entry.minPorts <= maxPorts && entry.minHackLvl < currentHackLevel) { + nMaxMoneyPerChance = (entry.maxMoney * entry.hackingChance) / entry.minSec; + //ns.tprint("nMaxMoneyPerChance " + nMaxMoneyPerChance); + /* + if (entry.factorMoneyPerTime > compareTime) { + compareTime = entry.factorMoneyPerTime; + bestEntry = name; + } + */ + if (nMaxMoneyPerChance > nBestMoneyPerChance) { + nBestMoneyPerChance = nMaxMoneyPerChance; + 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); + } + } + } +} \ No newline at end of file diff --git a/Ramses/home/settings.txt b/Ramses/home/settings.txt new file mode 100644 index 0000000..95d0f21 --- /dev/null +++ b/Ramses/home/settings.txt @@ -0,0 +1,4 @@ +{"setting":{ +"autoUpgrades":true, +"autoPurchaseServers":true +}} \ No newline at end of file diff --git a/Ramses/home/sharePserv.js b/Ramses/home/sharePserv.js new file mode 100644 index 0000000..0663fec --- /dev/null +++ b/Ramses/home/sharePserv.js @@ -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); + } + } +} \ No newline at end of file diff --git a/Ramses/home/singularity/RMroutelist.js b/Ramses/home/singularity/RMroutelist.js new file mode 100644 index 0000000..b869d2e --- /dev/null +++ b/Ramses/home/singularity/RMroutelist.js @@ -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) + } + } +} \ No newline at end of file diff --git a/Ramses/home/singularity/manualalgo.js b/Ramses/home/singularity/manualalgo.js new file mode 100644 index 0000000..682fa96 --- /dev/null +++ b/Ramses/home/singularity/manualalgo.js @@ -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("-------------------------------------------------------------------------"); + } + } +} \ No newline at end of file diff --git a/Ramses/home/test.js b/Ramses/home/test.js new file mode 100644 index 0000000..8a83ac5 --- /dev/null +++ b/Ramses/home/test.js @@ -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) + +} \ No newline at end of file diff --git a/Ramses/home/testhackgrow.js b/Ramses/home/testhackgrow.js new file mode 100644 index 0000000..c981745 --- /dev/null +++ b/Ramses/home/testhackgrow.js @@ -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); + */ +} \ No newline at end of file diff --git a/Ramses/home/upgrade.js b/Ramses/home/upgrade.js new file mode 100644 index 0000000..283be81 --- /dev/null +++ b/Ramses/home/upgrade.js @@ -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("----------------------------------------------------------------------"); +} \ No newline at end of file diff --git a/config.mjs b/config.mjs index 36e129a..01ef78a 100644 --- a/config.mjs +++ b/config.mjs @@ -15,7 +15,11 @@ const createContext = async () => await context({ port: 12525, types: 'NetscriptDefinitions.d.ts', mirror: { +<<<<<<< HEAD 'Mizzajl': ['home'] +======= + 'Ramses': ['home'] +>>>>>>> 1fa17ab0f5dd0456582c398342b6286d6e1c9de0 }, distribute: { },