Added ENABLE_TIMESTAMPS Fconf Setting. Put a soft-cap on stock price. Cleaned up a number rounding display issue for Gang UI (100.03% territory, etc.). Refactored ActiveSCriptsUI code to use a queue to sequentially run 'tasks' that handle the adding/deleting of items and server panels

This commit is contained in:
danielyxie 2018-05-07 12:25:44 -05:00
parent 9d1bcd989b
commit 96b12f7f68
21 changed files with 294 additions and 135 deletions

Binary file not shown.

Binary file not shown.

@ -779,6 +779,13 @@ scriptKill
Kills all scripts with the specified filename on the target server specified by *hostname/ip*, regardless of arguments. Returns
true if one or more scripts were successfully killed, and false if none were.
getScriptName
^^^^^^^^^^^^^
.. js:function:: getScriptName()
Returns the current script name
getScriptRam
^^^^^^^^^^^^

@ -17,6 +17,22 @@ hacknetnodes
accessed using *hacknetnodes[0]*. The fourth Hacknet Node you purchase will have the name
"hacknet-node-3" and can be accessed using *hacknetnodes[3]*.
Purchasing Hacknet Nodes
^^^^^^^^^^^^^^^^^^^^^^^^
The following is a list of supported functions for purchasing Hacknet Nodes.
.. js:function:: getNextHacknetNodeCost()
Returns the cost of purchasing a new Hacknet Node
.. js:function:: purchaseHacknetNode()
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.
Hacknet Node Member Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -25,6 +41,11 @@ a value to these.
Note that these must be called on an element inside the *hacknetnodes* array, not the array itself.
.. js:attribute:: hacknetnodes[i].name
Returns the name of the corresponding Hacknet Node
.. js:attribute:: hacknetnodes[i].level
Returns the level of the corresponding Hacknet Node

@ -179,7 +179,7 @@
</li>
<li><a href="netscriptfunctions.html#getHostname">getHostname() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getNextHacknetNodeCost">getNextHacknetNodeCost() (built-in function)</a>
<li><a href="netscriptfunctions.html#getNextHacknetNodeCost">getNextHacknetNodeCost() (built-in function)</a>, <a href="netscripthacknetnodeapi.html#getNextHacknetNodeCost">[1]</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getOwnedAugmentations">getOwnedAugmentations() (built-in function)</a>
</li>
@ -191,6 +191,8 @@
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptfunctions.html#getScriptName">getScriptName() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getScriptRam">getScriptRam() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getServerBaseSecurityLevel">getServerBaseSecurityLevel() (built-in function)</a>
@ -240,6 +242,8 @@
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].level">hacknetnodes[i].level (hacknetnodes[i] attribute)</a>
</li>
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].moneyGainRatePerSecond">hacknetnodes[i].moneyGainRatePerSecond (hacknetnodes[i] attribute)</a>
</li>
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].name">hacknetnodes[i].name (hacknetnodes[i] attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
@ -325,7 +329,7 @@
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptsingularityfunctions.html#purchaseAugmentation">purchaseAugmentation() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#purchaseHacknetNode">purchaseHacknetNode() (built-in function)</a>
<li><a href="netscriptfunctions.html#purchaseHacknetNode">purchaseHacknetNode() (built-in function)</a>, <a href="netscripthacknetnodeapi.html#purchaseHacknetNode">[1]</a>
</li>
<li><a href="netscriptsingularityfunctions.html#purchaseProgram">purchaseProgram() (built-in function)</a>
</li>

@ -130,6 +130,7 @@ secrets that you've been searching for.</p>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#rm">rm</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#scriptrunning">scriptRunning</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#scriptkill">scriptKill</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#getscriptname">getScriptName</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#getscriptram">getScriptRam</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethacktime">getHackTime</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#getgrowtime">getGrowTime</a></li>
@ -151,6 +152,7 @@ secrets that you've been searching for.</p>
</li>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a><ul>
<li class="toctree-l3"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknetnodes">hacknetnodes</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscripthacknetnodeapi.html#purchasing-hacknet-nodes">Purchasing Hacknet Nodes</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknet-node-member-variables">Hacknet Node Member Variables</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknet-node-methods">Hacknet Node Methods</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscripthacknetnodeapi.html#example-s">Example(s)</a></li>

