diff --git a/src/Constants.js b/src/Constants.js index 0b29f0503..8812dc76e 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -10,9 +10,9 @@ CONSTANTS = { CorpFactionRepRequirement: 250000, /* Base costs */ - BaseCostFor1GBOfRamHome: 100000, - BaseCostFor1GBOfRamServer: 75000, //1 GB of RAM - BaseCostFor1GBOfRamHacknetNode: 50000, + BaseCostFor1GBOfRamHome: 80000, + BaseCostFor1GBOfRamServer: 60000, //1 GB of RAM + BaseCostFor1GBOfRamHacknetNode: 40000, BaseCostForHacknetNode: 1000, BaseCostForHacknetNodeCore: 1000000, @@ -39,6 +39,12 @@ CONSTANTS = { ScriptIfRamCost: 0.1, ScriptHackRamCost: 0.25, ScriptGrowRamCost: 0.25, + ScriptNukeRamCost: 0.05, + ScriptBrutesshRamCost: 0.05, + ScriptFtpcrackRamCost: 0.05, + ScriptRelaysmtpRamCost: 0.05, + ScriptHttpwormRamCost: 0.05, + ScriptSqlinjectRamCost: 0.05, //Server growth rate ServerGrowthRate: 1.00075, diff --git a/src/CreateProgram.js b/src/CreateProgram.js index a23e45859..d48f57da4 100644 --- a/src/CreateProgram.js +++ b/src/CreateProgram.js @@ -25,7 +25,7 @@ function displayCreateProgramContent() { httpWormALink.style.display = "none"; sqlInjectALink.style.display = "none"; - //PortHack.exe (in case you delete it lol) + //NUKE.exe (in case you delete it lol) if (Player.getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) { nukeALink.style.display = "block"; } @@ -46,14 +46,12 @@ function displayCreateProgramContent() { if (Player.getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 && Player.hacking_skill >= 250) { relaySmtpALink.style.display = "block"; - } //HTTPWorm if (Player.getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 && Player.hacking_skill >= 500) { httpWormALink.style.display = "block"; - } //SQLInject diff --git a/src/Netscript/Evaluator.js b/src/Netscript/Evaluator.js index a3f1667a6..2944d4ac8 100644 --- a/src/Netscript/Evaluator.js +++ b/src/Netscript/Evaluator.js @@ -55,7 +55,7 @@ function evaluate(exp, workerScript) { } catch (e) { throw new Error("|" + workerScript.serverIp + "|" + workerScript.name + "|" + e.toString()); } - resolve(false); + resolve(false); //Return false so this doesnt cause loops/ifs to evaluate }, function(e) { reject(e); }); @@ -105,21 +105,32 @@ function evaluate(exp, workerScript) { //TODO case "if": - var numConds = exp.cond.length; - var numThens = exp.then.length; - if (numConds == 0 || numThens == 0 || numConds != numThens) { - reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Number of conds and thens in if structure don't match (or there are none)"); - } - - for (var i = 0; i < numConds; i++) { - var cond = evaluate(exp.cond[i], workerScript); - if (cond) return evaluate(exp.then[i], workerScript); - } - - //Evaluate else if it exists, snce none of the conditionals - //were true - return exp.else ? evaluate(exp.else, workerScript) : false; - + return new Promise(function(resolve, reject) { + var numConds = exp.cond.length; + var numThens = exp.then.length; + if (numConds == 0 || numThens == 0 || numConds != numThens) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Number of conds and thens in if structure don't match (or there are none)"); + } + + for (var i = 0; i < numConds; i++) { + var cond = evaluate(exp.cond[i], workerScript); + cond.then(function(condRes) { + if (cond) { + return evaluate(exp.then[i], workerScript); + } + }, function(e) { + reject(e); + }); + + } + + //Evaluate else if it exists, snce none of the conditionals + //were true + if (exp.else) { + return evaluate(exp.else, workerScript); + } + }); + break; case "for": return new Promise(function(resolve, reject) { if (env.stopFlag) {reject(workerScript);} @@ -177,11 +188,17 @@ function evaluate(exp, workerScript) { break; /* Currently supported function calls: - * hack() + * hack(server) * sleep(N) - sleep N seconds * print(x) - Prints a variable or constant - * - */ + * grow(server) + * nuke(server) + * brutessh(server) + * ftpcrack(server) + * relaysmtp(server) + * httpworm(server) + * sqlinject(server) + */ case "call": //Define only valid function calls here, like hack() and stuff //var func = evaluate(exp.func, env); @@ -196,23 +213,13 @@ function evaluate(exp, workerScript) { if (exp.args.length != 1) { reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Hack() call has incorrect number of arguments. Takes 1 argument"); } - - //IP of server to hack var ipPromise = evaluate(exp.args[0], workerScript); - + ipPromise.then(function(ip) { - //Check if its a valid IP address. If it's not, assume its a hostname and - //try to get the server. If its not a server, there is an error - var server = null; - if (!isValidIPAddress(ip)) { - //It's not an IP address, so see if its a hostanme - server = GetServerByHostname(ip); - } else { - server = AllServers[ip]; - } + var server = getServer(ip); if (server == null) { reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into hack() command"); - workerScript.scriptRef.log("Cannot hack(). Invalid IP or hostname passed in: " + ip); + workerScript.scriptRef.log("Cannot hack(). Invalid IP or hostname passed in: " + ip + ". Stopping..."); return; } @@ -287,9 +294,7 @@ function evaluate(exp, workerScript) { } else if (exp.func.value == "sleep") { if (exp.args.length != 1) { reject("|" + workerScript.serverIp + "|" + workerScript.name + "|sleep() call has incorrect number of arguments. Takes 1 argument."); - return; } - var sleepTimePromise = evaluate(exp.args[0], workerScript); sleepTimePromise.then(function(sleepTime) { workerScript.scriptRef.log("Sleeping for " + sleepTime + " milliseconds"); @@ -333,20 +338,10 @@ function evaluate(exp, workerScript) { if (exp.args.length != 1) { reject("|" + workerScript.serverIp + "|" + workerScript.name + "|grow() call has incorrect number of arguments. Takes 1 argument"); } - - //IP/hostname of server to hack var ipPromise = evaluate(exp.args[0], workerScript); ipPromise.then(function(ip) { - //Check if its a valid IP address. If it's not, assume its a hostname and - //try to get the server. If its not a server, there is an error - var server = null; - if (!isValidIPAddress(ip)) { - //It's not an IP address, so see if its a hostanme - server = GetServerByHostname(ip); - } else { - server = AllServers[ip]; - } + var server = getServer(ip); if (server == null) { reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into grow() command"); workerScript.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: " + ip); @@ -380,6 +375,256 @@ function evaluate(exp, workerScript) { }, function(e) { reject(e); }); + } else if (exp.func.value == "nuke") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|nuke() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into nuke() command"); + workerScript.scriptRef.log("Cannot nuke(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.NukeProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have NUKE program on home computer"); + return; + } + + if (server.openPortCount < server.numOpenPortsRequired) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Not enough ports opened to use NUKE.exe virus"); + return; + } + + workerScript.scriptRef.log("Running NUKE.exe on server " + server.hostname + " in 5 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (server.hasAdminRights) { + workerScript.scriptRef.log("Already have root access to " + server.hostname); + } else { + server.hasAdminRights = true; + workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access"); + } + resolve("nuke done"); + }, 5 * 1000); + }); + + p.then(function(res) { + resolve("nukeExecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "brutessh") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|brutessh() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into brutessh() command"); + workerScript.scriptRef.log("Cannot brutessh(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.BruteSSHProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have BruteSSH.exe program on home computer"); + return; + } + + workerScript.scriptRef.log("Running BruteSSH.exe on server " + server.hostname + " in 10 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (!server.sshPortOpen) { + workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)"); + server.sshPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname); + } + resolve("brutessh done"); + }, 10 * 1000); + }); + + p.then(function(res) { + resolve("bruteSSHExecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "ftpcrack") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|ftpcrack() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into ftpcrack() command"); + workerScript.scriptRef.log("Cannot ftpcrack(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.FTPCrackProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have FTPCrack.exe program on home computer"); + return; + } + + workerScript.scriptRef.log("Running FTPCrack.exe on server " + server.hostname + " in 15 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (!server.ftpPortOpen) { + workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)"); + server.ftpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname); + } + resolve("ftpcrack done"); + }, 15 * 1000); + }); + + p.then(function(res) { + resolve("ftpcrackexecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "relaysmtp") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|relaysmtp() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command"); + workerScript.scriptRef.log("Cannot relaysmtp(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.RelaySMTPProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have relaySMTP.exe program on home computer"); + return; + } + + workerScript.scriptRef.log("Running relaySMTP.exe on server " + server.hostname + " in 20 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (!server.smtpPortOpen) { + workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)"); + server.smtpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname); + } + resolve("relaysmtp done"); + }, 20 * 1000); + }); + + p.then(function(res) { + resolve("relaysmtpexecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "httpworm") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|httpworm() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command"); + workerScript.scriptRef.log("Cannot httpworm(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.HTTPWormProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have HTTPWorm.exe program on home computer"); + return; + } + + workerScript.scriptRef.log("Running HTTPWorm.exe on server " + server.hostname + " in 25 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (!server.httpPortOpen) { + workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)"); + server.httpPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname); + } + resolve("httpworm done"); + }, 25 * 1000); + }); + + p.then(function(res) { + resolve("HTTPWormexecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); + } else if (exp.func.value == "sqlinject") { + if (exp.args.length != 1) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|sqlinject() call has incorrect number of arguments. Takes 1 argument"); + } + var ipPromise = evaluate(exp.args[0], workerScript); + ipPromise.then(function(ip) { + var server = getServer(ip); + if (server == null) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into sqlinject() command"); + workerScript.scriptRef.log("Cannot sqlinject(). Invalid IP or hostname passed in: " + ip); + return; + } + + if (!Player.hasProgram(Programs.SQLInjectProgram)) { + reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Player does not have SQLInject.exe program on home computer"); + return; + } + + workerScript.scriptRef.log("Running SQLInject.exe on server " + server.hostname + " in 30 seconds"); + var p = new Promise(function(resolve, reject) { + if (env.stopFlag) {reject(workerScript);} + setTimeout(function() { + if (!server.sqlPortOpen) { + workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)"); + server.sqlPortOpen = true; + ++server.openPortCount; + } else { + workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname); + } + resolve("sqlinject done"); + }, 30 * 1000); + }); + + p.then(function(res) { + resolve("sqlinjectexecuted"); + }, function(e) { + reject(e); + }); + }, function(e) { + reject(e); + }); } }, CONSTANTS.CodeInstructionRunTime); }); diff --git a/src/Player.js b/src/Player.js index 383c6ed0a..e6c39d60a 100644 --- a/src/Player.js +++ b/src/Player.js @@ -249,8 +249,6 @@ PlayerObject.prototype.calculatePercentMoneyHacked = function() { //Returns how much EXP the player gains on a successful hack //The formula is: // difficulty * requiredLevel * hacking_multiplier -// -// Note: Keep it at an integer for now, PlayerObject.prototype.calculateExpGain = function() { return (this.getCurrentServer().hackDifficulty * this.hacking_exp_mult); } @@ -261,15 +259,21 @@ PlayerObject.prototype.calculateExpGain = function() { PlayerObject.prototype.hack = function() { this.actionTime = this.calculateHackingTime(); console.log("Hacking time: " + this.actionTime); - //Set the startAction flag so the engine starts the hacking process - this.startAction = true; + this.startAction = true; //Set the startAction flag so the engine starts the hacking process } PlayerObject.prototype.analyze = function() { - //TODO Analyze only takes 1 seconds for now..maybe change this in the future? this.actionTime = 1; this.startAction = true; -} +} + +PlayerObject.prototype.hasProgram = function(programName) { + var home = Player.getHomeComputer(); + for (var i = 0; i < home.programs.length; ++i) { + if (programName == home.programs[i]) {return true;} + } + return false; +} PlayerObject.prototype.gainMoney = function(money) { if (isNaN(money)) { @@ -645,7 +649,7 @@ PlayerObject.prototype.startFactionWork = function(faction) { PlayerObject.prototype.startFactionHackWork = function(faction) { this.resetWorkStatus(); - this.workHackExpGainRate = .02 * this.hacking_exp_mult; + this.workHackExpGainRate = .175 * this.hacking_exp_mult; this.workRepGainRate = this.hacking_skill / CONSTANTS.MaxSkillLevel * this.faction_rep_mult; this.factionWorkType = CONSTANTS.FactionWorkHacking; @@ -657,12 +661,12 @@ PlayerObject.prototype.startFactionHackWork = function(faction) { PlayerObject.prototype.startFactionFieldWork = function(faction) { this.resetWorkStatus(); - this.workHackExpGainRate = .05 * this.hacking_exp_mult; - this.workStrExpGainRate = .05 * this.strength_exp_mult; - this.workDefExpGainRate = .05 * this.defense_exp_mult; - this.workDexExpGainRate = .05 * this.dexterity_exp_mult; - this.workAgiExpGainRate = .05 * this.agility_exp_mult; - this.workChaExpGainRate = .05 * this.charisma_exp_mult; + this.workHackExpGainRate = .1 * this.hacking_exp_mult; + this.workStrExpGainRate = .1 * this.strength_exp_mult; + this.workDefExpGainRate = .1 * this.defense_exp_mult; + this.workDexExpGainRate = .1 * this.dexterity_exp_mult; + this.workAgiExpGainRate = .1 * this.agility_exp_mult; + this.workChaExpGainRate = .1 * this.charisma_exp_mult; this.workRepGainRate = this.getFactionFieldWorkRepGain(); this.factionWorkType = CONSTANTS.factionWorkField; @@ -674,12 +678,12 @@ PlayerObject.prototype.startFactionFieldWork = function(faction) { PlayerObject.prototype.startFactionSecurityWork = function(faction) { this.resetWorkStatus(); - this.workHackExpGainRate = 0.01 * this.hacking_exp_mult; - this.workStrExpGainRate = 0.01 * this.strength_exp_mult; - this.workDefExpGainRate = 0.01 * this.defense_exp_mult; - this.workDexExpGainRate = 0.01 * this.dexterity_exp_mult; - this.workAgiExpGainRate = 0.01 * this.agility_exp_mult; - this.workChaExpGainRate = 0.01 * this.charisma_exp_mult; + this.workHackExpGainRate = 0.05 * this.hacking_exp_mult; + this.workStrExpGainRate = 0.15 * this.strength_exp_mult; + this.workDefExpGainRate = 0.15 * this.defense_exp_mult; + this.workDexExpGainRate = 0.15 * this.dexterity_exp_mult; + this.workAgiExpGainRate = 0.15 * this.agility_exp_mult; + this.workChaExpGainRate = 0.00 * this.charisma_exp_mult; this.workRepGainRate = this.getFactionSecurityWorkRepGain(); this.factionWorkType = CONSTANTS.FactionWorkSecurity; diff --git a/src/Script.js b/src/Script.js index 76deefc4a..0a042147c 100644 --- a/src/Script.js +++ b/src/Script.js @@ -148,6 +148,7 @@ Script.prototype.reset = function() { this.onlineExpGained = 0; this.moneyStolenMap = new AllServersToMoneyMap(); + console.log("Reset moneyStolenMap: " + this.moneyStolenMap); } //Calculates the number of instructions, which is just determined by number of semicolons @@ -167,13 +168,25 @@ Script.prototype.updateRamUsage = function() { var ifCount = numOccurrences(codeCopy, "if("); var hackCount = numOccurrences(codeCopy, "hack("); var growCount = numOccurrences(codeCopy, "grow("); + var nukeCount = numOccurrences(codeCopy, "nuke("); + var brutesshCount = numOccurrences(codeCopy, "brutessh("); + var ftpcrackCount = numOccurrences(codeCopy, "ftpcrack("); + var relaysmtpCount = numOccurrences(codeCopy, "relaysmtp("); + var httpwormCount = numOccurrences(codeCopy, "httpworm("); + var sqlinjectCount = numOccurrences(codeCopy, "sqlinject("); this.ramUsage = baseRam + ((whileCount * CONSTANTS.ScriptWhileRamCost) + (forCount * CONSTANTS.ScriptForRamCost) + (ifCount * CONSTANTS.ScriptIfRamCost) + (hackCount * CONSTANTS.ScriptHackRamCost) + - (growCount * CONSTANTS.ScriptGrowRamCost)); + (growCount * CONSTANTS.ScriptGrowRamCost) + + (nukeCount * CONSTANTS.ScriptNukeRamCost) + + (brutesshCount * CONSTANTS.ScriptBrutesshRamCost) + + (ftpcrackCount * CONSTANTS.ScriptFtpcrackRamCost) + + (relaysmtpCount * CONSTANTS.ScriptRelaysmtpRamCost) + + (httpwormCount * CONSTANTS.ScriptHttpwormRamCost) + + (sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost)); console.log("ram usage: " + this.ramUsage); } diff --git a/src/Server.js b/src/Server.js index b1fe217c6..165765dee 100644 --- a/src/Server.js +++ b/src/Server.js @@ -713,6 +713,15 @@ GetServerByHostname = function(hostname) { return null; } +//Get server by IP or hostname. Returns null if invalid +getServer = function(s) { + if (!isValidIPAddress(s)) { + return GetServerByHostname(s); + } else { + return AllServers[s]; + } +} + //Debugging tool PrintAllServers = function() { for (var ip in AllServers) {