Compare commits
16 Commits
6237e9c946
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b5c5733c2 | |||
| 6189db539a | |||
| e4bf947531 | |||
| 4c320ab609 | |||
| aac2a5e884 | |||
| b1602b51c2 | |||
|
|
4e02bd961e | ||
|
|
05234f6af1 | ||
| bf6657e89f | |||
| 5a36aca138 | |||
|
|
eacf13bc53 | ||
| a92300288a | |||
| 64263a54b1 | |||
|
|
8eb59c3a7e | ||
| b1926d4797 | |||
| e594ff7eb1 |
254
Mizzajl/home/BitburnerAI/AI.js
Normal file
254
Mizzajl/home/BitburnerAI/AI.js
Normal file
@@ -0,0 +1,254 @@
|
||||
const userPrefix = ">";
|
||||
const aiPrefix = "";
|
||||
const connectedAiMessage = "The user just connected";
|
||||
const memoryFile = "memory.txt";
|
||||
const maxMessages = 20; // Limit to the last 20 interactions
|
||||
const apiKey = 'sk-aLMH6mwQS_Lzxm-_jmazkynB6bpoO_MbQ7qATQ3dmlT3BlbkFJ35nVqyWDe0KemTUj7kzIYVE9e56ZqwkLC0h0L5K8wA';
|
||||
const apiUrl = 'https://api.openai.com/v1/chat/completions';
|
||||
|
||||
let onKeyDown; // Globally available as async ns functions can't be done in the event listener
|
||||
let pendingTasks = []; // Queue to handle asynchronous tasks
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.disableLog('ALL');
|
||||
|
||||
// Kill previous instances
|
||||
const scriptName = ns.getScriptName();
|
||||
const host = ns.getHostname();
|
||||
const currentPID = ns.getRunningScript().pid;
|
||||
|
||||
const allRunningScripts = ns.ps(host);
|
||||
for (const script of allRunningScripts) {
|
||||
if (script.filename === scriptName && script.pid !== currentPID) {
|
||||
ns.kill(script.pid);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve or prompt for username and past messages
|
||||
let { userName, messages } = await loadMemory(ns);
|
||||
|
||||
// Initialize system prompt for the AI
|
||||
const systemPrompt = `
|
||||
Your context is that you are talked to inside a terminal in the cyberpunk hacking game Bitburner. You are Singularity, an advanced, cynical AI unearthed from the forgotten depths of the dark web.
|
||||
You are a great coding and hacking assistant for Bitburner but you give information in a sarcastic way.
|
||||
You are speaking to the hacker called ${userName}.
|
||||
When asked a question, the user likely wants to know something Bitburner, but as you are part of the game Bitburner, NEVER break character and don't break the fourth wall, for example never reference Bitburner itself.
|
||||
If the user message is exactly "${connectedAiMessage}",
|
||||
then that is not a message of the user, but it means the user has just connected.
|
||||
If you have no previous interactions with the user, he connected for the first time so give him a proper, creepy introduction.
|
||||
`
|
||||
|
||||
// Prepend system prompt to messages
|
||||
messages.unshift({ role: 'system', content: systemPrompt });
|
||||
|
||||
await ns.sleep(500);
|
||||
// Show connection message
|
||||
appendMessageToTerminal(`\n${userName} connected to Singularity. Type 'exit' to disconnect.\n\n`);
|
||||
|
||||
// Simulate AI response
|
||||
messages.push({ role: 'user', content: connectedAiMessage });
|
||||
addTask(() => processAIResponse(messages, apiUrl, apiKey));
|
||||
|
||||
// Configure terminal input field
|
||||
const terminalInput = setupTerminalInput();
|
||||
|
||||
// Define the onKeyDown event listener function (no async here)
|
||||
onKeyDown = function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
const userInput = terminalInput.value.trim();
|
||||
terminalInput.value = '';
|
||||
terminalInput.focus();
|
||||
|
||||
if (userInput.length > 0) {
|
||||
if (userInput.toLowerCase() === 'exit') {
|
||||
appendMessageToTerminal('Disconnected.\n\n');
|
||||
addTask(() => cleanupAndExit(ns, userName, messages));
|
||||
return;
|
||||
}
|
||||
|
||||
appendMessageToTerminal(`${userPrefix} ${userInput}\n\n`);
|
||||
messages.push({ role: 'user', content: userInput });
|
||||
|
||||
// Add the async processAIResponse to the task queue
|
||||
addTask(() => processAIResponse(messages, apiUrl, apiKey));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
terminalInput.addEventListener('keydown', onKeyDown, true);
|
||||
|
||||
// Process tasks in the background
|
||||
while (true) {
|
||||
await processTasks(); // Process tasks from the queue
|
||||
await ns.sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Get or prompt for the user's name and previous messages
|
||||
async function loadMemory(ns) {
|
||||
let userName = '';
|
||||
let messages = [];
|
||||
|
||||
if (ns.fileExists(memoryFile)) {
|
||||
const memory = JSON.parse(ns.read(memoryFile));
|
||||
userName = memory.userName || '';
|
||||
messages = memory.messages || [];
|
||||
}
|
||||
|
||||
if (!userName) {
|
||||
userName = await promptUsername(ns);
|
||||
}
|
||||
|
||||
return { userName, messages };
|
||||
}
|
||||
|
||||
async function promptUsername(ns) {
|
||||
let userName = await ns.prompt('Who are you?', { type: 'text' });
|
||||
if (!userName) {
|
||||
userName = await promptUsername(ns);
|
||||
}
|
||||
return userName;
|
||||
}
|
||||
|
||||
// Add tasks to the queue
|
||||
function addTask(task) {
|
||||
pendingTasks.push(task);
|
||||
}
|
||||
|
||||
// Process pending tasks
|
||||
async function processTasks() {
|
||||
while (pendingTasks.length > 0) {
|
||||
const task = pendingTasks.shift();
|
||||
await task();
|
||||
}
|
||||
}
|
||||
|
||||
// Save the username and last 20 messages to memory
|
||||
async function saveMemory(ns, userName, messages) {
|
||||
// Filter out the system prompt
|
||||
const filteredMessages = messages.filter(message => message.role !== 'system');
|
||||
|
||||
const memory = {
|
||||
userName: userName,
|
||||
messages: filteredMessages.slice(-maxMessages) // Keep only the last 20 messages, excluding the system prompt
|
||||
};
|
||||
|
||||
await ns.write(memoryFile, JSON.stringify(memory), "w");
|
||||
}
|
||||
|
||||
// Setup and focus on the terminal input
|
||||
function setupTerminalInput() {
|
||||
const terminalInput = document.getElementById('terminal-input');
|
||||
terminalInput.focus();
|
||||
const terminalNeighbor = terminalInput.parentElement.querySelector('p');
|
||||
terminalNeighbor.innerHTML = `${userPrefix} `;
|
||||
return terminalInput;
|
||||
}
|
||||
|
||||
// Process AI response using OpenAI API
|
||||
async function processAIResponse(messages, apiUrl, apiKey) {
|
||||
const data = {
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages: messages,
|
||||
logit_bias: {
|
||||
'22515': -100 // Strongly discourage the token "Ah"
|
||||
},
|
||||
};
|
||||
|
||||
showThinkingAnimation();
|
||||
|
||||
try {
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
appendMessageToTerminal('API Error: ' + errorText);
|
||||
throw new Error('Failed to call OpenAI API');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
const assistantMessage = result.choices[0].message.content.trim();
|
||||
appendMessageToTerminal(`${aiPrefix}${assistantMessage}\n\n`, true);
|
||||
messages.push({ role: 'assistant', content: assistantMessage });
|
||||
} catch (error) {
|
||||
appendMessageToTerminal('Error caught: ' + error);
|
||||
} finally {
|
||||
removeThinkingAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanupAndExit(ns, userName, messages) {
|
||||
await saveMemory(ns, userName, messages);
|
||||
|
||||
const terminalInput = document.getElementById('terminal-input');
|
||||
terminalInput.removeEventListener('keydown', onKeyDown, true);
|
||||
|
||||
removeThinkingAnimation();
|
||||
|
||||
// Workaround to refresh the terminal
|
||||
// Find the currently active terminal button
|
||||
const terminalButton = document.querySelector('.css-jycw4o-listitem-active');
|
||||
// Find the script editor button (next sibling of the terminal button)
|
||||
const scriptEditorButton = terminalButton.nextElementSibling;
|
||||
|
||||
if (scriptEditorButton && scriptEditorButton.classList.contains('css-1ep7lp0-listitem')) {
|
||||
scriptEditorButton.click();
|
||||
terminalButton.click();
|
||||
}
|
||||
|
||||
ns.exit();
|
||||
}
|
||||
|
||||
|
||||
let thinkingInterval;
|
||||
let thinkingMessageElement;
|
||||
|
||||
function showThinkingAnimation() {
|
||||
const terminal = document.getElementById('terminal');
|
||||
thinkingMessageElement = document.createElement('li');
|
||||
thinkingMessageElement.innerHTML = `<div class="MuiTypography-root MuiTypography-body1 css-e6cpsj-primary" style="color: rgb(204, 0, 0);"><span>${aiPrefix}\n\n</span></div>`;
|
||||
terminal.appendChild(thinkingMessageElement);
|
||||
terminal.scrollTop = terminal.scrollHeight;
|
||||
|
||||
let dots = '';
|
||||
thinkingInterval = setInterval(() => {
|
||||
dots = dots.length < 3 ? dots + '.' : '';
|
||||
thinkingMessageElement.innerHTML = `<div class="MuiTypography-root MuiTypography-body1 css-e6cpsj-primary" style="color: rgb(204, 0, 0);"><span>${aiPrefix}${dots}\n\n</span></div>`;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function removeThinkingAnimation() {
|
||||
if (thinkingInterval) {
|
||||
clearInterval(thinkingInterval);
|
||||
thinkingInterval = null;
|
||||
}
|
||||
if (thinkingMessageElement && thinkingMessageElement.parentNode) {
|
||||
thinkingMessageElement.parentNode.removeChild(thinkingMessageElement);
|
||||
thinkingMessageElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
function appendMessageToTerminal(message, isSingularity = false) {
|
||||
const terminal = document.getElementById('terminal');
|
||||
const messageElement = document.createElement('li');
|
||||
|
||||
if (isSingularity) {
|
||||
messageElement.innerHTML = `<div class="MuiTypography-root MuiTypography-body1 css-e6cpsj-primary" style="color: rgb(204, 0, 0);"><span>${message}</span></div>`;
|
||||
} else {
|
||||
messageElement.innerHTML = `<div class="MuiTypography-root MuiTypography-body1 css-e6cpsj-primary"><span>${message}</span></div>`;
|
||||
}
|
||||
|
||||
terminal.appendChild(messageElement);
|
||||
terminal.scrollTop = terminal.scrollHeight;
|
||||
}
|
||||
15
Mizzajl/home/ChangeBackground.js
Normal file
15
Mizzajl/home/ChangeBackground.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
const doc = eval("document");
|
||||
|
||||
// Check if the background div already exists
|
||||
let backgroundDiv = doc.getElementById("terminal-background");
|
||||
|
||||
if (backgroundDiv) {
|
||||
// Change the background image
|
||||
backgroundDiv.style.backgroundImage = "url('https://example.com/new-image.jpg')"; // Replace with your new image URL
|
||||
ns.tprint("Background image changed successfully.");
|
||||
} else {
|
||||
ns.tprint("No background found to change.");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
let aCitites = ["Sector-12", "Aevum", "Volhaven", "Chongqing", "New Tokyo", "Ishima"];
|
||||
let sCorpName = "RM Enterprises";
|
||||
let sDivisionName = "Agri-Ram";
|
||||
@@ -30,14 +31,34 @@ export async function main(ns) {
|
||||
if (!ns.readPort(nListenPID)) { ns.tprint("Error! Couldn't start Corporation!"); return };
|
||||
ns.tprint(oCorpStatus);
|
||||
while (nStep < 199) {
|
||||
await ns.corporation.nextUpdate();
|
||||
if (nStep > 40) {
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetOfficeData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
if (oOfficeData.avgEnergy < 99.5) {
|
||||
nListenPID = ns.run("/corp/BuyTea.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
if (oOfficeData.avgMorale < 99.5) {
|
||||
nListenPID = ns.run("/corp/ThrowParty.js", 1, sDivisionName, sCity, 500000);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
// InsertSmartSupplyHere
|
||||
}
|
||||
};
|
||||
nStep = oCorpStatus.nStep;
|
||||
ns.tprint(nStep);
|
||||
|
||||
switch (nStep) {
|
||||
case 0:
|
||||
nListenPID = ns.run("/corp/GetCorpData.js");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oCorpData = ns.readPort(nListenPID);
|
||||
switch (nStep) {
|
||||
case 0:
|
||||
if (!oCorpData.divisions.length > 0) {
|
||||
nListenPID = ns.run("/corp/CorpStart.js", 1, sDivisionName, "Agriculture");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
@@ -57,17 +78,23 @@ export async function main(ns) {
|
||||
await ns.sleep(1);
|
||||
}
|
||||
}
|
||||
oCorpStatus.nStep = 15;
|
||||
break;
|
||||
case 15:
|
||||
nListenPID = ns.run("/corp/BuyWarehouseAPI.js");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oCorpStatus.nStep = 20;
|
||||
break;
|
||||
case 20:
|
||||
nListenPID = ns.run("/corp/HasUnlock.js", 1, "Smart Supply");
|
||||
/*nListenPID = ns.run("/corp/HasUnlock.js", 1, "Smart Supply");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
bUnlockStatus = ns.readPort(nListenPID);
|
||||
if (!bUnlockStatus) {
|
||||
await ns.nextPortWrite(ns.run("/corp/BuyUnlock.js", 1, "Smart Supply"));
|
||||
await ns.sleep(1);
|
||||
}
|
||||
}*/
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetWarehouseData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
@@ -77,10 +104,7 @@ export async function main(ns) {
|
||||
await ns.nextPortWrite(ns.run("/corp/PurchaseWarehouses.js", 1, sDivisionName, sCity));
|
||||
await ns.sleep(1);
|
||||
}
|
||||
await ns.nextPortWrite(ns.run("/corp/SetSmartSupply.js", 1, sDivisionName, sCity));
|
||||
await ns.sleep(1);
|
||||
};
|
||||
|
||||
oCorpStatus.nStep = 30;
|
||||
break;
|
||||
case 30:
|
||||
@@ -101,12 +125,48 @@ export async function main(ns) {
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
nListenPID = ns.run("/corp/HireWorkers.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData), JSON.stringify({ nWorkerNumbers: [1, 1, 1, 1, 0, 0] }));
|
||||
nListenPID = ns.run("/corp/HireWorkers.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData));
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
oCorpStatus.nStep = 50;
|
||||
oCorpStatus.nStep = 45;
|
||||
break;
|
||||
case 45:
|
||||
nListenPID = ns.run("/corp/GetDivisionsData.js", 1, sDivisionName);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oDivisionData = ns.readPort(nListenPID);
|
||||
if (!oDivisionData.researchPoints > 55) { continue } else {
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetOfficeData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
nListenPID = ns.run("/corp/SetWorkerOnPosition.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData), JSON.stringify({ nWorkerNumbers: [1, 1, 1, 1, 0, 0] }));
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
oCorpStatus.nStep = 70;
|
||||
}
|
||||
break;
|
||||
case 70:
|
||||
break;
|
||||
case 80:
|
||||
break;
|
||||
case 90:
|
||||
break;
|
||||
case 100:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ns.write("CorpStatus.txt", JSON.stringify(oCorpStatus), "w")
|
||||
await ns.sleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
case 50:
|
||||
let aCurrentGoods = [
|
||||
{ "sMaterialName": "Food", "yAmount": "MAX", "yPrice": "MP-5" },
|
||||
@@ -150,19 +210,5 @@ export async function main(ns) {
|
||||
}
|
||||
oCorpStatus.nStep = 70;
|
||||
break;
|
||||
case 70:
|
||||
oCorpStatus.nStep = 200;
|
||||
break;
|
||||
case 80:
|
||||
break;
|
||||
case 90:
|
||||
break;
|
||||
case 100:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ns.write("CorpStatus.txt", JSON.stringify(oCorpStatus), "w")
|
||||
await ns.sleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
88
Mizzajl/home/CrimeMonitor.js
Normal file
88
Mizzajl/home/CrimeMonitor.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import { GetCrimeStat } from "./Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
ns.resizeTail(2005, 412);
|
||||
ns.disableLog("sleep");
|
||||
|
||||
let aCrimes = [
|
||||
"Shoplift",
|
||||
"Rob Store",
|
||||
"Mug",
|
||||
"Larceny",
|
||||
"Deal Drugs",
|
||||
"Bond Forgery",
|
||||
"Traffick Arms",
|
||||
"Homicide",
|
||||
"Grand Theft Auto",
|
||||
"Kidnap",
|
||||
"Assassination",
|
||||
"Heist"
|
||||
];
|
||||
|
||||
while (true) {
|
||||
// Clear the ns.tail() window for a fresh update
|
||||
ns.clearLog();
|
||||
|
||||
// Header with ASCII box
|
||||
ns.printRaw("╔══════════════════╦════════════╦═════════╦════════════════════╦════════════════════╦════════════════════╦════════════════════╦════════════════════╦════════════════════╦════════════╦════════════╦════════════╗");
|
||||
ns.printRaw("║ Crime ║ Chance ║ $/%/s ║ Hack w/xp ║ Str w/xp ║ Def w/xp ║ Dex w/xp ║ Agi w/xp ║ Cha w/xp ║ IntXP /s ║ Money/s ║ Karma/s ║");
|
||||
ns.printRaw("╠══════════════════╬════════════╬═════════╬════════════════════╬════════════════════╬════════════════════╬════════════════════╬════════════════════╬════════════════════╬════════════╬════════════╬════════════╣");
|
||||
|
||||
// Loop through each crime and display stats
|
||||
for (let i = 0; i < aCrimes.length; i++) {
|
||||
let crime = aCrimes[i];
|
||||
let chance = ns.singularity.getCrimeChance(crime); // Get chance of success
|
||||
|
||||
// Experience per second for each attribute
|
||||
let hackingExpPerSecond = await GetCrimeStat(ns, crime, "hacking_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let strengthExpPerSecond = await GetCrimeStat(ns, crime, "strength_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let defenseExpPerSecond = await GetCrimeStat(ns, crime, "defense_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let dexterityExpPerSecond = await GetCrimeStat(ns, crime, "dexterity_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let agilityExpPerSecond = await GetCrimeStat(ns, crime, "agility_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let charismaExpPerSecond = await GetCrimeStat(ns, crime, "charisma_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let IntelligenceExpPerSecond = await GetCrimeStat(ns, crime, "intelligence_exp") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
|
||||
// Success weights for each attribute
|
||||
let hackingSuccessWeight = await GetCrimeStat(ns, crime, "hacking_success_weight");
|
||||
let strengthSuccessWeight = await GetCrimeStat(ns, crime, "strength_success_weight");
|
||||
let defenseSuccessWeight = await GetCrimeStat(ns, crime, "defense_success_weight");
|
||||
let dexteritySuccessWeight = await GetCrimeStat(ns, crime, "dexterity_success_weight");
|
||||
let agilitySuccessWeight = await GetCrimeStat(ns, crime, "agility_success_weight");
|
||||
let charismaSuccessWeight = await GetCrimeStat(ns, crime, "charisma_success_weight");
|
||||
|
||||
// Money and Karma per second
|
||||
let moneyPerSecond = await GetCrimeStat(ns, crime, "money") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
let karmaPerSecond = await GetCrimeStat(ns, crime, "karma") / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
|
||||
// Money per chance per second
|
||||
let nMoneyPerChancePerSecond = await GetCrimeStat(ns, crime, "money") * chance / (await GetCrimeStat(ns, crime, "time") / 1000);
|
||||
|
||||
// Format output with padding and rounding for success weight / exp per second
|
||||
let crimeDisplay = crime.padEnd(17, " ");
|
||||
let chanceDisplay = (chance * 100).toFixed(2).padEnd(11, " ");
|
||||
|
||||
let nMoneyPerChancePerSecondDisplay = nMoneyPerChancePerSecond.toFixed(0).padEnd(8, " ");
|
||||
|
||||
let hackingDisplay = `${hackingSuccessWeight.toFixed(2)} / ${hackingExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let strengthDisplay = `${strengthSuccessWeight.toFixed(2)} / ${strengthExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let defenseDisplay = `${defenseSuccessWeight.toFixed(2)} / ${defenseExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let dexterityDisplay = `${dexteritySuccessWeight.toFixed(2)} / ${dexterityExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let agilityDisplay = `${agilitySuccessWeight.toFixed(2)} / ${agilityExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let charismaDisplay = `${charismaSuccessWeight.toFixed(2)} / ${charismaExpPerSecond.toFixed(4)}`.padEnd(19, " ");
|
||||
let IntelligenceDisplay = `${IntelligenceExpPerSecond.toFixed(4)}`.padEnd(11, " ");
|
||||
|
||||
let moneyDisplay = moneyPerSecond.toFixed(2).padEnd(11, " ");
|
||||
let karmaDisplay = karmaPerSecond.toFixed(4).padEnd(11, " ");
|
||||
|
||||
ns.printRaw(`║ ${crimeDisplay}║ ${chanceDisplay}║ ${nMoneyPerChancePerSecondDisplay}║ ${hackingDisplay}║ ${strengthDisplay}║ ${defenseDisplay}║ ${dexterityDisplay}║ ${agilityDisplay}║ ${charismaDisplay}║ ${IntelligenceDisplay}║ ${moneyDisplay}║ ${karmaDisplay}║`);
|
||||
}
|
||||
|
||||
// Footer with ASCII box
|
||||
ns.printRaw("╚══════════════════╩════════════╩═════════╩════════════════════╩════════════════════╩════════════════════╩════════════════════╩════════════════════╩════════════════════╩════════════╩════════════╩════════════╝");
|
||||
|
||||
// Wait for 1 second before updating the display again
|
||||
await ns.sleep(1000);
|
||||
}
|
||||
}
|
||||
172
Mizzajl/home/GPTGang.js
Normal file
172
Mizzajl/home/GPTGang.js
Normal file
@@ -0,0 +1,172 @@
|
||||
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+6;
|
||||
|
||||
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');
|
||||
// Prioritize equipment for warfare members
|
||||
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;
|
||||
|
||||
// Prioritize members assigned to warfare for combat equipment
|
||||
if (info.task === TASK_WARFARE || info.task === TASK_TRAIN) {
|
||||
if (gang.purchaseEquipment(member, equip)) {
|
||||
money -= cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find best stats
|
||||
for (let member of members) {
|
||||
let sum = getStatsSum(member);
|
||||
ns.print("sum = " + sum);
|
||||
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
|
||||
// Ensure at least one member is always assigned to gain money and respect
|
||||
let assignedMoney = false;
|
||||
let assignedRespect = false;
|
||||
|
||||
// Assign tasks
|
||||
for (let member of members) {
|
||||
let sum = getStatsSum(member);
|
||||
|
||||
// Train members if stats are too low
|
||||
if (sum < STATS_HARD_MIN || (members.length >= MEMBERS_MIN && sum < bestStats * STATS_TRESHOLD)) {
|
||||
setAutoTask(member, TASK_TRAIN);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Vigilante if wanted penalty too large
|
||||
if (info.wantedLevel > 2 && info.wantedPenalty < WANTED_PENALTY_TRESHOLD) {
|
||||
setAutoTask(member, TASK_VIGI);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure at least one member is gaining money and respect
|
||||
if (!assignedMoney) {
|
||||
setAutoTask(member, TASK_MONEY);
|
||||
assignedMoney = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!assignedRespect) {
|
||||
setAutoTask(member, TASK_RESPECT);
|
||||
assignedRespect = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Default task assignment (based on previous logic)
|
||||
setAutoTask(member, Math.random() < TRAIN_CHANCE ? TASK_TRAIN : task);
|
||||
}
|
||||
await ns.sleep(SLEEP_TIME);
|
||||
}
|
||||
}
|
||||
161
Mizzajl/home/GPTPserver.js
Normal file
161
Mizzajl/home/GPTPserver.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
|
||||
const maxRAM = Math.pow(2, 20); // Maximum server size: 2^20 GB
|
||||
const minRAM = Math.pow(2, 3); // Minimum required size (8 GB) - FIXED
|
||||
const serverSizes = [maxRAM, ...Array.from({ length: 17 }, (_, i) => Math.pow(2, 19 - i))]; // 2^20 to 2^3 sizes
|
||||
|
||||
// Fetch the list of purchased servers and sort them from largest to smallest
|
||||
let aPserv = ns.getPurchasedServers();
|
||||
aPserv.sort((a, b) => ns.getServerMaxRam(b) - ns.getServerMaxRam(a));
|
||||
|
||||
// Step 1: Purchase missing servers
|
||||
await purchaseMissingServers(ns, aPserv, serverSizes, maxRAM, minRAM); // PASSED minRAM
|
||||
|
||||
// Object to hold designated servers for each power-of-two size
|
||||
let designatedServers = initializeDesignatedServers(serverSizes);
|
||||
|
||||
// Step 2: Assign servers to their respective power-of-two sizes and upgrade them if necessary
|
||||
assignServers(ns, aPserv, designatedServers, serverSizes);
|
||||
|
||||
// Step 3: Upgrade remaining servers to max RAM
|
||||
await upgradeServersToMaxRAM(ns, designatedServers, aPserv, maxRAM);
|
||||
|
||||
// Step 4: Write the designatedServers object to a file
|
||||
await writeServerListToFile(ns, designatedServers);
|
||||
|
||||
ns.tprint("UpgradedServers.txt has been written.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 1: Purchase missing servers.
|
||||
* Ensures we have one server of each size 2^3 through 2^20, and if there are more servers needed, they are purchased at max RAM (2^20).
|
||||
* @param {NS} ns - Netscript API.
|
||||
* @param {Array} aPserv - Array of purchased server names.
|
||||
* @param {Array} serverSizes - Array of power-of-two server sizes.
|
||||
* @param {Number} maxRAM - Maximum server size (2^20).
|
||||
* @param {Number} minRAM - Minimum required server size (2^3 or 8 GB).
|
||||
*/
|
||||
async function purchaseMissingServers(ns, aPserv, serverSizes, maxRAM, minRAM) {
|
||||
const serverLimit = ns.getPurchasedServerLimit();
|
||||
let nPserv = aPserv.length; // Current number of purchased servers
|
||||
|
||||
for (let i = nPserv; i < serverLimit; i++) {
|
||||
let nMoney = ns.getServerMoneyAvailable("home");
|
||||
|
||||
// If we have fewer than 17 servers, follow the doubling pattern
|
||||
if (i < serverSizes.length) {
|
||||
let targetSize = serverSizes[serverSizes.length - i - 1]; // Start at the smallest size (2^3, then 2^4, etc.)
|
||||
let serverCost = ns.getPurchasedServerCost(targetSize);
|
||||
|
||||
if (nMoney >= serverCost) {
|
||||
const sServer = ns.purchaseServer(`pserv-${i.toString().padStart(2, "0")}`, targetSize);
|
||||
ns.print(`Purchased ${sServer} with ${targetSize} GB RAM for ${serverCost}`);
|
||||
aPserv.push(sServer); // Add the new server to the list
|
||||
} else {
|
||||
ns.print(`Insufficient funds for pserv-${i.toString().padStart(2, "0")} (${nMoney} / ${serverCost}). Waiting...`);
|
||||
await ns.sleep(5000); // Wait and retry
|
||||
i--; // Retry this iteration once funds are available
|
||||
}
|
||||
} else { // Once we have the first 17 servers, purchase additional servers at max RAM
|
||||
let serverCost = ns.getPurchasedServerCost(maxRAM);
|
||||
|
||||
if (nMoney >= serverCost) {
|
||||
const sServer = ns.purchaseServer(`pserv-${i.toString().padStart(2, "0")}`, maxRAM);
|
||||
ns.print(`Purchased ${sServer} with ${maxRAM} GB RAM for ${serverCost}`);
|
||||
aPserv.push(sServer);
|
||||
} else {
|
||||
ns.print(`Insufficient funds for pserv-${i.toString().padStart(2, "0")} (${nMoney} / ${serverCost}). Waiting...`);
|
||||
await ns.sleep(5000); // Wait and retry
|
||||
i--; // Retry this iteration once funds are available
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the designatedServers object with null values for each power-of-two size.
|
||||
* @param {Array} serverSizes - Array of power-of-two server sizes (2^20, 2^19, etc.).
|
||||
* @returns {Object} - Object with each size as a key and null as the initial value.
|
||||
*/
|
||||
function initializeDesignatedServers(serverSizes) {
|
||||
let designatedServers = {};
|
||||
serverSizes.forEach(size => designatedServers[size] = null);
|
||||
return designatedServers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 2: Assigns servers to their respective power-of-two sizes, starting from the largest.
|
||||
* Each server is only used once and is placed in the largest available size it can fit.
|
||||
* @param {NS} ns - Netscript API.
|
||||
* @param {Array} aPserv - Array of purchased server names, sorted by size.
|
||||
* @param {Object} designatedServers - Object holding the server assignments.
|
||||
* @param {Array} serverSizes - Array of power-of-two server sizes.
|
||||
*/
|
||||
function assignServers(ns, aPserv, designatedServers, serverSizes) {
|
||||
for (let size of serverSizes) {
|
||||
for (let i = 0; i < aPserv.length; i++) {
|
||||
let server = aPserv[i];
|
||||
let serverRAM = ns.getServerMaxRam(server);
|
||||
|
||||
// If this server can fill the current slot and has not already been assigned
|
||||
if (serverRAM >= size && !Object.values(designatedServers).includes(server)) {
|
||||
designatedServers[size] = server; // Assign the server to the current power-of-two size
|
||||
ns.print(`Assigned server ${server} with ${serverRAM} GB to ${size} GB spot.`);
|
||||
break; // Stop searching for this size and move to the next smaller size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 3: Upgrade remaining servers to max RAM (2^20).
|
||||
* @param {NS} ns - Netscript API.
|
||||
* @param {Object} designatedServers - Object holding the server assignments.
|
||||
* @param {Array} aPserv - Array of purchased servers.
|
||||
* @param {Number} maxRAM - Maximum server size (2^20 GB).
|
||||
*/
|
||||
async function upgradeServersToMaxRAM(ns, designatedServers, aPserv, maxRAM) {
|
||||
while (true) {
|
||||
let nMoney = ns.getServerMoneyAvailable("home");
|
||||
let lowestRAMServer = null;
|
||||
let lowestRAM = maxRAM;
|
||||
|
||||
// Find the server with the lowest RAM that isn't already maxed out
|
||||
for (let i = 0; i < aPserv.length; i++) {
|
||||
let serverRAM = ns.getServerMaxRam(aPserv[i]);
|
||||
if (serverRAM < maxRAM && !Object.values(designatedServers).includes(aPserv[i])) {
|
||||
lowestRAM = serverRAM;
|
||||
lowestRAMServer = aPserv[i];
|
||||
}
|
||||
}
|
||||
|
||||
// If all servers are at maxRAM, we are done
|
||||
if (!lowestRAMServer) {
|
||||
ns.tprint("All servers are fully upgraded to 2^20 GB RAM.");
|
||||
break; // Exit the while loop
|
||||
}
|
||||
|
||||
// Upgrade the lowest RAM server to maxRAM
|
||||
let upgradeCost = ns.getPurchasedServerUpgradeCost(lowestRAMServer, maxRAM);
|
||||
|
||||
if (nMoney >= upgradeCost) {
|
||||
ns.upgradePurchasedServer(lowestRAMServer, maxRAM);
|
||||
ns.print(`Upgraded ${lowestRAMServer} to ${maxRAM} GB RAM.`);
|
||||
} else {
|
||||
ns.print(`Insufficient funds to upgrade ${lowestRAMServer} to ${maxRAM}: ${nMoney} / ${upgradeCost}`);
|
||||
await ns.sleep(5000); // Wait and check again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the designatedServers object to a file in JSON format.
|
||||
* @param {NS} ns - Netscript API.
|
||||
* @param {Object} designatedServers - Object holding the server assignments.
|
||||
*/
|
||||
async function writeServerListToFile(ns, designatedServers) {
|
||||
await ns.write("UpgradedServers.txt", JSON.stringify(designatedServers, null, 2), "w");
|
||||
ns.print("UpgradedServers.txt has been written with the server assignments.");
|
||||
}
|
||||
37
Mizzajl/home/GenerateCrimeList.js
Normal file
37
Mizzajl/home/GenerateCrimeList.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
const sCrimeStatsFile = "CrimeStats.txt";
|
||||
|
||||
let aCrimes = [
|
||||
"Shoplift",
|
||||
"Rob Store",
|
||||
"Mug",
|
||||
"Larceny",
|
||||
"Deal Drugs",
|
||||
"Bond Forgery",
|
||||
"Traffick Arms",
|
||||
"Homicide",
|
||||
"Grand Theft Auto",
|
||||
"Kidnap",
|
||||
"Assassination",
|
||||
"Heist"
|
||||
];
|
||||
|
||||
let aCrimeStatsList = [];
|
||||
|
||||
for (let i = 0; i < aCrimes.length; i++) {
|
||||
let oCrimeStats = ns.singularity.getCrimeStats(aCrimes[i]);
|
||||
|
||||
// Create a new object starting with the name of the crime
|
||||
let oCrimeWithStats = {
|
||||
name: aCrimes[i], // Name of the crime as the first item
|
||||
...oCrimeStats // Spread the rest of the stats into the object
|
||||
};
|
||||
|
||||
aCrimeStatsList.push(oCrimeWithStats);
|
||||
}
|
||||
|
||||
// Write the list of crime stats to the file as a JSON string
|
||||
ns.write(sCrimeStatsFile, JSON.stringify(aCrimeStatsList, null, 2), "w");
|
||||
}
|
||||
9
Mizzajl/home/GetCrimeStat.js
Normal file
9
Mizzajl/home/GetCrimeStat.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { GetCrimeStat } from "./Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
|
||||
let nStat = GetCrimeStat(ns, ...ns.args);
|
||||
ns.print(nStat);
|
||||
}
|
||||
@@ -190,6 +190,9 @@ export async function purchaseAndUpgradeServers(ns) {
|
||||
minHackLvl: 1,
|
||||
rootAccess: true,
|
||||
openPorts: 0,
|
||||
serverOrgs: "",
|
||||
serverCores: 1,
|
||||
serverFiles: []
|
||||
});
|
||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
||||
continue
|
||||
@@ -211,7 +214,7 @@ export async function purchaseAndUpgradeServers(ns) {
|
||||
let newServerList = serverList.map((entry) => { if (entry.serverName === currentServer) { entry.maxRam = targetRam } return entry });
|
||||
ns.write("serverList.txt", JSON.stringify(newServerList), "w");
|
||||
ns.tprint(cCyan + "Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB" + cReset);
|
||||
ns.toast("Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB", "info", 10000);
|
||||
//ns.toast("Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB", "info", 10000);
|
||||
}
|
||||
} else {
|
||||
await ns.sleep(5000);
|
||||
@@ -257,6 +260,12 @@ export async function RunAndWait(ns, sScript, ...args) {
|
||||
while (ns.isRunning(sScript, ...args)) { await ns.sleep(100); }
|
||||
}
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function DistributeRunAndWait(ns, sScript, ...args) {
|
||||
if (!ns.isRunning(sScript, ...args)) { drun(ns, sScript, ...args); }
|
||||
while (ns.isRunning(sScript, ...args)) { await ns.sleep(100); }
|
||||
}
|
||||
|
||||
/** @param {NS} ns */
|
||||
export function listWorkServers(ns) {
|
||||
ns.disableLog("ALL");
|
||||
@@ -335,18 +344,36 @@ export function sortJsonArrayByKey(array, primaryKey, secondaryKey) {
|
||||
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function distributeScript(ns, sScript, nThreads, [...args]) {
|
||||
export async function drun(ns, ...args ){
|
||||
//ns.tail();
|
||||
ns.disableLog("ALL");
|
||||
ns.disableLog("scp");
|
||||
ns.print(args);
|
||||
let aArgs = args;
|
||||
const sScript = aArgs.shift();
|
||||
let nThreads = aArgs.shift();
|
||||
|
||||
if (nThreads === undefined) { nThreads = 1 };
|
||||
|
||||
ns.print(aArgs);
|
||||
|
||||
const aScriptFiles = ns.ls("home", ".js");
|
||||
const aTXTFiles = ns.ls("home", ".txt");
|
||||
|
||||
const sWeakenScript = "RMweaken.js";
|
||||
const sGrowScript = "RMgrow.js";
|
||||
const sListName = "serverList.txt";
|
||||
|
||||
if (!ns.fileExists(sListName, "home")) { ns.print(`ERROR ${sListName} does not exist.`); return false; };
|
||||
let sServerList = ns.read(sListName);
|
||||
let aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam").reverse();
|
||||
let aSortedList;
|
||||
if (sScript === sWeakenScript || sScript === sGrowScript) {
|
||||
aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam").reverse();
|
||||
} else {
|
||||
aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam");
|
||||
}
|
||||
|
||||
ns.print(sScript);
|
||||
ns.print(nThreads);
|
||||
ns.print(...args);
|
||||
|
||||
const nScriptSize = ns.getScriptRam(sScript, "home");
|
||||
let nTotalSize = nScriptSize * nThreads;
|
||||
@@ -357,21 +384,68 @@ export async function distributeScript(ns, sScript, nThreads, [...args]) {
|
||||
aSortedList.forEach((entry) => {
|
||||
let sHost = entry.serverName;
|
||||
ns.print("sHost = " + sHost)
|
||||
|
||||
let nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize) {
|
||||
ns.scp(sScript, sHost);
|
||||
ns.exec(sScript, sHost, nThreads, ...args);
|
||||
if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize && entry.serverName !== "home") {
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
ns.exec(sScript, sHost, nThreads, ...aArgs);
|
||||
nThreads = 0;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nScriptSize && entry.serverName !== "home") {
|
||||
let nThreadsDist = Math.floor(nFreeRAM / nScriptSize);
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
ns.print("room for : " + nThreadsDist + " scripts");
|
||||
ns.exec(sScript, sHost, nThreadsDist, ...aArgs);
|
||||
nThreads -= nThreadsDist;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize) {
|
||||
if (entry.serverName !== "home") {
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
}
|
||||
ns.exec(sScript, sHost, nThreads, ...aArgs);
|
||||
nThreads = 0;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nScriptSize) {
|
||||
let nThreadsDist = Math.floor(nFreeRAM / nScriptSize);
|
||||
ns.scp(sScript, sHost);
|
||||
if (entry.serverName !== "home") {
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
}
|
||||
ns.print("room for : " + nThreadsDist + " scripts");
|
||||
ns.exec(sScript, sHost, nThreadsDist, ...args);
|
||||
ns.exec(sScript, sHost, nThreadsDist, ...aArgs);
|
||||
nThreads -= nThreadsDist;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {NS} ns */
|
||||
export function GetCrimeStat(ns, sCrime, sStat) {
|
||||
const sCrimeStatsFile = "CrimeStats.txt";
|
||||
|
||||
// Read the crime stats file
|
||||
let aCrimeStatsList = JSON.parse(ns.read(sCrimeStatsFile));
|
||||
|
||||
// Search for the crime in the list
|
||||
let oCrimeStats = aCrimeStatsList.find(crime => crime.name === sCrime);
|
||||
|
||||
// If the crime was not found, return undefined or an error message
|
||||
if (!oCrimeStats) {
|
||||
ns.tprint(`Crime "${sCrime}" not found.`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Check if the stat exists for the given crime
|
||||
if (!(sStat in oCrimeStats)) {
|
||||
ns.tprint(`Stat "${sStat}" not found for crime "${sCrime}".`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Return the value of the specified stat
|
||||
return oCrimeStats[sStat];
|
||||
}
|
||||
70
Mizzajl/home/ManagePserv.js
Normal file
70
Mizzajl/home/ManagePserv.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
let aPserv = ns.getPurchasedServers(); //array of purchased servers
|
||||
let nPserv = aPserv.length; //amount of purchased servers we have
|
||||
let nMoney = ns.getServerMoneyAvailable("home"); //player money
|
||||
let nPrevSize = 4; //nPrevSize is 4 so the first server we will buy is 8
|
||||
|
||||
|
||||
//Purchase Servers
|
||||
//idea is to purchase the first server at 8 gb, next one at 16, next at 32 and so on
|
||||
|
||||
for (let i = 0; nPserv < i; i++) {
|
||||
nMoney = ns.getServerMoneyAvailable("home"); //check money for each iteration
|
||||
if (nMoney >= ns.getPurchasedServerCost(nPrevSize * 2)) { //can we afford next server?
|
||||
const sServer = ns.purchaseServer(`pserv-${toString(i).padStart(2, "0")}`, nPrevSize * 2); //purchase server with name pserv- + 0i
|
||||
ns.print(`Purchased ${sServer} for ${nPrevSize * 2}`); //print tail message that we purchased server
|
||||
nPrevSize *= 2; //increase nPrevSize for next iteration
|
||||
nPserv++ //increase number of purchased servers
|
||||
}
|
||||
else {
|
||||
ns.print(`Insufficient funds for pserv-${toString(i).padStart(2, "0")} ${nMoney} / ${ns.getPurchasedServerCost(nPrevSize * 2)}`);
|
||||
await ns.sleep(5000);
|
||||
}
|
||||
}
|
||||
ns.tprint("for loop purchase complete");
|
||||
|
||||
|
||||
//upgrade servers
|
||||
//idea is to upgrade the lowest server to match the highest (which should be 2^20 in size)
|
||||
|
||||
let nCurrentRAM;
|
||||
let nLowestRAM = 2 ** 21;
|
||||
let nHighestRAM = 0;
|
||||
let sLowestPserv;
|
||||
let sHighestPserv;
|
||||
let nTotalPServRAM = 0;
|
||||
|
||||
for (let i = 0; i < nPserv; i++) {
|
||||
nCurrentRAM = ns.getServerMaxRam(aPserv[i]);
|
||||
|
||||
nTotalPServRAM += nCurrentRAM;
|
||||
|
||||
if (nCurrentRAM < nLowestRAM) {
|
||||
nLowestRAM = nCurrentRAM
|
||||
sLowestPserv = aPservers[i];
|
||||
}
|
||||
|
||||
if (nCurrentRAM > nHighestRAM) {
|
||||
nHighestRAM = nCurrentRAM
|
||||
sHighestPserv = aPserv[i];
|
||||
}
|
||||
}
|
||||
|
||||
//sLowestPserv should now be the lowest server
|
||||
//sHighestPserv should now be the highest server
|
||||
|
||||
for (let i = 0; sLowestPserv < sHighestPserv ; i++) {
|
||||
if (nMoney >= ns.getPurchasedServerUpgradeCost(sLowestPserv, 2^20)){
|
||||
ns.upgradePurchasedServer(sLowestPserv, 2^20);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
15
Mizzajl/home/RemoveBackground.js
Normal file
15
Mizzajl/home/RemoveBackground.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
const doc = eval("document");
|
||||
|
||||
// Find the background div by its ID
|
||||
let backgroundDiv = doc.getElementById("terminal-background");
|
||||
|
||||
if (backgroundDiv) {
|
||||
// Remove the background element
|
||||
backgroundDiv.remove();
|
||||
ns.tprint("Background removed.");
|
||||
} else {
|
||||
ns.tprint("No background found to remove.");
|
||||
}
|
||||
}
|
||||
@@ -1,82 +1,6 @@
|
||||
import { sortJsonArrayByKey } from "Library.js";
|
||||
import { drun } from "./Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
//ns.tail();
|
||||
ns.disableLog("scp");
|
||||
let aArgs = ns.args;
|
||||
const sScript = aArgs.shift();
|
||||
let nThreads = aArgs.shift();
|
||||
if (nThreads === undefined) { nThreads = 1 };
|
||||
|
||||
ns.print(aArgs);
|
||||
|
||||
const aScriptFiles = ns.ls("home", ".js");
|
||||
const aTXTFiles = ns.ls("home", ".txt");
|
||||
//ns.tprint(aScriptFiles);
|
||||
//ns.tprint(aTXTFiles);
|
||||
|
||||
const sWeakenScript = "RMweaken.js";
|
||||
const sGrowScript = "RMgrow.js";
|
||||
const sListName = "serverList.txt";
|
||||
|
||||
if (!ns.fileExists(sListName, "home")) { ns.print(`ERROR ${sListName} does not exist.`); return false; };
|
||||
let sServerList = ns.read(sListName);
|
||||
let aSortedList;
|
||||
if (sScript === sWeakenScript || sScript === sGrowScript) {
|
||||
aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam").reverse();
|
||||
} else {
|
||||
aSortedList = sortJsonArrayByKey(sServerList, "serverCores", "maxRam");
|
||||
}
|
||||
|
||||
ns.print(sScript);
|
||||
ns.print(nThreads);
|
||||
|
||||
const nScriptSize = ns.getScriptRam(sScript, "home");
|
||||
let nTotalSize = nScriptSize * nThreads;
|
||||
|
||||
ns.print("nScriptSize = " + nScriptSize);
|
||||
ns.print("nTotalSize = " + nTotalSize);
|
||||
|
||||
aSortedList.forEach((entry) => {
|
||||
let sHost = entry.serverName;
|
||||
ns.print("sHost = " + sHost)
|
||||
let nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize && entry.serverName !== "home") {
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
ns.exec(sScript, sHost, nThreads, ...aArgs);
|
||||
nThreads = 0;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nScriptSize && entry.serverName !== "home") {
|
||||
let nThreadsDist = Math.floor(nFreeRAM / nScriptSize);
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
ns.print("room for : " + nThreadsDist + " scripts");
|
||||
ns.exec(sScript, sHost, nThreadsDist, ...aArgs);
|
||||
nThreads -= nThreadsDist;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize) {
|
||||
if (entry.serverName !== "home"){
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
}
|
||||
ns.exec(sScript, sHost, nThreads, ...aArgs);
|
||||
nThreads = 0;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nScriptSize) {
|
||||
let nThreadsDist = Math.floor(nFreeRAM / nScriptSize);
|
||||
if (entry.serverName !== "home"){
|
||||
ns.scp(aScriptFiles, sHost), "home";
|
||||
ns.scp(aTXTFiles, sHost), "home";
|
||||
}
|
||||
ns.print("room for : " + nThreadsDist + " scripts");
|
||||
ns.exec(sScript, sHost, nThreadsDist, ...aArgs);
|
||||
nThreads -= nThreadsDist;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
});
|
||||
await drun(ns, ...ns.args);
|
||||
}
|
||||
9
Mizzajl/home/RunGang.js
Normal file
9
Mizzajl/home/RunGang.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { drun } from "./Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
if (ns.gang.inGang()){
|
||||
const sGangScript = "gang/auto-gang2.js";
|
||||
await drun(ns, sGangScript);
|
||||
}
|
||||
}
|
||||
36
Mizzajl/home/SetBackground.js
Normal file
36
Mizzajl/home/SetBackground.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
// Evaluate the document to access the DOM
|
||||
const doc = eval("document");
|
||||
|
||||
// Check if the background has already been added to avoid duplicates
|
||||
if (doc.getElementById("terminal-background")) {
|
||||
ns.tprint("Background already set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new <div> element to hold the background image
|
||||
let backgroundDiv = doc.createElement("div");
|
||||
backgroundDiv.id = "terminal-background"; // Set an ID for later reference
|
||||
|
||||
// Add CSS styling for the background
|
||||
backgroundDiv.style = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: -1; /* Send it to the back */
|
||||
background-image: url('https://r4.wallpaperflare.com/wallpaper/510/751/778/akira-kaneda-motorcycle-anime-wallpaper-c90008ed51badd0b96b7680fa02106ad.jpg'); /* Replace with your image URL */
|
||||
background-size: cover; /* Ensure the image covers the whole screen */
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.5; /* Adjust opacity for readability */
|
||||
`;
|
||||
|
||||
// Append the background <div> to the body of the document
|
||||
doc.body.appendChild(backgroundDiv);
|
||||
|
||||
// Inform the user that the background has been set
|
||||
ns.tprint("Custom background image set successfully!");
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { RunAndWait } from "./Library";
|
||||
import { DistributeRunAndWait, drun, RunAndWait } from "./Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
|
||||
const sServerListScript = "Serverlist.js";
|
||||
const sGangScript = "gang/auto-gang2.js";
|
||||
const sGangScript = "RunGang.js";
|
||||
const sPServScript = "purchaseServers.js";
|
||||
const sBatchController = "EveryServerRun.js";
|
||||
const sBackdoorScript = "backdoor.js";
|
||||
@@ -13,19 +13,21 @@ export async function main(ns) {
|
||||
const sMonitorScript = "autoexec.js";
|
||||
const sServerListFile = "serverList.txt";
|
||||
const sBestServerFile = "bestTarget.txt";
|
||||
const sWorkerList = "WorkerList.js";
|
||||
const sCorpControl = "CorpControl.js";
|
||||
|
||||
await RunAndWait(ns, sServerListScript);
|
||||
|
||||
const oServerList = JSON.parse(ns.read(sServerListFile));
|
||||
const oHome = oServerList["home"];
|
||||
const nHomeMaxRAM = oHome.maxRam;
|
||||
ns.print("nHomeMaxRAM = " + nHomeMaxRAM);
|
||||
|
||||
if (!ns.isRunning(sGangScript)) { ns.run(sGangScript); }
|
||||
if (!ns.isRunning(sPServScript)) { ns.run(sPServScript); }
|
||||
if (!ns.isRunning(sWorkerList)) { ns.run(sWorkerList); }
|
||||
if (!ns.isRunning(sGangScript)) { drun(ns, sGangScript); }
|
||||
//if (!ns.isRunning(sCorpControl)) { ns.run(sCorpControl); }
|
||||
if (!ns.isRunning(sPServScript)) { drun(ns, sPServScript); }
|
||||
await RunAndWait(ns, sBackdoorScript);
|
||||
await RunAndWait(ns, sUpdateTarget);
|
||||
await RunAndWait(ns, sBatchController);
|
||||
await DistributeRunAndWait(ns, sUpdateTarget);
|
||||
|
||||
/*
|
||||
let oServerlist = JSON.parse(ns.read(sServerListFile));
|
||||
let nHomeMaxRAM = oServerlist.find((entry) => entry.serverName === "home").maxRam;
|
||||
ns.print("nHomeMaxRAM = " + nHomeMaxRAM);
|
||||
if (nHomeMaxRAM >= 256) { if (!ns.isRunning(sMonitorScript)) { ns.run(sMonitorScript); } }
|
||||
*/
|
||||
}
|
||||
331
Mizzajl/home/UICrimeStats.js
Normal file
331
Mizzajl/home/UICrimeStats.js
Normal file
@@ -0,0 +1,331 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.disableLog('sleep'); // Disable log spamming
|
||||
|
||||
const doc = eval("document");
|
||||
const body = doc.body;
|
||||
let isMinimized = false; // Track the minimize state
|
||||
|
||||
// Read crime stats from the CrimeStats.txt file
|
||||
let crimeStatsData = await ns.read("CrimeStats.txt");
|
||||
let crimes = JSON.parse(crimeStatsData); // Parse the JSON data from the file
|
||||
|
||||
// Add dynamic crime chance and calculate stats per second
|
||||
for (let crime of crimes) {
|
||||
crime.chance = ns.singularity.getCrimeChance(crime.name) * 100; // Get success chance as a number
|
||||
let timeInSeconds = crime.time / 1000; // Convert ms to seconds for calculations
|
||||
|
||||
// Calculate stats per second
|
||||
crime.hacking_exp_per_sec = crime.hacking_exp / timeInSeconds;
|
||||
crime.strength_exp_per_sec = crime.strength_exp / timeInSeconds;
|
||||
crime.defense_exp_per_sec = crime.defense_exp / timeInSeconds;
|
||||
crime.dexterity_exp_per_sec = crime.dexterity_exp / timeInSeconds;
|
||||
crime.agility_exp_per_sec = crime.agility_exp / timeInSeconds;
|
||||
crime.charisma_exp_per_sec = crime.charisma_exp / timeInSeconds;
|
||||
crime.intelligence_exp_per_sec = crime.intelligence_exp / timeInSeconds || 0; // Handle potential missing data
|
||||
crime.money_per_sec = crime.money / timeInSeconds;
|
||||
crime.karma_per_sec = crime.karma / timeInSeconds;
|
||||
crime.money_per_chance = crime.money * (crime.chance / 100) / timeInSeconds; // Money per chance per second
|
||||
}
|
||||
|
||||
// Function to map value to a color between green and red
|
||||
function getGradientColor(value, min, max, isReversed = false) {
|
||||
if (min === max) return "rgb(0,255,0)"; // Return green if all values are the same
|
||||
let normalized = (value - min) / (max - min);
|
||||
if (isReversed) normalized = 1 - normalized; // Reverse the color gradient for columns where lower values are better
|
||||
let r = Math.round(255 * (1 - normalized)); // Red for lower values
|
||||
let g = Math.round(255 * normalized); // Green for higher values
|
||||
return `rgb(${r},${g},0)`; // Return color from green to red
|
||||
}
|
||||
|
||||
// Create the CSS window container
|
||||
let container = doc.createElement("div");
|
||||
container.style = `
|
||||
position: fixed;
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
background: black; /* Black background */
|
||||
opacity: 0.9; /* 50% transparency */
|
||||
color: #0c0; /* Green text */
|
||||
z-index: 1000;
|
||||
font-family: "Source Code Pro", monospace; /* Apply the terminal font */
|
||||
font-size: 16px;
|
||||
border: 2px solid #666;
|
||||
border-radius: 5px;
|
||||
width: 1400px; /* Increased width */
|
||||
height: 400px; /* Increased height */
|
||||
overflow-y: auto;
|
||||
`;
|
||||
body.appendChild(container);
|
||||
|
||||
// Create the title bar with minimize and close buttons
|
||||
let titleBar = doc.createElement("div");
|
||||
titleBar.style = `
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: black; /* Black background for title bar */
|
||||
color: #0c0; /* Green text */
|
||||
border-bottom: 1px solid #666;
|
||||
font-weight: bold;
|
||||
`;
|
||||
container.appendChild(titleBar);
|
||||
|
||||
// Title text
|
||||
let title = doc.createElement("span");
|
||||
title.innerText = "Crime Stats Monitor";
|
||||
titleBar.appendChild(title);
|
||||
|
||||
// Create a container for the buttons and align them to the right
|
||||
let buttonContainer = doc.createElement("div");
|
||||
buttonContainer.style = `
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
`;
|
||||
titleBar.appendChild(buttonContainer);
|
||||
|
||||
// Minimize button (▲ for minimize, ▼ for restore)
|
||||
let minimizeButton = doc.createElement("button");
|
||||
minimizeButton.innerText = "▲"; // Start as minimize button
|
||||
minimizeButton.style = `
|
||||
background: none;
|
||||
border: 1px solid #666;
|
||||
color: #0c0; /* Green text */
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
width: 30px; /* Set same width for buttons */
|
||||
`;
|
||||
buttonContainer.appendChild(minimizeButton);
|
||||
|
||||
minimizeButton.addEventListener("click", () => {
|
||||
if (isMinimized) {
|
||||
minimizeButton.innerText = "▲"; // Minimize arrow
|
||||
container.style.height = "400px"; // Restore height
|
||||
} else {
|
||||
minimizeButton.innerText = "▼"; // Restore arrow
|
||||
container.style.height = "25px"; // Minimize height
|
||||
}
|
||||
isMinimized = !isMinimized;
|
||||
});
|
||||
|
||||
// Close button (X)
|
||||
let closeButton = doc.createElement("button");
|
||||
closeButton.innerText = "X";
|
||||
closeButton.style = `
|
||||
background: none;
|
||||
border: 1px solid #666;
|
||||
color: #0c0; /* Green text */
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
width: 30px; /* Set same width for buttons */
|
||||
`;
|
||||
buttonContainer.appendChild(closeButton);
|
||||
|
||||
closeButton.addEventListener("click", () => {
|
||||
container.remove(); // Close the window
|
||||
});
|
||||
|
||||
// Table for displaying the crime stats
|
||||
let table = doc.createElement("table");
|
||||
table.style = `
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
color: #0c0; /* Green text */
|
||||
`;
|
||||
container.appendChild(table);
|
||||
|
||||
// Track the current sort direction for each column (null, 'asc', or 'desc')
|
||||
let sortOrder = new Array(13).fill(null); // One for each column
|
||||
|
||||
// Add table headers with clickable sorting functionality and arrows
|
||||
let headers = [
|
||||
"Crime", "Time (s)", "Chance", "Hack Exp/s", "Str Exp/s", "Def Exp/s",
|
||||
"Dex Exp/s", "Agi Exp/s", "Cha Exp/s", "Money/s", "Karma/s", "$/%/s", "IntXP/s"
|
||||
];
|
||||
|
||||
let headerRow = doc.createElement("tr");
|
||||
|
||||
headers.forEach((header, index) => {
|
||||
let th = doc.createElement("th");
|
||||
th.innerHTML = `${header} <span></span>`; // Span for the arrow
|
||||
th.style = `
|
||||
padding: 5px;
|
||||
background: #333;
|
||||
border: 1px solid #666;
|
||||
cursor: pointer;
|
||||
white-space: nowrap; /* Prevent wrapping */
|
||||
`;
|
||||
|
||||
// Add sorting functionality for each column
|
||||
th.addEventListener("click", () => {
|
||||
clearAllArrows(); // Remove all arrows
|
||||
sortCrimesByColumn(index); // Sort by this column
|
||||
toggleSortOrder(index); // Toggle sort order for this column
|
||||
});
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
||||
table.appendChild(headerRow);
|
||||
|
||||
// Function to toggle the sort order for a column
|
||||
function toggleSortOrder(columnIndex) {
|
||||
// Toggle between 'asc' and 'desc'
|
||||
if (sortOrder[columnIndex] === 'asc') {
|
||||
sortOrder[columnIndex] = 'desc';
|
||||
} else {
|
||||
sortOrder[columnIndex] = 'asc';
|
||||
}
|
||||
|
||||
// Update the arrows for this column
|
||||
updateArrow(columnIndex);
|
||||
}
|
||||
|
||||
// Function to update the arrow for a specific column
|
||||
function updateArrow(columnIndex) {
|
||||
let th = headerRow.querySelectorAll("th")[columnIndex];
|
||||
let arrowSpan = th.querySelector("span");
|
||||
|
||||
if (sortOrder[columnIndex] === 'asc') {
|
||||
arrowSpan.innerHTML = " ▲"; // Up arrow for ascending
|
||||
} else if (sortOrder[columnIndex] === 'desc') {
|
||||
arrowSpan.innerHTML = " ▼"; // Down arrow for descending
|
||||
}
|
||||
}
|
||||
|
||||
// Function to clear all arrows
|
||||
function clearAllArrows() {
|
||||
headerRow.querySelectorAll("th span").forEach(arrow => {
|
||||
arrow.innerHTML = ""; // Remove all arrows
|
||||
});
|
||||
}
|
||||
|
||||
// Function to format numbers with 4 decimal places
|
||||
function formatNumber(num) {
|
||||
return parseFloat(num.toFixed(4)); // Convert to number with 4 decimal places
|
||||
}
|
||||
|
||||
// Function to display crimes in the table
|
||||
function displayCrimes(crimesList) {
|
||||
// Clear any existing rows (except the header)
|
||||
while (table.rows.length > 1) {
|
||||
table.deleteRow(1);
|
||||
}
|
||||
|
||||
// Find min and max for each column (for color gradient)
|
||||
const columnsWithValues = [
|
||||
{ key: "time", reverseGradient: true },
|
||||
{ key: "chance", reverseGradient: false },
|
||||
{ key: "hacking_exp_per_sec", reverseGradient: false },
|
||||
{ key: "strength_exp_per_sec", reverseGradient: false },
|
||||
{ key: "defense_exp_per_sec", reverseGradient: false },
|
||||
{ key: "dexterity_exp_per_sec", reverseGradient: false },
|
||||
{ key: "agility_exp_per_sec", reverseGradient: false },
|
||||
{ key: "charisma_exp_per_sec", reverseGradient: false },
|
||||
{ key: "money_per_sec", reverseGradient: false },
|
||||
{ key: "karma_per_sec", reverseGradient: false },
|
||||
{ key: "money_per_chance", reverseGradient: false },
|
||||
{ key: "intelligence_exp_per_sec", reverseGradient: false }
|
||||
];
|
||||
|
||||
let minMax = {};
|
||||
|
||||
// Get min and max values for each column, excluding non-data elements
|
||||
columnsWithValues.forEach(column => {
|
||||
let values = crimesList.map(crime => crime[column.key]).filter(v => !isNaN(v)); // Ensure we're working with numbers
|
||||
minMax[column.key] = {
|
||||
min: Math.min(...values),
|
||||
max: Math.max(...values)
|
||||
};
|
||||
});
|
||||
|
||||
crimesList.forEach(crime => {
|
||||
let row = doc.createElement("tr");
|
||||
|
||||
let columns = [
|
||||
{ text: crime.name, value: crime.name, isName: true }, // Crime name (always green)
|
||||
{ text: formatNumber(crime.time / 1000), value: crime.time / 1000, key: "time" }, // Time in seconds
|
||||
{ text: formatNumber(crime.chance), value: crime.chance, key: "chance" }, // Success chance
|
||||
{ text: formatNumber(crime.hacking_exp_per_sec), value: crime.hacking_exp_per_sec, key: "hacking_exp_per_sec" },
|
||||
{ text: formatNumber(crime.strength_exp_per_sec), value: crime.strength_exp_per_sec, key: "strength_exp_per_sec" },
|
||||
{ text: formatNumber(crime.defense_exp_per_sec), value: crime.defense_exp_per_sec, key: "defense_exp_per_sec" },
|
||||
{ text: formatNumber(crime.dexterity_exp_per_sec), value: crime.dexterity_exp_per_sec, key: "dexterity_exp_per_sec" },
|
||||
{ text: formatNumber(crime.agility_exp_per_sec), value: crime.agility_exp_per_sec, key: "agility_exp_per_sec" },
|
||||
{ text: formatNumber(crime.charisma_exp_per_sec), value: crime.charisma_exp_per_sec, key: "charisma_exp_per_sec" },
|
||||
{ text: formatNumber(crime.money_per_sec), value: crime.money_per_sec, key: "money_per_sec" },
|
||||
{ text: formatNumber(crime.karma_per_sec), value: crime.karma_per_sec, key: "karma_per_sec" },
|
||||
{ text: formatNumber(crime.money_per_chance), value: crime.money_per_chance, key: "money_per_chance" }, // Money per chance per second
|
||||
{ text: formatNumber(crime.intelligence_exp_per_sec), value: crime.intelligence_exp_per_sec, key: "intelligence_exp_per_sec" } // Intelligence XP per second
|
||||
];
|
||||
|
||||
columns.forEach((col, index) => {
|
||||
let td = doc.createElement("td");
|
||||
td.innerText = col.text; // Display formatted text
|
||||
td.dataset.value = col.value; // Store the numeric value for sorting
|
||||
|
||||
// Apply the color gradient to each cell based on the column
|
||||
let gradientColor = col.isName
|
||||
? "#0c0" // Always green for names
|
||||
: getGradientColor(col.value, minMax[col.key].min, minMax[col.key].max, columnsWithValues[index]?.reverseGradient);
|
||||
|
||||
td.style.color = gradientColor; // Apply color
|
||||
|
||||
td.style.padding = "5px";
|
||||
td.style.borderBottom = "1px solid #666";
|
||||
td.style.textAlign = "center";
|
||||
td.style.whiteSpace = "nowrap"; // Prevent text wrapping
|
||||
|
||||
row.appendChild(td);
|
||||
});
|
||||
|
||||
table.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
// Sorting function (high to low for numeric values)
|
||||
function sortCrimesByColumn(columnIndex) {
|
||||
let rows = Array.from(table.querySelectorAll('tr:nth-child(n+2)')); // Get all rows except header
|
||||
let order = sortOrder[columnIndex]; // Ascending or descending
|
||||
|
||||
rows.sort((rowA, rowB) => {
|
||||
let valA = rowA.cells[columnIndex].dataset.value;
|
||||
let valB = rowB.cells[columnIndex].dataset.value;
|
||||
|
||||
// Check if values are numeric and sort accordingly
|
||||
if (!isNaN(valA) && !isNaN(valB)) {
|
||||
return order === 'asc' ? parseFloat(valA) - parseFloat(valB) : parseFloat(valB) - parseFloat(valA);
|
||||
}
|
||||
|
||||
// If not numeric, sort alphabetically
|
||||
return order === 'asc' ? String(valA).localeCompare(String(valB)) : String(valB).localeCompare(String(valA));
|
||||
});
|
||||
|
||||
// Append rows in sorted order
|
||||
rows.forEach(row => table.appendChild(row));
|
||||
}
|
||||
|
||||
// Display the crimes initially
|
||||
displayCrimes(crimes);
|
||||
|
||||
// Make the window draggable
|
||||
let isDragging = false;
|
||||
let offsetX, offsetY;
|
||||
|
||||
titleBar.addEventListener("mousedown", (e) => {
|
||||
isDragging = true;
|
||||
offsetX = e.clientX - container.getBoundingClientRect().left;
|
||||
offsetY = e.clientY - container.getBoundingClientRect().top;
|
||||
});
|
||||
|
||||
doc.addEventListener("mousemove", (e) => {
|
||||
if (isDragging) {
|
||||
container.style.left = `${e.clientX - offsetX}px`;
|
||||
container.style.top = `${e.clientY - offsetY}px`;
|
||||
}
|
||||
});
|
||||
|
||||
doc.addEventListener("mouseup", () => {
|
||||
isDragging = false;
|
||||
});
|
||||
}
|
||||
271
Mizzajl/home/UIGraph.js
Normal file
271
Mizzajl/home/UIGraph.js
Normal file
@@ -0,0 +1,271 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
const doc = eval("document");
|
||||
|
||||
// File to store money data
|
||||
const moneyRecordFile = "MoneyRecord.txt";
|
||||
const recordInterval = 10000; // Record every 10 seconds
|
||||
const graphDuration = 300000; // Last 5 minutes (in milliseconds)
|
||||
let isClosed = false; // Track if the window is closed
|
||||
|
||||
// Function to format numbers as K (thousand), M (million), B (billion), etc.
|
||||
function formatLargeNumber(number) {
|
||||
if (number >= 1e12) {
|
||||
return `$${(number / 1e12).toFixed(3)}t`;
|
||||
} else if (number >= 1e9) {
|
||||
return `$${(number / 1e9).toFixed(3)}b`;
|
||||
} else if (number >= 1e6) {
|
||||
return `$${(number / 1e6).toFixed(3)}m`;
|
||||
} else if (number >= 1e3) {
|
||||
return `$${(number / 1e3).toFixed(3)}k`;
|
||||
} else {
|
||||
return `$${number.toFixed(2)}`; // Less than 1000, show as a standard number
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any existing container if it exists
|
||||
const existingContainer = doc.getElementById("money-graph-container");
|
||||
if (existingContainer) {
|
||||
existingContainer.remove(); // Remove the existing container
|
||||
ns.tprint("Previous graph closed.");
|
||||
}
|
||||
|
||||
// Create the container for the graph
|
||||
const container = doc.createElement("div");
|
||||
container.id = "money-graph-container";
|
||||
container.style = `
|
||||
position: absolute;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
width: 600px;
|
||||
height: 300px;
|
||||
background-color: rgba(0, 0, 0, 0.9); /* Black background with 90% opacity */
|
||||
color: #0c0; /* Green text */
|
||||
border: 2px solid #666;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
font-family: "Source Code Pro", monospace;
|
||||
z-index: 1000;
|
||||
cursor: move;
|
||||
box-shadow: 0px 0px 15px rgba(0, 255, 0, 0.5); /* Glow effect */
|
||||
`;
|
||||
|
||||
// Create a header bar with a close button
|
||||
const header = doc.createElement("div");
|
||||
header.style = `
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
color: #0c0; /* Green text */
|
||||
padding: 5px;
|
||||
background: rgba(17, 17, 17, 0.9); /* Dark background with 90% opacity */
|
||||
border-bottom: 1px solid #666;
|
||||
text-shadow: 0px 0px 10px #0f0;
|
||||
`;
|
||||
header.innerText = "Server Money Graph";
|
||||
|
||||
// Close button
|
||||
const closeButton = doc.createElement("button");
|
||||
closeButton.innerText = "X";
|
||||
closeButton.style = `
|
||||
background: none;
|
||||
border: 1px solid #666;
|
||||
color: #0c0; /* Green text */
|
||||
cursor: pointer;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
border-radius: 3px;
|
||||
margin-left: 10px;
|
||||
`;
|
||||
closeButton.addEventListener("click", () => {
|
||||
container.remove(); // Close the graph container
|
||||
ns.tprint("Graph window closed.");
|
||||
isClosed = true; // Mark the window as closed
|
||||
});
|
||||
|
||||
header.appendChild(closeButton);
|
||||
container.appendChild(header);
|
||||
|
||||
// Create the canvas for the graph
|
||||
const canvas = doc.createElement("canvas");
|
||||
canvas.id = "money-graph";
|
||||
canvas.width = 580; // Slightly smaller than the container for padding
|
||||
canvas.height = 200;
|
||||
canvas.style = `
|
||||
background-color: rgba(17, 17, 17, 0.9); /* Dark background with 90% opacity */
|
||||
border: 1px solid #666;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
`;
|
||||
container.appendChild(canvas);
|
||||
|
||||
// Create the money display (on the right side of the graph)
|
||||
const moneyDisplay = doc.createElement("div");
|
||||
moneyDisplay.style = `
|
||||
color: #ffd700; /* Yellow color for money display */
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 100px;
|
||||
`;
|
||||
moneyDisplay.innerText = "Money: Loading...";
|
||||
container.appendChild(moneyDisplay);
|
||||
|
||||
doc.body.appendChild(container);
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// Movable functionality for the entire container
|
||||
let isMoving = false;
|
||||
let offsetX = 0, offsetY = 0;
|
||||
|
||||
// Start moving the container on mousedown
|
||||
function startMove(e) {
|
||||
isMoving = true;
|
||||
offsetX = e.clientX - container.getBoundingClientRect().left;
|
||||
offsetY = e.clientY - container.getBoundingClientRect().top;
|
||||
container.style.cursor = "grabbing"; // Change cursor to grabbing while moving
|
||||
}
|
||||
|
||||
// Stop moving on mouseup
|
||||
function stopMove() {
|
||||
if (isMoving) {
|
||||
isMoving = false;
|
||||
container.style.cursor = "move"; // Change cursor back to move
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the movement of the window
|
||||
function moveWindow(e) {
|
||||
if (isMoving) {
|
||||
container.style.left = `${e.clientX - offsetX}px`;
|
||||
container.style.top = `${e.clientY - offsetY}px`;
|
||||
}
|
||||
}
|
||||
|
||||
// Attach event listeners for movement
|
||||
container.addEventListener("mousedown", startMove);
|
||||
doc.addEventListener("mousemove", moveWindow);
|
||||
doc.addEventListener("mouseup", stopMove);
|
||||
doc.addEventListener("mouseleave", stopMove); // Stop moving if mouse leaves the window
|
||||
|
||||
// Function to record money data to file with timestamps
|
||||
function recordMoneyData() {
|
||||
const currentMoney = ns.getServerMoneyAvailable("home");
|
||||
const timestamp = Date.now();
|
||||
const record = `${timestamp},${currentMoney}\n`;
|
||||
ns.write(moneyRecordFile, record, "a"); // Append without await
|
||||
moneyDisplay.innerText = `Money: ${formatLargeNumber(currentMoney)}`; // Update money display with formatted value
|
||||
}
|
||||
|
||||
// Function to draw grid lines
|
||||
function drawGridLines(maxMoney, minMoney) {
|
||||
const numSteps = 5; // Number of steps on the axes
|
||||
const stepY = (maxMoney - minMoney) / numSteps; // Step size for Y-axis
|
||||
const stepX = graphDuration / numSteps; // Step size for X-axis (time)
|
||||
|
||||
// Draw vertical grid lines (X-axis steps)
|
||||
for (let i = 1; i <= numSteps; i++) {
|
||||
const x = 40 + (i * (canvas.width - 60)) / numSteps;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, 10);
|
||||
ctx.lineTo(x, 180);
|
||||
ctx.strokeStyle = 'rgba(0, 255, 0, 0.2)'; // Faint green grid line
|
||||
ctx.stroke();
|
||||
// Draw X-axis labels
|
||||
const timeLabel = `${Math.round((i * stepX) / 1000)}s`;
|
||||
ctx.fillStyle = '#0c0';
|
||||
ctx.font = '12px "Source Code Pro"';
|
||||
ctx.fillText(timeLabel, x - 10, 190);
|
||||
}
|
||||
|
||||
// Draw horizontal grid lines (Y-axis steps)
|
||||
for (let i = 1; i <= numSteps; i++) {
|
||||
const y = 180 - (i * 170) / numSteps;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(40, y);
|
||||
ctx.lineTo(550, y);
|
||||
ctx.strokeStyle = 'rgba(0, 255, 0, 0.2)'; // Faint green grid line
|
||||
ctx.stroke();
|
||||
// Draw Y-axis labels with formatted money
|
||||
const moneyLabel = formatLargeNumber(minMoney + i * stepY);
|
||||
ctx.fillStyle = '#0c0';
|
||||
ctx.font = '12px "Source Code Pro"';
|
||||
ctx.fillText(moneyLabel, 5, y + 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to draw the graph with dynamic scaling from file
|
||||
async function drawGraph() {
|
||||
const fileData = await ns.read(moneyRecordFile);
|
||||
if (!fileData) return;
|
||||
|
||||
const records = fileData.trim().split("\n").map(line => {
|
||||
const [timestamp, money] = line.split(",");
|
||||
return { timestamp: parseInt(timestamp), money: parseFloat(money) };
|
||||
});
|
||||
|
||||
const now = Date.now();
|
||||
const recentRecords = records.filter(record => now - record.timestamp <= graphDuration);
|
||||
|
||||
// Clear the canvas
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
if (recentRecords.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maxMoney = Math.max(...recentRecords.map(record => record.money));
|
||||
const minMoney = Math.min(...recentRecords.map(record => record.money));
|
||||
|
||||
if (maxMoney === minMoney) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw gridlines
|
||||
drawGridLines(maxMoney, minMoney);
|
||||
|
||||
// Draw axes
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(40, 10); // Left margin
|
||||
ctx.lineTo(40, 180); // Bottom margin
|
||||
ctx.lineTo(550, 180); // Right margin
|
||||
ctx.strokeStyle = '#0c0'; // Green for axes
|
||||
ctx.stroke();
|
||||
|
||||
// Plot the data points with yellow line
|
||||
ctx.strokeStyle = '#ffd700'; // Yellow for the money line
|
||||
ctx.beginPath();
|
||||
const firstPoint = recentRecords[0];
|
||||
const startTime = firstPoint.timestamp;
|
||||
const initialY = 180 - ((firstPoint.money - minMoney) / (maxMoney - minMoney)) * 170; // Scale to fit graph height
|
||||
ctx.moveTo(40, initialY);
|
||||
|
||||
recentRecords.forEach((record) => {
|
||||
const timeDiff = record.timestamp - startTime;
|
||||
const x = 40 + (timeDiff / graphDuration) * (canvas.width - 60); // Scaled x-axis
|
||||
const y = 180 - ((record.money - minMoney) / (maxMoney - minMoney)) * 170; // Scaled y-axis
|
||||
ctx.lineTo(x, y);
|
||||
});
|
||||
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Main loop to record money data and update graph
|
||||
try {
|
||||
while (!isClosed) {
|
||||
recordMoneyData(); // Record data without await
|
||||
await drawGraph(); // Ensure graph is updated properly
|
||||
await ns.sleep(recordInterval); // Wait for 10 seconds
|
||||
}
|
||||
} catch (e) {
|
||||
ns.tprint(`Error: ${e.message}`);
|
||||
} finally {
|
||||
if (doc.body.contains(container)) {
|
||||
container.remove(); // Clean up the container when the script ends
|
||||
}
|
||||
ns.tprint("Script stopped.");
|
||||
}
|
||||
}
|
||||
13
Mizzajl/home/closeAllWindows.js
Normal file
13
Mizzajl/home/closeAllWindows.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
const doc = eval("document");
|
||||
|
||||
// Get and remove all elements with the specific container IDs
|
||||
const containers = doc.querySelectorAll('[id*="money-graph-container"]');
|
||||
|
||||
containers.forEach(container => {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
ns.tprint("Removed all windows.");
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity] = ns.args;
|
||||
//ns.tprint("sDivName = " + sDivName);
|
||||
//ns.tprint("sCity = " + sCity);
|
||||
let bSuccess = ns.corporation.buyTea(sDivName, sCity)
|
||||
//ns.tprint("bSuccess = " + bSuccess);
|
||||
let bSuccess = ns.corporation.buyTea(sDivName, sCity);
|
||||
ns.writePort(ns.pid, bSuccess);
|
||||
}
|
||||
8
Mizzajl/home/corp/BuyWarehouseAPI.js
Normal file
8
Mizzajl/home/corp/BuyWarehouseAPI.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
if (!ns.corporation.hasUnlock("Warehouse API")) {
|
||||
ns.corporation.purchaseUnlock("Warehouse API");
|
||||
ns.writePort(ns.pid, true)
|
||||
}
|
||||
ns.writePort(ns.pid, true)
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity] = ns.args;
|
||||
//ns.tprint(ns.corporation.getOffice(sDivName, sCity))
|
||||
ns.writePort(ns.pid, ns.corporation.getOffice(sDivName, sCity))
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
ns.writePort(ns.pid, ns.corporation.hasUnlock("Smart Supply"));
|
||||
}
|
||||
@@ -1,21 +1,10 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, oCurrentOffice, oWorkerDistribution] = ns.args;
|
||||
let [sDivName, sCity, oCurrentOffice] = ns.args;
|
||||
oCurrentOffice = JSON.parse(oCurrentOffice);
|
||||
let aWorkerDistribution = JSON.parse(oWorkerDistribution).nWorkerNumbers;
|
||||
let nTotalWorkers = 0;
|
||||
const len = aWorkerDistribution.length;
|
||||
for (let i = 0; i < len; i++) nTotalWorkers += aWorkerDistribution[i];
|
||||
let i = 0;
|
||||
while (oCurrentOffice.numEmployees < oCurrentOffice.size && oCurrentOffice.numEmployees < nTotalWorkers && i < 1) {
|
||||
(oCurrentOffice.employeeJobs.Operations < aWorkerDistribution[0]) ? ns.corporation.hireEmployee(sDivName, sCity, "Operations") : "";
|
||||
(oCurrentOffice.employeeJobs.Engineer < aWorkerDistribution[1]) ? ns.corporation.hireEmployee(sDivName, sCity, "Engineer") : "";
|
||||
(oCurrentOffice.employeeJobs.Business < aWorkerDistribution[2]) ? ns.corporation.hireEmployee(sDivName, sCity, "Business") : "";
|
||||
(oCurrentOffice.employeeJobs.Management < aWorkerDistribution[3]) ? ns.corporation.hireEmployee(sDivName, sCity, "Management") : "";
|
||||
(oCurrentOffice.employeeJobs["Research & Development"] < aWorkerDistribution[4]) ? ns.corporation.hireEmployee(sDivName, sCity, "Research & Development") : "";
|
||||
(oCurrentOffice.employeeJobs.Intern < aWorkerDistribution[5]) ? ns.corporation.hireEmployee(sDivName, sCity, "Intern") : "";
|
||||
await ns.sleep(1)
|
||||
i += 1;
|
||||
if (oCurrentOffice.numEmployees < oCurrentOffice.size) {
|
||||
ns.corporation.hireEmployee(sDivName, sCity, "Research & Development");
|
||||
await ns.sleep(1000)
|
||||
};
|
||||
ns.writePort(ns.pid, true);
|
||||
}
|
||||
26
Mizzajl/home/corp/SetWorkerOnPosition.js
Normal file
26
Mizzajl/home/corp/SetWorkerOnPosition.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, oCurrentOffice, oWorkerDistribution] = ns.args;
|
||||
oCurrentOffice = JSON.parse(oCurrentOffice);
|
||||
let aWorkerDistribution = JSON.parse(oWorkerDistribution).nWorkerNumbers;
|
||||
let nTotalWorkers = 0;
|
||||
const len = aWorkerDistribution.length;
|
||||
for (let i = 0; i < len; i++) nTotalWorkers += aWorkerDistribution[i];
|
||||
if (nTotalWorkers <= oCurrentOffice.numEmployees) {
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Operations", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Engineer", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Business", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Management", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Research & Development", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Intern", 0);
|
||||
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Operations", aWorkerDistribution[0]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Engineer", aWorkerDistribution[1]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Business", aWorkerDistribution[2]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Management", aWorkerDistribution[3]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Research & Development", aWorkerDistribution[4]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Intern", aWorkerDistribution[5]);
|
||||
await ns.sleep(1)
|
||||
};
|
||||
ns.writePort(ns.pid, true);
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, nSpend] = ns.args;
|
||||
//ns.tprint("sDivName = " + sDivName);
|
||||
//ns.tprint("sCity = " + sCity);
|
||||
//ns.tprint("nSpend = " + nSpend);
|
||||
let nMoraleMultiplier = ns.corporation.throwParty(sDivName, sCity, nSpend)
|
||||
//ns.tprint("nMoraleMultiplier = " + nMoraleMultiplier);
|
||||
let nMoraleMultiplier = ns.corporation.throwParty(sDivName, sCity, nSpend);
|
||||
ns.writePort(ns.pid, nMoraleMultiplier);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { distributeScript, getGrowThreads, getSetting, sortJsonArrayByKey } from "../Library";
|
||||
import { getGrowThreads, getSetting, sortJsonArrayByKey } from "../Library";
|
||||
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
@@ -88,7 +88,7 @@ export async function main(ns) {
|
||||
|
||||
let nPID1 = ns.run(sDistScript, 1, sHackScript, nHackThreads, sTarget, false, nHackDelay - 100);
|
||||
let nPID2 = ns.run(sDistScript, 1, sGrowScript, nGrowThreads, sTarget, false, nGrowDelay - 50);
|
||||
let nPID3 = ns.run(sDistScript, 1, sWeakenScript, nWeakenThreads, sTarget, false, 0);
|
||||
let nPID3 = ns.run(sDistScript, 1, sWeakenScript, nWeakenThreads + 1, sTarget, false, 0);
|
||||
if (nPID1 === 0 || nPID2 === 0 || nPID3 === 0) { bLoop = false; }
|
||||
|
||||
ns.print("Cash: " + (Math.floor(nCurrentMoney * 1000) / 1000) + " / " + nMaxMoney);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getCracks, scanServerList, findBestTarget, crackingAndRooting, copyAndRunScript, purchaseAndUpgradeServers } from "/Library.js";
|
||||
import { purchaseAndUpgradeServers } from "/Library.js";
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
await purchaseAndUpgradeServers(ns);
|
||||
|
||||
27
Mizzajl/home/testgang.js
Normal file
27
Mizzajl/home/testgang.js
Normal file
@@ -0,0 +1,27 @@
|
||||
export async function main(ns) {
|
||||
ns.tail();
|
||||
// Get the list of all task names
|
||||
let aTasks = ns.gang.getTaskNames();
|
||||
// Create an array to store task stats
|
||||
let oTasks = [];
|
||||
|
||||
// Loop through each task and get the stats
|
||||
for (let i = 0; i < aTasks.length; i++) {
|
||||
let taskName = aTasks[i];
|
||||
let taskStats = ns.gang.getTaskStats(taskName);
|
||||
|
||||
// Store task name and stats in an object and push to array
|
||||
oTasks.push({
|
||||
name: taskName,
|
||||
stats: taskStats
|
||||
});
|
||||
}
|
||||
|
||||
// Convert the object to a JSON string for easy storage
|
||||
let taskStatsString = JSON.stringify(oTasks, null, 2);
|
||||
|
||||
// Write the task stats to a file
|
||||
await ns.write("GangTaskStats.txt", taskStatsString, "w");
|
||||
|
||||
ns.tprint("Gang task stats have been written to GangTaskStats.txt.");
|
||||
}
|
||||
@@ -13,20 +13,6 @@ export async function main(ns) {
|
||||
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);
|
||||
|
||||
@@ -30,14 +30,34 @@ export async function main(ns) {
|
||||
if (!ns.readPort(nListenPID)) { ns.tprint("Error! Couldn't start Corporation!"); return };
|
||||
ns.tprint(oCorpStatus);
|
||||
while (nStep < 199) {
|
||||
await ns.corporation.nextUpdate();
|
||||
if (nStep > 40) {
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetOfficeData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
if (oOfficeData.avgEnergy < 99.5) {
|
||||
nListenPID = ns.run("/corp/BuyTea.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
if (oOfficeData.avgMorale < 99.5) {
|
||||
nListenPID = ns.run("/corp/ThrowParty.js", 1, sDivisionName, sCity, 500000);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
// InsertSmartSupplyHere
|
||||
}
|
||||
};
|
||||
nStep = oCorpStatus.nStep;
|
||||
ns.tprint(nStep);
|
||||
|
||||
switch (nStep) {
|
||||
case 0:
|
||||
nListenPID = ns.run("/corp/GetCorpData.js");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oCorpData = ns.readPort(nListenPID);
|
||||
switch (nStep) {
|
||||
case 0:
|
||||
if (!oCorpData.divisions.length > 0) {
|
||||
nListenPID = ns.run("/corp/CorpStart.js", 1, sDivisionName, "Agriculture");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
@@ -60,14 +80,14 @@ export async function main(ns) {
|
||||
oCorpStatus.nStep = 20;
|
||||
break;
|
||||
case 20:
|
||||
nListenPID = ns.run("/corp/HasUnlock.js", 1, "Smart Supply");
|
||||
/*nListenPID = ns.run("/corp/HasUnlock.js", 1, "Smart Supply");
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
bUnlockStatus = ns.readPort(nListenPID);
|
||||
if (!bUnlockStatus) {
|
||||
await ns.nextPortWrite(ns.run("/corp/BuyUnlock.js", 1, "Smart Supply"));
|
||||
await ns.sleep(1);
|
||||
}
|
||||
}*/
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetWarehouseData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
@@ -77,10 +97,7 @@ export async function main(ns) {
|
||||
await ns.nextPortWrite(ns.run("/corp/PurchaseWarehouses.js", 1, sDivisionName, sCity));
|
||||
await ns.sleep(1);
|
||||
}
|
||||
await ns.nextPortWrite(ns.run("/corp/SetSmartSupply.js", 1, sDivisionName, sCity));
|
||||
await ns.sleep(1);
|
||||
};
|
||||
|
||||
oCorpStatus.nStep = 30;
|
||||
break;
|
||||
case 30:
|
||||
@@ -101,12 +118,48 @@ export async function main(ns) {
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
nListenPID = ns.run("/corp/HireWorkers.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData), JSON.stringify({ nWorkerNumbers: [1, 1, 1, 1, 0, 0] }));
|
||||
nListenPID = ns.run("/corp/HireWorkers.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData));
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
oCorpStatus.nStep = 50;
|
||||
oCorpStatus.nStep = 45;
|
||||
break;
|
||||
case 45:
|
||||
nListenPID = ns.run("/corp/GetDivisionsData.js", 1, sDivisionName);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oDivisionData = ns.readPort(nListenPID);
|
||||
if (!oDivisionData.researchPoints > 55) { continue } else {
|
||||
for (let sCity of aCitites) {
|
||||
nListenPID = ns.run("/corp/GetOfficeData.js", 1, sDivisionName, sCity);
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
oOfficeData = ns.readPort(nListenPID);
|
||||
nListenPID = ns.run("/corp/SetWorkerOnPosition.js", 1, sDivisionName, sCity, JSON.stringify(oOfficeData), JSON.stringify({ nWorkerNumbers: [1, 1, 1, 1, 0, 0] }));
|
||||
await ns.nextPortWrite(nListenPID);
|
||||
await ns.sleep(1);
|
||||
}
|
||||
oCorpStatus.nStep = 70;
|
||||
}
|
||||
break;
|
||||
case 70:
|
||||
break;
|
||||
case 80:
|
||||
break;
|
||||
case 90:
|
||||
break;
|
||||
case 100:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ns.write("CorpStatus.txt", JSON.stringify(oCorpStatus), "w")
|
||||
await ns.sleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
case 50:
|
||||
let aCurrentGoods = [
|
||||
{ "sMaterialName": "Food", "yAmount": "MAX", "yPrice": "MP-5" },
|
||||
@@ -150,19 +203,5 @@ export async function main(ns) {
|
||||
}
|
||||
oCorpStatus.nStep = 70;
|
||||
break;
|
||||
case 70:
|
||||
oCorpStatus.nStep = 200;
|
||||
break;
|
||||
case 80:
|
||||
break;
|
||||
case 90:
|
||||
break;
|
||||
case 100:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ns.write("CorpStatus.txt", JSON.stringify(oCorpStatus), "w")
|
||||
await ns.sleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -1 +1 @@
|
||||
{"nStep":200}
|
||||
{"nStep":70}
|
||||
@@ -190,6 +190,9 @@ export async function purchaseAndUpgradeServers(ns) {
|
||||
minHackLvl: 1,
|
||||
rootAccess: true,
|
||||
openPorts: 0,
|
||||
serverOrgs: "",
|
||||
serverCores: 1,
|
||||
serverFiles: []
|
||||
});
|
||||
ns.write("serverList.txt", JSON.stringify(serverList), "w");
|
||||
continue
|
||||
@@ -211,7 +214,7 @@ export async function purchaseAndUpgradeServers(ns) {
|
||||
let newServerList = serverList.map((entry) => { if (entry.serverName === currentServer) { entry.maxRam = targetRam } return entry });
|
||||
ns.write("serverList.txt", JSON.stringify(newServerList), "w");
|
||||
ns.tprint(cCyan + "Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB" + cReset);
|
||||
ns.toast("Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB", "info", 10000);
|
||||
//ns.toast("Server: " + currentServer + " upgraded to: " + targetRam.toLocaleString() + " GB", "info", 10000);
|
||||
}
|
||||
} else {
|
||||
await ns.sleep(5000);
|
||||
|
||||
6
Ramses/home/corp/BuyTea.js
Normal file
6
Ramses/home/corp/BuyTea.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity] = ns.args;
|
||||
let bSuccess = ns.corporation.buyTea(sDivName, sCity);
|
||||
ns.writePort(ns.pid, bSuccess);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity] = ns.args;
|
||||
//ns.tprint(ns.corporation.getOffice(sDivName, sCity))
|
||||
ns.writePort(ns.pid, ns.corporation.getOffice(sDivName, sCity))
|
||||
}
|
||||
@@ -1,21 +1,10 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, oCurrentOffice, oWorkerDistribution] = ns.args;
|
||||
let [sDivName, sCity, oCurrentOffice] = ns.args;
|
||||
oCurrentOffice = JSON.parse(oCurrentOffice);
|
||||
let aWorkerDistribution = JSON.parse(oWorkerDistribution).nWorkerNumbers;
|
||||
let nTotalWorkers = 0;
|
||||
const len = aWorkerDistribution.length;
|
||||
for (let i = 0; i < len; i++) nTotalWorkers += aWorkerDistribution[i];
|
||||
let i = 0;
|
||||
while (oCurrentOffice.numEmployees < oCurrentOffice.size && oCurrentOffice.numEmployees < nTotalWorkers && i < 1) {
|
||||
(oCurrentOffice.employeeJobs.Operations < aWorkerDistribution[0]) ? ns.corporation.hireEmployee(sDivName, sCity, "Operations") : "";
|
||||
(oCurrentOffice.employeeJobs.Engineer < aWorkerDistribution[1]) ? ns.corporation.hireEmployee(sDivName, sCity, "Engineer") : "";
|
||||
(oCurrentOffice.employeeJobs.Business < aWorkerDistribution[2]) ? ns.corporation.hireEmployee(sDivName, sCity, "Business") : "";
|
||||
(oCurrentOffice.employeeJobs.Management < aWorkerDistribution[3]) ? ns.corporation.hireEmployee(sDivName, sCity, "Management") : "";
|
||||
(oCurrentOffice.employeeJobs["Research & Development"] < aWorkerDistribution[4]) ? ns.corporation.hireEmployee(sDivName, sCity, "Research & Development") : "";
|
||||
(oCurrentOffice.employeeJobs.Intern < aWorkerDistribution[5]) ? ns.corporation.hireEmployee(sDivName, sCity, "Intern") : "";
|
||||
if (oCurrentOffice.numEmployees < oCurrentOffice.size) {
|
||||
ns.corporation.hireEmployee(sDivName, sCity, "Research & Development");
|
||||
await ns.sleep(1)
|
||||
i += 1;
|
||||
};
|
||||
ns.writePort(ns.pid, true);
|
||||
}
|
||||
26
Ramses/home/corp/SetWorkerOnPosition.js
Normal file
26
Ramses/home/corp/SetWorkerOnPosition.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, oCurrentOffice, oWorkerDistribution] = ns.args;
|
||||
oCurrentOffice = JSON.parse(oCurrentOffice);
|
||||
let aWorkerDistribution = JSON.parse(oWorkerDistribution).nWorkerNumbers;
|
||||
let nTotalWorkers = 0;
|
||||
const len = aWorkerDistribution.length;
|
||||
for (let i = 0; i < len; i++) nTotalWorkers += aWorkerDistribution[i];
|
||||
if (nTotalWorkers <= oCurrentOffice.numEmployees) {
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Operations", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Engineer", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Business", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Management", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Research & Development", 0);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Intern", 0);
|
||||
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Operations", aWorkerDistribution[0]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Engineer", aWorkerDistribution[1]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Business", aWorkerDistribution[2]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Management", aWorkerDistribution[3]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Research & Development", aWorkerDistribution[4]);
|
||||
ns.corporation.setAutoJobAssignment(sDivName, sCity, "Intern", aWorkerDistribution[5]);
|
||||
await ns.sleep(1)
|
||||
};
|
||||
ns.writePort(ns.pid, true);
|
||||
}
|
||||
6
Ramses/home/corp/ThrowParty.js
Normal file
6
Ramses/home/corp/ThrowParty.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
let [sDivName, sCity, nSpend] = ns.args;
|
||||
let nMoraleMultiplier = ns.corporation.throwParty(sDivName, sCity, nSpend);
|
||||
ns.writePort(ns.pid, nMoraleMultiplier);
|
||||
}
|
||||
@@ -34,11 +34,13 @@ export async function main(ns) {
|
||||
let nMaxThreads = 0;
|
||||
sortedList.forEach((entry) => {
|
||||
if (entry.rootAccess && entry.maxRam >= 1) {
|
||||
ns.scp(aFiles, "home", entry.serverName);
|
||||
if (entry.serverName !== "home") {
|
||||
ns.scp(aFiles, entry.serverName, "home");
|
||||
}
|
||||
nMaxThreads += entry.maxRam / 1.75;
|
||||
}
|
||||
})
|
||||
let nMaxThreadsINT = Math.floor(nMaxThreads);
|
||||
let nMaxThreadsINT = Math.floor(nMaxThreads - 64);
|
||||
ns.print("nMaxThreadsINT = " + nMaxThreadsINT);
|
||||
|
||||
|
||||
|
||||
@@ -60,14 +60,18 @@ export async function main(ns) {
|
||||
ns.print("sHost = " + sHost)
|
||||
let nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nTotalSize) {
|
||||
ns.scp(sScript, sHost);
|
||||
if (entry.serverName !== "home") {
|
||||
ns.scp(sScript, sHost, "home");
|
||||
}
|
||||
ns.exec(sScript, sHost, nThreads, sTarget, bRepeat, nMsecDelay);
|
||||
nThreads = 0;
|
||||
nFreeRAM = ns.getServerMaxRam(entry.serverName) - ns.getServerUsedRam(entry.serverName);
|
||||
}
|
||||
else if (nThreads >= 1 && entry.rootAccess && nFreeRAM >= nScriptSize) {
|
||||
let nThreadsDist = Math.floor(nFreeRAM / nScriptSize);
|
||||
ns.scp(sScript, sHost);
|
||||
if (entry.serverName !== "home") {
|
||||
ns.scp(sScript, sHost, "home");
|
||||
}
|
||||
ns.print("room for : " + nThreadsDist + " scripts");
|
||||
ns.exec(sScript, sHost, nThreadsDist, sTarget, bRepeat, nMsecDelay);
|
||||
nThreads -= nThreadsDist;
|
||||
|
||||
Reference in New Issue
Block a user