Merge branch 'dev' into typescript

This commit is contained in:
Steven Evans 2018-06-20 22:10:20 -04:00 committed by GitHub
commit 942c26b27e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1632 additions and 2109 deletions

@ -22,12 +22,6 @@
background-color: #777;
}
/* Select industry type when creating a new division */
.cmpy-mgmt-industry-select {
color:white;
background-color:black;
}
/* Switch between Cities */
.cmpy-mgmt-city-tab {
display:inline-block;

@ -501,18 +501,6 @@
width: 50%;
}
.dev-text-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
.dev-dropdown-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
/* Location */
#location-container {
position: fixed;

@ -197,6 +197,16 @@ a:link, a:visited {
pointer-events: none;
}
.dropdown {
color:white;
background-color:black;
}
.text-input {
color:white;
background-color:black;
}
/* Notification icon (for create program right now only) */
#create-program-tab {
position:relative;

BIN
dist/android-chrome-192x192.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
dist/android-chrome-512x512.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
dist/apple-touch-icon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

9
dist/browserconfig.xml vendored Normal file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="dist/mstile-70x70.png"/>
<TileColor>#000000</TileColor>
</tile>
</msapplication>
</browserconfig>

3012
dist/engine.bundle.js vendored

File diff suppressed because it is too large Load Diff

BIN
dist/favicon-16x16.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

BIN
dist/favicon-32x32.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

BIN
dist/mstile-70x70.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

1
dist/safari-pinned-tab.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.2 KiB

19
dist/site.webmanifest vendored Normal file

