Skip to content

Instantly share code, notes, and snippets.

@KrunoSaho
Last active June 30, 2023 08:59
Show Gist options
  • Save KrunoSaho/ef66ef8c0e5c056604ec1046178499e3 to your computer and use it in GitHub Desktop.
Save KrunoSaho/ef66ef8c0e5c056604ec1046178499e3 to your computer and use it in GitHub Desktop.
new batcher
import { NS, Server } from "../NetscriptDefinitions";
import { getThreadCount, getAllServers, breakServers, makeColour } from "./Util";
type SubscriptPaths = { Path: string; Cost: number };
type ScriptInformation = { Hack: SubscriptPaths; Grow: SubscriptPaths; Weaken: SubscriptPaths };
type Operations = "hack" | "grow" | "weaken";
type Operation = (
operation: Operations,
srcServer: string,
targetServer: string,
threads: number
) => void;
type ScriptOptions = {};
enum WorkerTypes {
AnyThreads,
HighThreads,
}
enum ScriptTypes {
Hack = "hacks/SimpleHack.js",
Grow = "hacks/SimpleGrow.js",
Weaken = "hacks/SimpleWeaken.js",
}
export async function main(ns: NS) {
ns.disableLog("ALL");
// Log
ns.tail();
ns.resizeTail(565, 700);
ns.moveTail(1980, 600);
ns.clearLog();
const scriptData = {
Hack: {
Path: "hacks/SimpleHack.js",
Cost: 1.7,
} as SubscriptPaths,
Grow: {
Path: "hacks/SimpleGrow.js",
Cost: 1.75,
} as SubscriptPaths,
Weaken: {
Path: "hacks/SimpleWeaken.js",
Cost: 1.75,
} as SubscriptPaths,
} as ScriptInformation;
const scripts = getScriptRunner(ns, scriptData);
const [myNodes, otherNodes] = prepare(ns);
ns.print(`${makeColour(0, 255, 255)}Destroying n00dles`);
await assaultOnN00dles(ns, myNodes);
// while (true) {
// mastermindTheWork(ns, scripts, myNodes, otherNodes);
// await ns.sleep(1000);
// }
}
async function assaultOnN00dles(ns: NS, myNodes: string[]) {
const target = "phantasy";
const targetServer = ns.getServer(target);
const scriptRamUsage = 1.75;
const waitList = new Map<string, { waitTime: number; timeStamp: number }>();
let totalTime = 0;
let operationToPerform = ScriptTypes.Weaken;
let batchesSent = 0;
while (
Math.floor(ns.getServerMoneyAvailable(target)) !== Math.floor(ns.getServerMaxMoney(target))
) {
const t0 = Date.now();
if (batchesSent !== 0) {
ns.print(
`${makeColour(255, 255, 255)}Now performing ${makeColour(
255,
133,
233
)}${operationToPerform} ${makeColour(255, 255, 255)}on ${makeColour(
128,
33,
255
)}${target}`
);
batchesSent = 0;
}
let updates = 0;
for (const hostname of myNodes) {
if (
ns.getServerSecurityLevel(target) - ns.getServerMinSecurityLevel(target) <
0.00001
) {
operationToPerform = ScriptTypes.Grow;
}
if (waitList.has(hostname)) {
const { waitTime, timeStamp } = waitList.get(hostname) as {
waitTime: number;
timeStamp: number;
};
if (Date.now() - timeStamp < waitTime) continue;
}
const myServer = ns.getServer(hostname);
const threads = getThreadCount(ns, hostname, operationToPerform, target);
const weakenTime = Math.ceil(ns.formulas.hacking.weakenTime(myServer, ns.getPlayer()));
if (threads < 1) continue;
ns.exec(operationToPerform, hostname, threads, target);
waitList.set(hostname, { waitTime: weakenTime, timeStamp: Date.now() });
updates++;
}
batchesSent = updates > 0 ? batchesSent + 1 : batchesSent;
if (operationToPerform === ScriptTypes.Grow) {
operationToPerform = ScriptTypes.Weaken;
}
if (ns.getServerSecurityLevel(target) - ns.getServerMinSecurityLevel(target) < 0.00001) {
operationToPerform = ScriptTypes.Grow;
}
await ns.sleep(200);
totalTime += Date.now() - t0;
}
ns.print("n00dles has been destroyed");
ns.print(`Total time: ${totalTime}ms`);
ns.print(`Total batches: ${batchesSent}`);
ns.print(`Total money: ${ns.getServerMoneyAvailable(target)}`);
ns.print(`Max money: ${ns.getServerMaxMoney(target)}`);
}
///////////////////////////////////////////
// The Workhorse
///////////////////////////////////////////
function mastermindTheWork(ns: NS, script: Operation, myNodes: string[], targetNodes: string[]) {
const doOp = (operation: Operations, worker: string, targetServer: string) => {
let maxThreads = getThreadCount(ns, worker, ScriptTypes.Grow, worker);
script(operation, worker, targetServer, maxThreads);
};
const hostname = "n00dles";
for (const worker of myNodes) {
const server = ns.getServer(hostname);
const targetServer = server.hostname;
if (!ns.hasRootAccess(targetServer)) continue;
const [weakenTime, growTime, hackTime] = [
Math.ceil(ns.formulas.hacking.weakenTime(server, ns.getPlayer())),
Math.ceil(ns.formulas.hacking.growTime(server, ns.getPlayer())),
Math.ceil(ns.formulas.hacking.hackTime(server, ns.getPlayer())),
];
doOp("hack", worker, targetServer);
doOp("weaken", worker, targetServer);
doOp("grow", worker, targetServer);
doOp("weaken", worker, targetServer);
}
}
///////////////////////////////////////////
// Prep. Work
///////////////////////////////////////////
function prepare(ns: NS) {
const myServers = ns.getPurchasedServers();
copyHackFilesToServers(ns, myServers);
myServers.push("home");
const baseCostScript = 1.75; // TODO: Make this dynamic
const allServers = getAllServers(ns.scan, "home", [])
.filter((s) => !myServers.includes(s) && s != "home")
.filter((s) => ns.getServerSecurityLevel(s) <= 100)
.filter((s) => Math.floor(ns.getServerMaxRam(s)) >= baseCostScript)
.filter((s) => ns.getServerRequiredHackingLevel(s) <= ns.getHackingLevel())
.filter((s) => ns.getServerMaxMoney(s) > 0)
.map(ns.getServer)
.sort((a, b) => (b.moneyMax as number) - (a.moneyMax as number))
.map((s) => s.hostname);
// Break security on all servers
breakServers(ns, "home", allServers);
// Newly broken servers can be added here
const backDooredServers = allServers.filter((s) => ns.hasRootAccess(s));
copyHackFilesToServers(ns, backDooredServers);
myServers.push(...backDooredServers);
myServers.sort((a, b) => Math.random() - Math.random());
// The workhorse
return [myServers, allServers];
}
function copyHackFilesToServers(ns: NS, backDooredServers: string[]) {
const files = ["hacks/SimpleHack.js", "hacks/SimpleGrow.js", "hacks/SimpleWeaken.js"];
for (const server of backDooredServers) {
if (!ns.scp(files, server, "home")) {
ns.print(`ERROR: copyHackFilesToServers => Failed to copy files to ${server}`);
}
}
}
function getScriptRunner(ns: NS, scriptData: ScriptInformation) {
const Yellow = makeColour(255, 255, 0);
const Default = makeColour(255, 255, 255);
const Cyan = makeColour(0, 255, 255);
const Red = makeColour(255, 0, 0);
const Quest = makeColour(255, 255, 0);
return (
operation: Operations,
myServer: string,
targetServer: string,
threads: number,
extras: ScriptOptions = {}
) => {
if (threads <= 0) return;
const opGrow = operation === "grow";
const opHack = operation === "hack";
const [op, colour] = opGrow
? [scriptData.Grow.Path, Yellow]
: opHack
? [scriptData.Hack.Path, Red]
: [scriptData.Weaken.Path, Cyan];
ns.print(
`
${colour}${operation}${Default} on
${Yellow}${myServer}${Default} -> ${Yellow}${targetServer}${Default} with ${Cyan}${threads}${Default} threads
${Quest}
`
);
ns.exec(op, myServer, threads, targetServer);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment