Compare commits

..

11 Commits

37 changed files with 1828 additions and 232 deletions

View 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;
}

View 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.");
}
}

View File

@@ -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);
nListenPID = ns.run("/corp/GetCorpData.js");
await ns.nextPortWrite(nListenPID);
await ns.sleep(1);
oCorpData = ns.readPort(nListenPID);
switch (nStep) {
case 0:
nListenPID = ns.run("/corp/GetCorpData.js");
await ns.nextPortWrite(nListenPID);
await ns.sleep(1);
oCorpData = ns.readPort(nListenPID);
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,13 +125,49 @@ 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 50:
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" },
{ "sMaterialName": "Plants", "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)
}
}
*/

View 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
View 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
View 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.");
}

View 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");
}

View 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);
}

View File

@@ -260,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");
@@ -338,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;
@@ -360,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];
}

View 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);
}
}
}

View 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.");
}
}

View File

@@ -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
View 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);
}
}

View 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!");
}

View File

@@ -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";
@@ -14,23 +14,20 @@ export async function main(ns) {
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(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 DistributeRunAndWait(ns, sUpdateTarget);
/*
let oServerlist = JSON.parse(ns.read(sServerListFile));
let nHomeMaxRAM = oServerlist.find((entry) => entry.serverName === "home").maxRam;
ns.print("nHomeMaxRAM = " + nHomeMaxRAM);
if (!ns.isRunning(sGangScript)) { ns.run(sGangScript); }
if (!ns.isRunning(sPServScript)) { ns.run(sPServScript); }
await RunAndWait(ns, sBackdoorScript);
await RunAndWait(ns, sUpdateTarget);
//await RunAndWait(ns, sBatchController);
if (nHomeMaxRAM >= 256) { if (!ns.isRunning(sMonitorScript)) { ns.run(sMonitorScript); } }
*/
}

View 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
View 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.");
}
}

View 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.");
}

View File

@@ -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);
}

View 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)
}

View File

@@ -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))
}

View File

@@ -1,5 +1,5 @@
/** @param {NS} ns */
export async function main(ns) {
ns.writePort(ns.pid,ns.corporation.hasCorporation());
ns.writePort(ns.pid, ns.corporation.hasCorporation());
}

View File

@@ -1,4 +0,0 @@
/** @param {NS} ns */
export async function main(ns) {
ns.writePort(ns.pid, ns.corporation.hasUnlock("Smart Supply"));
}

View File

@@ -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);
}

View 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);
}

View File

@@ -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);
}

View File

@@ -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);

27
Mizzajl/home/testgang.js Normal file
View 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.");
}

View File

@@ -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);

View File

@@ -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);
nListenPID = ns.run("/corp/GetCorpData.js");
await ns.nextPortWrite(nListenPID);
await ns.sleep(1);
oCorpData = ns.readPort(nListenPID);
switch (nStep) {
case 0:
nListenPID = ns.run("/corp/GetCorpData.js");
await ns.nextPortWrite(nListenPID);
await ns.sleep(1);
oCorpData = ns.readPort(nListenPID);
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,13 +118,49 @@ 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 50:
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" },
{ "sMaterialName": "Plants", "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)
}
}
*/

View File

@@ -1 +1 @@
{"nStep":200}
{"nStep":70}

View File

@@ -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
@@ -208,10 +211,10 @@ export async function purchaseAndUpgradeServers(ns) {
if (ns.upgradePurchasedServer(currentServer, targetRam)) {
ns.print(currentServer + " upgraded to " + targetRam + " GB RAM");
serverList = JSON.parse(ns.read("serverList.txt"));
let newServerList = serverList.map((entry) => { if (entry.serverName === currentServer) { entry.maxRam = targetRam } { entry.serverOrgs = "" } { entry.serverCores = 1 } { entry.serverFiles = [] } return entry });
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);

View File

@@ -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);
}

View File

@@ -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))
}

View File

@@ -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);
}

View 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);
}

View File

@@ -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);
}