mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 01:33:54 +01:00
commit
870af53072
27
README.md
27
README.md
@ -5,31 +5,12 @@ TESTING TODO:
|
||||
|
||||
If a server has no more money available it cannot be hacked anymore
|
||||
Should work automatically...because your money gained percentage will be multiplied by 0
|
||||
When the game is loaded re-load all of the scripts in runningScripts
|
||||
- Seems to be working
|
||||
|
||||
Adjust leveling formula. Goes up way too high at first
|
||||
http://gamedev.stackexchange.com/questions/55151/rpg-logarithmic-leveling-formula
|
||||
- might be too slow now?
|
||||
|
||||
|
||||
Change Company pages to display "apply for promotion" and other stuff when you are already employed there
|
||||
|
||||
|
||||
rm command seems to work
|
||||
|
||||
|
||||
+ Traveling
|
||||
|
||||
Script logging functionality? Logs to internal "log file" (property of script itself)
|
||||
Can see log with tail.
|
||||
Should add something where if you click it in the "Active Scripts" GUI you can see the logs too
|
||||
|
||||
Seems to work fine
|
||||
|
||||
Gyms - Later..don't need for MVP
|
||||
|
||||
|
||||
Tasks TODO:
|
||||
Adding augmentations for Silhouette fac
|
||||
Factions Info page isn't formatted correctly
|
||||
@ -58,12 +39,4 @@ Private beta feedback
|
||||
Also not really a big deal, but I'm at 110% zoom on chrome and the tutorial window
|
||||
covers some of the text
|
||||
|
||||
For the last thing of the tutorial, I would just have a button like "Finish Tutorial" rather than "Next"
|
||||
|
||||
I'd put a little popup or something when you click save, so you know
|
||||
|
||||
Netscript commands:
|
||||
I just got two from the top of my head: a function to get the current cash on the server, and a function to know how much a hack would take
|
||||
Like, if I want to grow each time I take 5000$ from the server, that would be practical
|
||||
|
||||
Now, only other suggestion before sleep would be to be able to buy multiple Hacknet upgrades in one click
|
@ -23,11 +23,11 @@
|
||||
#script-editor-container {
|
||||
position: fixed;
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
width: 75%;
|
||||
width: 99%;
|
||||
color: #66ff33;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#script-editor-filename-tag {
|
||||
@ -36,14 +36,12 @@
|
||||
float: left;
|
||||
}
|
||||
|
||||
#script-editor-save-and-close-button {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#script-editor-save-and-close-button,
|
||||
#script-editor-netscript-doc-button {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
margin-right: 25%;
|
||||
}
|
||||
|
||||
#script-editor-netscript-doc-warning {
|
||||
@ -58,9 +56,9 @@
|
||||
float: left;
|
||||
resize: none;
|
||||
color: #66ff33;
|
||||
width: 100%;
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
width: 75%;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
|
||||
border: 2px solid white;
|
||||
-webkit-box-shadow:
|
||||
@ -81,10 +79,10 @@
|
||||
|
||||
#script-editor-text {
|
||||
color: #66ff33;
|
||||
width: 100%;
|
||||
width: 75%;
|
||||
height: 100%;
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
|
||||
border: 2px solid white;
|
||||
-webkit-box-shadow:
|
||||
|
@ -165,7 +165,7 @@ tr:focus {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Flashing button */
|
||||
/* Flashing button (Red) */
|
||||
@-webkit-keyframes glowing {
|
||||
0% { background-color: #B20000; -webkit-box-shadow: 0 0 3px #B20000; }
|
||||
50% { background-color: #FF0000; -webkit-box-shadow: 0 0 40px #FF0000; }
|
||||
@ -195,4 +195,30 @@ tr:focus {
|
||||
-moz-animation: glowing 1500ms infinite;
|
||||
-o-animation: glowing 1500ms infinite;
|
||||
animation: glowing 1500ms infinite;
|
||||
}
|
||||
}
|
||||
|
||||
/* Status text */
|
||||
@-webkit-keyframes status-text{
|
||||
from{
|
||||
opacity:1;
|
||||
top:0px;
|
||||
}
|
||||
to{
|
||||
opacity:0;
|
||||
top:0px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-text{
|
||||
display:inline;
|
||||
position:fixed;
|
||||
top:0px;
|
||||
-webkit-animation:status-text 3s 1;
|
||||
}
|
||||
|
||||
#status-text {
|
||||
font-size: 20px;
|
||||
color: #FFFFFF;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
10
index.html
10
index.html
@ -112,6 +112,10 @@
|
||||
<li class="delete-game-tab">
|
||||
<a href="#" id="delete-game-link"> Delete Game </a>
|
||||
</li>
|
||||
|
||||
<li class="debug-delete-scripts-tab">
|
||||
<a href="#" id="debug-delete-scripts-link"> (DEBUG) Delete Active Scripts </a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -148,6 +152,7 @@
|
||||
<br>
|
||||
<br><br>
|
||||
<textarea id="script-editor-text" tabindex="2" autofocus> </textarea>
|
||||
<p> <br><br> </p>
|
||||
</div>
|
||||
|
||||
<!-- Active scripts info page -->
|
||||
@ -693,5 +698,10 @@
|
||||
<span id="interactive-tutorial-back"> Back </span>
|
||||
</div>
|
||||
|
||||
<!-- Status text -->
|
||||
<div id="status-text-container">
|
||||
<p id="status-text"> </p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -760,7 +760,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(HacknetNodeNICUpload);
|
||||
|
||||
var HacknetNodeKernelDNI = new Augmentation(AugmentationNames.HacknetNodeKernelDNI);
|
||||
HacknetNodeKernelDNI.setRequirements(4000, 90000000);
|
||||
HacknetNodeKernelDNI.setRequirements(4000, 12000000);
|
||||
HacknetNodeKernelDNI.setInfo("Installs a Direct-Neural Interface jack into the arm that is capable of connecting to a " +
|
||||
"Hacknet Node. This lets the user access and manipulate the Node's kernel using the mind's " +
|
||||
"electrochemical signals.<br><br>" +
|
||||
|
@ -1,5 +1,5 @@
|
||||
CONSTANTS = {
|
||||
Version: "0.6",
|
||||
Version: "0.7",
|
||||
|
||||
//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
|
||||
@ -10,9 +10,9 @@ CONSTANTS = {
|
||||
CorpFactionRepRequirement: 250000,
|
||||
|
||||
/* Base costs */
|
||||
BaseCostFor1GBOfRamHome: 50000,
|
||||
BaseCostFor1GBOfRamServer: 40000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamHacknetNode: 25000,
|
||||
BaseCostFor1GBOfRamHome: 40000,
|
||||
BaseCostFor1GBOfRamServer: 35000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamHacknetNode: 30000,
|
||||
|
||||
BaseCostForHacknetNode: 1000,
|
||||
BaseCostForHacknetNodeCore: 1000000,
|
||||
@ -34,17 +34,21 @@ CONSTANTS = {
|
||||
CodeInstructionRunTime: 1500,
|
||||
|
||||
//RAM Costs for differenc commands
|
||||
ScriptWhileRamCost: 0.4,
|
||||
ScriptForRamCost: 0.4,
|
||||
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,
|
||||
ScriptWhileRamCost: 0.4,
|
||||
ScriptForRamCost: 0.4,
|
||||
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,
|
||||
ScriptRunRamCost: 0.75,
|
||||
ScriptGetHackingLevelRamCost: 0.1,
|
||||
ScriptGetServerMoneyRamCost: 0.1,
|
||||
ScriptOperatorRamCost: 0.01,
|
||||
|
||||
//Server growth rate
|
||||
ServerGrowthRate: 1.00075,
|
||||
@ -195,13 +199,18 @@ CONSTANTS = {
|
||||
"section of this 'Tutorial' page. <br><br>Running a script requires RAM. The more complex a script is, the more RAM " +
|
||||
"it requires to run. Scripts can be run on any server you have root access to. <br><br>" +
|
||||
"Here are some Terminal commands that are useful when working with scripts: <br>" +
|
||||
"free - Shows the current server's RAM usage <br>" +
|
||||
"free - Shows the current server's RAM usage and availability <br>" +
|
||||
"kill [script] - Stops a script that is running <br>" +
|
||||
"mem [script] - Check how much RAM a script requires to run<br>" +
|
||||
"nano [script] - Create/Edit a script <br>" +
|
||||
"ps - Displays all scripts that are actively running on the current server<br>" +
|
||||
"run [script] - Run a script <br>" +
|
||||
"tail [script] - Displays a script's logs<br>" +
|
||||
"top - Displays all active scripts and their RAM usage <br><br>",
|
||||
"top - Displays all active scripts and their RAM usage <br><br>" +
|
||||
"<strong>Note that because of the way the Netscript interpreter is implemented, " +
|
||||
"whenever you reload or re-open the game all of the scripts that you are running will " +
|
||||
"start running from the BEGINNING of the code. The game does not keep track of where exactly " +
|
||||
"the execution of a script is when it saves/loads. </strong><br><br>",
|
||||
TutorialNetscriptText: "Netscript is a very simple programming language implemented for this game. The language has " +
|
||||
"your basic programming constructs and several built-in commands that are used to hack. <br><br>" +
|
||||
"<u><h1> Variables and data types </h1></u><br>" +
|
||||
@ -247,6 +256,13 @@ CONSTANTS = {
|
||||
"<i>relaysmtp(hostname/ip)</i><br>Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer <br> Example: relaysmtp('foodnstuff');<br><br>" +
|
||||
"<i>httpworm(hostname/ip)</i><br>Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer <br> Example: httpworm('foodnstuff');<br><br>" +
|
||||
"<i>sqlinject(hostname/ip)</i><br>Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer <br> Example: sqlinject('foodnstuff');<br><br>" +
|
||||
"<i>run(script)</i> <br> Run a script as a separate process. The argument that is passed in is the name of the script as a string. This function can only " +
|
||||
"be used to run scripts located on the same server. Returns true if the script is successfully started, and false otherwise. Requires a significant amount " +
|
||||
"of RAM to run this command.<br>Example: run('hack-foodnstuff.script'); <br> The example above will try and launch the 'hack-foodnstuff.script' script on " +
|
||||
"the current server, if it exists. <br><br>" +
|
||||
"<i>getHackingLevel() </i><br> Returns the Player's current hacking level <br><br> " +
|
||||
"<i>getServerMoneyAvailable(hostname/ip)</i><br> Returns the amount of money available on a server. The argument passed in must be a string with either the " +
|
||||
"hostname or IP of the target server. <br> Example: getServerMoneyAvailable('foodnstuff');<br><br>" +
|
||||
"<u><h1>While loops </h1></u><br>" +
|
||||
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
|
||||
"<i>while (<i>[cond]</i>) {<br> <i>[code]</i><br>}</i><br><br>" +
|
||||
@ -257,14 +273,28 @@ CONSTANTS = {
|
||||
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
|
||||
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " +
|
||||
"<u><h1>For loops</h1></u><br>" +
|
||||
"A for loop is another control flow statement that allows code to by repeated by iterations. The structure is: <br><br> " +
|
||||
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " +
|
||||
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br> <i>code</i> <br> }; </i><br><br>" +
|
||||
"The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " +
|
||||
"as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " +
|
||||
"of the for loop. The following example shows code that will do the same thing as the while loop example above, " +
|
||||
"except using a for loop instead: <br><br>" +
|
||||
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
|
||||
" using a for loop: <br><br>" +
|
||||
"<i>for (i = 0; i < 10; i = i+1) { <br> hack('foodnstuff');<br>}; </i><br><br>" +
|
||||
"<u><h1> If statements </h1></u>",
|
||||
"<u><h1> If statements </h1></u><br>" +
|
||||
"If/Elif/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
|
||||
"<i>if (condition1) {<br> code1<br>} elif (condition2) {<br> code2<br>} else {<br>" +
|
||||
" code3<br>}</i><br><br>" +
|
||||
"In the code above, first <i>condition1</i> will be checked. If this condition is true, then <i>code1</i> will execute and the " +
|
||||
"rest of the if/elif/else statement will be skipped. If <i>condition1</i> is NOT true, then the code will then go on to check " +
|
||||
"<i>condition2</i>. If <i>condition2</i> is true, then <i>code2</i> will be executed, and the rest of the if/elif/else statement " +
|
||||
"will be skipped. If none of the conditions are true, then the code within the else block (<i>code3</i>) will be executed. " +
|
||||
"Note that a conditional statement can have any number of elif statements. <br><br>" +
|
||||
"Example: <br><br>" +
|
||||
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br> hack('foodnstuff');<br>" +
|
||||
"} else {<br> grow('foodnstuff');<br>};<br><br>" +
|
||||
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
|
||||
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
|
||||
"then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>",
|
||||
|
||||
TutorialTravelingText:"There are six major cities in the world that you are able to travel to: <br><br> " +
|
||||
" Aevum<br>" +
|
||||
@ -292,8 +322,10 @@ CONSTANTS = {
|
||||
"your stats. Different positions value different stats. When you are working, you are unable to perform any " +
|
||||
"other actions such as using your terminal or visiting other locations (However, note that any scripts you have " +
|
||||
"running on servers will continue to run as you work!). It is possible to cancel your work shift before the " +
|
||||
"8 hours is up, but doing so will result in you gaining only half of all of the money, experience, and reputation " +
|
||||
"that you had earned up to that point. <br><br>" +
|
||||
"8 hours is up. However, if you have a full-time job, then cancelling a shift early will result in you gaining " +
|
||||
"only half of all of the money, experience, and reputation " +
|
||||
"that you had earned up to that point. There are also part-time/consultant jobs available where you will not " +
|
||||
" be penalized if you cancel a work shift early. However, these positions pay less than full-time positions.<br><br>" +
|
||||
"As you continue to work at a company, you will gain more and more reputation at that company. When your stats " +
|
||||
"and reputation are high enough, you can get a promotion. You can apply for a promotion on the company page, just like " +
|
||||
"you applied for the job originally. Higher positions at a company provide better salaries and stat gains.",
|
||||
|
@ -16,12 +16,13 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
|
||||
//How much extra $/s is gained per level
|
||||
var gainPerLevel = CONSTANTS.HacknetNodeMoneyGainPerLevel;
|
||||
|
||||
//Each CPU core doubles the speed. Every 1GB of ram adds 20% increase
|
||||
//Each CPU core doubles the speed. Every 1GB of ram adds 15% increase
|
||||
this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
|
||||
Math.pow(1.2, this.ram-1) *
|
||||
Math.pow(1.15, this.ram-1) *
|
||||
this.numCores * Player.hacknet_node_money_mult;
|
||||
if (isNaN(this.moneyGainRatePerSecond)) {
|
||||
throw new Error("Money gain rate calculated for Hacknet Node is NaN");
|
||||
this.moneyGainRatePerSecond = 0;
|
||||
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer");
|
||||
}
|
||||
|
||||
updateTotalHacknetProduction();
|
||||
@ -175,7 +176,7 @@ updateHacknetNodesContent = function() {
|
||||
//Update player's money
|
||||
var moneyElem = document.getElementById("hacknet-nodes-money");
|
||||
moneyElem.innerHTML = "Money: $" + formatNumber(Player.money, 2) + "<br>" +
|
||||
"Total production from all Hacknet Nodes: $" + formatNumber(Player.totalHacknetNodeProduction, 2);
|
||||
"Total production from all Hacknet Nodes: $" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second";
|
||||
|
||||
//Update information in each owned hacknet node
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
|
@ -296,7 +296,7 @@ displayLocationContent = function() {
|
||||
travelToVolhaven.style.display = "block";
|
||||
break;
|
||||
|
||||
case Locations.AevumSummitUniveristy:
|
||||
case Locations.AevumSummitUniversity:
|
||||
var costMult = 4, expMult = 3;
|
||||
displayUniversityLocationContent(costMult);
|
||||
setUniversityLocationButtons(costMult, expMult);
|
||||
|
@ -209,6 +209,8 @@ function evaluate(exp, workerScript) {
|
||||
* relaysmtp(server)
|
||||
* httpworm(server)
|
||||
* sqlinject(server)
|
||||
* getHackingLevel()
|
||||
* run(script))
|
||||
*/
|
||||
case "call":
|
||||
//Define only valid function calls here, like hack() and stuff
|
||||
@ -223,6 +225,7 @@ function evaluate(exp, workerScript) {
|
||||
if (exp.func.value == "hack") {
|
||||
if (exp.args.length != 1) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Hack() call has incorrect number of arguments. Takes 1 argument");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
|
||||
@ -304,6 +307,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) {
|
||||
@ -325,6 +329,7 @@ function evaluate(exp, workerScript) {
|
||||
} else if (exp.func.value == "print") {
|
||||
if (exp.args.length != 1) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|print() call has incorrect number of arguments. Takes 1 argument");
|
||||
return;
|
||||
}
|
||||
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
@ -347,10 +352,11 @@ function evaluate(exp, workerScript) {
|
||||
} else if (exp.func.value == "grow") {
|
||||
if (exp.args.length != 1) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|grow() call has incorrect number of arguments. Takes 1 argument");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into grow() command");
|
||||
@ -388,9 +394,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into nuke() command");
|
||||
@ -433,9 +441,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into brutessh() command");
|
||||
@ -474,9 +484,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into ftpcrack() command");
|
||||
@ -515,9 +527,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command");
|
||||
@ -556,9 +570,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into relaysmtp() command");
|
||||
@ -597,9 +613,11 @@ function evaluate(exp, workerScript) {
|
||||
} 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");
|
||||
return;
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into sqlinject() command");
|
||||
@ -635,9 +653,63 @@ function evaluate(exp, workerScript) {
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "run") {
|
||||
if (exp.args.length != 1) {
|
||||
reject("|"+workerScript.serverIp+"|"+workerScript.name+"|run() call has incorrect number of arguments. Takes 1 argument");
|
||||
return;
|
||||
}
|
||||
var scriptNamePromise = evaluate(exp.args[0], workerScript);
|
||||
scriptNamePromise.then(function(scriptname) {
|
||||
var serverIp = workerScript.serverIp;
|
||||
var scriptServer = AllServers[serverIp];
|
||||
if (scriptServer == null) {
|
||||
reject("|"+workerScript.serverIp+"|"+workerScript.name+"|Could not find server. This is a bug in the game. Report to game dev");
|
||||
return;
|
||||
}
|
||||
|
||||
var runScriptPromise = runScriptFromScript(scriptServer, scriptname, workerScript);
|
||||
runScriptPromise.then(function(res) {
|
||||
resolve(res);
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "getHackingLevel") {
|
||||
if (exp.args.length != 0) {
|
||||
reject("|"+workerScript.serverIp+"|"+workerScript.name+"|getHackingLevel() call has incorrect number of arguments. Takes 0 arguments");
|
||||
return;
|
||||
}
|
||||
setTimeout(function() {
|
||||
Player.updateSkillLevels();
|
||||
workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill);
|
||||
resolve(Player.hacking_skill);
|
||||
}, CONSTANTS.CodeInstructionRunTime);
|
||||
} else if (exp.func.value == "getServerMoneyAvailable") {
|
||||
if (exp.args.length != 1) {
|
||||
reject("|"+workerScript.serverIp+"|"+workerScript.name+"|getServerMoneyAvailable() call has incorrect number of arguments. Takes 1 arguments");
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
ipPromise.then(function(ip) {
|
||||
setTimeout(function() {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Invalid IP or hostname passed into getServerMoneyAvailable() command");
|
||||
workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
|
||||
return;
|
||||
}
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable() returned " + server.moneyAvailable);
|
||||
resolve(server.moneyAvailable);
|
||||
}, CONSTANTS.CodeInstructionRunTime);
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
}
|
||||
}, CONSTANTS.CodeInstructionRunTime);
|
||||
});
|
||||
reject("|" + workerScript.serverIp + "|" + workerScript.name + "|Unrecognized function call");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -868,7 +940,54 @@ function apply_op(op, a, b) {
|
||||
case "!=": return a !== b;
|
||||
}
|
||||
throw new Error("Can't apply operator " + op);
|
||||
}
|
||||
}
|
||||
|
||||
//Run a script from inside a script using run() command
|
||||
function runScriptFromScript(server, scriptname, workerScript) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {reject(workerScript);}
|
||||
setTimeout(function() {
|
||||
//Check if the script is already running
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i] == scriptname) {
|
||||
workerScript.scriptRef.log(scriptname + " is already running on " + server.hostname);
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Check if the script exists and if it does run it
|
||||
for (var i = 0; i < server.scripts.length; ++i) {
|
||||
if (server.scripts[i].filename == scriptname) {
|
||||
//Check for admin rights and that there is enough RAM availble to run
|
||||
var ramUsage = server.scripts[i].ramUsage;
|
||||
var ramAvailable = server.maxRam - server.ramUsed;
|
||||
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot run script " + scriptname + " because you do not have root access!");
|
||||
resolve(false);
|
||||
return;
|
||||
} else if (ramUsage > ramAvailable){
|
||||
workerScript.scriptRef.log("Cannot run script " + scriptname + " because there is not enough available RAM!");
|
||||
resolve(false);
|
||||
return;
|
||||
} else {
|
||||
//Able to run script
|
||||
workerScript.scriptRef.log("Running script: " + scriptname + ". May take a few seconds to start up...");
|
||||
var script = server.scripts[i];
|
||||
server.runningScripts.push(script.filename); //Push onto runningScripts
|
||||
addWorkerScript(script, server);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
workerScript.scriptRef.log("Could not find script " + scriptname + " on " + server.hostname);
|
||||
resolve(false);
|
||||
}, CONSTANTS.CodeInstructionRunTime);
|
||||
});
|
||||
}
|
||||
|
||||
function isScriptErrorMessage(msg) {
|
||||
splitMsg = msg.split("|");
|
||||
@ -913,4 +1032,4 @@ function scriptCalculatePercentMoneyHacked(server) {
|
||||
if (percentMoneyHacked < 0) {return 0;}
|
||||
if (percentMoneyHacked > 1) {return 1;}
|
||||
return percentMoneyHacked;
|
||||
}
|
||||
}
|
@ -109,16 +109,13 @@ function Parser(input) {
|
||||
* else: {"type": "var", "value": "foo"}
|
||||
*/
|
||||
function parse_if() {
|
||||
console.log("Parsing if token");
|
||||
checkKeywordAndSkip("if");
|
||||
|
||||
//Conditional
|
||||
var cond = parse_expression();
|
||||
console.log("cond: " + cond);
|
||||
|
||||
//Body
|
||||
var then = parse_expression();
|
||||
console.log("then: " + then);
|
||||
var ret = {
|
||||
type: "if",
|
||||
cond: [],
|
||||
|
@ -31,6 +31,7 @@ function runScriptsLoop() {
|
||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
||||
try {
|
||||
var ast = Parser(Tokenizer(InputStream(workerScripts[i].code)));
|
||||
//console.log(ast);
|
||||
} catch (e) {
|
||||
dialogBoxCreate("Syntax ERROR in " + workerScripts[i].name + ":", e, "", "");
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
|
@ -168,6 +168,7 @@ function PlayerObject() {
|
||||
|
||||
//Used to store the last update time.
|
||||
this.lastUpdate = new Date().getTime();
|
||||
this.totalPlaytime = 0;
|
||||
};
|
||||
|
||||
PlayerObject.prototype.init = function() {
|
||||
@ -584,7 +585,7 @@ PlayerObject.prototype.finishWorkPartTime = function() {
|
||||
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" +
|
||||
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" +
|
||||
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>";
|
||||
txt = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ".<br><br> " + txt;
|
||||
txt = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br> " + txt;
|
||||
dialogBoxCreate(txt);
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
|
@ -22,6 +22,9 @@ BitburnerSaveObject.prototype.saveGame = function() {
|
||||
|
||||
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
|
||||
window.localStorage.setItem("bitburnerSave", saveString);
|
||||
|
||||
console.log("Game saved!");
|
||||
Engine.createStatusText("Game saved!");
|
||||
}
|
||||
|
||||
loadGame = function(saveObj) {
|
||||
@ -45,6 +48,7 @@ BitburnerSaveObject.prototype.deleteGame = function() {
|
||||
if (window.localStorage.getItem("bitburnerSave")) {
|
||||
window.localStorage.removeItem("bitburnerSave");
|
||||
}
|
||||
Engine.createStatusText("Game deleted!");
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,11 +96,6 @@ function Script() {
|
||||
this.logs = []; //Script logging. Array of strings, with each element being a log entry
|
||||
|
||||
/* Properties to calculate offline progress. Only applies for infinitely looping scripts */
|
||||
|
||||
//Number of instructions ("lines") in the code. Any call ending in a ;
|
||||
//is considered one instruction. Used to calculate ramUsage
|
||||
this.numInstructions = 0;
|
||||
|
||||
//Stats to display on the Scripts menu, and used to determine offline progress
|
||||
this.offlineRunningTime = 0.01; //Seconds
|
||||
this.offlineMoneyMade = 0;
|
||||
@ -125,8 +120,7 @@ Script.prototype.saveScript = function() {
|
||||
//Server
|
||||
this.server = Player.currentServer;
|
||||
|
||||
//Calculate/update number of instructions, ram usage, execution time, etc.
|
||||
this.updateNumInstructions();
|
||||
//Calculate/update ram usage, execution time, etc.
|
||||
this.updateRamUsage();
|
||||
|
||||
//Clear the stats when the script is updated
|
||||
@ -147,12 +141,7 @@ Script.prototype.reset = function() {
|
||||
this.onlineRunningTime = 0.01; //Seconds
|
||||
this.onlineMoneyMade = 0;
|
||||
this.onlineExpGained = 0;
|
||||
}
|
||||
|
||||
//Calculates the number of instructions, which is just determined by number of semicolons
|
||||
Script.prototype.updateNumInstructions = function() {
|
||||
var numSemicolons = this.code.split(";").length - 1;
|
||||
this.numInstructions = numSemicolons;
|
||||
this.logs = [];
|
||||
}
|
||||
|
||||
//Updates how much RAM the script uses when it is running.
|
||||
@ -172,6 +161,10 @@ Script.prototype.updateRamUsage = function() {
|
||||
var relaysmtpCount = numOccurrences(codeCopy, "relaysmtp(");
|
||||
var httpwormCount = numOccurrences(codeCopy, "httpworm(");
|
||||
var sqlinjectCount = numOccurrences(codeCopy, "sqlinject(");
|
||||
var runCount = numOccurrences(codeCopy, "run(");
|
||||
var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel(");
|
||||
var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable(");
|
||||
var numOperators = numNetscriptOperators(codeCopy);
|
||||
|
||||
this.ramUsage = baseRam +
|
||||
((whileCount * CONSTANTS.ScriptWhileRamCost) +
|
||||
@ -184,8 +177,15 @@ Script.prototype.updateRamUsage = function() {
|
||||
(ftpcrackCount * CONSTANTS.ScriptFtpcrackRamCost) +
|
||||
(relaysmtpCount * CONSTANTS.ScriptRelaysmtpRamCost) +
|
||||
(httpwormCount * CONSTANTS.ScriptHttpwormRamCost) +
|
||||
(sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost));
|
||||
(sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost) +
|
||||
(runCount * CONSTANTS.ScriptRunRamCost) +
|
||||
(getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) +
|
||||
(getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) +
|
||||
(numOperators * CONSTANTS.ScriptOperatorRamCost));
|
||||
console.log("ram usage: " + this.ramUsage);
|
||||
if (isNaN(this.ramUsage)) {
|
||||
dialogBoxCreate("ERROR in calculating ram usage. This is a bug, please report to game develoepr");
|
||||
}
|
||||
}
|
||||
|
||||
Script.prototype.log = function(txt) {
|
||||
@ -304,7 +304,6 @@ function AllServersToMoneyMap() {
|
||||
}
|
||||
|
||||
AllServersToMoneyMap.prototype.printConsole = function() {
|
||||
console.log("Printing AllServersToMoneyMap");
|
||||
for (var ip in this) {
|
||||
if (this.hasOwnProperty(ip)) {
|
||||
var serv = AllServers[ip];
|
||||
@ -312,7 +311,6 @@ AllServersToMoneyMap.prototype.printConsole = function() {
|
||||
console.log("Warning null server encountered with ip: " + ip);
|
||||
continue;
|
||||
}
|
||||
console.log(ip + "(" + serv.hostname + "): " + this[ip]);
|
||||
}
|
||||
}
|
||||
}
|
@ -452,7 +452,7 @@ initForeignServers = function() {
|
||||
var HaraKiriSushiBarServer = new Server();
|
||||
HaraKiriSushiBarServer.setHackingParameters(40, 2000000, 15, 40);
|
||||
HaraKiriSushiBarServer.init(createRandomIp(), "harakiri-sushi", "HaraKiri Sushi Bar Network", true, false, false, false, 4);
|
||||
HaraKiriSushiBarServer.setPortProperties(1);
|
||||
HaraKiriSushiBarServer.setPortProperties(0);
|
||||
AddToAllServers(HaraKiriSushiBarServer);
|
||||
|
||||
var PhantasyServer = new Server();
|
||||
|
@ -273,7 +273,8 @@ var Engine = {
|
||||
'Crime money multiplier: ' + formatNumber(Player.crime_money_mult * 100, 2) + '%<br><br><br>' +
|
||||
'<b>Misc</b><br><br>' +
|
||||
'Servers owned: ' + Player.purchasedServers.length + '<br>' +
|
||||
'Hacknet Nodes owned: ' + Player.hacknetNodes.length + '<br><br> ').replace( / /g, " " );
|
||||
'Hacknet Nodes owned: ' + Player.hacknetNodes.length + '<br>' +
|
||||
'Time played: ' + convertTimeMsToTimeElapsedString(Player.totalPlaytime) + '<br><br><br>').replace( / /g, " " );
|
||||
|
||||
},
|
||||
|
||||
@ -524,6 +525,11 @@ var Engine = {
|
||||
},
|
||||
|
||||
updateGame: function(numCycles = 1) {
|
||||
//Update total playtime
|
||||
var time = numCycles * Engine._idleSpeed;
|
||||
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
||||
Player.totalPlaytime += time;
|
||||
|
||||
//Start Manual hack
|
||||
if (Player.startAction == true) {
|
||||
Engine._totalActionTime = Player.actionTime;
|
||||
@ -685,6 +691,23 @@ var Engine = {
|
||||
}
|
||||
},
|
||||
|
||||
_prevTimeout: null,
|
||||
createStatusText: function(txt) {
|
||||
if (Engine._prevTimeout != null) {
|
||||
clearTimeout(Engine._prevTimeout);
|
||||
Engine._prevTimeout = null;
|
||||
}
|
||||
var statusText = document.getElementById("status-text")
|
||||
statusText.style.display = "inline-block";
|
||||
statusText.setAttribute("class", "status-text");
|
||||
statusText.innerHTML = txt;
|
||||
Engine._prevTimeout = setTimeout(function() {
|
||||
statusText.style.display = "none";
|
||||
statusText.removeAttribute("class");
|
||||
statusText.innerHTML = "";
|
||||
}, 3000);
|
||||
},
|
||||
|
||||
load: function() {
|
||||
//Load game from save or create new game
|
||||
if (loadGame(saveObject)) {
|
||||
@ -723,6 +746,11 @@ var Engine = {
|
||||
|
||||
//Passive faction rep gain offline
|
||||
processPassiveFactionRepGain(numCyclesOffline);
|
||||
|
||||
//Update total playtime
|
||||
var time = numCyclesOffline * Engine._idleSpeed;
|
||||
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
||||
Player.totalPlaytime += time;
|
||||
} else {
|
||||
//No save found, start new game
|
||||
console.log("Initializing new game");
|
||||
@ -987,7 +1015,7 @@ var Engine = {
|
||||
if (Player.workType == CONSTANTS.WorkTypeFaction) {
|
||||
var fac = Factions[Player.currentWorkFactionName];
|
||||
Player.finishFactionWork(true, fac);
|
||||
} else if (Player.WorkType == CONSTANTS.WorkTypeCreateProgram) {
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
|
||||
Player.finishCreateProgramWork(true, Player.createProgramName);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
|
||||
Player.finishClass();
|
||||
@ -1001,6 +1029,12 @@ var Engine = {
|
||||
});
|
||||
Engine.loadWorkInProgressContent();
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
document.getElementById("debug-delete-scripts-link").addEventListener("click", function() {
|
||||
Player.getHomeComputer().runningScripts = [];
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
start: function() {
|
||||
|
@ -34,10 +34,9 @@ purchaseRamForHomeBoxCreate = function() {
|
||||
var numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Base cost of RAM is 50k per 1GB...but lets have this increase by some percentage
|
||||
//each time the ram has been upgraded
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.32, numUpgrades);
|
||||
var mult = Math.pow(1.33, numUpgrades);
|
||||
cost = cost * mult;
|
||||
|
||||
purchaseRamForHomeBoxSetText("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
|
@ -32,6 +32,9 @@ function convertTimeMsToTimeElapsedString(time) {
|
||||
//Convert ms to seconds, since we only have second-level precision
|
||||
time = Math.floor(time / 1000);
|
||||
|
||||
var days = Math.floor(time / 86400);
|
||||
time %= 86400;
|
||||
|
||||
var hours = Math.floor(time / 3600);
|
||||
time %= 3600;
|
||||
|
||||
@ -40,7 +43,12 @@ function convertTimeMsToTimeElapsedString(time) {
|
||||
|
||||
var seconds = time;
|
||||
|
||||
return hours + " hours " + minutes + " minutes " + seconds + " seconds";
|
||||
var res = "";
|
||||
if (days) {res += days + " days";}
|
||||
if (hours) {res += hours + " hours ";}
|
||||
if (minutes) {res += minutes + " minutes ";}
|
||||
if (seconds) {res += seconds + " seconds ";}
|
||||
return res;
|
||||
}
|
||||
|
||||
//Finds the longest common starting substring in a set of strings
|
||||
@ -73,7 +81,7 @@ function formatNumber(num, numFractionDigits) {
|
||||
});
|
||||
}
|
||||
|
||||
//Counters the number of times a substring occurs in a string
|
||||
//Count the number of times a substring occurs in a string
|
||||
function numOccurrences(string, subString) {
|
||||
string += "";
|
||||
subString += "";
|
||||
@ -89,4 +97,27 @@ function numOccurrences(string, subString) {
|
||||
} else break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
//Counters the number of Netscript operators in a string
|
||||
function numNetscriptOperators(string) {
|
||||
var total = 0;
|
||||
total += numOccurrences(string, "+");
|
||||
total += numOccurrences(string, "-");
|
||||
total += numOccurrences(string, "*");
|
||||
total += numOccurrences(string, "/");
|
||||
total += numOccurrences(string, "%");
|
||||
total += numOccurrences(string, "&&");
|
||||
total += numOccurrences(string, "||");
|
||||
total += numOccurrences(string, "<");
|
||||
total += numOccurrences(string, ">");
|
||||
total += numOccurrences(string, "<=");
|
||||
total += numOccurrences(string, ">=");
|
||||
total += numOccurrences(string, "==");
|
||||
total += numOccurrences(string, "!=");
|
||||
if (isNaN(total)) {
|
||||
dialogBoxCreate("ERROR in counting number of operators in script. This is a bug, please report to game developer");
|
||||
total = 0;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user