@ -131,6 +131,7 @@ to reach out to the developer!</p>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#rm">rm</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#scriptrunning">scriptRunning</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#scriptkill">scriptKill</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#getscriptname">getScriptName</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#getscriptram">getScriptRam</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethacktime">getHackTime</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#getgrowtime">getGrowTime</a></li>
@ -152,6 +153,7 @@ to reach out to the developer!</p>
</li>
<li class="toctree-l1"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknetnodes">hacknetnodes</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html#purchasing-hacknet-nodes">Purchasing Hacknet Nodes</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknet-node-member-variables">Hacknet Node Member Variables</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html#hacknet-node-methods">Hacknet Node Methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html#example-s">Example(s)</a></li>
@ -234,6 +236,7 @@ to reach out to the developer!</p>
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
</ul>

@ -1310,6 +1310,15 @@ by its arguments.</p>
true if one or more scripts were successfully killed, and false if none were.</p>
</dd></dl>
</div>
<div class="section" id="getscriptname">
<h2>getScriptName<a class="headerlink" href="#getscriptname" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getScriptName">
<code class="descname">getScriptName</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getScriptName" title="Permalink to this definition"></a></dt>
<dd><p>Returns the current script name</p>
</dd></dl>
</div>
<div class="section" id="getscriptram">
<h2>getScriptRam<a class="headerlink" href="#getscriptram" title="Permalink to this headline"></a></h2>
@ -1641,6 +1650,7 @@ you create in functions such as <a class="reference external" href="https://deve
<li class="toctree-l3"><a class="reference internal" href="#rm">rm</a></li>
<li class="toctree-l3"><a class="reference internal" href="#scriptrunning">scriptRunning</a></li>
<li class="toctree-l3"><a class="reference internal" href="#scriptkill">scriptKill</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getscriptname">getScriptName</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getscriptram">getScriptRam</a></li>
<li class="toctree-l3"><a class="reference internal" href="#gethacktime">getHackTime</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getgrowtime">getGrowTime</a></li>
@ -1663,6 +1673,7 @@ you create in functions such as <a class="reference external" href="https://deve
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
</ul>

@ -66,12 +66,36 @@ correspond to the number at the end of the name of the Hacknet Node. For example
the first Hacknet Node you purchase will have the name &quot;hacknet-node-0&quot; and can be
accessed using <em>hacknetnodes[0]</em>. The fourth Hacknet Node you purchase will have the name
&quot;hacknet-node-3&quot; and can be accessed using <em>hacknetnodes[3]</em>.</div></blockquote>
</div>
<div class="section" id="purchasing-hacknet-nodes">
<h2>Purchasing Hacknet Nodes<a class="headerlink" href="#purchasing-hacknet-nodes" title="Permalink to this headline"></a></h2>
<p>The following is a list of supported functions for purchasing Hacknet Nodes.</p>
<dl class="function">
<dt id="getNextHacknetNodeCost">
<code class="descname">getNextHacknetNodeCost</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getNextHacknetNodeCost" title="Permalink to this definition"></a></dt>
<dd><p>Returns the cost of purchasing a new Hacknet Node</p>
</dd></dl>
<dl class="function">
<dt id="purchaseHacknetNode">
<code class="descname">purchaseHacknetNode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#purchaseHacknetNode" title="Permalink to this definition"></a></dt>
<dd><p>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.</p>
</dd></dl>
</div>
<div class="section" id="hacknet-node-member-variables">
<h2>Hacknet Node Member Variables<a class="headerlink" href="#hacknet-node-member-variables" title="Permalink to this headline"></a></h2>
<p>The following is a list of member variables for a Hacknet Node object. These variables are read-only, which means you cannot assign
a value to these.</p>
<p>Note that these must be called on an element inside the <em>hacknetnodes</em> array, not the array itself.</p>
<dl class="attribute">
<dt id="hacknetnodes[i].name">
<code class="descclassname">hacknetnodes[i].</code><code class="descname">name</code><a class="headerlink" href="#hacknetnodes[i].name" title="Permalink to this definition"></a></dt>
<dd><p>Returns the name of the corresponding Hacknet Node</p>
</dd></dl>
<dl class="attribute">
<dt id="hacknetnodes[i].level">
<code class="descclassname">hacknetnodes[i].</code><code class="descname">level</code><a class="headerlink" href="#hacknetnodes[i].level" title="Permalink to this definition"></a></dt>
@ -234,6 +258,7 @@ Nodes to a level of at least 75, RAM to at least 8GB, and number of cores to at
<li class="toctree-l2"><a class="reference internal" href="netscriptadvancedfunctions.html"> Advanced Functions</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"> Hacknet Node API</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#hacknetnodes">hacknetnodes</a></li>
<li class="toctree-l3"><a class="reference internal" href="#purchasing-hacknet-nodes">Purchasing Hacknet Nodes</a></li>
<li class="toctree-l3"><a class="reference internal" href="#hacknet-node-member-variables">Hacknet Node Member Variables</a></li>
<li class="toctree-l3"><a class="reference internal" href="#hacknet-node-methods">Hacknet Node Methods</a></li>
<li class="toctree-l3"><a class="reference internal" href="#example-s">Example(s)</a></li>
@ -244,6 +269,7 @@ Nodes to a level of at least 75, RAM to at least 8GB, and number of cores to at
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
</ul>

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -783,6 +783,7 @@ getScriptName
^^^^^^^^^^^^^
.. js:function:: getScriptName()
Returns the current script name
getScriptRam

