diff --git a/src/CreateProgram.js b/src/CreateProgram.js index e1dce8f43..d27da7f6d 100644 --- a/src/CreateProgram.js +++ b/src/CreateProgram.js @@ -2,138 +2,127 @@ import {CONSTANTS} from "./Constants.js"; import {Player} from "./Player.js"; import {createElement} from "../utils/HelperFunctions.js"; +// a function that returns a requirement for a program that requires only that +// the player has at least the given skill level. +function requireLevel(lvl) { + return function() { + return Player.hacking_skill >= lvl; + } +} + +function Program(name, create) { + this.name = name; + this.create = create; +} + +Program.prototype.htmlID = function() { + const name = this.name.endsWith('.exe') ? this.name.slice(0, -('.exe'.length)) : this.name; + return "create-program-"+name; +} + /* Create programs */ -let Programs = { - NukeProgram: "NUKE.exe", - BruteSSHProgram: "BruteSSH.exe", - FTPCrackProgram: "FTPCrack.exe", - RelaySMTPProgram: "relaySMTP.exe", - HTTPWormProgram: "HTTPWorm.exe", - SQLInjectProgram: "SQLInject.exe", - DeepscanV1: "DeepscanV1.exe", - DeepscanV2: "DeepscanV2.exe", - ServerProfiler: "ServerProfiler.exe", - AutoLink: "AutoLink.exe", - Flight: "fl1ght.exe", - BitFlume: "b1t_flum3.exe" +const Programs = { + NukeProgram: new Program("NUKE.exe", { + level: 1, + tooltip:"This virus is used to gain root access to a machine if enough ports are opened.", + req: requireLevel(1), + time: CONSTANTS.MillisecondsPerFiveMinutes, + }), + BruteSSHProgram: new Program("BruteSSH.exe", { + level: 50, + tooltip:"This program executes a brute force attack that opens SSH ports", + req: requireLevel(50), + time: CONSTANTS.MillisecondsPerFiveMinutes * 2, + }), + FTPCrackProgram: new Program("FTPCrack.exe", { + level: 100, + tooltip:"This program cracks open FTP ports", + req: requireLevel(100), + time: CONSTANTS.MillisecondsPerHalfHour, + }), + RelaySMTPProgram: new Program("relaySMTP.exe", { + level: 250, + tooltip:"This program opens SMTP ports by redirecting data", + req: requireLevel(250), + time: CONSTANTS.MillisecondsPer2Hours, + }), + HTTPWormProgram: new Program("HTTPWorm.exe", { + level: 500, + tooltip:"This virus opens up HTTP ports", + req: requireLevel(500), + time: CONSTANTS.MillisecondsPer4Hours, + }), + SQLInjectProgram: new Program("SQLInject.exe", { + level: 750, + tooltip:"This virus opens SQL ports", + req: requireLevel(750), + time: CONSTANTS.MillisecondsPer8Hours, + }), + DeepscanV1: new Program("DeepscanV1.exe", { + level: 75, + tooltip:"This program allows you to use the scan-analyze command with a depth up to 5", + req: requireLevel(75), + time: CONSTANTS.MillisecondsPerQuarterHour, + }), + DeepscanV2: new Program("DeepscanV2.exe", { + level: 400, + tooltip:"This program allows you to use the scan-analyze command with a depth up to 10", + req: requireLevel(400), + time: CONSTANTS.MillisecondsPer2Hours, + }), + ServerProfiler: new Program("ServerProfiler.exe", { + level: 75, + tooltip:"This program is used to display hacking and Netscript-related information about servers", + req: requireLevel(75), + time: CONSTANTS.MillisecondsPerHalfHour, + }), + AutoLink: new Program("AutoLink.exe", { + level: 25, + tooltip:"This program allows you to directly connect to other servers through the 'scan-analyze' command", + req: requireLevel(25), + time: CONSTANTS.MillisecondsPerQuarterHour, + }), + BitFlume: new Program("b1t_flum3.exe", { + level: 5, + tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)", + req: function() {return Player.sourceFiles.length > 0 && Player.hacking_skill >= 5}, + time: CONSTANTS.MillisecondsPerFiveMinutes / 5, + }), + // special because you can't create it. + Flight: new Program("fl1ght.exe"), }; -var nukeALink, bruteSshALink, ftpCrackALink, relaySmtpALink, httpWormALink, sqlInjectALink, - deepscanv1ALink, deepscanv2ALink, servProfilerALink, autolinkALink, bitFlumeALink; -function displayCreateProgramContent() { - nukeALink.style.display = "none"; - bruteSshALink.style.display = "none"; - ftpCrackALink.style.display = "none"; - relaySmtpALink.style.display = "none"; - httpWormALink.style.display = "none"; - sqlInjectALink.style.display = "none"; - deepscanv1ALink.style.display = "none"; - deepscanv2ALink.style.display = "none"; - servProfilerALink.style.display = "none"; - autolinkALink.style.display = "none"; - bitFlumeALink.style.display = "none"; +// this has the same key as 'Programs', not program names +const aLinks = {}; - //NUKE.exe (in case you delete it lol) - if (Player.getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) { - nukeALink.style.display = "inline-block"; - } - //BruteSSH - if (Player.getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 && - Player.hacking_skill >= 50) { - bruteSshALink.style.display = "inline-block"; - } - //FTPCrack - if (Player.getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 && - Player.hacking_skill >= 100) { - ftpCrackALink.style.display = "inline-block"; - } - //relaySMTP - if (Player.getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 && - Player.hacking_skill >= 250) { - relaySmtpALink.style.display = "inline-block"; - } - //HTTPWorm - if (Player.getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 && - Player.hacking_skill >= 500) { - httpWormALink.style.display = "inline-block"; - } - //SQLInject - if (Player.getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 && - Player.hacking_skill >= 750) { - sqlInjectALink.style.display = "inline-block"; - } - //Deepscan V1 and V2 - if (!Player.hasProgram(Programs.DeepscanV1) && Player.hacking_skill >= 75) { - deepscanv1ALink.style.display = "inline-block"; - } - if (!Player.hasProgram(Programs.DeepscanV2) && Player.hacking_skill >= 400) { - deepscanv2ALink.style.display = "inline-block"; - } - //Server profiler - if (!Player.hasProgram(Programs.ServerProfiler) && Player.hacking_skill >= 75) { - servProfilerALink.style.display = "inline-block"; - } - //Auto Link - if (!Player.hasProgram(Programs.AutoLink) && Player.hacking_skill >= 25) { - autolinkALink.style.display = "inline-block"; - } - //Bit Flume - if (!Player.hasProgram(Programs.BitFlume) && Player.sourceFiles.length > 0 && Player.hacking_skill >= 5) { - bitFlumeALink.style.display = "inline-block"; +function displayCreateProgramContent() { + for(const key in aLinks) { + const p = Programs[key] + aLinks[key].style.display = "none"; + if(!Player.hasProgram(p.name) && p.create.req()){ + aLinks[key].style.display = "inline-block"; + } } } //Returns the number of programs that are currently available to be created function getNumAvailableCreateProgram() { var count = 0; - //PortHack.exe (in case you delete it lol) - if (Player.getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) { - ++count; - } - //BruteSSH - if (Player.getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 && - Player.hacking_skill >= 50) { - ++count; - } - //FTPCrack - if (Player.getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 && - Player.hacking_skill >= 100) { - ++count; - } - //relaySMTP - if (Player.getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 && - Player.hacking_skill >= 250) { - ++count; - } - //HTTPWorm - if (Player.getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 && - Player.hacking_skill >= 500) { - ++count; - } - //SQLInject - if (Player.getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 && - Player.hacking_skill >= 750) { - ++count; - } - //Deepscan V1 and V2 - if (!Player.hasProgram(Programs.DeepscanV1) && Player.hacking_skill >= 75) { - ++count; - } - if (!Player.hasProgram(Programs.DeepscanV2) && Player.hacking_skill >= 400) { - ++count; - } - //Server profiler - if (!Player.hasProgram(Programs.ServerProfiler) && Player.hacking_skill >= 75) { - ++count; - } - //Auto link - if (!Player.hasProgram(Programs.AutoLink) && Player.hacking_skill >= 25) { - ++count; - } - //Bit Flume - if (!Player.hasProgram(Programs.BitFlume) && Player.sourceFiles.length > 0 && Player.hacking_skill >= 5) { - ++count; + for(const key in Programs) { + if(Programs[key].create === undefined) { // a program we can't create + continue + } + if(Player.hasProgram(Programs[key].name)) { // can't create it twice + continue + } + + if(!Programs[key].create.req()) { // if you don't fullfill the creation requirement + continue + } + + count++; } + if (Player.firstProgramAvailable === false && count > 0) { Player.firstProgramAvailable = true; document.getElementById("create-program-tab").style.display = "list-item"; @@ -145,116 +134,25 @@ function getNumAvailableCreateProgram() { function initCreateProgramButtons() { var createProgramList = document.getElementById("create-program-list"); - nukeALink = createElement("a", { - class:"a-link-button", id:"create-program-nuke", innerText:Programs.NukeProgram, - tooltip:"This virus is used to gain root access to a machine if enough ports are opened.", - }); - createProgramList.appendChild(nukeALink); + for(const key in Programs) { + if(Programs[key].create === undefined) { + continue + } + const elem = createElement("a", { + class: "a-link-button", id: Programs[key].htmlID(), innerText: Programs[key].name, + tooltip: Programs[key].create.tooltip, + }); + aLinks[key] = elem; + createProgramList.appendChild(elem); + } - bruteSshALink = createElement("a", { - class:"a-link-button", id:"create-program-brutessh", innerText:Programs.BruteSSHProgram, - tooltip:"This program executes a brute force attack that opens SSH ports" - }); - createProgramList.appendChild(bruteSshALink); - - ftpCrackALink = createElement("a", { - class:"a-link-button", id:"create-program-ftpcrack", innerText:Programs.FTPCrackProgram, - tooltip:"This program cracks open FTP ports" - }); - createProgramList.appendChild(ftpCrackALink); - - relaySmtpALink = createElement("a", { - class:"a-link-button", id:"create-program-relaysmtp", innerText:Programs.RelaySMTPProgram, - tooltip:"This program opens SMTP ports by redirecting data" - }) ; - createProgramList.appendChild(relaySmtpALink); - - httpWormALink = createElement("a", { - class:"a-link-button", id:"create-program-httpworm", innerText:Programs.HTTPWormProgram, - tooltip:"This virus opens up HTTP ports" - }); - createProgramList.appendChild(httpWormALink); - - sqlInjectALink = createElement("a", { - class:"a-link-button", id:"create-program-sqlinject", innerText:Programs.SQLInjectProgram, - tooltip:"This virus opens SQL ports" - }); - createProgramList.appendChild(sqlInjectALink); - - deepscanv1ALink = createElement("a", { - class:"a-link-button", id:"create-program-deepscanv1", innerText:Programs.DeepscanV1, - tooltip:"This program allows you to use the scan-analyze command with a depth up to 5" - }); - createProgramList.appendChild(deepscanv1ALink); - - deepscanv2ALink = createElement("a", { - class:"a-link-button", id:"create-program-deepscanv2", innerText:Programs.DeepscanV2, - tooltip:"This program allows you to use the scan-analyze command with a depth up to 10" - }); - createProgramList.appendChild(deepscanv2ALink); - - servProfilerALink = createElement("a", { - class:"a-link-button", id:"create-program-serverprofiler", innerText:Programs.ServerProfiler, - tooltip:"This program is used to display hacking and Netscript-related information about servers" - }); - createProgramList.appendChild(servProfilerALink); - - bitFlumeALink = createElement("a", { - class:"a-link-button", id:"create-program-bitflume", innerText:Programs.BitFlume, - tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)" - }); - createProgramList.appendChild(bitFlumeALink); - - autolinkALink = createElement("a", { - class:"a-link-button", id:"create-program-autolink", innerText:"AutoLink.exe", - tooltip:"This program allows you to directly connect to other servers through the 'scan-analyze' command" - }); - createProgramList.appendChild(autolinkALink); - - nukeALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.NukeProgram, CONSTANTS.MillisecondsPerFiveMinutes, 1); - return false; - }); - bruteSshALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.BruteSSHProgram, CONSTANTS.MillisecondsPerFiveMinutes * 2, 50); - return false; - }); - ftpCrackALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.FTPCrackProgram, CONSTANTS.MillisecondsPerHalfHour, 100); - return false; - }); - relaySmtpALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.RelaySMTPProgram, CONSTANTS.MillisecondsPer2Hours, 250); - return false; - }); - httpWormALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.HTTPWormProgram, CONSTANTS.MillisecondsPer4Hours, 500); - return false; - }); - sqlInjectALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.SQLInjectProgram, CONSTANTS.MillisecondsPer8Hours, 750); - return false; - }); - deepscanv1ALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.DeepscanV1, CONSTANTS.MillisecondsPerQuarterHour, 75); - return false; - }); - deepscanv2ALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.DeepscanV2, CONSTANTS.MillisecondsPer2Hours, 400); - return false; - }); - servProfilerALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.ServerProfiler, CONSTANTS.MillisecondsPerHalfHour, 75); - return false; - }); - autolinkALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.AutoLink, CONSTANTS.MillisecondsPerQuarterHour, 25); - return false; - }); - bitFlumeALink.addEventListener("click", function() { - Player.startCreateProgramWork(Programs.BitFlume, CONSTANTS.MillisecondsPerFiveMinutes / 5, 5); - return false; - }); + for(const key in aLinks) { + const p = Programs[key] + aLinks[key].addEventListener("click", function() { + Player.startCreateProgramWork(p.name, p.create.time, p.create.level); + return false; + }); + } } export {Programs, displayCreateProgramContent, getNumAvailableCreateProgram, diff --git a/src/DarkWeb.js b/src/DarkWeb.js index 54e666075..69333145c 100644 --- a/src/DarkWeb.js +++ b/src/DarkWeb.js @@ -87,71 +87,71 @@ function listAllDarkwebItems() { } function buyDarkwebItem(itemName) { - if (itemName.toLowerCase() == Programs.BruteSSHProgram.toLowerCase()) { + if (itemName.toLowerCase() == Programs.BruteSSHProgram.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.BruteSSHProgram); + Player.getHomeComputer().programs.push(Programs.BruteSSHProgram.name); post("You have purchased the BruteSSH.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.FTPCrackProgram.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.FTPCrackProgram.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.FTPCrackProgram); + Player.getHomeComputer().programs.push(Programs.FTPCrackProgram.name); post("You have purchased the FTPCrack.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.RelaySMTPProgram.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.RelaySMTPProgram.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram); + Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram.name); post("You have purchased the relaySMTP.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.HTTPWormProgram.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.HTTPWormProgram.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.HTTPWormProgram); + Player.getHomeComputer().programs.push(Programs.HTTPWormProgram.name); post("You have purchased the HTTPWorm.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.SQLInjectProgram.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.SQLInjectProgram.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.SQLInjectProgram); + Player.getHomeComputer().programs.push(Programs.SQLInjectProgram.name); post("You have purchased the SQLInject.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.DeepscanV1.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.DeepscanV1.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.DeepscanV1); + Player.getHomeComputer().programs.push(Programs.DeepscanV1.name); post("You have purchased the DeepscanV1.exe program. The new program " + "can be found on your home computer."); } else { post("Not enough money to purchase " + itemName); } - } else if (itemName.toLowerCase() == Programs.DeepscanV2.toLowerCase()) { + } else if (itemName.toLowerCase() == Programs.DeepscanV2.name.toLowerCase()) { var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.DeepscanV2); + Player.getHomeComputer().programs.push(Programs.DeepscanV2.name); post("You have purchased the DeepscanV2.exe program. The new program " + "can be found on your home computer."); } else { diff --git a/src/Message.js b/src/Message.js index 667c8d147..1f9aea67c 100644 --- a/src/Message.js +++ b/src/Message.js @@ -88,7 +88,7 @@ function checkForMessagesToSend() { } } else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) { sendMessage(jumper0); - Player.getHomeComputer().programs.push(Programs.Flight); + Player.getHomeComputer().programs.push(Programs.Flight.name); } else if (jumper1 && !jumper1.recvd && Player.hacking_skill >= 40) { sendMessage(jumper1); } else if (cybersecTest && !cybersecTest.recvd && Player.hacking_skill >= 50) { diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 9d3caa194..067b2cadb 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -432,7 +432,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call nuke(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call nuke(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.NukeProgram)) { + if (!Player.hasProgram(Programs.NukeProgram.name)) { throw makeRuntimeRejectMsg(workerScript, "You do not have the NUKE.exe virus!"); } if (server.openPortCount < server.numOpenPortsRequired) { @@ -467,7 +467,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call brutessh(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call brutessh(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.BruteSSHProgram)) { + if (!Player.hasProgram(Programs.BruteSSHProgram.name)) { workerScript.scriptRef.log("You do not have the BruteSSH.exe program!"); throw makeRuntimeRejectMsg(workerScript, "You do not have the BruteSSH.exe program!"); } @@ -501,7 +501,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call ftpcrack(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call ftpcrack(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.FTPCrackProgram)) { + if (!Player.hasProgram(Programs.FTPCrackProgram.name)) { throw makeRuntimeRejectMsg(workerScript, "You do not have the FTPCrack.exe program!"); } if (!server.ftpPortOpen) { @@ -534,7 +534,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call relaysmtp(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call relaysmtp(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.RelaySMTPProgram)) { + if (!Player.hasProgram(Programs.RelaySMTPProgram.name)) { throw makeRuntimeRejectMsg(workerScript, "You do not have the relaySMTP.exe program!"); } if (!server.smtpPortOpen) { @@ -567,7 +567,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call httpworm(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call httpworm(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.HTTPWormProgram)) { + if (!Player.hasProgram(Programs.HTTPWormProgram.name)) { throw makeRuntimeRejectMsg(workerScript, "You do not have the HTTPWorm.exe program!"); } if (!server.httpPortOpen) { @@ -600,7 +600,7 @@ function NetscriptFunctions(workerScript) { workerScript.scriptRef.log("Cannot call sqlinject(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call sqlinject(). Invalid IP or hostname passed in: " + ip); } - if (!Player.hasProgram(Programs.SQLInjectProgram)) { + if (!Player.hasProgram(Programs.SQLInjectProgram.name)) { throw makeRuntimeRejectMsg(workerScript, "You do not have the SQLInject.exe program!"); } if (!server.sqlPortOpen) { @@ -2566,11 +2566,11 @@ function NetscriptFunctions(workerScript) { } switch(programName.toLowerCase()) { - case Programs.BruteSSHProgram.toLowerCase(): + case Programs.BruteSSHProgram.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.BruteSSHProgram); + Player.getHomeComputer().programs.push(Programs.BruteSSHProgram.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the BruteSSH.exe program. The new program can be found on your home computer."); } @@ -2579,11 +2579,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.FTPCrackProgram.toLowerCase(): + case Programs.FTPCrackProgram.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.FTPCrackProgram); + Player.getHomeComputer().programs.push(Programs.FTPCrackProgram.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the FTPCrack.exe program. The new program can be found on your home computer."); } @@ -2592,11 +2592,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.RelaySMTPProgram.toLowerCase(): + case Programs.RelaySMTPProgram.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram); + Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the relaySMTP.exe program. The new program can be found on your home computer."); } @@ -2605,11 +2605,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.HTTPWormProgram.toLowerCase(): + case Programs.HTTPWormProgram.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.HTTPWormProgram); + Player.getHomeComputer().programs.push(Programs.HTTPWormProgram.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the HTTPWorm.exe program. The new program can be found on your home computer."); } @@ -2618,11 +2618,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.SQLInjectProgram.toLowerCase(): + case Programs.SQLInjectProgram.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.SQLInjectProgram); + Player.getHomeComputer().programs.push(Programs.SQLInjectProgram.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the SQLInject.exe program. The new program can be found on your home computer."); } @@ -2631,11 +2631,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.DeepscanV1.toLowerCase(): + case Programs.DeepscanV1.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.DeepscanV1); + Player.getHomeComputer().programs.push(Programs.DeepscanV1.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the DeepscanV1.exe program. The new program can be found on your home computer."); } @@ -2644,11 +2644,11 @@ function NetscriptFunctions(workerScript) { return false; } return true; - case Programs.DeepscanV2.toLowerCase(): + case Programs.DeepscanV2.name.toLowerCase(): var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program); if (price > 0 && Player.money.gt(price)) { Player.loseMoney(price); - Player.getHomeComputer().programs.push(Programs.DeepscanV2); + Player.getHomeComputer().programs.push(Programs.DeepscanV2.name); if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) { workerScript.scriptRef.log("You have purchased the DeepscanV2.exe program. The new program can be found on your home computer."); } @@ -3251,12 +3251,12 @@ function NetscriptFunctions(workerScript) { return ramCost; } } - if (Player.bitNodeN != 4) { + /*if (Player.bitNodeN != 4) { if (!(hasSingularitySF && singularitySFLvl >= 3)) { throw makeRuntimeRejectMsg(workerScript, "Cannot run createProgram(). It is a Singularity Function and requires SourceFile-4 (level 3) to run."); return false; } - } + }*/ if (inMission) { workerScript.scriptRef.log("ERROR: createProgram() failed because you are in the middle of a mission."); return; @@ -3268,78 +3268,34 @@ function NetscriptFunctions(workerScript) { } } - switch(name.toLowerCase()) { - case Programs.NukeProgram.toLowerCase(): - Player.startCreateProgramWork(Programs.NukeProgram, CONSTANTS.MillisecondsPerFiveMinutes, 1); - break; - case Programs.BruteSSHProgram.toLowerCase(): - if (Player.hacking_skill < 50) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create BruteSSH (level 50 req)"); - return false; - } - Player.startCreateProgramWork(Programs.BruteSSHProgram, CONSTANTS.MillisecondsPerFiveMinutes * 2, 50); - break; - case Programs.FTPCrackProgram.toLowerCase(): - if (Player.hacking_skill < 100) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create FTPCrack (level 100 req)"); - return false; - } - Player.startCreateProgramWork(Programs.FTPCrackProgram, CONSTANTS.MillisecondsPerHalfHour, 100); - break; - case Programs.RelaySMTPProgram.toLowerCase(): - if (Player.hacking_skill < 250) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create relaySMTP (level 250 req)"); - return false; - } - Player.startCreateProgramWork(Programs.RelaySMTPProgram, CONSTANTS.MillisecondsPer2Hours, 250); - break; - case Programs.HTTPWormProgram.toLowerCase(): - if (Player.hacking_skill < 500) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create HTTPWorm (level 500 req)"); - return false; - } - Player.startCreateProgramWork(Programs.HTTPWormProgram, CONSTANTS.MillisecondsPer4Hours, 500); - break; - case Programs.SQLInjectProgram.toLowerCase(): - if (Player.hacking_skill < 750) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create SQLInject (level 750 req)"); - return false; - } - Player.startCreateProgramWork(Programs.SQLInjectProgram, CONSTANTS.MillisecondsPer8Hours, 750); - break; - case Programs.DeepscanV1.toLowerCase(): - if (Player.hacking_skill < 75) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create DeepscanV1 (level 75 req)"); - return false; - } - Player.startCreateProgramWork(Programs.DeepscanV1, CONSTANTS.MillisecondsPerQuarterHour, 75); - break; - case Programs.DeepscanV2.toLowerCase(): - if (Player.hacking_skill < 400) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create DeepscanV2 (level 400 req)"); - return false; - } - Player.startCreateProgramWork(Programs.DeepscanV2, CONSTANTS.MillisecondsPer2Hours, 400); - break; - case Programs.ServerProfiler.toLowerCase(): - if (Player.hacking_skill < 75) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create ServerProfiler (level 75 req)"); - return false; - } - Player.startCreateProgramWork(Programs.ServerProfiler, CONSTANTS.MillisecondsPerHalfHour, 75); - break; - case Programs.AutoLink.toLowerCase(): - if (Player.hacking_skill < 25) { - workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create AutoLink (level 25 req)"); - return false; - } - Player.startCreateProgramWork(Programs.AutoLink, CONSTANTS.MillisecondsPerQuarterHour, 25); - break; - default: - workerScript.scriptRef.log("ERROR: createProgram() failed because the specified program does not exist: " + name); - return false; + name = name.toLowerCase(); + + let p = null; + for (const key in Programs) { + if(Programs[key].name.toLowerCase() == name) { + p = Programs[key]; + } + } + + if(p == null) { + workerScript.scriptRef.log("ERROR: createProgram() failed because the specified program does not exist: " + name); + return false; + } + + if(Player.hasProgram(p.name)) { + workerScript.scriptRef.log('ERROR: createProgram() failed because you already have the ' + p.name + ' program'); + return false; + } + + if(!p.create.req()) { + workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create " + p.name + " (level " + p.create.level + " req)"); + return false + } + + Player.startCreateProgramWork(p.name, p.create.time, p.create.level); + if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.createProgram == null) { + workerScript.scriptRef.log("Began creating program: " + name); } - workerScript.scriptRef.log("Began creating program: " + name); return true; }, commitCrime : function(crime) { diff --git a/src/Player.js b/src/Player.js index f61bbeb56..0f7141102 100644 --- a/src/Player.js +++ b/src/Player.js @@ -218,7 +218,7 @@ PlayerObject.prototype.init = function() { this.currentServer = t_homeComp.ip; AddToAllServers(t_homeComp); - this.getHomeComputer().programs.push(Programs.NukeProgram); + this.getHomeComputer().programs.push(Programs.NukeProgram.name); } PlayerObject.prototype.prestigeAugmentation = function() { diff --git a/src/Prestige.js b/src/Prestige.js index 2c3c68eae..49b26d8b6 100644 --- a/src/Prestige.js +++ b/src/Prestige.js @@ -56,13 +56,13 @@ function prestigeAugmentation() { if (augmentationExists(AugmentationNames.Neurolink) && Augmentations[AugmentationNames.Neurolink].owned) { - homeComp.programs.push(Programs.FTPCrackProgram); - homeComp.programs.push(Programs.RelaySMTPProgram); + homeComp.programs.push(Programs.FTPCrackProgram.name); + homeComp.programs.push(Programs.RelaySMTPProgram.name); } if (augmentationExists(AugmentationNames.CashRoot) && Augmentations[AugmentationNames.CashRoot].owned) { Player.setMoney(new Decimal(1000000)); - homeComp.programs.push(Programs.BruteSSHProgram); + homeComp.programs.push(Programs.BruteSSHProgram.name); } //Re-create foreign servers diff --git a/src/Server.js b/src/Server.js index a9346fc96..e4ce38c54 100644 --- a/src/Server.js +++ b/src/Server.js @@ -810,7 +810,7 @@ function prestigeHomeComputer(homeComp) { homeComp.serversOnNetwork = []; homeComp.isConnectedTo = true; homeComp.ramUsed = 0; - homeComp.programs.push(Programs.NukeProgram); + homeComp.programs.push(Programs.NukeProgram.name); //Update RAM usage on all scripts homeComp.scripts.forEach(function(script) { diff --git a/src/Terminal.js b/src/Terminal.js index 429a6e681..658a01afa 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -409,9 +409,9 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) { } if (input.startsWith ("buy ")) { - return [Programs.BruteSSHProgram, Programs.FTPCrackProgram, Programs.RelaySMTPProgram, - Programs.HTTPWormProgram, Programs.SQLInjectProgram, Programs.DeepscanV1, - Programs.DeepscanV2].concat(Object.keys(GlobalAliases)); + return [Programs.BruteSSHProgram.name, Programs.FTPCrackProgram.name, Programs.RelaySMTPProgram.name, + Programs.HTTPWormProgram.name, Programs.SQLInjectProgram.name, Programs.DeepscanV1.name, + Programs.DeepscanV2.name].concat(Object.keys(GlobalAliases)); } if (input.startsWith("scp ") && index == 1) { @@ -1352,11 +1352,11 @@ let Terminal = { post("Incorrect usage of scan-analyze command. depth argument must be positive numeric"); return; } - if (depth > 3 && !Player.hasProgram(Programs.DeepscanV1) && - !Player.hasProgram(Programs.DeepscanV2)) { + if (depth > 3 && !Player.hasProgram(Programs.DeepscanV1.name) && + !Player.hasProgram(Programs.DeepscanV2.name)) { post("You cannot scan-analyze with that high of a depth. Maximum depth is 3"); return; - } else if (depth > 5 && !Player.hasProgram(Programs.DeepscanV2)) { + } else if (depth > 5 && !Player.hasProgram(Programs.DeepscanV2.name)) { post("You cannot scan-analyze with that high of a depth. Maximum depth is 5"); return; } else if (depth > 10) { @@ -1757,7 +1757,7 @@ let Terminal = { } if (d == 0) {continue;} //Don't print current server var titleDashes = Array((d-1) * 4 + 1).join("-"); - if (Player.hasProgram(Programs.AutoLink)) { + if (Player.hasProgram(Programs.AutoLink.name)) { post("" + titleDashes + "> " + s.hostname + "", false); } else { post("" + titleDashes + ">" + s.hostname + ""); @@ -1822,7 +1822,7 @@ let Terminal = { programName = splitArgs[0]; } switch (programName) { - case Programs.NukeProgram: + case Programs.NukeProgram.name: if (s.hasAdminRights) { post("You already have root access to this computer. There is no reason to run NUKE.exe"); } else { @@ -1835,7 +1835,7 @@ let Terminal = { } } break; - case Programs.BruteSSHProgram: + case Programs.BruteSSHProgram.name: if (s.sshPortOpen) { post("SSH Port (22) is already open!"); } else { @@ -1844,7 +1844,7 @@ let Terminal = { ++s.openPortCount; } break; - case Programs.FTPCrackProgram: + case Programs.FTPCrackProgram.name: if (s.ftpPortOpen) { post("FTP Port (21) is already open!"); } else { @@ -1853,7 +1853,7 @@ let Terminal = { ++s.openPortCount; } break; - case Programs.RelaySMTPProgram: + case Programs.RelaySMTPProgram.name: if (s.smtpPortOpen) { post("SMTP Port (25) is already open!"); } else { @@ -1862,7 +1862,7 @@ let Terminal = { ++s.openPortCount; } break; - case Programs.HTTPWormProgram: + case Programs.HTTPWormProgram.name: if (s.httpPortOpen) { post("HTTP Port (80) is already open!"); } else { @@ -1871,7 +1871,7 @@ let Terminal = { ++s.openPortCount; } break; - case Programs.SQLInjectProgram: + case Programs.SQLInjectProgram.name: if (s.sqlPortOpen) { post("SQL Port (1433) is already open!"); } else { @@ -1880,7 +1880,7 @@ let Terminal = { ++s.openPortCount; } break; - case Programs.ServerProfiler: + case Programs.ServerProfiler.name: if (splitArgs.length != 2) { post("Must pass a server hostname or IP as an argument for ServerProfiler.exe"); return; @@ -1898,20 +1898,20 @@ let Terminal = { post("Netscript grow() execution time: " + formatNumber(scriptCalculateGrowTime(serv)/1000, 1) + "s"); post("Netscript weaken() execution time: " + formatNumber(scriptCalculateWeakenTime(serv)/1000, 1) + "s"); break; - case Programs.AutoLink: + case Programs.AutoLink.name: post("This executable cannot be run."); post("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'."); post("When using scan-analyze, click on a server's hostname to connect to it."); break; - case Programs.DeepscanV1: + case Programs.DeepscanV1.name: post("This executable cannot be run."); post("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5."); break; - case Programs.DeepscanV2: + case Programs.DeepscanV2.name: post("This executable cannot be run."); post("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10."); break; - case Programs.Flight: + case Programs.Flight.name: post("Augmentations: " + Player.augmentations.length + " / 30"); post("Money: $" + formatNumber(Player.money.toNumber(), 2) + " / $" + formatNumber(100000000000, 2)); post("One path below must be fulfilled..."); @@ -1923,7 +1923,7 @@ let Terminal = { post("Dexterity: " + Player.dexterity + " / 1500"); post("Agility: " + Player.agility + " / 1500"); break; - case Programs.BitFlume: + case Programs.BitFlume.name: var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton(); yesBtn.innerHTML = "Travel to BitNode Nexus"; diff --git a/src/engine.js b/src/engine.js index dd0845bc7..451990a61 100644 --- a/src/engine.js +++ b/src/engine.js @@ -20,7 +20,7 @@ import {cinematicTextFlag} from "./CinematicText.js"; import {CompanyPositions, initCompanies} from "./Company.js"; import {Corporation} from "./CompanyManagement.js"; import {CONSTANTS} from "./Constants.js"; -import {Programs, displayCreateProgramContent, +import {displayCreateProgramContent, getNumAvailableCreateProgram, initCreateProgramButtons} from "./CreateProgram.js"; import {displayFactionContent, joinFaction,