From a6406e785ae4677c22c044173f46466372e23bd9 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Fri, 23 Jun 2017 09:23:35 -0500 Subject: [PATCH] FIxed field work buff. Added AutoLink and ServerProfiler programs. PRogram work is now saved --- css/styles.css | 10 +++++ index.html | 30 ++++++++----- src/Constants.js | 16 +++++-- src/CreateProgram.js | 101 +++++++++++++++++++++++++++++++++++-------- src/Player.js | 21 ++++++++- src/SaveObject.js | 6 ++- src/Script.js | 2 + src/Terminal.js | 92 +++++++++++++++++++++++++++++++-------- src/engine.js | 42 +----------------- 9 files changed, 227 insertions(+), 93 deletions(-) diff --git a/css/styles.css b/css/styles.css index d958405aa..f773a83e9 100644 --- a/css/styles.css +++ b/css/styles.css @@ -293,3 +293,13 @@ tr:focus { #character-overview-options-button { display: inline-block; } + +/* Scan analyze links from AutoLink */ +.scan-analyze-link { + cursor:pointer; + color:#FFFFFF; + text-decoration:underline; +} +.scan-analyze-link:hover { + text-decoration:none; +} diff --git a/index.html b/index.html index b3a41bd94..2dc38708a 100644 --- a/index.html +++ b/index.html @@ -405,44 +405,52 @@

This page displays any programs that you are able to create. Writing the code for a program takes time, which - can vary based on how complex the program is. Once you start working on a program you must see it all the way - through. If you cancel before the program is complete you will lose all your progress and have to start all over - if you want to code it again. + can vary based on how complex the program is. If you are working on creating on a program you can cancel + at any time. Your progress will be saved and you can continue later.

diff --git a/src/Constants.js b/src/Constants.js index d1f4c1979..6bd6cf937 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -1,5 +1,5 @@ CONSTANTS = { - Version: "0.22.0", + Version: "0.22.1", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then @@ -655,6 +655,11 @@ CONSTANTS = { "RAM Upgrades on your home computer", Changelog: + "v0.22.1
" + + "-You no longer lose progress on creating programs when cancelling your work. Your progress will be saved and you will pick up " + + "where you left off when you start working on it again
" + + "-Added two new programs: AutoLink.exe and ServerProfiler.exe
" + + "-Fixed bug with Faction Field work reputation gain

" + "v0.22.0 - Major rebalancing, optimization, and favor system
" + "-Significantly nerfed most augmentations
" + "-Almost every server with a required hacking level of 200 or more now has slightly randomized server parameters. This means that after every Augmentation " + @@ -673,7 +678,7 @@ CONSTANTS = { "-Added getServerBaseSecurityLevel() Netscript function
" + "-New favor system for companies and factions. Earning reputation at a company/faction will give you favor for that entity when you " + "reset after installing an Augmentation. This favor persists through the rest of the game. The more favor you have, the faster you will earn " + - "reputation with that faction
" + + "reputation with that faction/company
" + "-You can no longer donate to a faction for reputation until you have 150 favor with that faction
" + "-Added unalias Terminal command
" + "-Changed requirements for endgame Factions

" + @@ -829,6 +834,11 @@ CONSTANTS = { "-You can now see what an Augmentation does and its price even while its locked

", LatestUpdate: + "v0.22.1
" + + "-You no longer lose progress on creating programs when cancelling your work. Your progress will be saved and you will pick up " + + "where you left off when you start working on it again
" + + "-Added two new programs: AutoLink.exe and ServerProfiler.exe
" + + "-Fixed bug with Faction Field work reputation gain

" + "v0.22.0 - Major rebalancing, optimization, and favor system
" + "-Significantly nerfed most augmentations
" + "-Almost every server with a required hacking level of 200 or more now has slightly randomized server parameters. This means that after every Augmentation " + @@ -847,7 +857,7 @@ CONSTANTS = { "-Added getServerBaseSecurityLevel() Netscript function
" + "-New favor system for companies and factions. Earning reputation at a company/faction will give you favor for that entity when you " + "reset after installing an Augmentation. This favor persists through the rest of the game. The more favor you have, the faster you will earn " + - "reputation with that faction
" + + "reputation with that faction/company
" + "-You can no longer donate to a faction for reputation until you have 150 favor with that faction
" + "-Added unalias Terminal command
" + "-Changed requirements for endgame Factions
", diff --git a/src/CreateProgram.js b/src/CreateProgram.js index e2ec91e3b..be8ca9e18 100644 --- a/src/CreateProgram.js +++ b/src/CreateProgram.js @@ -8,20 +8,24 @@ Programs = { SQLInjectProgram: "SQLInject.exe", DeepscanV1: "DeepscanV1.exe", DeepscanV2: "DeepscanV2.exe", + ServerProfiler: "ServerProfiler.exe", + AutoLink: "AutoLink.exe", Flight: "fl1ght.exe", } //TODO Right now the times needed to complete work are hard-coded... //maybe later make this dependent on hacking level or something function displayCreateProgramContent() { - var nukeALink = document.getElementById("create-program-nuke"); - var bruteSshALink = document.getElementById("create-program-brutessh"); - var ftpCrackALink = document.getElementById("create-program-ftpcrack"); - var relaySmtpALink = document.getElementById("create-program-relaysmtp"); - var httpWormALink = document.getElementById("create-program-httpworm"); - var sqlInjectALink = document.getElementById("create-program-sqlinject"); - var deepscanv1ALink = document.getElementById("create-program-deepscanv1"); - var deepscanv2ALink = document.getElementById("create-program-deepscanv2"); + var nukeALink = document.getElementById("create-program-nuke"); + var bruteSshALink = document.getElementById("create-program-brutessh"); + var ftpCrackALink = document.getElementById("create-program-ftpcrack"); + var relaySmtpALink = document.getElementById("create-program-relaysmtp"); + var httpWormALink = document.getElementById("create-program-httpworm"); + var sqlInjectALink = document.getElementById("create-program-sqlinject"); + var deepscanv1ALink = document.getElementById("create-program-deepscanv1"); + var deepscanv2ALink = document.getElementById("create-program-deepscanv2"); + var servProfilerALink = document.getElementById("create-program-serverprofiler"); + var autolinkALink = document.getElementById("create-program-autolink"); nukeALink.style.display = "none"; bruteSshALink.style.display = "none"; @@ -31,6 +35,8 @@ function displayCreateProgramContent() { sqlInjectALink.style.display = "none"; deepscanv1ALink.style.display = "none"; deepscanv2ALink.style.display = "none"; + servProfilerALink.style.display = "none"; + autolinkALink.style.display = "none"; //NUKE.exe (in case you delete it lol) if (Player.getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) { @@ -68,55 +74,116 @@ function displayCreateProgramContent() { 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"; + } } //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; + } return count; +} + +function initCreateProgramButtons() { + var nukeALink = document.getElementById("create-program-nuke"); + var bruteSshALink = document.getElementById("create-program-brutessh"); + var ftpCrackALink = document.getElementById("create-program-ftpcrack"); + var relaySmtpALink = document.getElementById("create-program-relaysmtp"); + var httpWormALink = document.getElementById("create-program-httpworm"); + var sqlInjectALink = document.getElementById("create-program-sqlinject"); + var deepscanv1ALink = document.getElementById("create-program-deepscanv1"); + var deepscanv2ALink = document.getElementById("create-program-deepscanv2"); + var servProfilerALink = document.getElementById("create-program-serverprofiler"); + var autolinkALink = document.getElementById("create-program-autolink"); + + 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; + }); } \ No newline at end of file diff --git a/src/Player.js b/src/Player.js index e8e99b64b..5cf95d6be 100644 --- a/src/Player.js +++ b/src/Player.js @@ -680,7 +680,7 @@ PlayerObject.prototype.startFactionFieldWork = function(faction) { this.workChaExpGainRate = .1 * this.charisma_exp_mult; this.workRepGainRate = this.getFactionFieldWorkRepGain(); - this.factionWorkType = CONSTANTS.factionWorkField; + this.factionWorkType = CONSTANTS.FactionWorkField; this.currentWorkFactionDescription = "carrying out field missions" this.startFactionWork(faction); @@ -855,7 +855,20 @@ PlayerObject.prototype.startCreateProgramWork = function(programName, time, reqL var timeMultiplier = (CONSTANTS.MaxSkillLevel - (this.hacking_skill - reqLevel)) / CONSTANTS.MaxSkillLevel; if (timeMultiplier > 1) {timeMultiplier = 1;} if (timeMultiplier < 0.01) {timeMultiplier = 0.01;} + this.timeNeededToCompleteWork = timeMultiplier * time; + //Check for incomplete program + for (var i = 0; i < Player.getHomeComputer().programs.length; ++i) { + var programFile = Player.getHomeComputer().programs[i]; + if (programFile.startsWith(programName) && programFile.endsWith("%-INC")) { + var res = programFile.split("-"); + if (res.length != 3) {break;} + var percComplete = Number(res[1].slice(0, -1)); + if (isNaN(percComplete) || percComplete <= 0 || percComplete >= 100) {break;} + this.timeWorked = percComplete / 100 * this.timeNeededToCompleteWork; + Player.getHomeComputer().programs.splice(i, 1); + } + } this.createProgramName = programName; @@ -882,7 +895,7 @@ PlayerObject.prototype.createProgramWork = function(numCycles) { txt.innerHTML = "You are currently working on coding " + programName + ".

" + "You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "

" + "The program is " + (this.timeWorked / this.timeNeededToCompleteWork * 100).toFixed(2) + "% complete.
" + - "If you cancel, you will lose all of your progress."; + "If you cancel, your work will be saved and you can come back to complete the program later."; } PlayerObject.prototype.finishCreateProgramWork = function(cancelled, programName) { @@ -891,6 +904,10 @@ PlayerObject.prototype.finishCreateProgramWork = function(cancelled, programName "The new program can be found on your home computer."); Player.getHomeComputer().programs.push(programName); + } else { + var perc = Math.floor(this.timeWorked / this.timeNeededToCompleteWork * 100).toString(); + var incompleteName = programName + "-" + perc + "%-INC"; + Player.getHomeComputer().programs.push(incompleteName); } var mainMenu = document.getElementById("mainmenu-container"); diff --git a/src/SaveObject.js b/src/SaveObject.js index 9fd3f99fc..0e38841bb 100644 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -83,7 +83,8 @@ loadGame = function(saveObj) { try { var ver = JSON.parse(saveObj.VersionSave, Reviver); if (ver != CONSTANTS.Version) { - if (CONSTANTS.Version == "0.21.0" || CONSTANTS.Version == "0.22.0") { + if (CONSTANTS.Version == "0.21.0" || CONSTANTS.Version == "0.22.0" || + CONSTANTS.Version == "0.22.1") { dialogBoxCreate("All scripts automatically killed for the sake of compatibility " + "with new version. If the game is still broken, try the following: " + "Options -> Soft Reset -> Save Game -> Reload page. If that STILL " + @@ -155,7 +156,8 @@ loadImportedGame = function(saveObj, saveString) { } if (ver != CONSTANTS.Version) { - if (CONSTANTS.Version == "0.21.0") { + if (CONSTANTS.Version == "0.21.0" || CONSTANTS.Version == "0.22.0" || + CONSTANTS.Version == "0.22.1") { console.log("here"); //This is the big update that might break games. Kill all running scripts for (var ip in tempAllServers) { diff --git a/src/Script.js b/src/Script.js index 6bd22cef3..9ac11c611 100644 --- a/src/Script.js +++ b/src/Script.js @@ -150,6 +150,7 @@ Script.prototype.updateRamUsage = function() { var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel("); var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable("); var getServerSecurityCount = numOccurrences(codeCopy, "getServerSecurityLevel("); + var getServerBaseSecurityCount = numOccurrences(codeCopy, "getServerBaseSecurityLevel("); var getServerReqdHackingCount = numOccurrences(codeCopy, "getServerRequiredHackingLevel("); var fileExistsCount = numOccurrences(codeCopy, "fileExists("); var isRunningCount = numOccurrences(codeCopy, "isRunning("); @@ -181,6 +182,7 @@ Script.prototype.updateRamUsage = function() { (getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) + (getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) + (getServerSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) + + (getServerBaseSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) + (getServerReqdHackingCount * CONSTANTS.ScriptGetServerReqdHackRamCost) + (fileExistsCount * CONSTANTS.ScriptFileExistsRamCost) + (isRunningCount * CONSTANTS.ScriptIsRunningRamCost) + diff --git a/src/Terminal.js b/src/Terminal.js index 490e34bab..0e7a45c6d 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -1,8 +1,13 @@ //Terminal /* Write text to terminal */ -var post = function(input) { - $("#terminal-input").before('' + input.replace( / /g, " " ) + ''); +var post = function(input, replace=true) { + if (replace) { + $("#terminal-input").before('' + input.replace( / /g, " " ) + ''); + } else { + $("#terminal-input").before('' + input + ''); + } + updateTerminalScroll(); } @@ -669,13 +674,7 @@ var Terminal = { for (var i = 0; i < Player.getCurrentServer().serversOnNetwork.length; i++) { if (Player.getCurrentServer().getServerOnNetwork(i).ip == ip || Player.getCurrentServer().getServerOnNetwork(i).hostname == ip) { - Player.getCurrentServer().isConnectedTo = false; - Player.currentServer = Player.getCurrentServer().getServerOnNetwork(i).ip; - Player.getCurrentServer().isConnectedTo = true; - post("Connected to " + ip); - if (Player.getCurrentServer().hostname == "darkweb") { - checkIfConnectedToDarkweb(); //Posts a 'help' message if connecting to dark web - } + Terminal.connectToServer(ip); return; } } @@ -1060,6 +1059,22 @@ var Terminal = { } }, + connectToServer: function(ip) { + console.log("Connect to server called"); + var serv = getServer(ip); + if (serv == null) { + post("Invalid server. Connection failed."); + return; + } + Player.getCurrentServer().isConnectedTo = false; + Player.currentServer = serv.ip; + Player.getCurrentServer().isConnectedTo = true; + post("Connected to " + serv.hostname); + if (Player.getCurrentServer().hostname == "darkweb") { + checkIfConnectedToDarkweb(); //Posts a 'help' message if connecting to dark web + } + }, + executeListCommand: function(commandArray) { if (commandArray.length != 1) { post("Incorrect usage of ls command. Usage: ls"); return; @@ -1146,7 +1161,12 @@ var Terminal = { } if (d == 0) {continue;} //Don't print current server var titleDashes = Array((d-1) * 4 + 1).join("-"); - post("" + titleDashes + ">" + s.hostname + ""); + if (Player.hasProgram(Programs.AutoLink)) { + post("" + titleDashes + "> " + s.hostname + "", false); + } else { + post("" + titleDashes + ">" + s.hostname + ""); + } + var dashes = titleDashes + "--"; //var dashes = Array(d * 2 + 1).join("-"); var c = "NO"; @@ -1156,6 +1176,17 @@ var Terminal = { post(dashes + "RAM: " + s.maxRam); post(" "); } + + var links = document.getElementsByClassName("scan-analyze-link"); + for (var i = 0; i < links.length; ++i) { + (function() { + var hostname = links[i].innerHTML.toString(); + links[i].onclick = function() { + Terminal.connectToServer(hostname); + } + }());//Immediate invocation + } + }, executeFreeCommand: function(commandArray) { @@ -1172,18 +1203,27 @@ var Terminal = { runProgram: function(programName) { //Check if you have the program on your computer. If you do, execute it, otherwise //display an error message - for (var i = 0; i < Player.getHomeComputer().programs.length; i++) { - if (Player.getHomeComputer().programs[i] == programName) { - Terminal.executeProgram(programName); - return; - } - } + var splitArgs = programName.split(" "); + var name = " "; + if (splitArgs.length > 1) { + name = splitArgs[0]; + } else { + name = programName; + } + if (Player.hasProgram(name)) { + Terminal.executeProgram(programName); + return; + } post("ERROR: No such executable on home computer (Only programs that exist on your home computer can be run)"); }, //Contains the implementations of all possible programs executeProgram: function(programName) { var s = Player.getCurrentServer(); + var splitArgs = programName.split(" "); + if (splitArgs.length > 1) { + programName = splitArgs[0]; + } switch (programName) { case Programs.NukeProgram: if (s.hasAdminRights) { @@ -1242,9 +1282,27 @@ var Terminal = { post("Opened SQL Port (1433)!"); ++s.openPortCount; } + break; + case Programs.ServerProfiler: + if (splitArgs.length != 2) { + post("Must pass a server hostname or IP as an argument for ServerProfiler.exe"); + return; + } + var serv = getServer(splitArgs[1]); + if (serv == null) { + post("Invalid server IP/hostname"); + return; + } + post(serv.hostname + ":"); + post("Server base security level: " + serv.baseDifficulty); + post("Server current security level: " + serv.hackDifficulty); + post("Server growth rate: " + serv.serverGrowth); + post("Netscript hack() execution time: " + formatNumber(scriptCalculateHackingTime(serv), 1) + "s"); + post("Netscript grow() execution time: " + formatNumber(scriptCalculateGrowTime(serv)/1000, 1) + "s"); + post("Netscript weaken() execution time: " + formatNumber(scriptCalculateWeakenTime(serv)/1000, 1) + "s"); break; default: - post("Executable not found"); + post("Invalid executable. Cannot be run"); return; } }, diff --git a/src/engine.js b/src/engine.js index 92b7cf255..8ee744759 100644 --- a/src/engine.js +++ b/src/engine.js @@ -938,47 +938,7 @@ var Engine = { }); //Create Program buttons - var nukeALink = document.getElementById("create-program-nuke"); - var bruteSshALink = document.getElementById("create-program-brutessh"); - var ftpCrackALink = document.getElementById("create-program-ftpcrack"); - var relaySmtpALink = document.getElementById("create-program-relaysmtp"); - var httpWormALink = document.getElementById("create-program-httpworm"); - var sqlInjectALink = document.getElementById("create-program-sqlinject"); - var deepscanv1ALink = document.getElementById("create-program-deepscanv1"); - var deepscanv2ALink = document.getElementById("create-program-deepscanv2"); - - 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; - }); + initCreateProgramButtons(); //Message at the top of terminal postNetburnerText();