@ -6,7 +6,7 @@ import {getServer} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {printArray, createElement,
createAccordionElement, removeElement,
removeChildrenFromElement} from "../utils/HelperFunctions.js";
removeChildrenFromElement, exceptionAlert} from "../utils/HelperFunctions.js";
import {logBoxCreate} from "../utils/LogBox.js";
import numeral from "../utils/numeral.min.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
@ -22,58 +22,64 @@ import {formatNumber} from "../utils/StringHelperF
* ...
*/
let ActiveScriptsUI = {};
let ActiveScriptsTasks = []; //Sequentially schedule the creation/deletion of UI elements
function createActiveScriptsServerPanel(server) {
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] != null) {
console.log("WARNING: Tried to create already-existing Active Scripts Server panel. Aborting");
return;
}
var activeScriptsList = document.getElementById("active-scripts-list");
ActiveScriptsTasks.push(function(server) {
let hostname = server.hostname;
let res = createAccordionElement({hdrText:hostname});
let li = res[0];
var hdr = res[1];
let panel = res[2];
var activeScriptsList = document.getElementById("active-scripts-list");
var panelScriptList = createElement("ul");
panel.appendChild(panelScriptList);
activeScriptsList.appendChild(li);
let res = createAccordionElement({hdrText:hostname});
let li = res[0];
var hdr = res[1];
let panel = res[2];
ActiveScriptsUI[hostname] = {
header: hdr,
panel: panel,
panelList: panelScriptList,
scripts: {}, //Holds references to li elements for each active script
scriptHdrs: {}, //Holds references to header elements for each active script
scriptStats: {} //Holds references to the p elements containing text for each active script
};
if (ActiveScriptsUI[hostname] != null) {
console.log("WARNING: Tried to create already-existing Active Scripts Server panel. This is most likely fine. It probably means many scripts just got started up on a new server. Aborting");
return;
}
return li;
var panelScriptList = createElement("ul");
panel.appendChild(panelScriptList);
activeScriptsList.appendChild(li);
ActiveScriptsUI[hostname] = {
header: hdr,
panel: panel,
panelList: panelScriptList,
scripts: {}, //Holds references to li elements for each active script
scriptHdrs: {}, //Holds references to header elements for each active script
scriptStats: {} //Holds references to the p elements containing text for each active script
};
return li;
}.bind(null, server));
}
//Deletes the info for a particular server (Dropdown header + Panel with all info)
//in the Active Scripts page if it exists
function deleteActiveScriptsServerPanel(server) {
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
console.log("WARNING: Tried to delete non-existent Active Scripts Server panel. Aborting");
return;
}
ActiveScriptsTasks.push(function(server) {
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
console.log("WARNING: Tried to delete non-existent Active Scripts Server panel. Aborting");
return;
}
//Make sure it's empty
if (Object.keys(ActiveScriptsUI[hostname].scripts).length > 0) {
console.log("WARNING: Tried to delete Active Scripts Server panel that still has scripts. Aborting");
return;
}
//Make sure it's empty
if (Object.keys(ActiveScriptsUI[hostname].scripts).length > 0) {
console.log("WARNING: Tried to delete Active Scripts Server panel that still has scripts. Aborting");
return;
}
removeElement(ActiveScriptsUI[hostname].panel);
removeElement(ActiveScriptsUI[hostname].header);
delete ActiveScriptsUI[hostname];
removeElement(ActiveScriptsUI[hostname].panel);
removeElement(ActiveScriptsUI[hostname].header);
delete ActiveScriptsUI[hostname];
}.bind(null, server));
}
function addActiveScriptsItem(workerscript) {
//Get server panel
var server = getServer(workerscript.serverIp);
if (server == null) {
console.log("ERROR: Invalid server IP for workerscript in addActiveScriptsItem()");
@ -84,96 +90,116 @@ function addActiveScriptsItem(workerscript) {
createActiveScriptsServerPanel(server);
}
//Create the unique identifier (key) for this script
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i]));
}
var itemName = itemNameArray.join("-");
let res = createAccordionElement({hdrText:workerscript.name});
let li = res[0];
let hdr = res[1];
let panel = res[2];
hdr.classList.remove("accordion-header");
hdr.classList.add("active-scripts-script-header");
panel.classList.remove("accordion-panel");
panel.classList.add("active-scripts-script-panel");
//Handle the constant elements on the panel that don't change after creation
//Threads, args, kill/log button
panel.appendChild(createElement("p", {
innerHTML: "Threads: " + workerscript.scriptRef.threads + "<br>" +
"Args: " + printArray(workerscript.args)
}));
var panelText = createElement("p", {
innerText:"Loading...", fontSize:"14px",
});
updateActiveScriptsText(workerscript, panelText, itemName);
panel.appendChild(panelText);
panel.appendChild(createElement("br"));
panel.appendChild(createElement("span", {
innerText:"Log", class:"active-scripts-button", margin:"4px", padding:"4px",
clickListener:()=>{
logBoxCreate(workerscript.scriptRef);
return false;
ActiveScriptsTasks.push(function(workerscript, hostname) {
//Create the unique identifier (key) for this script
var itemNameArray = ["active", "scripts", hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i]));
}
}));
panel.appendChild(createElement("span", {
innerText:"Kill Script", class:"active-scripts-button", margin:"4px", padding:"4px",
clickListener:()=>{
killWorkerScript(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
dialogBoxCreate("Killing script, may take a few minutes to complete...");
return false;
}
}));
var itemName = itemNameArray.join("-");
//Append element to list
ActiveScriptsUI[hostname]["panelList"].appendChild(li);
ActiveScriptsUI[hostname].scripts[itemName] = li;
ActiveScriptsUI[hostname].scriptHdrs[itemName] = hdr;
ActiveScriptsUI[hostname].scriptStats[itemName] = panelText;
let res = createAccordionElement({hdrText:workerscript.name});
let li = res[0];
let hdr = res[1];
let panel = res[2];
hdr.classList.remove("accordion-header");
hdr.classList.add("active-scripts-script-header");
panel.classList.remove("accordion-panel");
panel.classList.add("active-scripts-script-panel");
//Handle the constant elements on the panel that don't change after creation
//Threads, args, kill/log button
panel.appendChild(createElement("p", {
innerHTML: "Threads: " + workerscript.scriptRef.threads + "<br>" +
"Args: " + printArray(workerscript.args)
}));
var panelText = createElement("p", {
innerText:"Loading...", fontSize:"14px",
});
panel.appendChild(panelText);
panel.appendChild(createElement("br"));
panel.appendChild(createElement("span", {
innerText:"Log", class:"active-scripts-button", margin:"4px", padding:"4px",
clickListener:()=>{
logBoxCreate(workerscript.scriptRef);
return false;
}
}));
panel.appendChild(createElement("span", {
innerText:"Kill Script", class:"active-scripts-button", margin:"4px", padding:"4px",
clickListener:()=>{
killWorkerScript(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
dialogBoxCreate("Killing script, may take a few minutes to complete...");
return false;
}
}));
//Append element to list
ActiveScriptsUI[hostname]["panelList"].appendChild(li);
ActiveScriptsUI[hostname].scripts[itemName] = li;
ActiveScriptsUI[hostname].scriptHdrs[itemName] = hdr;
ActiveScriptsUI[hostname].scriptStats[itemName] = panelText;
}.bind(null, workerscript, hostname));
}
function deleteActiveScriptsItem(workerscript) {
var server = getServer(workerscript.serverIp);
if (server == null) {
console.log("ERROR: Invalid server IP for workerscript.");
return;
}
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
console.log("ERROR: Trying to delete Active Script UI Element with a hostname that cant be found in ActiveScriptsUI: " + hostname);
return;
}
ActiveScriptsTasks.push(function(workerscript) {
var server = getServer(workerscript.serverIp);
if (server == null) {
console.log("ERROR: Invalid server IP for workerscript.");
return;
}
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
console.log("ERROR: Trying to delete Active Script UI Element with a hostname that cant be found in ActiveScriptsUI: " + hostname);
return;
}
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i]));
}
var itemName = itemNameArray.join("-");
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i]));
}
var itemName = itemNameArray.join("-");
let li = ActiveScriptsUI[hostname].scripts[itemName];
if (li == null) {
console.log("ERROR: Cannot find Active Script UI element for workerscript: ");
console.log(workerscript);
return;
}
removeElement(li);
delete ActiveScriptsUI[hostname].scripts[itemName];
delete ActiveScriptsUI[hostname].scriptHdrs[itemName];
delete ActiveScriptsUI[hostname].scriptStats[itemName];
if (Object.keys(ActiveScriptsUI[hostname].scripts).length === 0) {
deleteActiveScriptsServerPanel(server);
}
let li = ActiveScriptsUI[hostname].scripts[itemName];
if (li == null) {
console.log("ERROR: Cannot find Active Script UI element for workerscript: ");
console.log(workerscript);
return;
}
removeElement(li);
delete ActiveScriptsUI[hostname].scripts[itemName];
delete ActiveScriptsUI[hostname].scriptHdrs[itemName];
delete ActiveScriptsUI[hostname].scriptStats[itemName];
if (Object.keys(ActiveScriptsUI[hostname].scripts).length === 0) {
deleteActiveScriptsServerPanel(server);
}
}.bind(null, workerscript));
}
//Update the ActiveScriptsItems array
function updateActiveScriptsItems() {
//Run tasks that need to be done sequentially (adding items, creating/deleting server panels)
//We'll limit this to 50 at a time in case someone decides to start a bunch of scripts all at once...
let numTasks = Math.min(50, ActiveScriptsTasks.length);
for (let i = 0; i < numTasks; ++i) {
let task = ActiveScriptsTasks.shift();
try {
task();
} catch(e) {
exceptionAlert(e);
console.log(task);
}
}
var total = 0;
for (var i = 0; i < workerScripts.length; ++i) {
total += updateActiveScriptsItemContent(workerScripts[i]);
try {
total += updateActiveScriptsItemContent(workerScripts[i]);
} catch(e) {
exceptionAlert(e);
}
}
document.getElementById("active-scripts-total-prod").innerHTML =
"Total online production of Active Scripts: " + numeral(total).format('$0.000a') + " / sec<br>" +
@ -192,8 +218,7 @@ function updateActiveScriptsItemContent(workerscript) {
}
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
console.log("ERROR: Trying to update Active Script UI Element with a hostname that cant be found in ActiveScriptsUI: " + hostname);
return;
return; //Hasn't been created yet. We'll skip it
}
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
@ -201,6 +226,10 @@ function updateActiveScriptsItemContent(workerscript) {
itemNameArray.push(String(workerscript.args[i]));
}
var itemName = itemNameArray.join("-");
if (ActiveScriptsUI[hostname].scriptStats[itemName] == null) {
return; //Hasn't been fully added yet. We'll skip it
}
var item = ActiveScriptsUI[hostname].scriptStats[itemName];
//Update the text if necessary. This fn returns the online $/s production
@ -214,7 +243,7 @@ function updateActiveScriptsText(workerscript, item, itemName) {
return;
}
let hostname = server.hostname;
if (ActiveScriptsUI[hostname] == null) {
if (ActiveScriptsUI[hostname] == null || ActiveScriptsUI[hostname].scriptHdrs[itemName] == null) {
console.log("ERROR: Trying to update Active Script UI Element with a hostname that cant be found in ActiveScriptsUI: " + hostname);
return;
}

@ -691,6 +691,7 @@ let CONSTANTS = {
"hostname/ip, regardless of arguments. Returns true if one or more scripts were successfully killed, and false if there were none. <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. Both arguments are required.<br><br>" +
"<i><u>getScriptName()</u></i><br>Returns the filename of the current script (including the extension)<br><br>" +
"<i><u>getScriptRam(scriptname, hostname/ip)</u></i><br>Returns the amount of RAM required to run the specified script on the " +
"target server. 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 server where that script is. Both arguments are required.<br><br>" +
@ -1143,11 +1144,16 @@ let CONSTANTS = {
"* Bladeburner Changes: <br>" +
"** Bug Fix: You can no longer get Bladeburner faction reputation through Infiltration<br>" +
"** Initial difficulty of Tracking contracts reduced<br>" +
"** Datamancer skill effect increased from 4% per level to 5%<br>" +
"* Crime, Infiltration, and Hacking are now slightly more profitable in BN-6<br>" +
"* Added getScriptName() Netscript function (added by Github user hydroflame)<br>" +
"* There is now a soft-cap on stock price, which means it's no longer possible for the price of a stock to reach insanely-high values<br>" +
"* The ctrl+b hotkey in the text editor is now also triggered by command+b or winkey+b<br>" +
"* Many servers now have additional RAM<br>" +
"* Added an option to disable hotkeys/keyboard shortcuts<br>" +
"* Refactored 'Active Scripts' UI page to optimize its performance<br>" +
"* Added a new .fconf setting: ENABLE_TIMESTAMP<br>" +
"* Bug Fix: Fixed a typo in the Fulcrum Technologies company name (Technolgies -> Technologies)<br>" +
"v0.36.0<br>" +
"* Added BN-6: Bladeburners<br>" +
"* Rebalanced many combat Augmentations so that they are slightly less powerful<br>" +

@ -1,7 +1,8 @@
import {parse, Node} from "../utils/acorn.js";
var FconfSettings = {
ENABLE_BASH_HOTKEYS: false
ENABLE_BASH_HOTKEYS: false,
ENABLE_TIMESTAMPS: false,
}
var FconfComments = {
@ -12,6 +13,8 @@ var FconfComments = {
"shortcuts.\n\n" +
"To see a full list of the Terminal shortcuts that this enables, see:\n" +
"http://bitburner.readthedocs.io/en/latest/shortcuts.html",
ENABLE_TIMESTAMPS: "Terminal commands and log entries will be timestamped. The timestamp\n" +
"will have the format: M/D h:m",
}
//Parse Fconf settings from the config text
@ -70,6 +73,7 @@ function parseFconfSetting(setting, value) {
//Needed to convert entered value to boolean/strings accordingly
switch(setting) {
case "ENABLE_BASH_HOTKEYS":
case "ENABLE_TIMESTAMPS":
var value = value.toLowerCase();
if (value === "1" || value === "true" || value === "y") {
value = true;
@ -105,14 +109,19 @@ function createFconf() {
} else {
value = String(FconfSettings[setting]);
}
res += (setting + "=" + value + "\n");
res += (setting + "=" + value + "\n\n");
}
}
return res;
}
function loadFconf(saveString) {
FconfSettings = JSON.parse(saveString);
let tempFconfSettings = JSON.parse(saveString);
for (var setting in tempFconfSettings) {
if (tempFconfSettings.hasOwnProperty(setting)) {
FconfSettings[setting] = tempFconfSettings[setting];
}
}
}
export {FconfSettings, createFconf, parseFconfSettings, loadFconf}

@ -1170,12 +1170,24 @@ function updateGangContent() {
for (var gangname in AllGangs) {
if (AllGangs.hasOwnProperty(gangname)) {
var gangTerritoryInfo = AllGangs[gangname];
let territory = gangTerritoryInfo.territory*100;
//Fix some rounding issues graphically
let displayNumber;
if (territory <= 0) {
displayNumber = formatNumber(0, 2);
} else if (territory >= 100) {
displayNumber = formatNumber(100, 2);
} else {
displayNumber = formatNumber(territory, 2);
}
if (gangname == Player.gang.facName) {
gangTerritoryInfoText.innerHTML += ("<b>" + gangname + "</b><br>(Power: " + formatNumber(gangTerritoryInfo.power, 6) + "): " +
formatNumber(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
displayNumber + "%<br><br>");
} else {
gangTerritoryInfoText.innerHTML += (gangname + "<br>(Power: " + formatNumber(gangTerritoryInfo.power, 6) + "): " +
formatNumber(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
displayNumber + "%<br><br>");
}
}
}
@ -1227,10 +1239,19 @@ function updateGangContent() {
}));
gangInfo.appendChild(createElement("br", {}));
var territoryMult = AllGangs[Player.gang.facName].territory;
//Fix some rounding issues graphically
var territoryMult = AllGangs[Player.gang.facName].territory * 100;
let displayNumber;
if (territoryMult <= 0) {
displayNumber = formatNumber(0, 2);
} else if (territoryMult >= 100) {
displayNumber = formatNumber(100, 2);
} else {
displayNumber = formatNumber(territoryMult, 2);
}
gangInfo.appendChild(createElement("p", { //Territory multiplier
display:"inline-block",
innerText:"Territory: " + formatNumber(territoryMult * 100, 3) + "%",
innerText:"Territory: " + formatNumber(displayNumber, 3) + "%",
tooltip:"The percentage of total territory your Gang controls"
}));
gangInfo.appendChild(createElement("br", {}));

@ -52,7 +52,7 @@ var Locations = {
AevumECorp: "ECorp",
AevumBachmanAndAssociates: "Bachman & Associates",
AevumClarkeIncorporated: "Clarke Incorporated",
AevumFulcrumTechnologies: "Fulcrum Technolgies",
AevumFulcrumTechnologies: "Fulcrum Technologies",
AevumAeroCorp: "AeroCorp",
AevumGalacticCybersystems: "Galactic Cybersystems",
AevumWatchdogSecurity: "Watchdog Security",

@ -18,7 +18,7 @@ const walk = require("acorn/dist/walk");
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {parseFconfSettings} from "./Fconf.js";
import {FconfSettings, parseFconfSettings} from "./Fconf.js";
import {iTutorialSteps, iTutorialNextStep,
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
import {evaluateImport} from "./NetscriptEvaluator.js";
@ -28,7 +28,7 @@ import {addWorkerScript, killWorkerScript,
import {Player} from "./Player.js";
import {AllServers, processSingleServerGrowth} from "./Server.js";
import {Settings} from "./Settings.js";
import {post} from "./Terminal.js";
import {post, Terminal} from "./Terminal.js";
import {TextFile} from "./TextFile.js";
import {parse, Node} from "../utils/acorn.js";
@ -595,7 +595,7 @@ function calculateRamUsage(codeCopy) {
}
//Search through AST, scanning for any 'Identifier' nodes for functions, or While/For/If nodes
var queue = [], ramUsage = 1.4;
var queue = [], ramUsage = CONSTANTS.ScriptBaseRamCost;
var whileUsed = false, forUsed = false, ifUsed = false;
queue.push(ast);
while (queue.length != 0) {
@ -859,7 +859,11 @@ RunningScript.prototype.log = function(txt) {
//to improve performance
this.logs.shift();
}
this.logs.push(txt);
let logEntry = txt;
if (FconfSettings.ENABLE_TIMESTAMPS) {
logEntry = "[" + Terminal.getTimestamp() + "] " + logEntry;
}
this.logs.push(logEntry);
this.logUpd = true;
}

@ -19,7 +19,8 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoTxtInpBoxGetInput, yesNoBoxClose,
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox.js";
/* StockMarket.js */
let StockPriceCap = 1e9; //Put a limit on how high a price can go
function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
this.symbol = symbol;
this.name = name;
@ -580,6 +581,10 @@ function updateStockPrices() {
chc = (chc - stock.otlkMag)/100;
if (isNaN(chc)) {chc = 0.5;}
}
if (stock.price >= StockPriceCap) {
chc = -1; //Limit on stock price
stock.b = false;
}
var c = Math.random();
if (c < chc) {

@ -110,7 +110,12 @@ $(document).keydown(function(event) {
event.preventDefault(); //Prevent newline from being entered in Script Editor
var command = $('input[class=terminal-input]').val();
if (command.length > 0) {
post("[" + Player.getCurrentServer().hostname + " ~]> " + command);
post(
"[" +
(FconfSettings.ENABLE_TIMESTAMPS ? Terminal.getTimestamp() + " " : "") +
Player.getCurrentServer().hostname +
" ~]> " + command
);
Terminal.resetTerminalInput(); //Clear input first
Terminal.executeCommand(command);
@ -632,6 +637,11 @@ let Terminal = {
}
},
getTimestamp: function() {
let d = new Date();
return (d.getMonth() + "/" + d.getDay() + " " + d.getHours() + ":" + d.getMinutes());
},
finishAction: function(cancelled = false) {
if (Terminal.hackFlag) {
Terminal.finishHack(cancelled);