@ -0,0 +1,19 @@
{
"name": "Bitburner",
"short_name": "Bitburner",
"icons": [
{
"src": "android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -387,6 +387,34 @@ ls
Returns an array with the filenames of all files on the specified server (as strings). The returned array
is sorted in alphabetic order
ps
^^
.. js:function:: ps(hostname/ip=current ip)
:param string ip: Hostname or IP address of the target server.
If not specified, it will be the current server's IP by default
Returns an array with general information about all scripts running on the specified
target server. The information for each server is given in an object with
the following structure::
{
filename: Script name,
threads: Number of threads script is running with,
args: Script's arguments
}
Example usage (using :doc:`netscriptjs`)::
export async function main(ns) {
const ps = ns.ps("home");
for (let i = 0; i < ps.length; ++i) {
ns.tprint(ps[i].filename + ' ' + ps[i].threads);
ns.tprint(ps[i].args);
}
}
hasRootAccess
^^^^^^^^^^^^^

@ -1,3 +1,5 @@
.. _netscriptjs:
NetscriptJS (Netscript 2.0)
===========================
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that

@ -326,6 +326,8 @@
<li><a href="netscriptfunctions.html#print">print() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#prompt">prompt() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#ps">ps() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>

@ -110,6 +110,7 @@ secrets that you've been searching for.</p>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#exit">exit</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#scp">scp</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#ls">ls</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#ps">ps</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#hasrootaccess">hasRootAccess</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethostname">getHostname</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li>

@ -111,6 +111,7 @@ to reach out to the developer!</p>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#exit">exit</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#scp">scp</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#ls">ls</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#ps">ps</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#hasrootaccess">hasRootAccess</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethostname">getHostname</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li>
@ -249,6 +250,7 @@ to reach out to the developer!</p>
</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>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

@ -671,6 +671,46 @@ then this function will return true if at least one of the files in the array is
is sorted in alphabetic order</p>
</dd></dl>
</div>
<div class="section" id="ps">
<h2>ps<a class="headerlink" href="#ps" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt>
<code class="descname">ps</code><span class="sig-paren">(</span><em>hostname/ip=current ip</em><span class="sig-paren">)</span></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Arguments:</th><td class="field-body"><ul class="first last simple">
<li><strong>ip</strong> (<em>string</em>) -- Hostname or IP address of the target server.
If not specified, it will be the current server's IP by default</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns an array with general information about all scripts running on the specified
target server. The information for each server is given in an object with
the following structure:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="n">filename</span><span class="p">:</span> <span class="n">Script</span> <span class="n">name</span><span class="p">,</span>
<span class="n">threads</span><span class="p">:</span> <span class="n">Number</span> <span class="n">of</span> <span class="n">threads</span> <span class="n">script</span> <span class="ow">is</span> <span class="n">running</span> <span class="k">with</span><span class="p">,</span>
<span class="n">args</span><span class="p">:</span> <span class="n">Script</span><span class="s1">&#39;s arguments</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Example usage (using <a class="reference internal" href="netscriptjs.html"><span class="doc">NetscriptJS (Netscript 2.0)</span></a>):</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="k">async</span> <span class="n">function</span> <span class="n">main</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span> <span class="p">{</span>
<span class="n">const</span> <span class="n">ps</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">ps</span><span class="p">(</span><span class="s2">&quot;home&quot;</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">let</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">ps</span><span class="o">.</span><span class="n">length</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ns</span><span class="o">.</span><span class="n">tprint</span><span class="p">(</span><span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">threads</span><span class="p">);</span>
<span class="n">ns</span><span class="o">.</span><span class="n">tprint</span><span class="p">(</span><span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">args</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</dd></dl>
</div>
<div class="section" id="hasrootaccess">
<h2>hasRootAccess<a class="headerlink" href="#hasrootaccess" title="Permalink to this headline"></a></h2>
@ -1648,6 +1688,7 @@ you create in functions such as <a class="reference external" href="https://deve
<li class="toctree-l3"><a class="reference internal" href="#exit">exit</a></li>
<li class="toctree-l3"><a class="reference internal" href="#scp">scp</a></li>
<li class="toctree-l3"><a class="reference internal" href="#ls">ls</a></li>
<li class="toctree-l3"><a class="reference internal" href="#ps">ps</a></li>
<li class="toctree-l3"><a class="reference internal" href="#hasrootaccess">hasRootAccess</a></li>
<li class="toctree-l3"><a class="reference internal" href="#gethostname">getHostname</a></li>
<li class="toctree-l3"><a class="reference internal" href="#gethackinglevel">getHackingLevel</a></li>
@ -1702,6 +1743,7 @@ you create in functions such as <a class="reference external" href="https://deve
</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>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

@ -52,7 +52,7 @@
<div class="body" role="main">
<div class="section" id="netscriptjs-netscript-2-0">
<h1>NetscriptJS (Netscript 2.0)<a class="headerlink" href="#netscriptjs-netscript-2-0" title="Permalink to this headline"></a></h1>
<span id="netscriptjs"></span><h1>NetscriptJS (Netscript 2.0)<a class="headerlink" href="#netscriptjs-netscript-2-0" title="Permalink to this headline"></a></h1>
<p>Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
allows users to write (almost) full-fledged Javascript code in their scripts, while
still being able to access the Netscript functions.</p>
@ -278,6 +278,7 @@ NetscriptJS and report any serious exploits.</p>
</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>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -3,6 +3,21 @@
Changelog
=========
v0.38.1 - 6/15/2018
-------------------
* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS
* Implemented by Github user hydroflame:
* Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)
* Added game option to suppress travel confirmation
* Text on buttons can no longer be highlighted
* Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations
* Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)
* Added ps() Netscript function
* Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money
* Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips
* Bug Fix: Sever's security level should now properly increase when its money is grown to max value
v0.38.0 - 6/12/2018
-------------------
* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame

@ -387,6 +387,34 @@ ls
Returns an array with the filenames of all files on the specified server (as strings). The returned array
is sorted in alphabetic order
ps
^^
.. js:function:: ps(hostname/ip=current ip)
:param string ip: Hostname or IP address of the target server.
If not specified, it will be the current server's IP by default
Returns an array with general information about all scripts running on the specified
target server. The information for each server is given in an object with
the following structure::
{
filename: Script name,
threads: Number of threads script is running with,
args: Script's arguments
}
Example usage (using :doc:`netscriptjs`)::
export async function main(ns) {
const ps = ns.ps("home");
for (let i = 0; i < ps.length; ++i) {
ns.tprint(ps[i].filename + ' ' + ps[i].threads);
ns.tprint(ps[i].args);
}
}
hasRootAccess
^^^^^^^^^^^^^

@ -1,3 +1,5 @@
.. _netscriptjs:
NetscriptJS (Netscript 2.0)
===========================
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -3,6 +3,17 @@
<head>
<meta charset="utf-8">
<title>Bitburner</title>
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
<link rel="manifest" href="dist/site.webmanifest">
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000">
<link rel="shortcut icon" href="favicon.ico">
<meta name="apple-mobile-web-app-title" content="Bitburner">
<meta name="application-name" content="Bitburner">
<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-config" content="dist/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" type="text/css" href="css/styles.css" />
<link rel="stylesheet" type="text/css" href="css/terminal.css" />
<link rel="stylesheet" type="text/css" href="css/menupages.css" />
@ -99,7 +110,7 @@
<div id="script-editor-filename-wrapper">
<p id="script-editor-filename-tag"> <strong style="background-color:#555;">Script name: </strong></p>
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1"> </input>
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1" />
</div>
<div id="javascript-editor"></div>
@ -149,9 +160,7 @@
<fieldset>
<label for="script-editor-option-maxerr" class="tooltip">Max Error Count</label>
<input type="range" max="1000" min="50" value="200"
step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr"
</input>
<input type="range" max="1000" min="50" value="200" step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr" />
<em id="script-editor-option-maxerror-value-label" style="font-style: normal;"></em>
</fieldset>
</div> <!-- End script editor options panel -->
@ -162,8 +171,7 @@
<table id="terminal">
<tr id="terminal-input">
<td id="terminal-input-td" tabindex="2">$
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"
onfocus="this.value = this.value;"/>
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;"/>
</td>
</tr>
</table>
@ -488,20 +496,20 @@
<p id='dev-menu-text'>Augmentation related: </p>
<!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
<input id="dev-sf-n" type="number" class="dev-text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="dev-text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<p id='dev-menu-text'>Faction related: </p>
<select id="dev-menu-faction-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
<p id='dev-menu-text'>Program related: </p>
<select id="dev-menu-connect-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
<select id="dev-menu-add-program-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-add-program-dropdown" class="dropdown"></select>
<a id="dev-add-program" class="a-link-button tooltip">Add Program<span class="tooltiptext">Add this program to the player home server, won't add the same program twice.</span></a>
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
@ -512,19 +520,19 @@
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
<p id='dev-menu-text'>Exp/stats related: </p>
<input id="dev-hacking-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-strength-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-strength" class="a-link-button tooltip">add strength exp<span class="tooltiptext">Add that many strength experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-defense-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-defense-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-defense" class="a-link-button tooltip">add defense exp<span class="tooltiptext">Add that many defense experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-dexterity-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-dexterity-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-dexterity" class="a-link-button tooltip">add dexterity exp<span class="tooltiptext">Add that many dexterity experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-agility-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-agility-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-agility" class="a-link-button tooltip">add agility exp<span class="tooltiptext">Add that many agility experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-charisma-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-charisma-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-charisma" class="a-link-button tooltip">add charisma exp<span class="tooltiptext">Add that many charisma experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-intelligence-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-intelligence-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-intelligence" class="a-link-button tooltip">add intelligence exp<span class="tooltiptext">Add that many intelligence experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<a id="dev-enable-intelligence" class="a-link-button tooltip"> enable intelligence<span class="tooltiptext">Enables the intelligence stat</span></a>
<a id="dev-disable-intelligence" class="a-link-button tooltip"> disable intelligence<span class="tooltiptext">Disables the intelligence stat</span></a>
@ -711,7 +719,7 @@
<div id="yes-no-text-input-box-container" class="popup-box-container">
<div id="yes-no-text-input-box-content" class="popup-box-content">
<p id="yes-no-text-input-box-text"> </p>
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"> </input>
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30" />
<span id="yes-no-text-input-box-yes" class="popup-box-button"> Yes </span>
<span id="yes-no-text-input-box-no" class="popup-box-button"> No </span>
</div>
@ -801,9 +809,7 @@
</span>
</label>
<input type ="range" max="250" min="15"
step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100">
</input>
<input type ="range" max="250" min="15" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100" />
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -817,9 +823,7 @@
</span>
</label>
<input type="range" max="100" min="20"
step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50">
</input>
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50" />
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -833,9 +837,7 @@
</span>
</label>
<input type="range" max="100" min="20"
step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50">
</input>
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50" />
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -847,9 +849,7 @@
</span>
</label>
<input type="range" max="600" min="0"
step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60">
</input>
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60" />
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
</fieldset>
@ -910,7 +910,7 @@
<div id="game-options-right-panel">
<a class="a-link-button" style="display:block;" href="https://bitburner.wikia.com/wiki/Changelog" target="_blank"> Changelog </a>
<a class="a-link-button" style="display:block;" href="https://bitburner.wikia.com" target="_blank">Wiki</a>
<a class="a-link-button" style="display:block;", href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
<a class="a-link-button" style="display:block;" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
<a id="save-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Save Game </a>
<a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a>
<a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a>
@ -939,6 +939,6 @@
<div class="loaderspinner"></div>
<div class="loaderlabel">Loading Bitburner...</div>
</div>
</body>
<script src="dist/engine.bundle.js"></script>
</body>
</html>

@ -2431,8 +2431,9 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
});
//Select industry and city to export to
var citySelector = createElement("select");
var citySelector = createElement("select", {class: "dropdown"});
var industrySelector = createElement("select", {
class: "dropdown",
changeListener:()=>{
var industryName = industrySelector.options[industrySelector.selectedIndex].value;
for (var foo = 0; foo < company.divisions.length; ++foo) {
@ -2475,6 +2476,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
//Select amount to export
var exportAmount = createElement("input", {
class: "text-input",
placeholder:"Export amount / s"
});
@ -2696,11 +2698,12 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
//Completed products
var cmpAndDmdText = "";
if (company.unlockUpgrades[2] === 1) {
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
}
if (company.unlockUpgrades[3] === 1) {
cmpAndDmdText += "<br>Demand: " + formatNumber(product.dmd, 3);
}
if (company.unlockUpgrades[3] === 1) {
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
}
var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
div.appendChild(createElement("p", {
innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity
@ -3422,15 +3425,14 @@ Corporation.prototype.updateUIHeaderTabs = function() {
innerHTML: "Create a new division to expand into a new industry:",
});
var selector = createElement("select", {
class:"cmpy-mgmt-industry-select"
class:"dropdown"
});
var industryDescription = createElement("p", {});
var yesBtn;
var nameInput = createElement("input", {
type:"text",
id:"cmpy-mgmt-expand-industry-name-input",
color:"white",
backgroundColor:"black",
class: "text-input",
display:"block",
maxLength: 30,
pattern:"[a-zA-Z0-9-_]",
@ -4068,7 +4070,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
innerText: "Would you like to expand into a new city by opening an office? " +
"This would cost " + numeral(OfficeInitialCost).format('$0.000a'),
});
var citySelector = createElement("select", {margin:"5px"});
var citySelector = createElement("select", {class: "dropdown", margin:"5px"});
for (var cityName in division.offices) {
if (division.offices.hasOwnProperty(cityName)) {
if (!(division.offices[cityName] instanceof OfficeSpace)) {

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.38.0",
Version: "0.38.1",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -43,7 +43,7 @@ let CONSTANTS = {
/* Netscript Constants */
//RAM Costs for different commands
ScriptBaseRamCost: 1.4,
ScriptCheatRamCost: 1e21, // if someone tries to cheat by using window or document we just spike the ram cost.
ScriptDomRamCost: 100,
ScriptWhileRamCost: 0.2,
ScriptForRamCost: 0.2,
ScriptIfRamCost: 0.15,
@ -489,20 +489,19 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.38.0<br>" +
"* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame<br>" +
"* Bladeburner Changes:<br>" +
"*** Bladeburner progress is no longer reset when installing Augmentations<br>" +
"*** The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)<br>" +
"*** All Bladeburner Augmentations are now slightly more expensive and require more reputation<br>" +
"*** Black Operations now give higher rank rewards<br>" +
"*** Doubled the base amount of money gained from Contracts<br>" +
"*** Increased the amount of experience gained from Contracts/Actions<br>" +
"*** Added a new Augmentation: The Blade's Simulacrum<br>" +
"*** Bladeburner faction reputation gain is now properly affected by favor<br>" +
"* Hacking is now slightly less profitable in BitNode-3<br>" +
"* Updated Hacknet Nodes UI - Implemented by Github user kopelli<br>" +
"* Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS<br>"
"v0.38.1<br>" +
"* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS<br>" +
"* Implemented by Github user hydroflame:<br>" +
"*** Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)<br>" +
"*** Added game option to suppress travel confirmation<br>" +
"*** Text on buttons can no longer be highlighted<br>" +
"*** Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations<br>" +
"*** Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)<br>" +
"*** Added ps() Netscript function<br>" +
"*** Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money<br>" +
"*** Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips<br>" +
"*** Bug Fix: Sever's security level should now properly increase when its money is grown to max value"
}
export {CONSTANTS};

@ -19,7 +19,6 @@ function checkIfConnectedToDarkweb() {
"to purchase an item");
}
}
}
//Handler for dark web commands. The terminal's executeCommand() function will pass
@ -49,150 +48,68 @@ function executeDarkwebTerminalCommand(commandArray) {
}
function listAllDarkwebItems() {
for (var item in DarkWebItems) {
if (DarkWebItems.hasOwnProperty(item)) {
var item = DarkWebItems[item];
//Convert string using toLocaleString
var split = item.split(" - ");
if (split.length == 3 && split[1].charAt(0) == '$') {
split[1] = split[1].slice(1);
split[1] = split[1].replace(/,/g, '');
var price = parseFloat(split[1]);
if (isNaN(price)) {
post(item);
return;
}
price = formatNumber(price, 0);
split[1] = "$" + price.toString();
post(split.join(" - "));
} else {
post(item);
}
}
}
var priceString = split[1];
//Check for errors
if (priceString.length == 0 || priceString.charAt(0) != '$') {
return -1;
for(const key in DarkWebItems) {
const item = DarkWebItems[key];
post(item.toString());
}
//Remove dollar sign and commas
priceString = priceString.slice(1);
priceString = priceString.replace(/,/g, '');
//Convert string to numeric
var price = parseFloat(priceString);
if (isNaN(price)) {return -1;}
else {return price;}
}
function buyDarkwebItem(itemName) {
if (itemName.toLowerCase() == Programs.BruteSSHProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram);
post("You have purchased the BruteSSH.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
itemName = itemName.toLowerCase();
// find the program that matches, if any
let item = null;
for(const key in DarkWebItems) {
const i = DarkWebItems[key];
if(i.program.toLowerCase() == itemName) {
item = i;
}
} else if (itemName.toLowerCase() == Programs.FTPCrackProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram);
post("You have purchased the FTPCrack.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.RelaySMTPProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram);
post("You have purchased the relaySMTP.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.HTTPWormProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram);
post("You have purchased the HTTPWorm.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.SQLInjectProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram);
post("You have purchased the SQLInject.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.DeepscanV1.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV1);
post("You have purchased the DeepscanV1.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.DeepscanV2.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV2);
post("You have purchased the DeepscanV2.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else {
post("Unrecognized item");
}
}
function parseDarkwebItemPrice(itemDesc) {
var split = itemDesc.split(" - ");
if (split.length == 3) {
var priceString = split[1];
//Check for errors
if (priceString.length == 0 || priceString.charAt(0) != '$') {
return -1;
}
//Remove dollar sign and commas
priceString = priceString.slice(1);
priceString = priceString.replace(/,/g, '');
//Convert string to numeric
var price = parseFloat(priceString);
if (isNaN(price)) {return -1;}
else {return price;}
} else {
return -1;
// return if invalid
if(item === null) {
post("Unrecognized item: "+itemName);
return;
}
// return if the player already has it.
if(Player.hasProgram(item.program)) {
post('You already have the '+item.program+' program');
return;
}
// return if the player doesn't have enough money
if(Player.money.lt(item.price)) {
post("Not enough money to purchase " + item.program);
return;
}
// buy and push
Player.loseMoney(item.price);
Player.getHomeComputer().programs.push(item.program);
post('You have purchased the '+item.program+' program. The new program can be found on your home computer.');
}
let DarkWebItems = {
BruteSSHProgram: "BruteSSH.exe - $500,000 - Opens up SSH Ports",
FTPCrackProgram: "FTPCrack.exe - $1,500,000 - Opens up FTP Ports",
RelaySMTPProgram: "relaySMTP.exe - $5,000,000 - Opens up SMTP Ports",
HTTPWormProgram: "HTTPWorm.exe - $30,000,000 - Opens up HTTP Ports",
SQLInjectProgram: "SQLInject.exe - $250,000,000 - Opens up SQL Ports",
DeepScanV1Program: "DeepscanV1.exe - $500,000 - Enables 'scan-analyze' with a depth up to 5",
DeepScanV2Program: "DeepscanV2.exe - $25,000,000 - Enables 'scan-analyze' with a depth up to 10",
function DarkWebItem(program, price, description) {
this.program = program;
this.price = price;
this.description = description;
}
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand,
listAllDarkwebItems, buyDarkwebItem, parseDarkwebItemPrice,
DarkWebItems};
// formats the item for the terminal (eg. "BruteSSH.exe - $500,000 - Opens up SSH Ports")
DarkWebItem.prototype.toString = function() {
return [this.program, "$"+formatNumber(this.price), this.description].join(' - ');
}
const DarkWebItems = {
BruteSSHProgram: new DarkWebItem(Programs.BruteSSHProgram, 500000, "Opens up SSH Ports"),
FTPCrackProgram: new DarkWebItem(Programs.FTPCrackProgram, 1500000, "Opens up FTP Ports"),
RelaySMTPProgram: new DarkWebItem(Programs.RelaySMTPProgram, 5000000, "Opens up SMTP Ports"),
HTTPWormProgram: new DarkWebItem(Programs.HTTPWormProgram, 30000000, "Opens up HTTP Ports"),
SQLInjectProgram: new DarkWebItem(Programs.SQLInjectProgram, 250000000, "Opens up SQL Ports"),
DeepscanV1: new DarkWebItem(Programs.DeepscanV1, 500000, "Enables 'scan-analyze' with a depth up to 5"),
DeepscanV2: new DarkWebItem(Programs.DeepscanV2, 25000000, "Enables 'scan-analyze' with a depth up to 10"),
};
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand, DarkWebItems};

@ -279,7 +279,10 @@ function displayLocationContent() {
purchase256gb.innerHTML = "Purchase 256GB Server - $" + formatNumber(256*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchase512gb.innerHTML = "Purchase 512GB Server - $" + formatNumber(512*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchase1tb.innerHTML = "Purchase 1TB Server - $" + formatNumber(1024*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchaseTor.innerHTML = "Purchase TOR Router - $" + formatNumber(CONSTANTS.TorRouterCost, 2);
if (!SpecialServerIps.hasOwnProperty("Darkweb Server")) {
purchaseTor.innerHTML = "Purchase TOR Router - $" + formatNumber(CONSTANTS.TorRouterCost, 2);
}
travelAgencyText.style.display = "none";
travelToAevum.style.display = "none";
@ -2005,7 +2008,7 @@ function purchaseTorRouter() {
const purchaseTor = document.getElementById("location-purchase-tor");
purchaseTor.setAttribute("class", "a-link-button-bought");
purchaseTor.innerHTML = "TOR Router - purchased";
purchaseTor.innerHTML = "TOR Router - Purchased";
Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);

@ -12,7 +12,7 @@ import {Companies, Company, CompanyPosition,
CompanyPositions, companyExists} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js";
import {DarkWebItems} from "./DarkWeb.js";
import {Engine} from "./engine.js";
import {AllGangs} from "./Gang.js";
import {Factions, Faction, joinFaction,
@ -81,6 +81,8 @@ var possibleLogs = {
relaysmtp: true,
httpworm: true,
sqlinject: true,
run:true,
exec:true,
spawn: true,
kill: true,
killall: true,
@ -325,7 +327,7 @@ function NetscriptFunctions(workerScript) {
}
workerScript.scriptRef.onlineExpGained += expGain;
Player.gainHackingExp(expGain);
return Promise.resolve(growthPercentage);
return Promise.resolve(moneyAfter/moneyBefore);
});
},
weaken : function(ip){
@ -644,7 +646,22 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeRejectMsg(workerScript, "Invalid scriptname or numThreads argument passed to spawn()");
}
setTimeout(()=>{
NetscriptFunctions(workerScript).run.apply(this, arguments);
if (scriptname === undefined) {
throw makeRuntimeRejectMsg(workerScript, "spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");
}
if (isNaN(threads) || threads < 1) {
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0");
}
var argsForNewScript = [];
for (var i = 2; i < arguments.length; ++i) {
argsForNewScript.push(arguments[i]);
}
var scriptServer = getServer(workerScript.serverIp);
if (scriptServer == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
}
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
}, 20000);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.spawn == null) {
workerScript.scriptRef.log("spawn() will execute " + scriptname + " in 20 seconds");
@ -709,10 +726,7 @@ function NetscriptFunctions(workerScript) {
return scriptsRunning;
},
exit : function() {
if (workerScript.checkingRam) {
return updateStaticRam("exit", CONSTANTS.ScriptKillRamCost);
}
updateDynamicRam("exit", CONSTANTS.ScriptKillRamCost);
if (workerScript.checkingRam) {return 0;}
var server = getServer(workerScript.serverIp);
if (server == null) {
throw makeRuntimeRejectMsg(workerScript, "Error getting Server for this script in exit(). This is a bug please contact game dev");
@ -2292,7 +2306,9 @@ function NetscriptFunctions(workerScript) {
AddToAllServers(darkweb);
SpecialServerIps.addIp("Darkweb Server", darkweb.ip);
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button-inactive");
const purchaseTor = document.getElementById("location-purchase-tor");
purchaseTor.setAttribute("class", "a-link-button-bought");
purchaseTor.innerHTML = "TOR Router - Purchased";
Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);
@ -2317,105 +2333,40 @@ function NetscriptFunctions(workerScript) {
}
if (SpecialServerIps["Darkweb Server"] == null) {
workerScript.scriptRef.log("ERROR: You do not have TOR router. purchaseProgram() failed.");
workerScript.scriptRef.log("ERROR: You do not have the TOR router. purchaseProgram() failed.");
return false;
}
switch(programName.toLowerCase()) {
case Programs.BruteSSHProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the BruteSSH.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.FTPCrackProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the FTPCrack.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.RelaySMTPProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the relaySMTP.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.HTTPWormProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the HTTPWorm.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.SQLInjectProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the SQLInject.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV1.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV1);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the DeepscanV1.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV2.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV2);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the DeepscanV2.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
default:
workerScript.scriptRef.log("ERROR: Invalid program passed into purchaseProgram().");
return false;
programName = programName.toLowerCase();
let item = null;
for(const key in DarkWebItems) {
const i = DarkWebItems[key];
if(i.program.toLowerCase() == programName) {
item = i;
}
}
if(item == null) {
workerScript.scriptRef.log("ERROR: Invalid program name passed into purchaseProgram().");
return false;
}
if(Player.money.lt(item.price)) {
workerScript.scriptRef.log("Not enough money to purchase " + item.program);
return false;
}
if(Player.hasProgram(item.program)) {
workerScript.scriptRef.log('You already have the '+item.program+' program');
return true;
}
Player.loseMoney(item.price);
Player.getHomeComputer().programs.push(item.program);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the "+item.program+" program. The new program can be found on your home computer.");
}
return true;
},
@ -2798,7 +2749,7 @@ function NetscriptFunctions(workerScript) {
}
// if the player is in a gang and the target faction is any of the gang faction, fail
if(Player.gang != null && AllGangs[name] !== undefined) {
if(Player.inGang() && AllGangs[name] !== undefined) {
workerScript.scriptRef.log("ERROR: Faction specified in workForFaction() does not offer work at the moment.");
return;
}

@ -1,4 +1,5 @@
var ace = require('brace');
var beautify = require('js-beautify').js_beautify;
require('brace/mode/javascript');
require('../netscript');
require('brace/theme/chaos');
@ -57,6 +58,15 @@ function scriptEditorInit() {
console.log("Error finding 'script-editor-buttons-wrapper'");
return;
}
var beautifyButton = createElement("a", {
class:"a-link-button", display:"inline-block",
innerText:"beautify",
clickListener:()=>{
beautifyScript();
return false;
}
});
var closeButton = createElement("a", {
class:"a-link-button", display:"inline-block",
innerText:"Save & Close (Ctrl/Cmd + b)",
@ -90,6 +100,7 @@ function scriptEditorInit() {
target:"_blank"
});
wrapper.appendChild(beautifyButton);
wrapper.appendChild(closeButton);
wrapper.appendChild(scriptEditorRamText);
wrapper.appendChild(scriptEditorRamCheck);
@ -243,6 +254,13 @@ $(document).keydown(function(e) {
}
});
function beautifyScript() {
var editor = ace.edit('javascript-editor');
var code = editor.getValue();
code = beautify(code, { indent_size: 4 })
editor.setValue(code);
}
function saveAndCloseScriptEditor() {
var filename = document.getElementById("script-editor-filename").value;
var editor = ace.edit('javascript-editor');
@ -448,7 +466,7 @@ function parseOnlyRamCalculate(server, code, workerScript) {
if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost;
if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost;
if (ref == "hacknetnodes") ram += CONSTANTS.ScriptHacknetNodesRamCost;
if (ref == "document" || ref == "window") ram += CONSTANTS.ScriptCheatRamCost;
if (ref == "document" || ref == "window") ram += CONSTANTS.ScriptDomRamCost;
// Check if this ident is a function in the workerscript env. If it is, then we need to
// get its RAM cost. We do this by calling it, which works because the running script
@ -509,11 +527,15 @@ function parseOnlyCalculateDeps(code, currentModule) {
s.add(name); // For builtins like hack.
}
//A list of identifiers that resolve to "native Javascript code"
const objectPrototypeProperties = Object.getOwnPropertyNames(Object.prototype);
// If we discover a dependency identifier, state.key is the dependent identifier.
// walkDeeper is for doing recursive walks of expressions in composites that we handle.
function commonVisitors() {
return {
Identifier: (node, st, walkDeeper) => {
if (objectPrototypeProperties.includes(node.name)) {return;}
addRef(st.key, node.name);
},
WhileStatement: (node, st, walkDeeper) => {

@ -768,19 +768,31 @@ function initForeignServers() {
}
}
function numCycleForGrowth(server, growth) {
let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty;
if(ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) {
ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate;
}
const serverGrowthPercentage = server.serverGrowth / 100;
const cycles = Math.log(growth)/(Math.log(ajdGrowthRate)*Player.hacking_grow_mult*serverGrowthPercentage);
return cycles;
}
//Applied server growth for a single server. Returns the percentage growth
function processSingleServerGrowth(server, numCycles) {
//Server growth processed once every 450 game cycles
var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
const numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
//Get adjusted growth rate, which accounts for server security
var growthRate = CONSTANTS.ServerBaseGrowthRate;
const growthRate = CONSTANTS.ServerBaseGrowthRate;
var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty;
if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;}
//Calculate adjusted server growth rate based on parameters
var serverGrowthPercentage = server.serverGrowth / 100;
var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
const serverGrowthPercentage = server.serverGrowth / 100;
const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
//Apply serverGrowth for the calculated number of growth cycles
var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult);
@ -789,19 +801,26 @@ function processSingleServerGrowth(server, numCycles) {
serverGrowth = 1;
}
var oldMoneyAvailable = server.moneyAvailable;
const oldMoneyAvailable = server.moneyAvailable;
server.moneyAvailable *= serverGrowth;
// in case of data corruption
if (server.moneyMax && isNaN(server.moneyAvailable)) {
server.moneyAvailable = server.moneyMax;
}
// cap at max
if (server.moneyMax && server.moneyAvailable > server.moneyMax) {
server.moneyAvailable = server.moneyMax;
return server.moneyAvailable / oldMoneyAvailable;
}
//Growing increases server security twice as much as hacking
server.fortify(2 * CONSTANTS.ServerFortifyAmount * numServerGrowthCycles);
return serverGrowth;
// if there was any growth at all, increase security
if(oldMoneyAvailable !== server.moneyAvailable) {
//Growing increases server security twice as much as hacking
const usedCycles = numCycleForGrowth(server, server.moneyAvailable / oldMoneyAvailable);
server.fortify(2 * CONSTANTS.ServerFortifyAmount * Math.ceil(usedCycles));
}
return server.moneyAvailable / oldMoneyAvailable;
}
function prestigeHomeComputer(homeComp) {
@ -873,9 +892,11 @@ function GetServerByHostname(hostname) {
function getServer(s) {
if (!isValidIPAddress(s)) {
return GetServerByHostname(s);
} else {
}
if(AllServers[s] !== undefined) {
return AllServers[s];
}
return null;
}
//Debugging tool

@ -48,7 +48,7 @@ function setSettingsLabels() {
nsPortLimit.innerHTML = Settings.MaxPortCapacity;
suppressMsgs.checked = Settings.SuppressMessages;
suppressFactionInv.checked = Settings.SuppressFactionInvites;
suppressTravelConfirmation.checked = Settings.suppressTravelConfirmation;
suppressTravelConfirmation.checked = Settings.SuppressTravelConfirmation;
autosaveInterval.innerHTML = Settings.AutosaveInterval;
disableHotkeys.checked = Settings.DisableHotkeys;

@ -1729,7 +1729,9 @@ let Engine = {
//If DarkWeb already purchased, disable the button
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button-inactive");
const purchaseTor = document.getElementById("location-purchase-tor");
purchaseTor.setAttribute("class", "a-link-button-bought");
purchaseTor.innerHTML = "TOR Router - Purchased";
}
},