mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 06:32:26 +01:00
commit
9581798bcf
@ -26,7 +26,7 @@
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
width: 99%;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
margin-right: 0px;
|
||||
padding-left: 6px;
|
||||
width: 100%;
|
||||
border: 2px solid white;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
}
|
||||
|
||||
#script-editor-filename-tag {
|
||||
@ -71,6 +71,7 @@
|
||||
padding-bottom: 0px;
|
||||
float:center;
|
||||
background-color: #555;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#script-editor-filename {
|
||||
@ -83,7 +84,7 @@ background-color: #555;
|
||||
|
||||
padding: 2px;
|
||||
|
||||
border: 2px solid white;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
-webkit-box-shadow:
|
||||
inset 0 0 8px rgba(0,0,0,0.1),
|
||||
0 0 16px rgba(0,0,0,0.1);
|
||||
@ -101,7 +102,7 @@ background-color: #555;
|
||||
}
|
||||
|
||||
#script-editor-text {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
height: 80%;
|
||||
width: 100%;
|
||||
margin-left: 6px;
|
||||
@ -110,7 +111,7 @@ background-color: #555;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
|
||||
border: 2px solid white;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
-webkit-box-shadow:
|
||||
inset 0 0 8px rgba(0,0,0,0.1),
|
||||
0 0 16px rgba(0,0,0,0.1);
|
||||
@ -198,7 +199,7 @@ background-color: #555;
|
||||
|
||||
.active-scripts-script-header {
|
||||
background-color: #555;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
padding: 4px;
|
||||
padding-left: 10px;
|
||||
cursor: pointer;
|
||||
@ -220,7 +221,7 @@ background-color: #555;
|
||||
.active-scripts-script-header:after {
|
||||
content: '\02795'; /* "plus" sign (+) */
|
||||
font-size: 13px;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
}
|
||||
@ -228,7 +229,7 @@ background-color: #555;
|
||||
.active-scripts-script-header.active:after {
|
||||
content: "\2796"; /* "minus" sign (-) */
|
||||
font-size: 13px;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
}
|
||||
@ -291,7 +292,7 @@ background-color: #555;
|
||||
margin: 6px;
|
||||
padding: 6px;
|
||||
width: 85%;
|
||||
border: 2px solid white;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
-webkit-box-shadow:
|
||||
inset 0 0 8px rgba(0,0,0,0.1),
|
||||
0 0 16px rgba(0,0,0,0.1);
|
||||
@ -375,7 +376,7 @@ background-color: #555;
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
width: 99%;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@ -425,7 +426,7 @@ background-color: #555;
|
||||
padding: 6px;
|
||||
margin: 6px;
|
||||
display: inline-block;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#faction-donate-amount-txt {
|
||||
@ -450,7 +451,7 @@ div.faction-clear {
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
width: 99%;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#faction-augmentations-container p,
|
||||
@ -480,7 +481,7 @@ div.faction-clear {
|
||||
height: 100%;
|
||||
margin-left: 10%;
|
||||
width: 99%;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
@ -492,7 +493,7 @@ div.faction-clear {
|
||||
#augmentations-list h2,
|
||||
#augmentations-list p {
|
||||
margin: 4px;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
padding: 8px;
|
||||
width: 70%;
|
||||
background-color: #333;
|
||||
@ -522,7 +523,7 @@ div.faction-clear {
|
||||
|
||||
/* Location */
|
||||
#location-container {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
position: fixed;
|
||||
padding: 6px;
|
||||
height: 100%;
|
||||
|
@ -8,11 +8,13 @@
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: black; /* Fallback color */
|
||||
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
||||
/*background-color: black; /* Fallback color */
|
||||
/*background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
||||
background-color: rbga(var(--my-background-color), 0.4);
|
||||
}
|
||||
|
||||
.dialog-box-container {
|
||||
.dialog-box-container,
|
||||
#log-box-container {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
@ -23,18 +25,19 @@
|
||||
left: 50%;
|
||||
margin: -10% 0 0 -25%;
|
||||
overflow: auto;
|
||||
background-color: black;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
border: 5px solid #FFFFFF;
|
||||
background-color: var(--my-background-color);
|
||||
border: 5px solid var(--my-highlight-color);
|
||||
}
|
||||
|
||||
.dialog-box-content {
|
||||
.dialog-box-content,
|
||||
#log-box-content {
|
||||
z-index: 2;
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.dialog-box-close-button {
|
||||
.dialog-box-close-button,
|
||||
#log-box-close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
@ -48,7 +51,9 @@
|
||||
}
|
||||
|
||||
.dialog-box-close-button:hover,
|
||||
.dialog-box-close-button:focus {
|
||||
.dialog-box-close-button:focus,
|
||||
#log-box-close:hover,
|
||||
#log-box-close:focus {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
@ -60,12 +65,12 @@
|
||||
}
|
||||
|
||||
#purchase-server-box-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 12px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);;
|
||||
width: 80%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#purchase-server-box-input {
|
||||
@ -85,14 +90,14 @@
|
||||
|
||||
#purchase-server-box-confirm:hover,
|
||||
#purchase-server-box-confirm:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#purchase-server-box-cancel:hover,
|
||||
#purchase-server-box-cancel:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -103,12 +108,12 @@
|
||||
}
|
||||
|
||||
#purchase-ram-for-home-box-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 12px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);
|
||||
width: 50%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#purchase-ram-for-home-box-confirm,
|
||||
@ -124,14 +129,14 @@
|
||||
|
||||
#purchase-ram-for-home-box-confirm:hover,
|
||||
#purchase-ram-for-home-box-confirm:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#purchase-ram-for-home-box-cancel:hover,
|
||||
#purchase-ram-for-home-box-cancel:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -142,12 +147,12 @@
|
||||
}
|
||||
|
||||
#purchase-augmentation-box-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 8px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);;
|
||||
width: 80%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#purchase-augmentation-box-confirm,
|
||||
@ -163,14 +168,14 @@
|
||||
|
||||
#purchase-augmentation-box-confirm:hover,
|
||||
#purchase-augmentation-box-confirm:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#purchase-augmentation-box-cancel:hover,
|
||||
#purchase-augmentation-box-cancel:focus {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -181,12 +186,12 @@
|
||||
}
|
||||
|
||||
#faction-invitation-box-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 10px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);;
|
||||
width: 80%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#faction-invitation-box-warning {
|
||||
@ -225,12 +230,12 @@
|
||||
}
|
||||
|
||||
#travel-box-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 10px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);;
|
||||
width: 50%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#travel-box-text {
|
||||
@ -268,12 +273,12 @@
|
||||
}
|
||||
|
||||
#game-options-content {
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
margin: 15% auto; /* 15% from the top and centered */
|
||||
padding: 10px;
|
||||
border: 5px solid #FFFFFF;
|
||||
border: 5px solid var(--my-highlight-color);
|
||||
width: 50%; /* Could be more or less, depending on screen size */
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
#game-options-close-button {
|
||||
@ -301,3 +306,4 @@
|
||||
#import-game-file-selector {
|
||||
display:none;
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,34 @@
|
||||
/** This removes all padding and margins as well as
|
||||
setting a default font size and family for the page **/
|
||||
|
||||
|
||||
:root{
|
||||
--my-font-color: #66ff33;
|
||||
--my-background-color: #000000;
|
||||
--my-highlight-color: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
font-family: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
|
||||
background-color: #252527;
|
||||
background-color: black;
|
||||
/*background-color: #252527;*/
|
||||
background-color: var(--my-background-color);
|
||||
}
|
||||
|
||||
p {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
ul {
|
||||
@ -151,8 +160,8 @@ tr:focus {
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
width: 300px;
|
||||
background-color: black;
|
||||
border: 2px solid white;
|
||||
background-color: var(--my-background-color);
|
||||
border: 2px solid var(--my-highlight-color);;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
@ -228,6 +237,7 @@ tr:focus {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 4px;
|
||||
margin-right: 14px;
|
||||
background-color: transparent;
|
||||
z-index: 2;
|
||||
}
|
||||
@ -241,10 +251,10 @@ tr:focus {
|
||||
position: absolute; /* Stay in place */
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 175px; /* Full height */
|
||||
height: 185px; /* Full height */
|
||||
/*margin: 50% auto;*/
|
||||
padding: 5px;
|
||||
border: 2px solid #66ff33;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
width: 18%;
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: #444; /* Fallback color */
|
||||
@ -253,12 +263,13 @@ tr:focus {
|
||||
|
||||
#character-overview-text {
|
||||
padding: 4px;
|
||||
margin: 12px;
|
||||
margin: 10px;
|
||||
color: white;
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
#character-overview-save-button {
|
||||
#character-overview-save-button,
|
||||
#character-overview-options-button {
|
||||
color: #aaa;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
@ -271,8 +282,14 @@ tr:focus {
|
||||
}
|
||||
|
||||
#character-overview-save-button:hover,
|
||||
#character-overview-save-button:focus {
|
||||
#character-overview-save-button:focus,
|
||||
#character-overview-options-button:hover,
|
||||
#character-overview-options-button:focus {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#character-overview-options-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -15,11 +15,12 @@
|
||||
font-size: 16px;
|
||||
overflow: auto;
|
||||
overflow-y: scroll;
|
||||
background-color: var(--my-background-color);
|
||||
}
|
||||
|
||||
#terminal-input {
|
||||
background-color: black;
|
||||
color: #66ff33;
|
||||
background-color: var(--my-background-color);
|
||||
color: var(--my-font-color);
|
||||
transition: height 1s;
|
||||
}
|
||||
|
||||
@ -29,10 +30,10 @@
|
||||
padding: 0px !important;
|
||||
margin: 0px !important;
|
||||
border: 0px;
|
||||
background-color: black;
|
||||
background-color: var(--my-background-color);
|
||||
font-size: 16px;
|
||||
outline: none;
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#work-in-progress-container {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
position: fixed;
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
@ -8,7 +8,7 @@
|
||||
}
|
||||
|
||||
#work-in-progress-text {
|
||||
color: #66ff33;
|
||||
color: var(--my-font-color);
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
|
10
index.html
10
index.html
@ -25,6 +25,7 @@
|
||||
<script src="utils/TravelBox.js"></script>
|
||||
<script src="utils/PurchaseRamForHomeBox.js"></script>
|
||||
<script src="utils/GameOptions.js"></script>
|
||||
<script src="utils/LogBox.js"></script>
|
||||
|
||||
<!-- Netscript -->
|
||||
<script src="src/NetscriptWorker.js"></script>
|
||||
@ -645,6 +646,14 @@
|
||||
<a id="location-slums-heist" class="a-link-button tooltip"> Heist </a>
|
||||
</div>
|
||||
|
||||
<!-- Log Box -->
|
||||
<div id="log-box-container">
|
||||
<div id="log-box-content">
|
||||
<span id="log-box-close"> × </span>
|
||||
<p id="log-box-text"> </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Purchase Server Pop-up Box -->
|
||||
<div id="purchase-server-box-container" class="popup-box-container">
|
||||
<div id="purchase-server-box-content">
|
||||
@ -732,6 +741,7 @@
|
||||
<div id="character-overview-container">
|
||||
<p id="character-overview-text"> </p>
|
||||
<span id="character-overview-save-button"> Save Game </span>
|
||||
<span id="character-overview-options-button"> Options </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -117,7 +117,12 @@ function addActiveScriptsItem(workerscript) {
|
||||
}
|
||||
|
||||
//Create the element itself. Each element is an accordion collapsible
|
||||
var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
|
||||
for (var i = 0; i < workerscript.args.length; ++i) {
|
||||
itemNameArray.push(workerscript.args[i].toString());
|
||||
}
|
||||
var itemName = itemNameArray.join("-");
|
||||
//var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var item = document.createElement("li");
|
||||
item.setAttribute("id", itemName);
|
||||
|
||||
@ -147,7 +152,12 @@ function deleteActiveScriptsItem(workerscript) {
|
||||
console.log("ERROR: Invalid server IP for workerscript.");
|
||||
return;
|
||||
}
|
||||
var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
|
||||
for (var i = 0; i < workerscript.args.length; ++i) {
|
||||
itemNameArray.push(workerscript.args[i].toString());
|
||||
}
|
||||
var itemName = itemNameArray.join("-");
|
||||
//var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var li = document.getElementById(itemName);
|
||||
if (li == null) {
|
||||
console.log("could not find Active scripts li element for: " + workerscript.name);
|
||||
@ -174,7 +184,12 @@ function updateActiveScriptsItemContent(workerscript) {
|
||||
console.log("ERROR: Invalid server IP for workerscript.");
|
||||
return;
|
||||
}
|
||||
var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
|
||||
for (var i = 0; i < workerscript.args.length; ++i) {
|
||||
itemNameArray.push(workerscript.args[i].toString());
|
||||
}
|
||||
var itemName = itemNameArray.join("-");
|
||||
//var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
|
||||
var itemContent = document.getElementById(itemName + "-content")
|
||||
|
||||
//Clear the item
|
||||
@ -190,7 +205,8 @@ function createActiveScriptsText(workerscript, item) {
|
||||
var itemText = document.createElement("p");
|
||||
|
||||
//Server ip/hostname
|
||||
var serverIpHostname = "Threads: " + workerscript.scriptRef.threads;
|
||||
var threads = "Threads: " + workerscript.scriptRef.threads;
|
||||
var args = "Args: " + printArray(workerscript.args);
|
||||
|
||||
//Online
|
||||
var onlineTotalMoneyMade = "Total online production: $" + formatNumber(workerscript.scriptRef.onlineMoneyMade, 2);
|
||||
@ -210,7 +226,7 @@ function createActiveScriptsText(workerscript, item) {
|
||||
var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
|
||||
var offlineEpsText = (Array(26).join(" ") + formatNumber(offlineEps, 4) + " hacking exp/second").replace( / /g, " ");
|
||||
|
||||
itemText.innerHTML = serverIpHostname + "<br>" + onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
|
||||
itemText.innerHTML = threads + "<br>" + args + "<br>" + onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
|
||||
onlineMpsText + "<br>" + onlineEpsText + "<br>" + offlineTotalMoneyMade + "<br>" + offlineTotalExpEarned + "<br>" +
|
||||
offlineMpsText + "<br>" + offlineEpsText + "<br>";
|
||||
|
||||
|
249
src/Constants.js
249
src/Constants.js
@ -1,5 +1,5 @@
|
||||
CONSTANTS = {
|
||||
Version: "0.20.2",
|
||||
Version: "0.21.0",
|
||||
|
||||
//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
|
||||
@ -78,7 +78,7 @@ CONSTANTS = {
|
||||
AugmentationRepMultiplier: 1.5, //Used for balancing rep cost without having to readjust every value
|
||||
|
||||
//Maximum number of log entries for a script
|
||||
MaxLogCapacity: 40,
|
||||
MaxLogCapacity: 50,
|
||||
|
||||
//How much a TOR router costs
|
||||
TorRouterCost: 200000,
|
||||
@ -153,6 +153,7 @@ CONSTANTS = {
|
||||
HelpText: 'alias [name="value"] Create aliases for Terminal commands, or list existing aliases<br>' +
|
||||
"analyze Get statistics and information about current machine <br>" +
|
||||
"cat [message] Display a .msg file<br>" +
|
||||
"check [script] [args...] Print logs to Terminal for the script with the specified name and arguments<br>" +
|
||||
"clear Clear all text on the terminal <br>" +
|
||||
"cls See 'clear' command <br>" +
|
||||
"connect [ip/hostname] Connects to the machine given by its IP or hostname <br>" +
|
||||
@ -162,19 +163,20 @@ CONSTANTS = {
|
||||
"home Connect to home computer<br>" +
|
||||
"hostname Displays the hostname of the machine<br>" +
|
||||
"ifconfig Displays the IP address of the machine<br>" +
|
||||
"kill [script] Stops a script that is running on the current machine<br>" +
|
||||
"kill [script] [args...] Stops a script on the current server with the specified name and arguments<br>" +
|
||||
"killall Stops all running scripts on the current machine<br>" +
|
||||
"ls Displays all programs and scripts on the machine<br>" +
|
||||
"mem [script] [-t] [n] Displays the amount of RAM the script requires to run with n threads<br>" +
|
||||
"nano [script] Text editor - Open up and edit a script<br>" +
|
||||
"ps Display all scripts that are currently running<br>" +
|
||||
"rm Delete a script/program from the machine. (WARNING: Permanent)<br>" +
|
||||
"run [name] [-t] [n] Execute a program or a script with n threads<br>" +
|
||||
"run [name] [-t] [n] [args...] Execute a program or a script with n threads and the specified arguments<br>" +
|
||||
"scan Displays all available network connections<br>" +
|
||||
"scan-analyze [depth] Displays hacking-related information for all servers up to <i>depth</i> nodes away<br>" +
|
||||
"scp [script] [server] Copies a script to a destination server (specified by ip or hostname)<br>" +
|
||||
"sudov Shows whether or not you have root access on this computer<br>" +
|
||||
"tail [script] Display script logs (logs contain details about active scripts)<br>" +
|
||||
"tail [script] [args...] Display dynamic logs for the script with the specified name and arguments<br>" +
|
||||
"theme [preset] | bg txt hlgt Change the color scheme of the UI<br>" +
|
||||
"top Display all running scripts and their RAM usage<br>",
|
||||
|
||||
/* Tutorial related things */
|
||||
@ -248,16 +250,30 @@ CONSTANTS = {
|
||||
"syntax will vary a little bit. </strong> <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 and availability <br>" +
|
||||
"kill [script] - Stops a script that is running <br>" +
|
||||
"mem [script] [-t] [n] - Check how much RAM a script requires to run with n threads<br>" +
|
||||
"nano [script] - Create/Edit a script <br>" +
|
||||
"ps - Displays all scripts that are actively running on the current server<br>" +
|
||||
"rm [script] - Delete a script<br>" +
|
||||
"run [script] [-t] [n] - Run a script with n threads<br>" +
|
||||
"tail [script] - Displays a script's logs<br>" +
|
||||
"top - Displays all active scripts and their RAM usage <br><br>" +
|
||||
"Here are some Terminal commands that are useful when working with scripts: <br><br>" +
|
||||
"<i>check [script] [args...]</i><br>Prints the logs of the script specified by the name and arguments to Terminal. Arguments should be separated " +
|
||||
"by a space. Note that scripts are uniquely " +
|
||||
"identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'check' it you must " +
|
||||
"also add the 'foodnstuff' argument to the check command as so: <br>check foo.script foodnstuff<br><br>" +
|
||||
"<i>free</i><br>Shows the current server's RAM usage and availability <br><br>" +
|
||||
"<i>kill [script] [args...]</i><br>Stops a script that is running with the specified script name and arguments. " +
|
||||
"Arguments should be separated by a space. Note that " +
|
||||
"scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the " +
|
||||
"argument 1 and 2, then just typing 'kill foo.script' will not work. You have to use 'kill foo.script 1 2'. <br><br>" +
|
||||
"<i>mem [script] [-t] [n]</i><br>Check how much RAM a script requires to run with n threads<br><br>" +
|
||||
"<i>nano [script]</i><br>Create/Edit a script. The name of the script must end with the '.script' extension <br><br>" +
|
||||
"<i>ps</i><br>Displays all scripts that are actively running on the current server<br><br>" +
|
||||
"<i>rm [script]</i><br>Delete a script<br><br>" +
|
||||
"<i>run [script] [-t] [n] [args...]</i><br>Run a script with n threads and the specified arguments. Each argument should be separated by a space. " +
|
||||
"Both the arguments and thread specification are optional. If neither are specified, then the script will be run single-threaded with no arguments.<br>" +
|
||||
"Examples:<br>run foo.script<br>The command above will run 'foo.script' single-threaded with no arguments." +
|
||||
"<br>run foo.script -t 10<br>The command above will run 'foo.script' with 10 threads and no arguments." +
|
||||
"<br>run foo.script foodnstuff sigma-cosmetics 10<br>The command above will run 'foo.script' single-threaded with three arguments: [foodnstuff, sigma-cosmetics, 10]" +
|
||||
"<br>run foo.script -t 50 foodnstuff<br>The command above will run 'foo.script' with 50 threads and a single argument: [foodnstuff]<br><br>" +
|
||||
"<i>tail [script] [args...]</i><br>Displays the logs of the script specified by the name and arguments. Note that scripts are uniquely " +
|
||||
"identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'tail' it you must " +
|
||||
"also add the 'foodnstuff' argument to the tail command as so: <br>tail foo.script foodnstuff<br><br>" +
|
||||
"<i>top</i><br>Displays all active scripts and their RAM usage <br><br>" +
|
||||
"<u><h1> Multithreading scripts </h1></u><br>" +
|
||||
"Scripts can be multithreaded. A multithreaded script runs the script's code once in each thread. The result is that " +
|
||||
"every call to the hack(), grow(), and weaken() Netscript functions will have its effect multiplied by the number of scripts. " +
|
||||
@ -318,22 +334,52 @@ CONSTANTS = {
|
||||
" ==<br>" +
|
||||
" !=<br><br>" +
|
||||
"<u><h1> Arrays </h1></u><br>" +
|
||||
"Note: Currently arrays are fixed-size once they are declared. Eventually, functionality will be added to make these " +
|
||||
"dynamic arrays <br><br>" +
|
||||
"Arrays are special container objects. Arrays can holy many values under a single name. Each value in the array " +
|
||||
"Arrays are special container objects. Arrays can hold many values under a single name. Each value in the array " +
|
||||
"can be accessed using an index number. The following example shows how to declare an array: <br><br>" +
|
||||
"thisIsAnArray = Array[1, 2, 3, 'bitburner!', false];<br><br>" +
|
||||
"Note that the values in an array can be different types. To access this array we just declared, we can use the index " +
|
||||
"operator on the array's name: <br><br>" +
|
||||
"print(thisIsAnArray[0]); <br>" +
|
||||
"thisIsAnArray[1] = 5<br>" +
|
||||
"thisIsAnArray[3] = 'string concatenation ' + 123<br><br>" +
|
||||
"thisIsAnArray[1] = 5;<br>" +
|
||||
"thisIsAnArray[3] = 'string concatenation ' + 123;<br><br>" +
|
||||
"Note that arrays are indexed starting at index 0. Using an index that is too large or less than 0 will result in an " +
|
||||
"out of bounds runtime error. <br><br>" +
|
||||
"If an element in an array is assigned to a value that includes a variable, then it holds a reference to that variable. " +
|
||||
"What this means is that if the variable changes, the array element will also change accordingly. For example:<br><br>" +
|
||||
"x = 10;<br>testArr = Array[x];<br>print(testArr[0]);<br>x = 20;<br>print(testArr[0]);<br><br>" +
|
||||
"This code will print: <br><br>10<br>20<br><br>" +
|
||||
"<strong>Array functions</strong><br>" +
|
||||
"Arrays have built-in functions/properties that can be used to more easily access and manipulate the containers. <br><br>"+
|
||||
"<i>length/length()</i><br>Returns the number of elements in the array.<br>" +
|
||||
"The example below will print out 5:<br><br>" +
|
||||
"arr = Array[1, 2, 3, 4, 5];<br>print(arr.length);<br><br>" +
|
||||
"<i>clear/clear()</i><br>Removes all elements from the array.<br>" +
|
||||
"The example below creates an array with three strings and then uses clear to remove all of those strings. The result is that 'arr' will be " +
|
||||
"an empty array.<br><br>" +
|
||||
"arr = Array['str1', 'str2', 'str3'];<br>arr.clear();<br><br>" +
|
||||
"<i>push(e)</i><br>Adds the element e to the end of the array.<br>" +
|
||||
"The example below will create an array holding one element: the number 1. It will then push the number 2 onto the array. The result " +
|
||||
"is that 'arr' will be an array of size 2 with arr[0] == 1 and arr[1] == 2<br><br>" +
|
||||
"arr = Array[1];<br>arr.push(2);<br><br>" +
|
||||
"<i>insert(e)</i><br>Inserts an element e into an array at a specified index. Every element in the array that is at or after " +
|
||||
"the specified index is shifted down. The array must be indexed with the [] operator when using this function.<br>" +
|
||||
"The following example will insert the number 2 into index 1 of the array. The result afterwards is that 'arr' will hold the values [1, 2, 3, 4].<br><br>" +
|
||||
"arr = Array[1, 3, 4];<br>arr[1].insert(2);<br><br>" +
|
||||
"<i>remove()</i><br>Removes an element from a specified index. Every element in the array that is after the specified index " +
|
||||
"will be shifted up. The array must be indexed with the [] operator when using this function.<br>" +
|
||||
"The following example will remove the first element of the array. The result afterwards is that 'arr' will hold the values [2, 3].<br><br>" +
|
||||
"arr = Array[1, 2, 3];<br>arr[0].remove();<br><br>" +
|
||||
"<u><h1> Script Arguments </h1></u><br>" +
|
||||
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
|
||||
"operator. (args[0], args[1], args[2]...) <br><br>" +
|
||||
"For example, let's say we want to make a generic script 'generic-run.script' and we plan to pass two arguments into that script. The first argument will be the name of " +
|
||||
"another script, and the second argument will be a number. This generic script will run the script specified in the first argument " +
|
||||
"with the amount of threads specified in the second element. The code would look like:<br><br>" +
|
||||
"run(args[0], args[1]);<br><br>" +
|
||||
"It is also possible to get the number of arguments that was passed into a script using:<br><br>" +
|
||||
"args.length<br><br>" +
|
||||
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
|
||||
"args array.<br><br>" +
|
||||
"<u><h1> Functions </h1></u><br>" +
|
||||
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
|
||||
"you may use: <br><br> " +
|
||||
@ -361,36 +407,56 @@ CONSTANTS = {
|
||||
"any server, regardless of where the script is running. This command requires root access to the target server, but " +
|
||||
"there is no required hacking level to run the command. Grants 3 hacking exp when it completes. Returns " +
|
||||
"0.1. Works offline at a slower rate<br> Example: weaken('foodnstuff');<br><br>" +
|
||||
"<i>print(x)</i> <br> Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command )<br><br>" +
|
||||
"<i>print(x)</i> <br> Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br>" +
|
||||
"WARNING: Do NOT call print() on an array. The script will crash. You can, however, call print on single elements of an array. For example, if " +
|
||||
"the variable 'a' is an array, then do NOT call print(a), but it is okay to call print(a[0]).<br><br>" +
|
||||
"<i>nuke(hostname/ip)</i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline <br> Example: nuke('foodnstuff'); <br><br>" +
|
||||
"<i>brutessh(hostname/ip)</i><br>Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline <br> Example: brutessh('foodnstuff');<br><br>" +
|
||||
"<i>ftpcrack(hostname/ip)</i><br>Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer. Does NOT work while offline <br> Example: ftpcrack('foodnstuff');<br><br>" +
|
||||
"<i>relaysmtp(hostname/ip)</i><br>Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer. Does NOT work while offline <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. Does NOT work while offline <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. Does NOT work while offline <br> Example: sqlinject('foodnstuff');<br><br>" +
|
||||
"<i>run(script, [numThreads])</i> <br> Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " +
|
||||
"<i>run(script, [numThreads], [args...])</i> <br> Run a script as a separate process. The first 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 current server (the server running the script that calls this function). The second argument " +
|
||||
"is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " +
|
||||
"This second argument must be a number that is greater than 0. " +
|
||||
"is optional, and it specifies how many threads to run the script with. This argument must be a number greater than 0. If it is omitted, then the script will be run single-threaded. Any additional arguments will specify " +
|
||||
"arguments to pass into the new script that is being run. If arguments are specified for the new script, then the second argument numThreads argument must be filled in with a value.<br><br>" +
|
||||
"Returns true if the script is successfully started, and false otherwise. Requires a significant amount " +
|
||||
"of RAM to run this command. Does NOT work while offline <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>exec(script, hostname/ip, [numThreads])</i><br>Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
|
||||
"of RAM to run this command. Does NOT work while offline <br><br>" +
|
||||
"The simplest way to use the run command is to call it with just the script name. The following example will run 'foo.script' single-threaded with no arguments:<br><br>" +
|
||||
"run('foo.script');<br><br>" +
|
||||
"The following example will run 'foo.script' but with 5 threads instead of single-threaded:<br><br>" +
|
||||
"run('foo.script', 5);<br><br>" +
|
||||
"The following example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script as an argument:<br><br>" +
|
||||
"run('foo.script', 1, 'foodnstuff');<br><br>" +
|
||||
"<i>exec(script, hostname/ip, [numThreads], [args...])</i><br>Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
|
||||
"second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. " +
|
||||
"The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " +
|
||||
"This argument must be a number that is greater than 0. Returns " +
|
||||
"true if the script is successfully started, and false otherwise. Does NOT work while offline<br> " +
|
||||
"Example: exec('generic-hack.script', 'foodnstuff'); <br> The example above will try to launch the script 'generic-hack.script' on the 'foodnstuff' server.<br><br>" +
|
||||
"<i>kill(script, [hostname/ip])</i><br> Kills a script on a server. The first argument must be a string with the name of the script. The name is case-sensitive. " +
|
||||
"The second argument must be a string with the hostname or IP of the target server. The function will try to kill the specified script on the target server. " +
|
||||
"The second argument is optional. If it is omitted, then the function will try to kill the specified script on the current server (the server running " +
|
||||
"the script that calls this function). If the script is found on the specified server and is running, then it will be killed and this function " +
|
||||
"will return true. Otherwise, this function will return false. <br> " +
|
||||
"Example: kill('foo.script', 'foodnstuff');<br>" +
|
||||
"Example: kill('foo.script');<br>" +
|
||||
"The first example above will look for a script called 'foo.script' on the 'foodnstuff' server. If the script exists and is running, then it will " +
|
||||
"be killed and the function will return true. Otherwise false will be returned. The second example above will do the same thing, except on the " +
|
||||
"current server (the server running the script that calls the kill() function).<br><br>" +
|
||||
"This argument must be a number that is greater than 0. Any additional arguments will specify arguments to pass into the new script that is being run. If " +
|
||||
"arguments are specified for the new script, then the third argument numThreads must be filled in with a value.<br><br>Returns " +
|
||||
"true if the script is successfully started, and false otherwise. Does NOT work while offline<br><br> " +
|
||||
"The simplest way to use the exec command is to call it with just the script name and the target server. The following example will try to run 'generic-hack.script' " +
|
||||
"on the 'foodnstuff' server:<br><br>" +
|
||||
"exec('generic-hack.script', 'foodnstuff');<br><br>" +
|
||||
"The following example will try to run the script 'generic-hack.script' on the 'joesguns' server with 10 threads:<br><br>" +
|
||||
"exec('generic-hack.script', 'joesguns', 10);<br><br>" +
|
||||
"The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " +
|
||||
"to the script.<br><br>" +
|
||||
"exec('foo.script', 'foodnstuff', 5, 1, 'test');<br><br>" +
|
||||
"<i>kill(script, hostname/ip, [args...])</i><br> Kills the script on the target server specified by the script's name and arguments. Remember that " +
|
||||
"scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " +
|
||||
"same as 'foo.script' run with the argument 2, even though they have the same code. <br><br>" +
|
||||
"The first argument must be a string with the name of the script. The name is case-sensitive. " +
|
||||
"The second argument must be a string with the hostname or IP of the target server. Any additional arguments to the function will specify the arguments passed " +
|
||||
"into the script that should be killed. <br><br>The function will try to kill the specified script on the target server. " +
|
||||
"If the script is found on the specified server and is running, then it will be killed and this function " +
|
||||
"will return true. Otherwise, this function will return false. <br><br>" +
|
||||
"Examples:<br>" +
|
||||
"If you are trying to kill a script named 'foo.script' on the 'foodnstuff' server that was ran with no arguments, use this:<br><br>" +
|
||||
"kill('foo.script', 'foodnstuff');<br><br>" +
|
||||
"If you are trying to kill a script named 'foo.script' on the current server that was ran with no arguments, use this:<br><br>" +
|
||||
"kill('foo.script', getHostname());<br><br>" +
|
||||
"If you are trying to kill a script named 'foo.script' on the current server that was ran with the arguments 1 and 'foodnstuff', use this:<br><br>" +
|
||||
"kill('foo.script', getHostname(), 1, 'foodnstuff');<br><br>" +
|
||||
"<i>killall(hostname/ip)</i><br> Kills all running scripts on the specified server. This function takes a single argument which " +
|
||||
"must be a string containing the hostname or IP of the target server. This function will always return true. <br><br>" +
|
||||
"<i>scp(script, hostname/ip)</i><br>Copies a script to another server. The first argument is a string with the filename of the script " +
|
||||
@ -416,14 +482,18 @@ CONSTANTS = {
|
||||
"Example: fileExists('ftpcrack.exe');<br><br>" +
|
||||
"The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " +
|
||||
"return true if the current server (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise. <br><br>" +
|
||||
"<i>isRunning(filename, [hostname/ip])</i><br> Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
|
||||
"<i>isRunning(filename, hostname/ip, [args...])</i><br> Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
|
||||
"Remember that a script is uniquely identified by both its name and its arguments. <br><br>" +
|
||||
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " +
|
||||
"hostname or IP of the target server. The function will check whether the script is running on that target server. The second argument is optional. " +
|
||||
"If it is omitted, then the function will check if the script is running on the current server (the server running the script that calls this function). <br>" +
|
||||
"hostname or IP of the target server. Any additional arguments passed to the function will specify the arguments passed into the target script. " +
|
||||
"The function will check whether the script is running on that target server.<br>" +
|
||||
"Example: isRunning('foo.script', 'foodnstuff');<br>" +
|
||||
"Example: isRunning('foo.script'); <br><br>" +
|
||||
"The first example above will return true if there is a script called 'foo.script' is running on the 'foodnstuff' server, and false otherwise. The second " +
|
||||
"example above will return true if there is a script called 'foo.script' running on the current server, and false otherwise. <br><br>" +
|
||||
"Example: isRunning('foo.script', getHostname());<br>" +
|
||||
"Example: isRunning('foo.script', 'joesguns', 1, 5, 'test');<br><br>" +
|
||||
"The first example above will return true if there is a script named 'foo.script' with no arguments running on the 'foodnstuff' server, and false otherwise. The second " +
|
||||
"example above will return true if there is a script named 'foo.script' with no arguments running on the current server, and false otherwise. " +
|
||||
"The third example above will return true if there is a script named 'foo.script' with the arguments 1, 5, and 'test' running on the 'joesguns' server, and " +
|
||||
"false otherwise.<br><br>" +
|
||||
"<i>purchaseHacknetNode()</i><br> Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " +
|
||||
"at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " +
|
||||
"a new Hacknet Node then the function will return false. Does NOT work offline<br><br>" +
|
||||
@ -573,6 +643,27 @@ CONSTANTS = {
|
||||
"RAM Upgrades on your home computer",
|
||||
|
||||
Changelog:
|
||||
"v0.21.0<br>" +
|
||||
"-Added dynamic arrays. See Netscript documentation<br>" +
|
||||
"-Added ability to pass arguments into scripts. See documentation<br>" +
|
||||
"-The implementation/function signature of functions that deal with scripts have changed. Therefore, some old scripts might not " +
|
||||
"work anymore. Some of these functions include run(), exec(), isRunning(), kill(), and some others I may have forgot about. " +
|
||||
"Please check the updated Netscript documentation if you run into issues." +
|
||||
"-Note that scripts are now uniquely identified by the script name and their arguments. For example, you can run " +
|
||||
"a script using <br>run foodnstuff.script 1<br> and you can also run the same script with a different argument " +
|
||||
"<br>run foodnstuff.script 2<br>These will be considered two different scripts. To kill the first script you must " +
|
||||
"run <br>kill foodnstuff.script 1<br> and to kill the second you must run <br>kill foodnstuff.script 2<br> Similar concepts " +
|
||||
"apply for Terminal Commands such as tail, and Netscript commands such as run(), exec(), kill(), isRunning(), etc.<br>" +
|
||||
"-Added basic theme functionality using the 'theme' Terminal command - All credit goes to /u/0x726564646974 who implemented the awesome feature<br>" +
|
||||
"-Optimized Script objects, which were causing save errors when the player had too many scripts<br>" +
|
||||
"-Formula for determining exp gained from hacking was changed<br>" +
|
||||
"-Fixed bug where you could purchase Darkweb items without TOR router<br>" +
|
||||
"-Slightly increased cost multiplier for Home Computer RAM<br>" +
|
||||
"-Fixed bug where you could hack too much money from a server (and bring its money available below zero)<br>" +
|
||||
"-Changed tail command so that it brings up a display box with dynamic log contents. To get " +
|
||||
"old functionality where the logs are printed to the Terminal, use the new 'check' command<br>" +
|
||||
"-As a result of the change above, you can no longer call tail/check on scripts that are not running<br>" +
|
||||
"-Added autocompletion for buying Programs in Darkweb<br>" +
|
||||
"v0.20.2<br>" +
|
||||
"-Fixed several small bugs<br>" +
|
||||
"-Added basic array functionality to Netscript<br>" +
|
||||
@ -701,49 +792,25 @@ CONSTANTS = {
|
||||
"-You can now see what an Augmentation does and its price even while its locked<br><br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.20.2<br>" +
|
||||
"-Fixed several small bugs<br>" +
|
||||
"-Added basic array functionality to Netscript<br>" +
|
||||
"-Added ability to run scripts with multiple threads. Running a script with n threads will multiply the effects of all " +
|
||||
"hack(), grow(), and weaken() commands by n. However, running a script with multiple threads has drawbacks in terms of " +
|
||||
"RAM usage. A script's ram usage when it is 'multithreaded' is calculated as: base cost * numThreads * (1.02 ^ numThreads). " +
|
||||
"A script can be run multithreaded using the 'run [script] -t n' Terminal command or by passing in an argument to the " +
|
||||
"run() and exec() Netscript commands. See documentation.<br>" +
|
||||
"-RAM is slightly (~10%) more expensive (affects purchasing server and upgrading RAM on home computer)<br>" +
|
||||
"-NeuroFlux Governor augmentation cost multiplier decreased<br>" +
|
||||
"-Netscript default operation runtime lowered to 200ms (was 500ms previously)<br><br>" +
|
||||
"v0.20.1<br>" +
|
||||
"-Fixed bug where sometimes scripts would crash without showing the error<br>" +
|
||||
"-Added Deepscan programs to Dark Web<br>" +
|
||||
"-Declining a faction invite will stop you from receiving invitations from that faction for the rest of the run<br>" +
|
||||
"-(BETA) Added functionality to export/import saves. WARNING This is only lightly tested. You cannot choose where to save your file " +
|
||||
"it just goes to the default save location. Also I have no idea what will happen if you try to import a file " +
|
||||
"that is not a valid save. I will address these in later updates<br><br>" +
|
||||
"v0.20.0<br>" +
|
||||
"-Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation " +
|
||||
"such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, " +
|
||||
"now each one should only take ~500 milliseconds). <br><br>" +
|
||||
"-Percentage money stolen when hacking lowered to compensate for faster script speeds<br><br>" +
|
||||
"-Hacking experience granted by grow() halved<br><br>" +
|
||||
"-Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5 <br><br>" +
|
||||
"-Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() " +
|
||||
"and weaken() all cost slightly less RAM than before <br><br>" +
|
||||
"-Added getServerRequiredHackingLevel(server) Netscript command. <br><br>" +
|
||||
"-Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a " +
|
||||
"specified server<br><br>" +
|
||||
"-Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server<br><br>" +
|
||||
"-Added killall Terminal command. Kills all running scripts on the current machine<br><br>" +
|
||||
"-Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation<br><br>" +
|
||||
"-Re-designed 'Active Scripts' tab<br><br>" +
|
||||
"-Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)<br><br>" +
|
||||
"-Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)<br><br>" +
|
||||
"-NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level " +
|
||||
"will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that " +
|
||||
"server's security level by 0.004. For reference, if a server has a security level of 10 " +
|
||||
"it will have approximately the same growth rate as before. <br><br>" +
|
||||
"-Server growth no longer happens naturally<br><br>" +
|
||||
"-Servers now have a maximum limit to their money. This limit is 50 times it's starting money<br><br>" +
|
||||
"-Hacking now grants 10% less hacking experience<br><br>" +
|
||||
"-You can now edit scripts that are running<br><br>" +
|
||||
"-Augmentations cost ~11% more money and 25% more faction reputation<br><br>",
|
||||
"v0.21.0<br>" +
|
||||
"-Added dynamic arrays. See Netscript documentation<br>" +
|
||||
"-Added ability to pass arguments into scripts. See documentation<br>" +
|
||||
"-The implementation/function signature of functions that deal with scripts have changed. Therefore, some old scripts might not " +
|
||||
"work anymore. Some of these functions include run(), exec(), isRunning(), kill(), and some others I may have forgot about. " +
|
||||
"Please check the updated Netscript documentation if you run into issues." +
|
||||
"-Note that scripts are now uniquely identified by the script name and their arguments. For example, you can run " +
|
||||
"a script using <br>run foodnstuff.script 1<br> and you can also run the same script with a different argument " +
|
||||
"<br>run foodnstuff.script 2<br>These will be considered two different scripts. To kill the first script you must " +
|
||||
"run <br>kill foodnstuff.script 1<br> and to kill the second you must run <br>kill foodnstuff.script 2<br> Similar concepts " +
|
||||
"apply for Terminal Commands such as tail, and Netscript commands such as run(), exec(), kill(), isRunning(), etc.<br>" +
|
||||
"-Added basic theme functionality using the 'theme' Terminal command - All credit goes to /u/0x726564646974 who implemented the awesome feature<br>" +
|
||||
"-Optimized Script objects, which were causing save errors when the player had too many scripts<br>" +
|
||||
"-Formula for determining exp gained from hacking was changed<br>" +
|
||||
"-Fixed bug where you could purchase Darkweb items without TOR router<br>" +
|
||||
"-Slightly increased cost multiplier for Home Computer RAM<br>" +
|
||||
"-Fixed bug where you could hack too much money from a server (and bring its money available below zero)<br>" +
|
||||
"-Changed tail command so that it brings up a display box with dynamic log contents. To get " +
|
||||
"old functionality where the logs are printed to the Terminal, use the new 'check' command<br>" +
|
||||
"-As a result of the change above, you can no longer call tail/check on scripts that are not running<br>" +
|
||||
"-Added autocompletion for buying Programs in Darkweb<br>",
|
||||
}
|
@ -28,6 +28,26 @@ function evaluate(exp, workerScript) {
|
||||
reject(e);
|
||||
});
|
||||
return;
|
||||
} else if (exp.value == "args") {
|
||||
if (exp.index) {
|
||||
var iPromise = evaluate(exp.index.value, workerScript);
|
||||
iPromise.then(function(i) {
|
||||
if (isNaN(i)) {
|
||||
reject(makeRuntimeRejectMsg(workerScript, "Invalid access to args array. Index is not a number: " + i));
|
||||
} else if (i >= workerScript.args.length || i < 0) {
|
||||
reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
resolve(workerScript.args[i]);
|
||||
}
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.op && exp.op.type == "var" && exp.op.value == "length") {
|
||||
resolve(workerScript.args.length);
|
||||
} else {
|
||||
reject(makeRuntimeRejectMsg(workerScript, "Invalid access to args array"));
|
||||
}
|
||||
return;
|
||||
} else if (exp.value == "array") {
|
||||
//A raw array. This will be called under something like this:
|
||||
// x = Array[1, 2, 3];
|
||||
@ -40,25 +60,13 @@ function evaluate(exp, workerScript) {
|
||||
}
|
||||
try {
|
||||
var res = env.get(exp.value);
|
||||
if (exp.index) {
|
||||
//If theres an index field, then this variable is supposed to be an array
|
||||
//and the user needs to be indexing it
|
||||
if (res.constructor === Array || res instanceof Array) {
|
||||
var iPromise = evaluate(exp.index.value, workerScript);
|
||||
iPromise.then(function(i) {
|
||||
if (i >= res.length || i < 0) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
return evaluate(res[i], workerScript);
|
||||
}
|
||||
}).then(function(res) {
|
||||
var evalArrayPromise = netscriptArray(exp, workerScript);
|
||||
evalArrayPromise.then(function(res) {
|
||||
resolve(res);
|
||||
}).catch(function(e) {
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
} else {
|
||||
reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator"));
|
||||
}
|
||||
} else {
|
||||
resolve(res);
|
||||
}
|
||||
@ -255,8 +263,8 @@ function evaluate(exp, workerScript) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "run") {
|
||||
if (exp.args.length != 1 && exp.args.length != 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Takes 1 or 2 arguments"));
|
||||
if (exp.args.length < 1) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Usage: run(scriptname, [numThreads], [arg1], [arg2]...)"));
|
||||
}
|
||||
var argPromises = exp.args.map(function(arg) {
|
||||
return evaluate(arg, workerScript);
|
||||
@ -266,9 +274,14 @@ function evaluate(exp, workerScript) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
var scriptname = args[0];
|
||||
var threads = 1;
|
||||
if (exp.args.length == 2) {
|
||||
if (exp.args.length >= 2) {
|
||||
threads = args[1];
|
||||
}
|
||||
var argsForNewScript = [];
|
||||
for (var i = 2; i < exp.args.length; ++i) {
|
||||
argsForNewScript.push(args[i]);
|
||||
}
|
||||
|
||||
if (isNaN(threads) || threads < 1) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0"));
|
||||
}
|
||||
@ -277,7 +290,7 @@ function evaluate(exp, workerScript) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev"));
|
||||
}
|
||||
|
||||
var runScriptPromise = runScriptFromScript(scriptServer, scriptname, workerScript, threads);
|
||||
var runScriptPromise = runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
||||
return runScriptPromise;
|
||||
}).then(function(res) {
|
||||
resolve(res);
|
||||
@ -285,8 +298,8 @@ function evaluate(exp, workerScript) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "exec") {
|
||||
if (exp.args.length != 2 && exp.args.length != 3) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Takes 2 arguments"));
|
||||
if (exp.args.length < 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)"));
|
||||
}
|
||||
var argPromises = exp.args.map(function(arg) {
|
||||
return evaluate(arg, workerScript);
|
||||
@ -295,9 +308,14 @@ function evaluate(exp, workerScript) {
|
||||
Promise.all(argPromises).then(function(args) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
var threads = 1;
|
||||
if (exp.args.length == 3) {
|
||||
if (exp.args.length >= 3) {
|
||||
threads = args[2];
|
||||
}
|
||||
var argsForNewScript = [];
|
||||
for (var i = 3; i < exp.args.length; ++i) {
|
||||
argsForNewScript.push(args[i]);
|
||||
}
|
||||
|
||||
if (isNaN(threads) || threads < 1) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into exec(). Must be numeric and greater than 0"));
|
||||
}
|
||||
@ -306,42 +324,43 @@ function evaluate(exp, workerScript) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + args[1]));
|
||||
}
|
||||
|
||||
return runScriptFromScript(server, args[0], workerScript, threads);
|
||||
return runScriptFromScript(server, args[0], argsForNewScript, workerScript, threads);
|
||||
}).then(function(res) {
|
||||
resolve(res);
|
||||
}).catch(function(e) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "kill") {
|
||||
if (exp.args.length != 1 && exp.args.length != 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Takes 1 or 2 arguments"));
|
||||
if (exp.args.length < 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Usage: kill(scriptname, server, [arg1], [arg2]...)"));
|
||||
}
|
||||
var argPromises = exp.args.map(function(arg) {
|
||||
return evaluate(arg, workerScript);
|
||||
});
|
||||
|
||||
var filename = "";
|
||||
Promise.all(argPromises).then(function(args) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
filename = args[0];
|
||||
if (exp.args.length == 1) {
|
||||
return Promise.resolve(workerScript.serverIp);
|
||||
} else {
|
||||
return evaluate(exp.args[1], workerScript);
|
||||
}
|
||||
}).then(function(ip) {
|
||||
var server = getServer(ip);
|
||||
var filename = args[0];
|
||||
var server = getServer(args[1]);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("kill() failed. Invalid IP or hostname passed in: " + ip);
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into kill() command"));
|
||||
}
|
||||
|
||||
var res = killWorkerScript(filename, server.ip);
|
||||
var argsForKillTarget = [];
|
||||
for (var i = 2; i < exp.args.length; ++i) {
|
||||
argsForKillTarget.push(args[i]);
|
||||
}
|
||||
var runningScriptObj = findRunningScript(filename, argsForKillTarget, server);
|
||||
if (runningScriptObj == null) {
|
||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
var res = killWorkerScript(runningScriptObj, server.ip);
|
||||
if (res) {
|
||||
workerScript.scriptRef.log("Killing " + filename + ". May take up to a few minutes for the scripts to die...");
|
||||
workerScript.scriptRef.log("Killing " + filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget) + ". May take up to a few minutes for the scripts to die...");
|
||||
return Promise.resolve(true);
|
||||
} else {
|
||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname);
|
||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}).then(function(res) {
|
||||
@ -361,10 +380,10 @@ function evaluate(exp, workerScript) {
|
||||
workerScript.scriptRef.log("killall() failed. Invalid IP or hostname passed in: " + ip);
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into killall() command"));
|
||||
}
|
||||
workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die");
|
||||
for (var i = server.runningScripts.length; i >= 0; --i) {
|
||||
for (var i = server.runningScripts.length-1; i >= 0; --i) {
|
||||
killWorkerScript(server.runningScripts[i], server.ip);
|
||||
}
|
||||
workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die");
|
||||
resolve(true);
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
@ -532,35 +551,31 @@ function evaluate(exp, workerScript) {
|
||||
reject(e);
|
||||
});
|
||||
} else if (exp.func.value == "isRunning") {
|
||||
if (exp.args.length != 1 && exp.args.length != 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "isRunning() call has incorrect number of arguments. Takes 1 or 2 arguments"));
|
||||
if (exp.args.length < 2) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "isRunning() call has incorrect number of arguments. Usage: isRunning(scriptname, server, [arg1], [arg2]...)"));
|
||||
}
|
||||
var argPromises = exp.args.map(function(arg) {
|
||||
return evaluate(arg, workerScript);
|
||||
});
|
||||
|
||||
var filename = "";
|
||||
var argsForTargetScript = [];
|
||||
Promise.all(argPromises).then(function(args) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
filename = args[0];
|
||||
if (exp.args.length == 1) {
|
||||
return Promise.resolve(workerScript.serverIp);
|
||||
} else {
|
||||
return evaluate(exp.args[1], workerScript);
|
||||
var ip = args[1];
|
||||
for (var i = 2; i < args.length; ++i) {
|
||||
argsForTargetScript.push(args[i]);
|
||||
}
|
||||
}).then(function(ip) {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("isRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into isRunning() command"));
|
||||
}
|
||||
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (filename == server.runningScripts[i]) {
|
||||
var runningScriptObj = findRunningScript(filename, argsForTargetScript, server);
|
||||
if (runningScriptObj != null) {
|
||||
return resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
return resolve(false);
|
||||
}).catch(function(e) {
|
||||
reject(e);
|
||||
@ -763,7 +778,7 @@ function evaluateHacknetNode(exp, workerScript) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
setTimeout(function() {
|
||||
if (exp.index == null) {
|
||||
if ((exp.op.type == "call" && exp.op.value == "length") ||
|
||||
if ((exp.op.type == "call" && exp.op.func.value == "length") ||
|
||||
(exp.op.type == "var" && exp.op.value == "length")) {
|
||||
resolve(Player.hacknetNodes.length);
|
||||
workerScript.scriptRef.log("hacknetnodes.length returned " + Player.hacknetNodes.length);
|
||||
@ -938,45 +953,41 @@ function apply_op(op, a, b) {
|
||||
}
|
||||
|
||||
//Run a script from inside a script using run() command
|
||||
function runScriptFromScript(server, scriptname, workerScript, threads=1) {
|
||||
function runScriptFromScript(server, scriptname, args, workerScript, threads=1) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {reject(workerScript); return;}
|
||||
setTimeout(function() {
|
||||
//Check if the script is already running
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i] == scriptname) {
|
||||
var runningScriptObj = findRunningScript(scriptname, args, server);
|
||||
if (runningScriptObj != null) {
|
||||
workerScript.scriptRef.log(scriptname + " is already running on " + server.hostname);
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
//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 script = server.scripts[i];
|
||||
var ramUsage = script.ramUsage;
|
||||
ramUsage = ramUsage * threads * Math.pow(1.02, threads-1);
|
||||
var ramAvailable = server.maxRam - server.ramUsed;
|
||||
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot run script " + scriptname + " on " + server.hostname + " because you do not have root access!");
|
||||
resolve(false);
|
||||
return;
|
||||
return resolve(false);
|
||||
} else if (ramUsage > ramAvailable){
|
||||
workerScript.scriptRef.log("Cannot run script " + scriptname + "(t=" + threads + ") on " + server.hostname + " because there is not enough available RAM!");
|
||||
resolve(false);
|
||||
return;
|
||||
return resolve(false);
|
||||
} else {
|
||||
//Able to run script
|
||||
workerScript.scriptRef.log("Running script: " + scriptname + " on " + server.hostname + " with " + threads + " threads. May take a few seconds to start up...");
|
||||
var script = server.scripts[i];
|
||||
script.threads = threads;
|
||||
server.runningScripts.push(script.filename); //Push onto runningScripts
|
||||
addWorkerScript(script, server);
|
||||
resolve(true);
|
||||
return;
|
||||
workerScript.scriptRef.log("Running script: " + scriptname + " on " + server.hostname + " with " + threads + " threads and args: " + printArray(args) + ". May take a few seconds to start up...");
|
||||
var runningScriptObj = new RunningScript(script, args);
|
||||
runningScriptObj.threads = threads;
|
||||
server.runningScripts.push(runningScriptObj); //Push onto runningScripts
|
||||
addWorkerScript(runningScriptObj, server);
|
||||
return resolve(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1018,7 +1029,10 @@ function scriptCalculateHackingTime(server) {
|
||||
|
||||
//The same as Player's calculateExpGain() function but takes in the server as an argument
|
||||
function scriptCalculateExpGain(server) {
|
||||
return (server.hackDifficulty * Player.hacking_exp_mult * 0.9);
|
||||
if (server.baseDifficulty == null) {
|
||||
server.baseDifficulty = server.hackDifficulty;
|
||||
}
|
||||
return (server.baseDifficulty * Player.hacking_exp_mult * 0.5 + 4);
|
||||
}
|
||||
|
||||
//The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument
|
||||
|
@ -1,72 +1,76 @@
|
||||
/* Netscript Functions
|
||||
* Implementation for Netscript features */
|
||||
/*
|
||||
function netscriptAssign(exp, workerScript) {
|
||||
function netscriptArray(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
var arr = env.get(exp.value);
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
|
||||
if (exp.left.type != "var") {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Cannot assign to " + JSON.stringify(exp.left)));
|
||||
if (exp.index == null || exp.index == undefined) {
|
||||
if ((exp.op.type == "call" && exp.op.func.value == "length") ||
|
||||
(exp.op.type == "var" && exp.op.value == "length")) {
|
||||
return resolve(arr.length);
|
||||
} else if ((exp.op.type == "call" && exp.op.func.value == "clear") ||
|
||||
(exp.op.type == "var" && exp.op.value == "clear")) {
|
||||
arr.length = 0;
|
||||
return resolve(true);
|
||||
} else if (exp.op.type == "call" && exp.op.func.value == "push") {
|
||||
if (exp.op.args.length == 1) {
|
||||
var entry = Object.assign({}, exp.op.args[0]);
|
||||
arr.push(entry);
|
||||
return resolve(true);
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array.push() command. Takes 1 argument"));
|
||||
}
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid operation on an array"));
|
||||
}
|
||||
}
|
||||
|
||||
//Assigning an element in an array
|
||||
if (exp.left.index) {
|
||||
try {
|
||||
var res = env.get(exp.left.value);
|
||||
if (res.constructor === Array || res instanceof Array) {
|
||||
var i = 0;
|
||||
var iPromise = evaluate(exp.left.index.value, workerScript);
|
||||
iPromise.then(function(idx) {
|
||||
if (idx >= res.length || idx < 0) {
|
||||
//The array is being indexed
|
||||
var indexPromise = evaluate(exp.index.value, workerScript);
|
||||
indexPromise.then(function(i) {
|
||||
if (isNaN(i)) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
||||
} else if (i >= arr.length || i < 0) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
//TODO evaluate exp.right here....and then determine its type and
|
||||
//set the type and value below accordingly
|
||||
i = idx;
|
||||
return evaluate(exp.right, workerScript);
|
||||
}
|
||||
}).then(function(right) {
|
||||
console.log("evaluate right with result: " + right);
|
||||
if (right === true || right === false) {
|
||||
res[i].type = "bool";
|
||||
res[i].value = right;
|
||||
} else if (!isNaN(right) || typeof right == 'number') {
|
||||
res[i].type = "num";
|
||||
res[i].value = right;
|
||||
} else { //String
|
||||
res[i].type = "str";
|
||||
res[i].value = right.toString();
|
||||
}
|
||||
console.log(res);
|
||||
return resolve(true);
|
||||
}).then(function(finalRes) {
|
||||
resolve(finalRes);
|
||||
}).catch(function(e) {
|
||||
return reject(e);
|
||||
});
|
||||
if (exp.op && exp.op.type == "call") {
|
||||
switch(exp.op.func.value) {
|
||||
case "insert":
|
||||
if (exp.op.args.length == 1) {
|
||||
var entry = Object.assign({}, exp.op.args[0]);
|
||||
arr.splice(i, 0, entry);
|
||||
return resolve(arr.length);
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator"));
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array insert() call. Takes 1 argument"));
|
||||
}
|
||||
} catch(e) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, e.toString()));
|
||||
break;
|
||||
case "remove":
|
||||
if (exp.op.args.length == 0) {
|
||||
return resolve(arr.splice(i, 1));
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array remove() call. Takes 1 argument"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid call on array element: " + exp.op.func.value));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
var expRightPromise = evaluate(exp.right, workerScript);
|
||||
expRightPromise.then(function(expRight) {
|
||||
try {
|
||||
env.set(exp.left.value, expRight);
|
||||
} catch (e) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString()));
|
||||
}
|
||||
resolve(false); //Return false so this doesnt cause conditionals to evaluate
|
||||
//Return the indexed element
|
||||
var resPromise = evaluate(arr[i], workerScript);
|
||||
resPromise.then(function(res) {
|
||||
resolve(res);
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
function netscriptAssign(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
return new Promise(function(resolve, reject) {
|
||||
@ -84,7 +88,9 @@ function netscriptAssign(exp, workerScript) {
|
||||
var i = 0;
|
||||
var iPromise = evaluate(exp.left.index.value, workerScript);
|
||||
iPromise.then(function(idx) {
|
||||
if (idx >= res.length || idx < 0) {
|
||||
if (isNaN(idx)) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
||||
} else if (idx >= res.length || idx < 0) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
//Clone res to be exp.right
|
||||
@ -181,10 +187,12 @@ function netscriptHack(exp, workerScript) {
|
||||
var moneyGained = scriptCalculatePercentMoneyHacked(server);
|
||||
moneyGained = Math.floor(server.moneyAvailable * moneyGained) * threads;
|
||||
|
||||
//Safety check
|
||||
//Over-the-top safety checks
|
||||
if (moneyGained <= 0) {moneyGained = 0;}
|
||||
|
||||
if (moneyGained > server.moneyAvailable) {moneyGained = server.moneyAvailable;}
|
||||
server.moneyAvailable -= moneyGained;
|
||||
if (server.moneyAvailable < 0) {server.moneyAvailable = 0;}
|
||||
|
||||
Player.gainMoney(moneyGained);
|
||||
workerScript.scriptRef.onlineMoneyMade += moneyGained;
|
||||
workerScript.scriptRef.recordHack(server.ip, moneyGained, threads);
|
||||
@ -416,7 +424,7 @@ function netscriptRunHttpwormProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.httpPortOpen) {
|
||||
workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (25)");
|
||||
workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (80)");
|
||||
server.httpPortOpen = true;
|
||||
++server.openPortCount;
|
||||
} else {
|
||||
|
@ -216,8 +216,8 @@ function Parser(input) {
|
||||
unexpected();
|
||||
}
|
||||
|
||||
function parse_array() {
|
||||
//Declaring a new array with Array[1,2,3]
|
||||
function parse_arraydecl() {
|
||||
var array = delimited("[", "]", ",", parse_expression);
|
||||
return {type: "var",
|
||||
value: "array",
|
||||
@ -225,14 +225,38 @@ function Parser(input) {
|
||||
};
|
||||
}
|
||||
|
||||
//Parsing an operation on an array, such as accessing, push(), etc.
|
||||
//tok is a reference to a token of type var
|
||||
function parse_arrayop(tok) {
|
||||
//Returns a variable node except with an extra "index" field so
|
||||
//we can identify it as an index
|
||||
if (is_punc("[")) {
|
||||
var index = parse_arrayindex();
|
||||
if (index.type != "index") {
|
||||
unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
var op = null;
|
||||
if (is_punc(".")) {
|
||||
checkPuncAndSkip(".");
|
||||
op = maybe_call(function() {
|
||||
var callTok = input.next();
|
||||
return callTok;
|
||||
});
|
||||
}
|
||||
tok.index = index;
|
||||
tok.op = op; //Will be null if no operation
|
||||
return tok;
|
||||
}
|
||||
|
||||
function parse_arrayindex() {
|
||||
var index = delimited("[", "]", ";", parse_expression);
|
||||
var val = 0;
|
||||
if (index.length == 1 && (index[0].type == "num" || index[0].type == "var")) {
|
||||
if (index.length == 1) {
|
||||
val = index[0];
|
||||
} else {
|
||||
val = 0;
|
||||
console.log("WARNING: Extra indices passed in")
|
||||
unexpected();
|
||||
}
|
||||
|
||||
return { type: "index", value: val };
|
||||
@ -267,16 +291,9 @@ function Parser(input) {
|
||||
|
||||
var tok = input.next();
|
||||
if (tok.type == "var" && tok.value == "hacknetnodes") return parse_hacknetnodes();
|
||||
if (tok.type == "var" && tok.value == "Array") return parse_array();
|
||||
if (tok.type == "var" && is_punc("[")) {
|
||||
//Returns a variable node except with an extra "index" field so
|
||||
//we can identify it as an index
|
||||
var index = parse_arrayindex();
|
||||
if (index.type != "index") {
|
||||
unexpected();
|
||||
}
|
||||
tok.index = index;
|
||||
return tok;
|
||||
if (tok.type == "var" && tok.value == "Array") return parse_arraydecl();
|
||||
if (tok.type == "var" && (is_punc("[") || is_punc("."))) {
|
||||
return parse_arrayop(tok);
|
||||
}
|
||||
if (tok.type == "var" || tok.type == "num" || tok.type == "str")
|
||||
return tok;
|
||||
|
@ -3,16 +3,17 @@
|
||||
//TODO Tested For and while and generic call statements. Have not tested if statements
|
||||
|
||||
/* Actual Worker Code */
|
||||
function WorkerScript(script) {
|
||||
this.name = "";
|
||||
function WorkerScript(runningScriptObj) {
|
||||
this.name = runningScriptObj.filename;
|
||||
this.running = false;
|
||||
this.serverIp = null;
|
||||
this.code = "";
|
||||
this.code = runningScriptObj.scriptRef.code;
|
||||
this.env = new Environment();
|
||||
this.output = "";
|
||||
this.ramUsage = 0;
|
||||
this.scriptRef = script;
|
||||
this.scriptRef = runningScriptObj;
|
||||
this.errorMessage = "";
|
||||
this.args = runningScriptObj.args;
|
||||
}
|
||||
|
||||
//Returns the server on which the workerScript is running
|
||||
@ -47,33 +48,12 @@ function runScriptsLoop() {
|
||||
console.log("Stopping script " + w.name + " because it finished running naturally");
|
||||
w.running = false;
|
||||
w.env.stopFlag = true;
|
||||
w.scriptRef.log("Script finished running");
|
||||
}, function(w) {
|
||||
if (w instanceof Error) {
|
||||
//Error text format: |serverip|scriptname|error message
|
||||
var errorText = w.toString();
|
||||
if (Engine.Debug) {
|
||||
console.log("Error in script: " + errorText);
|
||||
}
|
||||
var errorTextArray = errorText.split("|");
|
||||
if (errorTextArray.length != 4) {
|
||||
console.log("ERROR: Something wrong with Error text in evaluator...");
|
||||
console.log("Error text: " + errorText);
|
||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
||||
console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN");
|
||||
return;
|
||||
}
|
||||
var serverIp = errorTextArray[1];
|
||||
var scriptName = errorTextArray[2];
|
||||
var errorMsg = errorTextArray[3];
|
||||
|
||||
dialogBoxCreate("Script runtime error:<br>Server Ip: " + serverIp + "<br>Script name: " + scriptName + "<br>" + errorMsg);
|
||||
|
||||
//Find the corresponding workerscript and set its flags to kill it
|
||||
for (var i = 0; i < workerScripts.length; ++i) {
|
||||
if (workerScripts[i].serverIp == serverIp && workerScripts[i].name == scriptName) {
|
||||
workerScripts[i].running = false;
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (w instanceof WorkerScript) {
|
||||
if (isScriptErrorMessage(w.errorMessage)) {
|
||||
var errorTextArray = w.errorMessage.split("|");
|
||||
@ -86,31 +66,20 @@ function runScriptsLoop() {
|
||||
var scriptName = errorTextArray[2];
|
||||
var errorMsg = errorTextArray[3];
|
||||
|
||||
dialogBoxCreate("Script runtime error: <br>Server Ip: " + serverIp + "<br>Script name: " + scriptName + "<br>" + errorMsg);
|
||||
dialogBoxCreate("Script runtime error: <br>Server Ip: " + serverIp +
|
||||
"<br>Script name: " + scriptName +
|
||||
"<br>Args:" + printArray(w.args) + "<br>" + errorMsg);
|
||||
w.scriptRef.log("Script crashed with runtime error");
|
||||
} else {
|
||||
w.scriptRef.log("Script killed");
|
||||
}
|
||||
w.running = false;
|
||||
w.env.stopFlag = true;
|
||||
|
||||
} else if (isScriptErrorMessage(w)) {
|
||||
var errorTextArray = errorText.split("|");
|
||||
if (errorTextArray.length != 4) {
|
||||
console.log("ERROR: Something wrong with Error text in evaluator...");
|
||||
console.log("Error text: " + errorText);
|
||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
||||
console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN");
|
||||
return;
|
||||
}
|
||||
var serverIp = errorTextArray[1];
|
||||
var scriptName = errorTextArray[2];
|
||||
var errorMsg = errorTextArray[3];
|
||||
|
||||
dialogBoxCreate("Script runtime error: <br>Server Ip: " + serverIp + "<br>Script name: " + scriptName + "<br>" + errorMsg);
|
||||
|
||||
//Find the corresponding workerscript and set its flags to kill it
|
||||
for (var i = 0; i < workerScripts.length; ++i) {
|
||||
if (workerScripts[i].serverIp == serverIp && workerScripts[i].name == scriptName) {
|
||||
workerScripts[i].running = false;
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev");
|
||||
}
|
||||
@ -127,7 +96,8 @@ function runScriptsLoop() {
|
||||
var ip = workerScripts[i].serverIp;
|
||||
var name = workerScripts[i].name;
|
||||
for (var j = 0; j < AllServers[ip].runningScripts.length; j++) {
|
||||
if (AllServers[ip].runningScripts[j] == name) {
|
||||
if (AllServers[ip].runningScripts[j].filename == name &&
|
||||
compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
|
||||
AllServers[ip].runningScripts.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
@ -150,9 +120,10 @@ function runScriptsLoop() {
|
||||
//Queues a script to be killed by settings its stop flag to true. Then, the code will reject
|
||||
//all of its promises recursively, and when it does so it will no longer be running.
|
||||
//The runScriptsLoop() will then delete the script from worker scripts
|
||||
function killWorkerScript(scriptName, serverIp) {
|
||||
function killWorkerScript(runningScriptObj, serverIp) {
|
||||
for (var i = 0; i < workerScripts.length; i++) {
|
||||
if (workerScripts[i].name == scriptName && workerScripts[i].serverIp == serverIp) {
|
||||
if (workerScripts[i].name == runningScriptObj.filename && workerScripts[i].serverIp == serverIp &&
|
||||
compareArrays(workerScripts[i].args, runningScriptObj.args)) {
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
return true;
|
||||
}
|
||||
@ -161,23 +132,21 @@ function killWorkerScript(scriptName, serverIp) {
|
||||
}
|
||||
|
||||
//Queues a script to be run
|
||||
function addWorkerScript(script, server) {
|
||||
var filename = script.filename;
|
||||
function addWorkerScript(runningScriptObj, server) {
|
||||
var filename = runningScriptObj.filename;
|
||||
|
||||
//Update server's ram usage
|
||||
var threads = 1;
|
||||
if (script.threads && !isNaN(script.threads)) {
|
||||
threads = script.threads;
|
||||
if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) {
|
||||
threads = runningScriptObj.threads;
|
||||
} else {
|
||||
script.threads = 1;
|
||||
runningScriptObj.threads = 1;
|
||||
}
|
||||
var ramUsage = script.ramUsage * threads * Math.pow(1.02, threads-1);
|
||||
var ramUsage = runningScriptObj.scriptRef.ramUsage * threads * Math.pow(1.02, threads-1);
|
||||
server.ramUsed += ramUsage;
|
||||
|
||||
//Create the WorkerScript
|
||||
var s = new WorkerScript(script);
|
||||
s.name = filename;
|
||||
s.code = script.code;
|
||||
var s = new WorkerScript(runningScriptObj);
|
||||
s.serverIp = server.ip;
|
||||
s.ramUsage = ramUsage;
|
||||
|
||||
|
@ -213,7 +213,7 @@ PlayerObject.prototype.updateSkillLevels = function() {
|
||||
//The formula is:
|
||||
// (2 * hacking_chance_multiplier * hacking_skill - requiredLevel) 100 - difficulty
|
||||
// ----------------------------------------------------------- * -----------------
|
||||
// (hacking_chance_multiplier * hacking_skill) 100
|
||||
// (2 * hacking_chance_multiplier * hacking_skill) 100
|
||||
PlayerObject.prototype.calculateHackingChance = function() {
|
||||
var difficultyMult = (100 - this.getCurrentServer().hackDifficulty) / 100;
|
||||
var skillMult = (2 * this.hacking_chance_mult * this.hacking_skill);
|
||||
@ -254,7 +254,11 @@ PlayerObject.prototype.calculatePercentMoneyHacked = function() {
|
||||
//The formula is:
|
||||
// difficulty * requiredLevel * hacking_multiplier
|
||||
PlayerObject.prototype.calculateExpGain = function() {
|
||||
return (this.getCurrentServer().hackDifficulty * this.hacking_exp_mult * 0.9);
|
||||
var s = this.getCurrentServer();
|
||||
if (s.baseDifficulty == null) {
|
||||
s.baseDifficulty = s.hackDifficulty;
|
||||
}
|
||||
return (s.baseDifficulty * this.hacking_exp_mult * 0.5 + 4);
|
||||
}
|
||||
|
||||
//Hack/Analyze a server. Return the amount of time the hack will take. This lets the Terminal object know how long to disable itself for
|
||||
|
@ -107,7 +107,7 @@ function prestigeAugmentation() {
|
||||
|
||||
Player.lastUpdate = new Date().getTime();
|
||||
|
||||
//Delete all running scripts objects
|
||||
//Delete all Worker Scripts objects
|
||||
for (var i = 0; i < workerScripts.length; ++i) {
|
||||
deleteActiveScriptsItem(workerScripts[i]);
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
@ -158,7 +158,6 @@ function prestigeAugmentation() {
|
||||
//Reset statistics of all scripts on home computer
|
||||
for (var i = 0; i < homeComp.scripts.length; ++i) {
|
||||
var s = homeComp.scripts[i];
|
||||
s.reset();
|
||||
}
|
||||
//Delete messages on home computer
|
||||
homeComp.messages.length = 0;
|
||||
|
316
src/Script.js
316
src/Script.js
@ -72,14 +72,6 @@ function saveAndCloseScriptEditor() {
|
||||
|
||||
filename += ".script";
|
||||
|
||||
//If the current script matches one thats currently running, throw an error
|
||||
for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) {
|
||||
if (filename == Player.getCurrentServer().runningScripts[i].filename) {
|
||||
dialogBoxCreate("Cannot write to script that is currently running!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If the current script already exists on the server, overwrite it
|
||||
for (var i = 0; i < Player.getCurrentServer().scripts.length; i++) {
|
||||
if (filename == Player.getCurrentServer().scripts[i].filename) {
|
||||
@ -112,22 +104,6 @@ function Script() {
|
||||
this.code = "";
|
||||
this.ramUsage = 0;
|
||||
this.server = ""; //IP of server this script is on
|
||||
this.logs = []; //Script logging. Array of strings, with each element being a log entry
|
||||
|
||||
//Stats to display on the Scripts menu, and used to determine offline progress
|
||||
this.offlineRunningTime = 0.01; //Seconds
|
||||
this.offlineMoneyMade = 0;
|
||||
this.offlineExpGained = 0;
|
||||
this.onlineRunningTime = 0.01; //Seconds
|
||||
this.onlineMoneyMade = 0;
|
||||
this.onlineExpGained = 0;
|
||||
|
||||
this.moneyStolenMap = new AllServersMap();
|
||||
this.numTimesHackMap = new AllServersMap();
|
||||
this.numTimesGrowMap = new AllServersMap();
|
||||
this.numTimesWeakenMap = new AllServersMap();
|
||||
|
||||
this.threads = 1;
|
||||
};
|
||||
|
||||
//Get the script data from the Script Editor and save it to the object
|
||||
@ -145,65 +121,9 @@ Script.prototype.saveScript = function() {
|
||||
|
||||
//Calculate/update ram usage, execution time, etc.
|
||||
this.updateRamUsage();
|
||||
|
||||
//Clear the stats when the script is updated
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
Script.prototype.reset = function() {
|
||||
this.updateRamUsage();
|
||||
|
||||
this.offlineRunningTime = 0.01; //Seconds
|
||||
this.offlineMoneyMade = 0;
|
||||
this.offlineExpGained = 0;
|
||||
this.onlineRunningTime = 0.01; //Seconds
|
||||
this.onlineMoneyMade = 0;
|
||||
this.onlineExpGained = 0;
|
||||
this.logs = [];
|
||||
|
||||
if (this.moneyStolenMap != null) {
|
||||
try {
|
||||
this.moneyStolenMap.reset();
|
||||
} catch(e) {
|
||||
this.moneyStolenMap = null;
|
||||
}
|
||||
} else {
|
||||
this.moneyStolenMap = new AllServersMap();
|
||||
}
|
||||
|
||||
if (this.numTimesHackMap != null) {
|
||||
try {
|
||||
this.numTimesHackMap.reset();
|
||||
} catch(e) {
|
||||
this.numTimesHackMap = null;
|
||||
}
|
||||
} else {
|
||||
this.numTimesHackMap = new AllServersMap();
|
||||
}
|
||||
|
||||
if (this.numTimesGrowMap != null) {
|
||||
try {
|
||||
this.numTimesGrowMap.reset();
|
||||
} catch(e) {
|
||||
this.numTimesGrowMap = null;
|
||||
}
|
||||
} else {
|
||||
this.numTimesGrowMap = new AllServersMap();
|
||||
}
|
||||
|
||||
if (this.numTimesWeakenMap != null) {
|
||||
try {
|
||||
this.numTimesWeakenMap.reset();
|
||||
} catch(e) {
|
||||
this.numTimesWeakenMap = null;
|
||||
}
|
||||
} else {
|
||||
this.numTimesWeakenMap = new AllServersMap();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Updates how much RAM the script uses when it is running.
|
||||
Script.prototype.updateRamUsage = function() {
|
||||
var baseRam = 1.4;
|
||||
@ -276,50 +196,6 @@ Script.prototype.updateRamUsage = function() {
|
||||
}
|
||||
}
|
||||
|
||||
Script.prototype.log = function(txt) {
|
||||
if (this.logs.length > CONSTANTS.MaxLogCapacity) {
|
||||
//Delete first element and add new log entry to the end.
|
||||
//TODO Eventually it might be better to replace this with circular array
|
||||
//to improve performance
|
||||
this.logs.shift();
|
||||
}
|
||||
this.logs.push(txt);
|
||||
}
|
||||
|
||||
Script.prototype.displayLog = function() {
|
||||
for (var i = 0; i < this.logs.length; ++i) {
|
||||
post(this.logs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Update the moneyStolen and numTimesHack maps when hacking
|
||||
Script.prototype.recordHack = function(serverIp, moneyGained, n=1) {
|
||||
if (this.moneyStolenMap == null) {
|
||||
this.moneyStolenMap = new AllServersMap();
|
||||
}
|
||||
if (this.numTimesHackMap == null) {
|
||||
this.numTimesHackMap = new AllServersMap();
|
||||
}
|
||||
this.moneyStolenMap[serverIp] += moneyGained;
|
||||
this.numTimesHackMap[serverIp] += n;
|
||||
}
|
||||
|
||||
//Update the grow map when calling grow()
|
||||
Script.prototype.recordGrow = function(serverIp, n=1) {
|
||||
if (this.numTimesGrowMap == null) {
|
||||
this.numTimesGrowMap = new AllServersMap();
|
||||
}
|
||||
this.numTimesGrowMap[serverIp] += n;
|
||||
}
|
||||
|
||||
//Update the weaken map when calling weaken() {
|
||||
Script.prototype.recordWeaken = function(serverIp, n=1) {
|
||||
if (this.numTimesWeakenMap == null) {
|
||||
this.numTimesWeakenMap = new AllServersMap();
|
||||
}
|
||||
this.numTimesWeakenMap[serverIp] += n;
|
||||
}
|
||||
|
||||
Script.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Script", this);
|
||||
}
|
||||
@ -331,7 +207,6 @@ Script.fromJSON = function(value) {
|
||||
|
||||
Reviver.constructors.Script = Script;
|
||||
|
||||
|
||||
//Called when the game is loaded. Loads all running scripts (from all servers)
|
||||
//into worker scripts so that they will start running
|
||||
loadAllRunningScripts = function() {
|
||||
@ -346,13 +221,10 @@ loadAllRunningScripts = function() {
|
||||
|
||||
for (var j = 0; j < server.runningScripts.length; ++j) {
|
||||
count++;
|
||||
//runningScripts array contains only names, so find the actual script object
|
||||
var script = server.getScript(server.runningScripts[j]);
|
||||
if (script == null) {continue;}
|
||||
addWorkerScript(script, server);
|
||||
addWorkerScript(server.runningScripts[j], server);
|
||||
|
||||
//Offline production
|
||||
total += scriptCalculateOfflineProduction(script);
|
||||
total += scriptCalculateOfflineProduction(server.runningScripts[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -360,7 +232,7 @@ loadAllRunningScripts = function() {
|
||||
console.log("Loaded " + count.toString() + " running scripts");
|
||||
}
|
||||
|
||||
scriptCalculateOfflineProduction = function(script) {
|
||||
scriptCalculateOfflineProduction = function(runningScriptObj) {
|
||||
//The Player object stores the last update time from when we were online
|
||||
var thisUpdate = new Date().getTime();
|
||||
var lastUpdate = Player.lastUpdate;
|
||||
@ -370,26 +242,38 @@ scriptCalculateOfflineProduction = function(script) {
|
||||
//Calculate the "confidence" rating of the script's true production. This is based
|
||||
//entirely off of time. We will arbitrarily say that if a script has been running for
|
||||
//4 hours (14400 sec) then we are completely confident in its ability
|
||||
var confidence = (script.onlineRunningTime) / 14400;
|
||||
var confidence = (runningScriptObj.onlineRunningTime) / 14400;
|
||||
if (confidence >= 1) {confidence = 1;}
|
||||
console.log("onlineRunningTime: " + script.onlineRunningTime);
|
||||
console.log("Confidence: " + confidence);
|
||||
|
||||
var totalOfflineProduction = 0;
|
||||
for (var ip in script.moneyStolenMap) {
|
||||
if (script.moneyStolenMap.hasOwnProperty(ip)) {
|
||||
if (script.moneyStolenMap[ip] == 0 || script.moneyStolenMap[ip] == null) {continue;}
|
||||
//Grow
|
||||
for (var ip in runningScriptObj.numTimesGrowMap) {
|
||||
if (runningScriptObj.numTimesGrowMap.hasOwnProperty(ip)) {
|
||||
if (runningScriptObj.numTimesGrowMap[ip] == 0 || runningScriptObj.numTimesGrowMap[ip] == null) {continue;}
|
||||
var serv = AllServers[ip];
|
||||
if (serv == null) {continue;}
|
||||
var production = 0.5 * script.moneyStolenMap[ip] / script.onlineRunningTime * timePassed;
|
||||
var timesGrown = Math.round(0.5 * runningScriptObj.numTimesGrowMap[ip] / runningScriptObj.onlineRunningTime * timePassed);
|
||||
console.log(runningScriptObj.filename + " called grow() on " + serv.hostname + " " + timesGrown + " times while offline");
|
||||
runningScriptObj.log("Called grow() on " + serv.hostname + " " + timesGrown + " times while offline");
|
||||
var growth = processSingleServerGrowth(serv, timesGrown * 450);
|
||||
runningScriptObj.log(serv.hostname + " grown by " + formatNumber(growth * 100 - 100, 6) + "% from grow() calls made while offline");
|
||||
}
|
||||
}
|
||||
|
||||
var totalOfflineProduction = 0;
|
||||
for (var ip in runningScriptObj.moneyStolenMap) {
|
||||
if (runningScriptObj.moneyStolenMap.hasOwnProperty(ip)) {
|
||||
if (runningScriptObj.moneyStolenMap[ip] == 0 || runningScriptObj.moneyStolenMap[ip] == null) {continue;}
|
||||
var serv = AllServers[ip];
|
||||
if (serv == null) {continue;}
|
||||
var production = 0.5 * runningScriptObj.moneyStolenMap[ip] / runningScriptObj.onlineRunningTime * timePassed;
|
||||
production *= confidence;
|
||||
if (production > serv.moneyAvailable) {
|
||||
production = serv.moneyAvailable;
|
||||
}
|
||||
totalOfflineProduction += production;
|
||||
Player.gainMoney(production);
|
||||
console.log(script.filename + " generated $" + production + " while offline by hacking " + serv.hostname);
|
||||
script.log(script.filename + " generated $" + production + " while offline by hacking " + serv.hostname);
|
||||
console.log(runningScriptObj.filename + " generated $" + production + " while offline by hacking " + serv.hostname);
|
||||
runningScriptObj.log(runningScriptObj.filename + " generated $" + production + " while offline by hacking " + serv.hostname);
|
||||
serv.moneyAvailable -= production;
|
||||
if (serv.moneyAvailable < 0) {serv.moneyAvailable = 0;}
|
||||
}
|
||||
@ -397,60 +281,148 @@ scriptCalculateOfflineProduction = function(script) {
|
||||
|
||||
//Offline EXP gain
|
||||
//A script's offline production will always be at most half of its online production.
|
||||
var expGain = 0.5 * (script.onlineExpGained / script.onlineRunningTime) * timePassed;
|
||||
var expGain = 0.5 * (runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime) * timePassed;
|
||||
expGain *= confidence;
|
||||
|
||||
Player.gainHackingExp(expGain);
|
||||
|
||||
//Update script stats
|
||||
script.offlineMoneyMade += totalOfflineProduction;
|
||||
script.offlineRunningTime += timePassed;
|
||||
script.offlineExpGained += expGain;
|
||||
runningScriptObj.offlineMoneyMade += totalOfflineProduction;
|
||||
runningScriptObj.offlineRunningTime += timePassed;
|
||||
runningScriptObj.offlineExpGained += expGain;
|
||||
|
||||
//Fortify a server's security based on how many times it was hacked
|
||||
for (var ip in script.numTimesHackMap) {
|
||||
if (script.numTimesHackMap.hasOwnProperty(ip)) {
|
||||
if (script.numTimesHackMap[ip] == 0 || script.numTimesHackMap[ip] == null) {continue;}
|
||||
for (var ip in runningScriptObj.numTimesHackMap) {
|
||||
if (runningScriptObj.numTimesHackMap.hasOwnProperty(ip)) {
|
||||
if (runningScriptObj.numTimesHackMap[ip] == 0 || runningScriptObj.numTimesHackMap[ip] == null) {continue;}
|
||||
var serv = AllServers[ip];
|
||||
if (serv == null) {continue;}
|
||||
var timesHacked = Math.round(0.5 * script.numTimesHackMap[ip] / script.onlineRunningTime * timePassed);
|
||||
console.log(script.filename + " hacked " + serv.hostname + " " + timesHacked + " times while offline");
|
||||
script.log("Hacked " + serv.hostname + " " + timesHacked + " times while offline");
|
||||
var timesHacked = Math.round(0.5 * runningScriptObj.numTimesHackMap[ip] / runningScriptObj.onlineRunningTime * timePassed);
|
||||
console.log(runningScriptObj.filename + " hacked " + serv.hostname + " " + timesHacked + " times while offline");
|
||||
runningScriptObj.log("Hacked " + serv.hostname + " " + timesHacked + " times while offline");
|
||||
serv.fortify(CONSTANTS.ServerFortifyAmount * timesHacked);
|
||||
}
|
||||
}
|
||||
|
||||
//Weaken
|
||||
for (var ip in script.numTimesWeakenMap) {
|
||||
if (script.numTimesWeakenMap.hasOwnProperty(ip)) {
|
||||
if (script.numTimesWeakenMap[ip] == 0 || script.numTimesWeakenMap[ip] == null) {continue;}
|
||||
for (var ip in runningScriptObj.numTimesWeakenMap) {
|
||||
if (runningScriptObj.numTimesWeakenMap.hasOwnProperty(ip)) {
|
||||
if (runningScriptObj.numTimesWeakenMap[ip] == 0 || runningScriptObj.numTimesWeakenMap[ip] == null) {continue;}
|
||||
var serv = AllServers[ip];
|
||||
if (serv == null) {continue;}
|
||||
var timesWeakened = Math.round(0.5 * script.numTimesWeakenMap[ip] / script.onlineRunningTime * timePassed);
|
||||
console.log(script.filename + " called weaken() on " + serv.hostname + " " + timesWeakened + " times while offline");
|
||||
script.log("Called weaken() on " + serv.hostname + " " + timesWeakened + " times while offline");
|
||||
var timesWeakened = Math.round(0.5 * runningScriptObj.numTimesWeakenMap[ip] / runningScriptObj.onlineRunningTime * timePassed);
|
||||
console.log(runningScriptObj.filename + " called weaken() on " + serv.hostname + " " + timesWeakened + " times while offline");
|
||||
runningScriptObj.log("Called weaken() on " + serv.hostname + " " + timesWeakened + " times while offline");
|
||||
serv.weaken(CONSTANTS.ServerWeakenAmount * timesWeakened);
|
||||
}
|
||||
}
|
||||
|
||||
//Grow
|
||||
for (var ip in script.numTimesGrowMap) {
|
||||
if (script.numTimesGrowMap.hasOwnProperty(ip)) {
|
||||
if (script.numTimesGrowMap[ip] == 0 || script.numTimesGrowMap[ip] == null) {continue;}
|
||||
var serv = AllServers[ip];
|
||||
if (serv == null) {continue;}
|
||||
var timesGrown = Math.round(0.5 * script.numTimesGrowMap[ip] / script.onlineRunningTime * timePassed);
|
||||
console.log(script.filename + " called grow() on " + serv.hostname + " " + timesGrown + " times while offline");
|
||||
script.log("Called grow() on " + serv.hostname + " " + timesGrown + " times while offline");
|
||||
var growth = processSingleServerGrowth(serv, timesGrown * 450);
|
||||
script.log(serv.hostname + " grown by " + formatNumber(growth * 100 - 100, 6) + "% from grow() calls made while offline");
|
||||
}
|
||||
}
|
||||
|
||||
return totalOfflineProduction;
|
||||
}
|
||||
|
||||
//Creates a function that creates a map/dictionary with the IP of each existing server as
|
||||
//Returns a RunningScript object matching the filename and arguments on the
|
||||
//designated server, and false otherwise
|
||||
function findRunningScript(filename, args, server) {
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i].filename == filename &&
|
||||
compareArrays(server.runningScripts[i].args, args)) {
|
||||
return server.runningScripts[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function RunningScript(script, args) {
|
||||
if (script == null || script == undefined) {return;}
|
||||
this.filename = script.filename;
|
||||
this.args = args;
|
||||
this.scriptRef = script;
|
||||
this.server = script.server; //IP Address only
|
||||
|
||||
this.logs = []; //Script logging. Array of strings, with each element being a log entry
|
||||
|
||||
//Stats to display on the Scripts menu, and used to determine offline progress
|
||||
this.offlineRunningTime = 0.01; //Seconds
|
||||
this.offlineMoneyMade = 0;
|
||||
this.offlineExpGained = 0;
|
||||
this.onlineRunningTime = 0.01; //Seconds
|
||||
this.onlineMoneyMade = 0;
|
||||
this.onlineExpGained = 0;
|
||||
|
||||
this.threads = 1;
|
||||
|
||||
this.moneyStolenMap = new AllServersMap();
|
||||
this.numTimesHackMap = new AllServersMap();
|
||||
this.numTimesGrowMap = new AllServersMap();
|
||||
this.numTimesWeakenMap = new AllServersMap();
|
||||
}
|
||||
|
||||
RunningScript.prototype.reset = function() {
|
||||
this.scriptRef.updateRamUsage();
|
||||
|
||||
this.offlineRunningTime = 0.01; //Seconds
|
||||
this.offlineMoneyMade = 0;
|
||||
this.offlineExpGained = 0;
|
||||
this.onlineRunningTime = 0.01; //Seconds
|
||||
this.onlineMoneyMade = 0;
|
||||
this.onlineExpGained = 0;
|
||||
this.logs = [];
|
||||
}
|
||||
|
||||
RunningScript.prototype.log = function(txt) {
|
||||
if (this.logs.length > CONSTANTS.MaxLogCapacity) {
|
||||
//Delete first element and add new log entry to the end.
|
||||
//TODO Eventually it might be better to replace this with circular array
|
||||
//to improve performance
|
||||
this.logs.shift();
|
||||
}
|
||||
this.logs.push(txt);
|
||||
}
|
||||
|
||||
RunningScript.prototype.displayLog = function() {
|
||||
for (var i = 0; i < this.logs.length; ++i) {
|
||||
post(this.logs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Update the moneyStolen and numTimesHack maps when hacking
|
||||
RunningScript.prototype.recordHack = function(serverIp, moneyGained, n=1) {
|
||||
if (this.moneyStolenMap == null) {
|
||||
this.moneyStolenMap = new AllServersMap();
|
||||
}
|
||||
if (this.numTimesHackMap == null) {
|
||||
this.numTimesHackMap = new AllServersMap();
|
||||
}
|
||||
this.moneyStolenMap[serverIp] += moneyGained;
|
||||
this.numTimesHackMap[serverIp] += n;
|
||||
}
|
||||
|
||||
//Update the grow map when calling grow()
|
||||
RunningScript.prototype.recordGrow = function(serverIp, n=1) {
|
||||
if (this.numTimesGrowMap == null) {
|
||||
this.numTimesGrowMap = new AllServersMap();
|
||||
}
|
||||
this.numTimesGrowMap[serverIp] += n;
|
||||
}
|
||||
|
||||
//Update the weaken map when calling weaken() {
|
||||
RunningScript.prototype.recordWeaken = function(serverIp, n=1) {
|
||||
if (this.numTimesWeakenMap == null) {
|
||||
this.numTimesWeakenMap = new AllServersMap();
|
||||
}
|
||||
this.numTimesWeakenMap[serverIp] += n;
|
||||
}
|
||||
|
||||
RunningScript.prototype.toJSON = function() {
|
||||
return Generic_toJSON("RunningScript", this);
|
||||
}
|
||||
|
||||
|
||||
RunningScript.fromJSON = function(value) {
|
||||
return Generic_fromJSON(RunningScript, value.data);
|
||||
}
|
||||
|
||||
//Creates an object that creates a map/dictionary with the IP of each existing server as
|
||||
//a key, and 0 as the value. This is used to keep track of how much money a script
|
||||
//hacks from that server
|
||||
function AllServersMap() {
|
||||
|
@ -21,7 +21,7 @@ function Server() {
|
||||
this.cpuSpeed = 1; //MHz
|
||||
|
||||
this.scripts = [];
|
||||
this.runningScripts = []; //Names (and only names) of scripts being run
|
||||
this.runningScripts = []; //Stores RunningScript objects
|
||||
this.programs = [];
|
||||
this.messages = [];
|
||||
|
||||
|
221
src/Terminal.js
221
src/Terminal.js
@ -2,18 +2,18 @@
|
||||
|
||||
/* Write text to terminal */
|
||||
var post = function(input) {
|
||||
$("#terminal-input").before('<tr class="posted"><td style="color: #66ff33;">' + input.replace( / /g, " " ) + '</td></tr>');
|
||||
$("#terminal-input").before('<tr class="posted"><td style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input.replace( / /g, " " ) + '</td></tr>');
|
||||
updateTerminalScroll();
|
||||
}
|
||||
|
||||
//Same thing as post but the td cells have ids so they can be animated for the hack progress bar
|
||||
var hackProgressBarPost = function(input) {
|
||||
$("#terminal-input").before('<tr class="posted"><td id="hack-progress-bar" style="color: #66ff33;">' + input + '</td></tr>');
|
||||
$("#terminal-input").before('<tr class="posted"><td id="hack-progress-bar" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
|
||||
updateTerminalScroll();
|
||||
}
|
||||
|
||||
var hackProgressPost = function(input) {
|
||||
$("#terminal-input").before('<tr class="posted"><td id="hack-progress" style="color: #66ff33;">' + input + '</td></tr>');
|
||||
$("#terminal-input").before('<tr class="posted"><td id="hack-progress" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
|
||||
updateTerminalScroll();
|
||||
}
|
||||
|
||||
@ -235,10 +235,16 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
|
||||
|
||||
//Autocomplete the command
|
||||
if (index == -1) {
|
||||
return ["alias", "analyze", "cat", "clear", "cls", "connect", "free",
|
||||
return ["alias", "analyze", "cat", "check", "clear", "cls", "connect", "free",
|
||||
"hack", "help", "home", "hostname", "ifconfig", "kill", "killall",
|
||||
"ls", "mem", "nano", "ps", "rm", "run", "scan", "scan-analyze",
|
||||
"scp", "sudov", "tail", "top"];
|
||||
"scp", "sudov", "tail", "theme", "top"];
|
||||
}
|
||||
|
||||
if (input.startsWith ("buy ")) {
|
||||
return [Programs.BruteSSHProgram, Programs.FTPCrackProgram, Programs.RelaySMTPProgram,
|
||||
Programs.HTTPWormProgram, Programs.SQLInjectProgram, Programs.DeepscanV1,
|
||||
Programs.DeepscanV2];
|
||||
}
|
||||
|
||||
if (input.startsWith("scp ") && index == 1) {
|
||||
@ -263,7 +269,7 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
|
||||
|
||||
if (input.startsWith("kill ") || input.startsWith("nano ") ||
|
||||
input.startsWith("tail ") || input.startsWith("rm ") ||
|
||||
input.startsWith("mem ") ||
|
||||
input.startsWith("mem ") || input.startsWith("check ") ||
|
||||
(input.startsWith("scp ") && index == 0)) {
|
||||
//All Scripts
|
||||
for (var i = 0; i < currServ.scripts.length; ++i) {
|
||||
@ -564,6 +570,7 @@ var Terminal = {
|
||||
/****************** END INTERACTIVE TUTORIAL ******************/
|
||||
|
||||
/* Command parser */
|
||||
var s = Player.getCurrentServer();
|
||||
switch (commandArray[0].toLowerCase()) {
|
||||
case "alias":
|
||||
if (commandArray.length == 1) {
|
||||
@ -595,7 +602,11 @@ var Terminal = {
|
||||
$('input[class=terminal-input]').prop('disabled', true);
|
||||
break;
|
||||
case "buy":
|
||||
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||
executeDarkwebTerminalCommand(commandArray);
|
||||
} else {
|
||||
post("You need to be connected to the Dark Web to use the buy command");
|
||||
}
|
||||
break;
|
||||
case "cat":
|
||||
if (commandArray.length != 2) {
|
||||
@ -606,7 +617,6 @@ var Terminal = {
|
||||
if (filename.endsWith(".msg") == false) {
|
||||
post("Error: Only .msg files are viewable with cat (filename must end with .msg)"); return;
|
||||
}
|
||||
var s = Player.getCurrentServer();
|
||||
for (var i = 0; i < s.messages.length; ++i) {
|
||||
if (s.messages[i].filename == filename) {
|
||||
showMessage(s.messages[i]);
|
||||
@ -614,6 +624,31 @@ var Terminal = {
|
||||
}
|
||||
}
|
||||
post("Error: No such file " + filename);
|
||||
break;
|
||||
case "check":
|
||||
if (commandArray.length < 2) {
|
||||
post("Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...");
|
||||
} else {
|
||||
var results = commandArray[1].split(" ");
|
||||
var scriptName = results[0];
|
||||
var args = [];
|
||||
for (var i = 1; i < results.length; ++i) {
|
||||
args.push(results[i]);
|
||||
}
|
||||
|
||||
//Can only tail script files
|
||||
if (scriptName.endsWith(".script") == false) {
|
||||
post("Error: tail can only be called on .script files (filename must end with .script)"); return;
|
||||
}
|
||||
|
||||
//Check that the script exists on this machine
|
||||
var runningScript = findRunningScript(scriptName, args, s);
|
||||
if (runningScript == null) {
|
||||
post("Error: No such script exists");
|
||||
return;
|
||||
}
|
||||
logBoxCreate(runningScript);
|
||||
}
|
||||
break;
|
||||
case "clear":
|
||||
case "cls":
|
||||
@ -704,23 +739,25 @@ var Terminal = {
|
||||
post(Player.getCurrentServer().ip);
|
||||
break;
|
||||
case "kill":
|
||||
if (commandArray.length != 2) {
|
||||
post("Incorrect usage of kill command. Usage: kill [scriptname]"); return;
|
||||
if (commandArray.length < 2) {
|
||||
post("Incorrect usage of kill command. Usage: kill [scriptname] [arg1] [arg2]..."); return;
|
||||
}
|
||||
|
||||
var scriptName = commandArray[1];
|
||||
for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) {
|
||||
if (Player.getCurrentServer().runningScripts[i] == scriptName) {
|
||||
killWorkerScript(scriptName, Player.getCurrentServer().ip);
|
||||
post("Killing " + scriptName + ". May take up to a few minutes for the scripts to die...");
|
||||
var results = commandArray[1].split(" ");
|
||||
var scriptName = results[0];
|
||||
var args = [];
|
||||
for (var i = 1; i < results.length; ++i) {
|
||||
args.push(results[i]);
|
||||
}
|
||||
var runningScript = findRunningScript(scriptName, args, s);
|
||||
if (runningScript == null) {
|
||||
post("No such script is running. Nothing to kill");
|
||||
return;
|
||||
}
|
||||
}
|
||||
post("No such script is running. Nothing to kill");
|
||||
killWorkerScript(runningScript, s.ip);
|
||||
post("Killing " + scriptName + ". May take up to a few minutes for the scripts to die...");
|
||||
break;
|
||||
case "killall":
|
||||
var s = Player.getCurrentServer();
|
||||
for (var i = s.runningScripts.length; i >= 0; --i) {
|
||||
for (var i = s.runningScripts.length-1; i >= 0; --i) {
|
||||
killWorkerScript(s.runningScripts[i], s.ip);
|
||||
}
|
||||
post("Killing all running scripts. May take up to a few minutes for the scripts to die...");
|
||||
@ -788,8 +825,13 @@ var Terminal = {
|
||||
if (commandArray.length != 1) {
|
||||
post("Incorrect usage of ps command. Usage: ps"); return;
|
||||
}
|
||||
for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) {
|
||||
post(Player.getCurrentServer().runningScripts[i]);
|
||||
for (var i = 0; i < s.runningScripts.length; i++) {
|
||||
var rsObj = s.runningScripts[i];
|
||||
var res = rsObj.filename;
|
||||
for (var j = 0; j < rsObj.args.length; ++j) {
|
||||
res += (" " + rsObj.args[j].toString());
|
||||
}
|
||||
post(res);
|
||||
}
|
||||
break;
|
||||
case "rm":
|
||||
@ -799,7 +841,6 @@ var Terminal = {
|
||||
|
||||
//Check programs
|
||||
var delTarget = commandArray[1];
|
||||
var s = Player.getCurrentServer();
|
||||
for (var i = 0; i < s.programs.length; ++i) {
|
||||
if (s.programs[i] == delTarget) {
|
||||
s.programs.splice(i, 1);
|
||||
@ -811,11 +852,13 @@ var Terminal = {
|
||||
for (var i = 0; i < s.scripts.length; ++i) {
|
||||
if (s.scripts[i].filename == delTarget) {
|
||||
//Check that the script isnt currently running
|
||||
if (s.runningScripts.indexOf(delTarget) > -1) {
|
||||
for (var j = 0; j < s.runningScripts.length; ++j) {
|
||||
if (s.runningScripts[j].filename == delTarget) {
|
||||
post("Cannot delete a script that is currently running!");
|
||||
} else {
|
||||
s.scripts.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
s.scripts.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -825,7 +868,7 @@ var Terminal = {
|
||||
case "run":
|
||||
//Run a program or a script
|
||||
if (commandArray.length != 2) {
|
||||
post("Incorrect number of arguments. Usage: run [program/script] [-t] [number threads]");
|
||||
post("Incorrect number of arguments. Usage: run [program/script] [-t] [num threads] [arg1] [arg2]...");
|
||||
} else {
|
||||
var executableName = commandArray[1];
|
||||
//Check if its a script or just a program/executable
|
||||
@ -931,10 +974,15 @@ var Terminal = {
|
||||
}
|
||||
break;
|
||||
case "tail":
|
||||
if (commandArray.length != 2) {
|
||||
post("Incorrect number of arguments. Usage: tail [script]");
|
||||
if (commandArray.length < 2) {
|
||||
post("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
|
||||
} else {
|
||||
var scriptName = commandArray[1];
|
||||
var results = commandArray[1].split(" ");
|
||||
var scriptName = results[0];
|
||||
var args = [];
|
||||
for (var i = 1; i < results.length; ++i) {
|
||||
args.push(results[i]);
|
||||
}
|
||||
|
||||
//Can only tail script files
|
||||
if (scriptName.endsWith(".script") == false) {
|
||||
@ -942,15 +990,50 @@ var Terminal = {
|
||||
}
|
||||
|
||||
//Check that the script exists on this machine
|
||||
var currScripts = Player.getCurrentServer().scripts;
|
||||
for (var i = 0; i < currScripts.length; ++i) {
|
||||
if (scriptName == currScripts[i].filename) {
|
||||
currScripts[i].displayLog();
|
||||
var runningScript = findRunningScript(scriptName, args, s);
|
||||
if (runningScript == null) {
|
||||
post("Error: No such script exists");
|
||||
return;
|
||||
}
|
||||
logBoxCreate(runningScript);
|
||||
}
|
||||
break;
|
||||
case "theme":
|
||||
//todo support theme saving
|
||||
var args = commandArray[1] ? commandArray[1].split(" ") : [];
|
||||
if(args.length != 1 && args.length != 3) {
|
||||
post("Incorrect number of arguments.");
|
||||
post("Usage: theme [default|muted|solarized] | [background color hex] [text color hex] [highlight color hex]");
|
||||
}else if(args.length == 1){
|
||||
var themeName = args[0];
|
||||
if(themeName == "default"){
|
||||
document.body.style.setProperty('--my-highlight-color',"#ffffff");
|
||||
document.body.style.setProperty('--my-font-color',"#66ff33");
|
||||
document.body.style.setProperty('--my-background-color',"#000000");
|
||||
}else if(themeName == "muted"){
|
||||
document.body.style.setProperty('--my-highlight-color',"#ffffff");
|
||||
document.body.style.setProperty('--my-font-color',"#66ff33");
|
||||
document.body.style.setProperty('--my-background-color',"#252527");
|
||||
}else if(themeName == "solarized"){
|
||||
document.body.style.setProperty('--my-highlight-color',"#6c71c4");
|
||||
document.body.style.setProperty('--my-font-color',"#839496");
|
||||
document.body.style.setProperty('--my-background-color',"#002b36");
|
||||
}else{
|
||||
post("Theme not found");
|
||||
}
|
||||
}else{
|
||||
inputBackgroundHex = args[0];
|
||||
inputTextHex = args[1];
|
||||
inputHighlightHex = args[2];
|
||||
if(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputBackgroundHex) &&
|
||||
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputTextHex) &&
|
||||
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputHighlightHex)){
|
||||
document.body.style.setProperty('--my-highlight-color',inputHighlightHex);
|
||||
document.body.style.setProperty('--my-font-color',inputTextHex);
|
||||
document.body.style.setProperty('--my-background-color',inputBackgroundHex);
|
||||
}else{
|
||||
post("Invalid Hex Input for theme");
|
||||
}
|
||||
|
||||
post("Error: No such script exists");
|
||||
}
|
||||
break;
|
||||
case "top":
|
||||
@ -1155,35 +1238,71 @@ var Terminal = {
|
||||
var server = Player.getCurrentServer();
|
||||
|
||||
var numThreads = 1;
|
||||
//Get the number of threads
|
||||
if (scriptName.indexOf(" -t ") != -1) {
|
||||
var args = [];
|
||||
var results = scriptName.split(" ");
|
||||
if (results.length != 3) {
|
||||
post("Invalid use of run command. Usage: run [script] [-t] [number threads]");
|
||||
return;
|
||||
if (results.length <= 0) {
|
||||
post("This is a bug. Please contact developer");
|
||||
}
|
||||
scriptName = results[0];
|
||||
if (results.length > 1) {
|
||||
if (results.length >= 3 && results[1] == "-t") {
|
||||
numThreads = Math.round(Number(results[2]));
|
||||
if (isNaN(numThreads) || numThreads < 1) {
|
||||
post("Invalid number of threads specified. Number of threads must be greater than 0");
|
||||
return;
|
||||
}
|
||||
scriptName = results[0];
|
||||
for (var i = 3; i < results.length; ++i) {
|
||||
var arg = results[i];
|
||||
|
||||
//Forced string
|
||||
if ((arg.startsWith("'") && arg.endsWith("'")) ||
|
||||
(arg.startsWith('"') && arg.endsWith('"'))) {
|
||||
args.push(arg.slice(1, -1));
|
||||
continue;
|
||||
}
|
||||
//Number
|
||||
var tempNum = Number(arg);
|
||||
if (!isNaN(tempNum)) {
|
||||
args.push(tempNum);
|
||||
continue;
|
||||
}
|
||||
//Otherwise string
|
||||
args.push(arg);
|
||||
}
|
||||
} else {
|
||||
for (var i = 1; i < results.length; ++i) {
|
||||
var arg = results[i];
|
||||
|
||||
//Forced string
|
||||
if ((arg.startsWith("'") && arg.endsWith("'")) ||
|
||||
(arg.startsWith('"') && arg.endsWith('"'))) {
|
||||
args.push(arg.slice(1, -1));
|
||||
continue;
|
||||
}
|
||||
//Number
|
||||
var tempNum = Number(arg);
|
||||
if (!isNaN(tempNum)) {
|
||||
args.push(tempNum);
|
||||
continue;
|
||||
}
|
||||
//Otherwise string
|
||||
args.push(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Check if this script is already running
|
||||
for (var i = 0; i < server.runningScripts.length; i++) {
|
||||
if (server.runningScripts[i] == scriptName) {
|
||||
if (findRunningScript(scriptName, args, server) != null) {
|
||||
post("ERROR: This script is already running. Cannot run multiple instances");
|
||||
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 script = server.scripts[i];
|
||||
script.threads = numThreads;
|
||||
var ramUsage = script.ramUsage * numThreads * Math.pow(1.02, numThreads-1);
|
||||
var ramAvailable = server.maxRam - server.ramUsed;
|
||||
|
||||
@ -1192,13 +1311,17 @@ var Terminal = {
|
||||
return;
|
||||
} else if (ramUsage > ramAvailable){
|
||||
post("This machine does not have enough RAM to run this script with " +
|
||||
script.threads + " threads. Script requires " + ramUsage + "GB of RAM");
|
||||
numThreads + " threads. Script requires " + ramUsage + "GB of RAM");
|
||||
return;
|
||||
} else {
|
||||
//Able to run script
|
||||
post("Running script with " + script.threads + " thread(s). May take a few seconds to start up the process...");
|
||||
server.runningScripts.push(script.filename); //Push onto runningScripts
|
||||
addWorkerScript(script, server);
|
||||
post("Running script with " + numThreads + " thread(s) and args: " + printArray(args) + ".");
|
||||
post("May take a few seconds to start up the process...");
|
||||
var runningScriptObj = new RunningScript(script, args);
|
||||
runningScriptObj.threads = numThreads;
|
||||
server.runningScripts.push(runningScriptObj);
|
||||
|
||||
addWorkerScript(runningScriptObj, server);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -545,6 +545,10 @@ var Engine = {
|
||||
displayCreateProgramContent();
|
||||
}
|
||||
|
||||
if (logBoxOpened) {
|
||||
logBoxUpdateText();
|
||||
}
|
||||
|
||||
Engine.Counters.updateDisplays = 3;
|
||||
}
|
||||
|
||||
@ -908,13 +912,17 @@ var Engine = {
|
||||
return false;
|
||||
});
|
||||
|
||||
//Character Overview Save button
|
||||
var charOverviewSaveButton = document.getElementById("character-overview-save-button");
|
||||
charOverviewSaveButton.addEventListener("click", function() {
|
||||
//Character Overview buttons
|
||||
document.getElementById("character-overview-save-button").addEventListener("click", function() {
|
||||
saveObject.saveGame();
|
||||
return false;
|
||||
});
|
||||
|
||||
document.getElementById("character-overview-options-button").addEventListener("click", function() {
|
||||
gameOptionsBoxOpen();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Script Editor Netscript documentation button
|
||||
var netscriptDocButton = document.getElementById("script-editor-netscript-doc-button");
|
||||
netscriptDocButton.addEventListener("click", function() {
|
||||
|
@ -2,22 +2,6 @@
|
||||
dialogBoxes = [];
|
||||
|
||||
//Close dialog box when clicking outside
|
||||
/*
|
||||
$(document).click(function(event) {
|
||||
if (dialogBoxOpened) {
|
||||
if (!$(event.target).closest('.dialog-box-container').length){
|
||||
--dialogBoxCount;
|
||||
dialogBoxes.splice(0, 1);
|
||||
$(".dialog-box-container").remove();
|
||||
|
||||
if (dialogBoxes.length == 0) {
|
||||
dialogBoxOpened = false;
|
||||
} else {
|
||||
dialogBoxes[0].style.display +
|
||||
}
|
||||
}
|
||||
}
|
||||
});*/
|
||||
$(document).click(function(event) {
|
||||
if (dialogBoxOpened && dialogBoxes.length >= 1) {
|
||||
if (!$(event.target).closest(dialogBoxes[0]).length){
|
||||
@ -34,18 +18,6 @@ $(document).click(function(event) {
|
||||
|
||||
|
||||
//Dialog box close buttons
|
||||
/*
|
||||
$(document).on('click', '.dialog-box-close-button', function( event ) {
|
||||
console.log("clicked close button");
|
||||
if (dialogBoxOpened) {
|
||||
$(this).closest('.dialog-box-container').remove();
|
||||
--dialogBoxCount;
|
||||
if (dialogBoxes.length == 0) {
|
||||
dialogBoxOpened = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
$(document).on('click', '.dialog-box-close-button', function( event ) {
|
||||
if (dialogBoxOpened && dialogBoxes.length >= 1) {
|
||||
dialogBoxes[0].remove();
|
||||
|
@ -33,3 +33,20 @@ function clearEventListeners(elemId) {
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
//Returns true if all elements are equal, and false otherwise
|
||||
//Assumes both arguments are arrays and that there are no nested arrays
|
||||
function compareArrays(a1, a2) {
|
||||
if (a1.length != a2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < a1.length; ++i) {
|
||||
if (a1[i] != a2[i]) {return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function printArray(a) {
|
||||
return "[" + a.join(", ") + "]";
|
||||
}
|
59
utils/LogBox.js
Normal file
59
utils/LogBox.js
Normal file
@ -0,0 +1,59 @@
|
||||
/* Log Box */
|
||||
|
||||
//Close box when clicking outside
|
||||
/*
|
||||
$(document).click(function(event) {
|
||||
if (logBoxOpened) {
|
||||
if ( $(event.target).closest("#log-box-container").get(0) == null ) {
|
||||
logBoxClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
function logBoxInit() {
|
||||
var closeButton = document.getElementById("log-box-close");
|
||||
logBoxClose();
|
||||
|
||||
//Close Dialog box
|
||||
closeButton.addEventListener("click", function() {
|
||||
logBoxClose();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", logBoxInit, false);
|
||||
|
||||
logBoxClose = function() {
|
||||
logBoxOpened = false;
|
||||
var logBox = document.getElementById("log-box-container");
|
||||
logBox.style.display = "none";
|
||||
}
|
||||
|
||||
logBoxOpen = function() {
|
||||
logBoxOpened = true;
|
||||
|
||||
var logBox = document.getElementById("log-box-container");
|
||||
logBox.style.display = "block";
|
||||
}
|
||||
|
||||
|
||||
var logBoxOpened = false;
|
||||
var logBoxCurrentScript = null;
|
||||
//ram argument is in GB
|
||||
logBoxCreate = function(script) {
|
||||
logBoxCurrentScript = script;
|
||||
logBoxOpen();
|
||||
logBoxUpdateText();
|
||||
}
|
||||
|
||||
logBoxUpdateText = function() {
|
||||
var txt = document.getElementById("log-box-text");
|
||||
if (logBoxCurrentScript && logBoxOpened && txt) {
|
||||
txt.innerHTML = logBoxCurrentScript.filename + ":<br>";
|
||||
for (var i = 0; i < logBoxCurrentScript.logs.length; ++i) {
|
||||
txt.innerHTML += logBoxCurrentScript.logs[i];
|
||||
txt.innerHTML += "<br>";
|
||||
}
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ purchaseRamForHomeBoxCreate = function() {
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.40, numUpgrades);
|
||||
var mult = Math.pow(1.43, numUpgrades);
|
||||
cost = cost * mult;
|
||||
|
||||
purchaseRamForHomeBoxSetText("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
|
Loading…
Reference in New Issue
Block a user