mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 07:33:48 +01:00
Tutorial: Remove NS1 tutorial, change getting started guide to .js (#258)
This commit is contained in:
parent
b004b7203d
commit
addcee73fc
@ -28,7 +28,7 @@ entire "quest-line".
|
|||||||
First Steps
|
First Steps
|
||||||
-----------
|
-----------
|
||||||
I'm going to assume you followed the introductory tutorial when you first began the game.
|
I'm going to assume you followed the introductory tutorial when you first began the game.
|
||||||
In this introductory tutorial you created a script called :code:`n00dles.script` and ran it
|
In this introductory tutorial you created a script called :code:`n00dles.js` and ran it
|
||||||
on the :code:`n00dles` server. Right now, we'll kill this script. There are two ways
|
on the :code:`n00dles` server. Right now, we'll kill this script. There are two ways
|
||||||
to do this:
|
to do this:
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ to do this:
|
|||||||
$ kill n00dles.script
|
$ kill n00dles.script
|
||||||
|
|
||||||
2. You can go to the :code:`Active Scripts` page (|Keyboard shortcut| Alt + s) and
|
2. You can go to the :code:`Active Scripts` page (|Keyboard shortcut| Alt + s) and
|
||||||
press the "Kill Script" button for :code:`n00dles.script`.
|
press the "Kill Script" button for :code:`n00dles.js`.
|
||||||
|
|
||||||
If you skipped the introductory tutorial, then ignore the part above. Instead, go to the
|
If you skipped the introductory tutorial, then ignore the part above. Instead, go to the
|
||||||
:code:`Hacknet Nodes` page (|Keyboard shortcut| Alt + h) and purchase a
|
:code:`Hacknet Nodes` page (|Keyboard shortcut| Alt + h) and purchase a
|
||||||
@ -67,11 +67,11 @@ the amount of money available on a server. The :js:func:`weaken` Netscript funct
|
|||||||
used to decrease a server's security level.
|
used to decrease a server's security level.
|
||||||
|
|
||||||
Now let's move on to actually creating the script.
|
Now let's move on to actually creating the script.
|
||||||
Go to your home computer and then create a script called :code:`early-hack-template.script` by
|
Go to your home computer and then create a script called :code:`early-hack-template.js` by
|
||||||
going to Terminal and entering the following two commands::
|
going to Terminal and entering the following two commands::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ nano early-hack-template.script
|
$ nano early-hack-template.js
|
||||||
|
|
||||||
This will take you to the script editor, which you can use to code and create
|
This will take you to the script editor, which you can use to code and create
|
||||||
:ref:`gameplay_scripts`. It will be helpful to consult the :ref:`netscript` documentation.
|
:ref:`gameplay_scripts`. It will be helpful to consult the :ref:`netscript` documentation.
|
||||||
@ -80,49 +80,50 @@ Specifically, you'll want to take a look at :ref:`netscriptfunctions`.
|
|||||||
Enter the following code in the script editor:
|
Enter the following code in the script editor:
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
// Defines the "target server", which is the server
|
||||||
|
// that we're going to hack. In this case, it's "n00dles"
|
||||||
|
const target = "n00dles";
|
||||||
|
|
||||||
// Defines the "target server", which is the server
|
// Defines how much money a server should have before we hack it
|
||||||
// that we're going to hack. In this case, it's "n00dles"
|
// In this case, it is set to 75% of the server's max money
|
||||||
var target = "n00dles";
|
const moneyThresh = ns.getServerMaxMoney(target) * 0.75;
|
||||||
|
|
||||||
// Defines how much money a server should have before we hack it
|
// Defines the maximum security level the target server can
|
||||||
// In this case, it is set to 75% of the server's max money
|
// have. If the target's security level is higher than this,
|
||||||
var moneyThresh = getServerMaxMoney(target) * 0.75;
|
// we'll weaken it before doing anything else
|
||||||
|
const securityThresh = ns.getServerMinSecurityLevel(target) + 5;
|
||||||
|
|
||||||
// Defines the maximum security level the target server can
|
// If we have the BruteSSH.exe program, use it to open the SSH Port
|
||||||
// have. If the target's security level is higher than this,
|
// on the target server
|
||||||
// we'll weaken it before doing anything else
|
if (ns.fileExists("BruteSSH.exe", "home")) {
|
||||||
var securityThresh = getServerMinSecurityLevel(target) + 5;
|
ns.brutessh(target);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have the BruteSSH.exe program, use it to open the SSH Port
|
// Get root access to target server
|
||||||
// on the target server
|
ns.nuke(target);
|
||||||
if (fileExists("BruteSSH.exe", "home")) {
|
|
||||||
brutessh(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get root access to target server
|
// Infinite loop that continously hacks/grows/weakens the target server
|
||||||
nuke(target);
|
while(true) {
|
||||||
|
if (ns.getServerSecurityLevel(target) > securityThresh) {
|
||||||
// Infinite loop that continously hacks/grows/weakens the target server
|
// If the server's security level is above our threshold, weaken it
|
||||||
while(true) {
|
await ns.weaken(target);
|
||||||
if (getServerSecurityLevel(target) > securityThresh) {
|
} else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
|
||||||
// If the server's security level is above our threshold, weaken it
|
// If the server's money is less than our threshold, grow it
|
||||||
weaken(target);
|
await ns.grow(target);
|
||||||
} else if (getServerMoneyAvailable(target) < moneyThresh) {
|
} else {
|
||||||
// If the server's money is less than our threshold, grow it
|
// Otherwise, hack it
|
||||||
grow(target);
|
await ns.hack(target);
|
||||||
} else {
|
}
|
||||||
// Otherwise, hack it
|
|
||||||
hack(target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The script above contains comments that document what it does, but let's go through it
|
The script above contains comments that document what it does, but let's go through it
|
||||||
step-by-step anyways.
|
step-by-step anyways.
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
var target = "n00dles";
|
const target = "n00dles";
|
||||||
|
|
||||||
This first command defines a string which contains our target server. That's the server
|
This first command defines a string which contains our target server. That's the server
|
||||||
that we're going to hack. For now, it's set to `n00dles` because that's the only
|
that we're going to hack. For now, it's set to `n00dles` because that's the only
|
||||||
@ -132,7 +133,7 @@ variable to be the hostname of another server.
|
|||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
var moneyThresh = getServerMaxMoney(target) * 0.75;
|
const moneyThresh = ns.getServerMaxMoney(target) * 0.75;
|
||||||
|
|
||||||
This second command defines a numerical value representing the minimum
|
This second command defines a numerical value representing the minimum
|
||||||
amount of money that must be available on the target server in order for our script
|
amount of money that must be available on the target server in order for our script
|
||||||
@ -143,7 +144,7 @@ The :js:func:`getServerMaxMoney` Netscript function is used to find this value
|
|||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
var securityThresh = getServerMinSecurityLevel(target) + 5;
|
const securityThresh = ns.getServerMinSecurityLevel(target) + 5;
|
||||||
|
|
||||||
This third command defines a numerical value representing the maximum security level
|
This third command defines a numerical value representing the maximum security level
|
||||||
the target server can have. If the target server's security level is higher than
|
the target server can have. If the target server's security level is higher than
|
||||||
@ -151,11 +152,11 @@ this value, then our script will :js:func:`weaken` the script before doing anyth
|
|||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
if (fileExists("BruteSSH.exe", "home")) {
|
if (ns.fileExists("BruteSSH.exe", "home")) {
|
||||||
brutessh(target);
|
ns.brutessh(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
nuke(target);
|
ns.nuke(target);
|
||||||
|
|
||||||
This section of code is used to gain root access on the target server. This is
|
This section of code is used to gain root access on the target server. This is
|
||||||
necessary for hacking. See :ref:`here for more details <gameplay_hacking>`.
|
necessary for hacking. See :ref:`here for more details <gameplay_hacking>`.
|
||||||
@ -163,15 +164,15 @@ necessary for hacking. See :ref:`here for more details <gameplay_hacking>`.
|
|||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (getServerSecurityLevel(target) > securityThresh) {
|
if (ns.getServerSecurityLevel(target) > securityThresh) {
|
||||||
// If the server's security level is above our threshold, weaken it
|
// If the server's security level is above our threshold, weaken it
|
||||||
weaken(target);
|
await ns.weaken(target);
|
||||||
} else if (getServerMoneyAvailable(target) < moneyThresh) {
|
} else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
|
||||||
// Otherwise, if the server's money is less than our threshold, grow it
|
// Otherwise, if the server's money is less than our threshold, grow it
|
||||||
grow(target);
|
await ns.grow(target);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, hack it
|
// Otherwise, hack it
|
||||||
hack(target);
|
await ns.hack(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +180,12 @@ This is the main section that drives our script. It dictates the script's logic
|
|||||||
and carries out the hacking operations. The `while (true)` creates an infinite loop
|
and carries out the hacking operations. The `while (true)` creates an infinite loop
|
||||||
that will continuously run the hacking logic until the the script is killed.
|
that will continuously run the hacking logic until the the script is killed.
|
||||||
|
|
||||||
|
The await keyword is needed for `hack` / `grow` / `weaken` because these commands take
|
||||||
|
time to execute, unlike the others. If you forget to await these commands, you will get
|
||||||
|
an exception saying you tried to do multiple things at once, because your code will
|
||||||
|
immediately finish the function call without waiting for the operation to be done. Also
|
||||||
|
important is that await can only be used in functions marked async (which main() is).
|
||||||
|
|
||||||
Running our Scripts
|
Running our Scripts
|
||||||
-------------------
|
-------------------
|
||||||
Now we want to start running our hacking script so that it can start earning us
|
Now we want to start running our hacking script so that it can start earning us
|
||||||
@ -268,7 +275,7 @@ First, let's determine how many threads of our hacking script we can run.
|
|||||||
The script we wrote
|
The script we wrote
|
||||||
uses 2.6GB of RAM. You can check this using the following |Terminal| command::
|
uses 2.6GB of RAM. You can check this using the following |Terminal| command::
|
||||||
|
|
||||||
$ mem early-hack-template.script
|
$ mem early-hack-template.js
|
||||||
|
|
||||||
This means we can run 6 threads on a 16GB server. Now, to run our scripts on all of these
|
This means we can run 6 threads on a 16GB server. Now, to run our scripts on all of these
|
||||||
servers, we have to do the following:
|
servers, we have to do the following:
|
||||||
@ -283,36 +290,36 @@ servers, we have to do the following:
|
|||||||
Here's the sequence of |Terminal| commands I used in order to achieve this::
|
Here's the sequence of |Terminal| commands I used in order to achieve this::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ scp early-hack-template.script n00dles
|
$ scp early-hack-template.js n00dles
|
||||||
$ scp early-hack-template.script sigma-cosmetics
|
$ scp early-hack-template.js sigma-cosmetics
|
||||||
$ scp early-hack-template.script joesguns
|
$ scp early-hack-template.js joesguns
|
||||||
$ scp early-hack-template.script nectar-net
|
$ scp early-hack-template.js nectar-net
|
||||||
$ scp early-hack-template.script hong-fang-tea
|
$ scp early-hack-template.js hong-fang-tea
|
||||||
$ scp early-hack-template.script harakiri-sushi
|
$ scp early-hack-template.js harakiri-sushi
|
||||||
$ connect n00dles
|
$ connect n00dles
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 1
|
$ run early-hack-template.js -t 1
|
||||||
$ home
|
$ home
|
||||||
$ connect sigma-cosmetics
|
$ connect sigma-cosmetics
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 6
|
$ run early-hack-template.js -t 6
|
||||||
$ home
|
$ home
|
||||||
$ connect joesguns
|
$ connect joesguns
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 6
|
$ run early-hack-template.js -t 6
|
||||||
$ home
|
$ home
|
||||||
$ connect hong-fang-tea
|
$ connect hong-fang-tea
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 6
|
$ run early-hack-template.js -t 6
|
||||||
$ home
|
$ home
|
||||||
$ connect harakiri-sushi
|
$ connect harakiri-sushi
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 6
|
$ run early-hack-template.js -t 6
|
||||||
$ home
|
$ home
|
||||||
$ connect hong-fang-tea
|
$ connect hong-fang-tea
|
||||||
$ connect nectar-net
|
$ connect nectar-net
|
||||||
$ run NUKE.exe
|
$ run NUKE.exe
|
||||||
$ run early-hack-template.script -t 6
|
$ run early-hack-template.js -t 6
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -322,7 +329,7 @@ Here's the sequence of |Terminal| commands I used in order to achieve this::
|
|||||||
This works for most commands in the game!
|
This works for most commands in the game!
|
||||||
|
|
||||||
The :ref:`home_terminal_command` |Terminal| command is used to connect to the home
|
The :ref:`home_terminal_command` |Terminal| command is used to connect to the home
|
||||||
computer. When running our scripts with the :code:`run early-hack-template.script -t 6`
|
computer. When running our scripts with the :code:`run early-hack-template.js -t 6`
|
||||||
command, the :code:`-t 6` specifies that the script should be run with 6 threads.
|
command, the :code:`-t 6` specifies that the script should be run with 6 threads.
|
||||||
|
|
||||||
Note that the |nectar-net| server isn't in the home computer's immediate network.
|
Note that the |nectar-net| server isn't in the home computer's immediate network.
|
||||||
@ -371,13 +378,13 @@ script to target :code:`joesguns` instead of :code:`n00dles`.
|
|||||||
Go to |Terminal| and edit the hacking script by entering::
|
Go to |Terminal| and edit the hacking script by entering::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ nano early-hack-template.script
|
$ nano early-hack-template.js
|
||||||
|
|
||||||
At the top of the script, change the `target` variable to be `joesguns`:
|
At the top of the script, change the `target` variable to be `joesguns`:
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
var target = "joesguns";
|
const target = "joesguns";
|
||||||
|
|
||||||
Note that this will **NOT** affect any instances of the script that are already running.
|
Note that this will **NOT** affect any instances of the script that are already running.
|
||||||
This will only affect instances of the script that are ran from this point forward.
|
This will only affect instances of the script that are ran from this point forward.
|
||||||
@ -401,33 +408,38 @@ Netscript functions:
|
|||||||
Create the script by going to |Terminal| and typing::
|
Create the script by going to |Terminal| and typing::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ nano purchase-server-8gb.script
|
$ nano purchase-server-8gb.js
|
||||||
|
|
||||||
Paste the following code into the script editor:
|
Paste the following code into the script editor:
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
// How much RAM each purchased server will have. In this case, it'll
|
||||||
|
// be 8GB.
|
||||||
|
const ram = 8;
|
||||||
|
|
||||||
// How much RAM each purchased server will have. In this case, it'll
|
// Iterator we'll use for our loop
|
||||||
// be 8GB.
|
let i = 0;
|
||||||
var ram = 8;
|
|
||||||
|
|
||||||
// Iterator we'll use for our loop
|
// Continuously try to purchase servers until we've reached the maximum
|
||||||
var i = 0;
|
// amount of servers
|
||||||
|
while (i < ns.getPurchasedServerLimit()) {
|
||||||
// Continuously try to purchase servers until we've reached the maximum
|
// Check if we have enough money to purchase a server
|
||||||
// amount of servers
|
if (ns.getServerMoneyAvailable("home") > ns.getPurchasedServerCost(ram)) {
|
||||||
while (i < getPurchasedServerLimit()) {
|
// If we have enough money, then:
|
||||||
// Check if we have enough money to purchase a server
|
// 1. Purchase the server
|
||||||
if (getServerMoneyAvailable("home") > getPurchasedServerCost(ram)) {
|
// 2. Copy our hacking script onto the newly-purchased server
|
||||||
// If we have enough money, then:
|
// 3. Run our hacking script on the newly-purchased server with 3 threads
|
||||||
// 1. Purchase the server
|
// 4. Increment our iterator to indicate that we've bought a new server
|
||||||
// 2. Copy our hacking script onto the newly-purchased server
|
let hostname = ns.purchaseServer("pserv-" + i, ram);
|
||||||
// 3. Run our hacking script on the newly-purchased server with 3 threads
|
ns.scp("early-hack-template.script", hostname);
|
||||||
// 4. Increment our iterator to indicate that we've bought a new server
|
ns.exec("early-hack-template.script", hostname, 3);
|
||||||
var hostname = purchaseServer("pserv-" + i, ram);
|
++i;
|
||||||
scp("early-hack-template.script", hostname);
|
}
|
||||||
exec("early-hack-template.script", hostname, 3);
|
//Make the script wait for a second before looping again.
|
||||||
++i;
|
//Removing this line will cause an infinite loop and crash the game.
|
||||||
|
await ns.sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +455,7 @@ execute it on that server.
|
|||||||
|
|
||||||
To run this script, go to |Terminal| and type::
|
To run this script, go to |Terminal| and type::
|
||||||
|
|
||||||
$ run purchase-server-8gb.script
|
$ run purchase-server-8gb.js
|
||||||
|
|
||||||
This purchase will continuously run until it has purchased the maximum number of servers.
|
This purchase will continuously run until it has purchased the maximum number of servers.
|
||||||
When this happens, it'll mean that you have a bunch of new servers that are all running
|
When this happens, it'll mean that you have a bunch of new servers that are all running
|
||||||
@ -540,7 +552,7 @@ finish running. This will free up some RAM on your home computer. We don't want
|
|||||||
to go to waste, so we'll make use of it. Go to |Terminal| and enter the following commands::
|
to go to waste, so we'll make use of it. Go to |Terminal| and enter the following commands::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ run early-hack-template.script -t 3
|
$ run early-hack-template.js -t 3
|
||||||
|
|
||||||
Reaching a Hacking Level of 50
|
Reaching a Hacking Level of 50
|
||||||
------------------------------
|
------------------------------
|
||||||
@ -680,10 +692,10 @@ All of these servers have 32GB of RAM. You can use the |Terminal| command
|
|||||||
go to |Terminal| and run::
|
go to |Terminal| and run::
|
||||||
|
|
||||||
$ home
|
$ home
|
||||||
$ scp early-hack-template.script neo-net
|
$ scp early-hack-template.js neo-net
|
||||||
$ scp early-hack-template.script zer0
|
$ scp early-hack-template.js zer0
|
||||||
$ scp early-hack-template.script max-hardware
|
$ scp early-hack-template.js max-hardware
|
||||||
$ scp early-hack-template.script iron-gym
|
$ scp early-hack-template.js iron-gym
|
||||||
|
|
||||||
Since each of these servers has 32GB of RAM, we can run our hacking script with 12 threads
|
Since each of these servers has 32GB of RAM, we can run our hacking script with 12 threads
|
||||||
on each server. By now, you should know how to connect to servers. So find and connect to
|
on each server. By now, you should know how to connect to servers. So find and connect to
|
||||||
@ -691,7 +703,7 @@ each of the servers above using the :code:`scan-analyze 3` |Terminal| command. T
|
|||||||
following |Terminal| command to run our hacking
|
following |Terminal| command to run our hacking
|
||||||
script with 12 threads::
|
script with 12 threads::
|
||||||
|
|
||||||
$ run early-hack-template.script -t 12
|
$ run early-hack-template.js -t 12
|
||||||
|
|
||||||
Remember that if you have the |AutoLink| program, you can simply click on the hostname of a server
|
Remember that if you have the |AutoLink| program, you can simply click on the hostname of a server
|
||||||
after running :ref:`scan_analyze_terminal_command` to connect to it.
|
after running :ref:`scan_analyze_terminal_command` to connect to it.
|
||||||
@ -766,7 +778,7 @@ much more money, and then you can come back later on and get all these Augmentat
|
|||||||
|
|
||||||
Right now, I suggest purchasing at the very least the :code:`Neurotrainer I` Augmentation from
|
Right now, I suggest purchasing at the very least the :code:`Neurotrainer I` Augmentation from
|
||||||
|CyberSec|. If you have the money to spare, I would also suggest getting :code:`BitWire` and
|
|CyberSec|. If you have the money to spare, I would also suggest getting :code:`BitWire` and
|
||||||
several levels of the :code:`NeuroFlux Governor` Augmentations. Note that each time
|
several levels of the :code:`NeuroFlux Governor` (:code:`NFG`) Augmentations. Note that each time
|
||||||
you purchase an Augmentation,
|
you purchase an Augmentation,
|
||||||
:ref:`the price of purchasing another increases by 90% <gameplay_augmentations_purchasingmultiple>`,
|
:ref:`the price of purchasing another increases by 90% <gameplay_augmentations_purchasingmultiple>`,
|
||||||
so make sure you buy the most expensive Augmentation first. Don't worry, once you choose to
|
so make sure you buy the most expensive Augmentation first. Don't worry, once you choose to
|
||||||
@ -803,50 +815,51 @@ so you should write a script to automate the process. Here's a simple example fo
|
|||||||
startup script. Feel free to adjust it to your liking.
|
startup script. Feel free to adjust it to your liking.
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
/** @param {NS} ns */
|
||||||
|
export async function main(ns) {
|
||||||
|
// Array of all servers that don't need any ports opened
|
||||||
|
// to gain root access. These have 16 GB of RAM
|
||||||
|
const servers0Port = ["sigma-cosmetics",
|
||||||
|
"joesguns",
|
||||||
|
"nectar-net",
|
||||||
|
"hong-fang-tea",
|
||||||
|
"harakiri-sushi"];
|
||||||
|
|
||||||
// Array of all servers that don't need any ports opened
|
// Array of all servers that only need 1 port opened
|
||||||
// to gain root access. These have 16 GB of RAM
|
// to gain root access. These have 32 GB of RAM
|
||||||
var servers0Port = ["sigma-cosmetics",
|
const servers1Port = ["neo-net",
|
||||||
"joesguns",
|
"zer0",
|
||||||
"nectar-net",
|
"max-hardware",
|
||||||
"hong-fang-tea",
|
"iron-gym"];
|
||||||
"harakiri-sushi"];
|
|
||||||
|
|
||||||
// Array of all servers that only need 1 port opened
|
// Copy our scripts onto each server that requires 0 ports
|
||||||
// to gain root access. These have 32 GB of RAM
|
// to gain root access. Then use nuke() to gain admin access and
|
||||||
var servers1Port = ["neo-net",
|
// run the scripts.
|
||||||
"zer0",
|
for (let i = 0; i < servers0Port.length; ++i) {
|
||||||
"max-hardware",
|
const serv = servers0Port[i];
|
||||||
"iron-gym"];
|
|
||||||
|
|
||||||
// Copy our scripts onto each server that requires 0 ports
|
ns.scp("early-hack-template.script", serv);
|
||||||
// to gain root access. Then use nuke() to gain admin access and
|
ns.nuke(serv);
|
||||||
// run the scripts.
|
ns.exec("early-hack-template.script", serv, 6);
|
||||||
for (var i = 0; i < servers0Port.length; ++i) {
|
}
|
||||||
var serv = servers0Port[i];
|
|
||||||
|
|
||||||
scp("early-hack-template.script", serv);
|
// Wait until we acquire the "BruteSSH.exe" program
|
||||||
nuke(serv);
|
while (!ns.fileExists("BruteSSH.exe")) {
|
||||||
exec("early-hack-template.script", serv, 6);
|
await ns.sleep(60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy our scripts onto each server that requires 1 port
|
||||||
|
// to gain root access. Then use brutessh() and nuke()
|
||||||
|
// to gain admin access and run the scripts.
|
||||||
|
for (let i = 0; i < servers1Port.length; ++i) {
|
||||||
|
const serv = servers1Port[i];
|
||||||
|
|
||||||
|
ns.scp("early-hack-template.script", serv);
|
||||||
|
ns.brutessh(serv);
|
||||||
|
ns.nuke(serv);
|
||||||
|
ns.exec("early-hack-template.script", serv, 12);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until we acquire the "BruteSSH.exe" program
|
|
||||||
while (!fileExists("BruteSSH.exe")) {
|
|
||||||
sleep(60000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy our scripts onto each server that requires 1 port
|
|
||||||
// to gain root access. Then use brutessh() and nuke()
|
|
||||||
// to gain admin access and run the scripts.
|
|
||||||
for (var i = 0; i < servers1Port.length; ++i) {
|
|
||||||
var serv = servers1Port[i];
|
|
||||||
|
|
||||||
scp("early-hack-template.script", serv);
|
|
||||||
brutessh(serv);
|
|
||||||
nuke(serv);
|
|
||||||
exec("early-hack-template.script", serv, 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
Random Tips
|
Random Tips
|
||||||
-----------
|
-----------
|
||||||
* Early on in the game, it's better to spend your money on upgrading RAM and purchasing
|
* Early on in the game, it's better to spend your money on upgrading RAM and purchasing
|
||||||
@ -861,7 +874,7 @@ Random Tips
|
|||||||
as useful as your hacking stat. Do not invest too much time or money into gaining combat
|
as useful as your hacking stat. Do not invest too much time or money into gaining combat
|
||||||
stat exp.
|
stat exp.
|
||||||
* As a rule of thumb, your hacking target should be the server with highest max money that's
|
* As a rule of thumb, your hacking target should be the server with highest max money that's
|
||||||
required hacking level is under 1/3 of your hacking level.
|
required hacking level is under 1/2 of your hacking level.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import { ITutorialEvents } from "./ui/InteractiveTutorial/ITutorialEvents";
|
|||||||
// Ordered array of keys to Interactive Tutorial Steps
|
// Ordered array of keys to Interactive Tutorial Steps
|
||||||
enum iTutorialSteps {
|
enum iTutorialSteps {
|
||||||
Start,
|
Start,
|
||||||
NSSelection,
|
|
||||||
GoToCharacterPage, // Click on 'Stats' page
|
GoToCharacterPage, // Click on 'Stats' page
|
||||||
CharacterPage, // Introduction to 'Stats' page
|
CharacterPage, // Introduction to 'Stats' page
|
||||||
CharacterGoToTerminalPage, // Go back to Terminal
|
CharacterGoToTerminalPage, // Go back to Terminal
|
||||||
@ -46,7 +45,6 @@ const ITutorial = {
|
|||||||
// Keeps track of whether each step has been done
|
// Keeps track of whether each step has been done
|
||||||
stepIsDone: {
|
stepIsDone: {
|
||||||
[iTutorialSteps.Start]: false,
|
[iTutorialSteps.Start]: false,
|
||||||
[iTutorialSteps.NSSelection]: false,
|
|
||||||
[iTutorialSteps.GoToCharacterPage]: false,
|
[iTutorialSteps.GoToCharacterPage]: false,
|
||||||
[iTutorialSteps.CharacterPage]: false,
|
[iTutorialSteps.CharacterPage]: false,
|
||||||
[iTutorialSteps.CharacterGoToTerminalPage]: false,
|
[iTutorialSteps.CharacterGoToTerminalPage]: false,
|
||||||
|
@ -139,7 +139,7 @@ const Messages: Record<MessageFilenames, Message> = {
|
|||||||
|
|
||||||
[MessageFilenames.Jumper1]: new Message(
|
[MessageFilenames.Jumper1]: new Message(
|
||||||
MessageFilenames.Jumper1,
|
MessageFilenames.Jumper1,
|
||||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
`Soon you will be contacted by a hacking group known as ${FactionNames.CyberSec}. ` +
|
||||||
"They can help you with your search. \n\n" +
|
"They can help you with your search. \n\n" +
|
||||||
"You should join them, garner their favor, and " +
|
"You should join them, garner their favor, and " +
|
||||||
"exploit them for their Augmentations. But do not trust them. " +
|
"exploit them for their Augmentations. But do not trust them. " +
|
||||||
|
@ -9,7 +9,6 @@ import ArrowBackIos from "@mui/icons-material/ArrowBackIos";
|
|||||||
import { ITutorialEvents } from "./ITutorialEvents";
|
import { ITutorialEvents } from "./ITutorialEvents";
|
||||||
import { CopyableText } from "../React/CopyableText";
|
import { CopyableText } from "../React/CopyableText";
|
||||||
|
|
||||||
import List from "@mui/material/List";
|
|
||||||
import ListItem from "@mui/material/ListItem";
|
import ListItem from "@mui/material/ListItem";
|
||||||
import EqualizerIcon from "@mui/icons-material/Equalizer";
|
import EqualizerIcon from "@mui/icons-material/Equalizer";
|
||||||
import LastPageIcon from "@mui/icons-material/LastPage";
|
import LastPageIcon from "@mui/icons-material/LastPage";
|
||||||
@ -28,7 +27,6 @@ import {
|
|||||||
iTutorialSteps,
|
iTutorialSteps,
|
||||||
iTutorialEnd,
|
iTutorialEnd,
|
||||||
} from "../../InteractiveTutorial";
|
} from "../../InteractiveTutorial";
|
||||||
import { NSSelection } from "./NSSelection";
|
|
||||||
|
|
||||||
interface IContent {
|
interface IContent {
|
||||||
content: React.ReactElement;
|
content: React.ReactElement;
|
||||||
@ -47,23 +45,10 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
enum Language {
|
|
||||||
None,
|
|
||||||
NS1,
|
|
||||||
NS2,
|
|
||||||
}
|
|
||||||
|
|
||||||
export function InteractiveTutorialRoot(): React.ReactElement {
|
export function InteractiveTutorialRoot(): React.ReactElement {
|
||||||
const [nsSelectionOpen, setNSSelectionOpen] = useState(false);
|
|
||||||
const [language, setLanguage] = useState(Language.None);
|
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
const tutorialScriptExtension = {
|
const tutorialScriptName = `n00dles.js`;
|
||||||
[Language.None]: ".script",
|
|
||||||
[Language.NS1]: ".script",
|
|
||||||
[Language.NS2]: ".js",
|
|
||||||
}[language];
|
|
||||||
const tutorialScriptName = `n00dles${tutorialScriptExtension}`;
|
|
||||||
|
|
||||||
const contents: { [number: string]: IContent | undefined } = {
|
const contents: { [number: string]: IContent | undefined } = {
|
||||||
[iTutorialSteps.Start as number]: {
|
[iTutorialSteps.Start as number]: {
|
||||||
@ -83,47 +68,6 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
),
|
),
|
||||||
canNext: true,
|
canNext: true,
|
||||||
},
|
},
|
||||||
[iTutorialSteps.NSSelection as number]: {
|
|
||||||
content: (
|
|
||||||
<>
|
|
||||||
<Typography>The tutorial will adjust to your programming ability.</Typography>
|
|
||||||
<Typography>Bitburner has 2 types of scripts:</Typography>
|
|
||||||
<List>
|
|
||||||
<ListItem>
|
|
||||||
<Typography>NS1: Javascript from 2009, very simple. Recommended for beginners to programming.</Typography>
|
|
||||||
</ListItem>
|
|
||||||
<ListItem>
|
|
||||||
<Typography>
|
|
||||||
NS2: Native, modern Javascript. Recommended if you know any programming language or are serious about
|
|
||||||
learning programming.
|
|
||||||
</Typography>
|
|
||||||
</ListItem>
|
|
||||||
</List>
|
|
||||||
<Typography>
|
|
||||||
Both are available at all time and interchangeably. This choice is only for the tutorial.
|
|
||||||
</Typography>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setLanguage(Language.NS1);
|
|
||||||
iTutorialNextStep();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Use NS1
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setLanguage(Language.NS2);
|
|
||||||
iTutorialNextStep();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Use NS2
|
|
||||||
</Button>
|
|
||||||
<Button onClick={() => setNSSelectionOpen(true)}>More info</Button>
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
canNext: false,
|
|
||||||
},
|
|
||||||
[iTutorialSteps.GoToCharacterPage as number]: {
|
[iTutorialSteps.GoToCharacterPage as number]: {
|
||||||
content: (
|
content: (
|
||||||
<>
|
<>
|
||||||
@ -320,7 +264,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
<Typography></Typography>
|
<Typography></Typography>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
canNext: true,
|
canNext: false,
|
||||||
},
|
},
|
||||||
[iTutorialSteps.TerminalManualHack as number]: {
|
[iTutorialSteps.TerminalManualHack as number]: {
|
||||||
content: (
|
content: (
|
||||||
@ -364,7 +308,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
<Typography>Let's head home before creating our first script!</Typography>
|
<Typography>Let's head home before creating our first script!</Typography>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
canNext: true,
|
canNext: false,
|
||||||
},
|
},
|
||||||
[iTutorialSteps.TerminalCreateScript as number]: {
|
[iTutorialSteps.TerminalCreateScript as number]: {
|
||||||
content: (
|
content: (
|
||||||
@ -378,9 +322,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Typography classes={{ root: classes.textfield }}>{"[home ~/]> nano"}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{"[home ~/]> nano"}</Typography>
|
||||||
|
|
||||||
<Typography>
|
<Typography>Scripts must end with the .js extension. Let's make a script now by entering </Typography>
|
||||||
Scripts must end with the {tutorialScriptExtension} extension. Let's make a script now by entering{" "}
|
|
||||||
</Typography>
|
|
||||||
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> nano ${tutorialScriptName}`}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> nano ${tutorialScriptName}`}</Typography>
|
||||||
|
|
||||||
<Typography>
|
<Typography>
|
||||||
@ -394,20 +336,12 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
content: (
|
content: (
|
||||||
<>
|
<>
|
||||||
<Typography>
|
<Typography>
|
||||||
This is the script editor. You can use it to program your scripts.{" "}
|
This is the script editor. You can use it to program your scripts. Copy and paste the following code into
|
||||||
{language !== Language.NS2 && <>Scripts are written in a simplified version of javascript.</>} Copy and
|
the script editor: <br />
|
||||||
paste the following code into the script editor: <br />
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Typography classes={{ root: classes.code }}>
|
<Typography classes={{ root: classes.code }}>
|
||||||
{language !== Language.NS2 && (
|
{
|
||||||
<CopyableText
|
|
||||||
value={`while(true) {
|
|
||||||
hack('n00dles');
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{language === Language.NS2 && (
|
|
||||||
<CopyableText
|
<CopyableText
|
||||||
value={`export async function main(ns) {
|
value={`export async function main(ns) {
|
||||||
while(true) {
|
while(true) {
|
||||||
@ -415,7 +349,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
}
|
}
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
)}
|
}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
For anyone with basic programming experience, this code should be straightforward. This script will
|
For anyone with basic programming experience, this code should be straightforward. This script will
|
||||||
@ -589,8 +523,17 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
content: (
|
content: (
|
||||||
<Typography>
|
<Typography>
|
||||||
This page contains a lot of different documentation about the game's content and mechanics. I know it's a lot,
|
This page contains a lot of different documentation about the game's content and mechanics. I know it's a lot,
|
||||||
but I highly suggest you read (or at least skim) through this before you start playing . That's the end of the
|
but I highly suggest you read (or at least skim) through this before you start playing.
|
||||||
tutorial. Hope you enjoy the game!
|
<br />
|
||||||
|
<br />
|
||||||
|
The{" "}
|
||||||
|
<a href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html">
|
||||||
|
Getting Started
|
||||||
|
</a>{" "}
|
||||||
|
contains the guide for new players, navigating you through most of early game.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
That's the end of the tutorial. Hope you enjoy the game!
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
canNext: true,
|
canNext: true,
|
||||||
@ -614,7 +557,6 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
if (content === undefined) throw new Error("error in the tutorial");
|
if (content === undefined) throw new Error("error in the tutorial");
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NSSelection open={nsSelectionOpen} onClose={() => setNSSelectionOpen(false)} />
|
|
||||||
<Paper square sx={{ maxWidth: "70vw", p: 2 }}>
|
<Paper square sx={{ maxWidth: "70vw", p: 2 }}>
|
||||||
{content.content}
|
{content.content}
|
||||||
{step !== iTutorialSteps.TutorialPageInfo && (
|
{step !== iTutorialSteps.TutorialPageInfo && (
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
import Editor from "@monaco-editor/react";
|
|
||||||
import { Tab, Tabs, Typography } from "@mui/material";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
import { Modal } from "../React/Modal";
|
|
||||||
|
|
||||||
import * as monaco from "monaco-editor";
|
|
||||||
|
|
||||||
type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
open: boolean;
|
|
||||||
onClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ns1Example = `while(true) {
|
|
||||||
hack('n00dles');
|
|
||||||
}`;
|
|
||||||
const ns2Example = `/** @param {NS} ns */
|
|
||||||
export async function main(ns) {
|
|
||||||
while(true) {
|
|
||||||
await ns.hack('n00dles');
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
export function NSSelection(props: IProps): React.ReactElement {
|
|
||||||
const [value, setValue] = React.useState(0);
|
|
||||||
|
|
||||||
function handleChange(event: React.SyntheticEvent, tab: number): void {
|
|
||||||
setValue(tab);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMount(editor: IStandaloneCodeEditor): void {
|
|
||||||
editor.updateOptions({ readOnly: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal open={props.open} onClose={props.onClose} sx={{ zIndex: 999999 }}>
|
|
||||||
<Tabs variant="fullWidth" value={value} onChange={handleChange}>
|
|
||||||
<Tab label="NS1" />
|
|
||||||
<Tab label="NS2" />
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
{value === 0 && (
|
|
||||||
<>
|
|
||||||
<Typography>
|
|
||||||
These scripts end with '.script'. Using a very old interpreted version of javascript. It is perfect for
|
|
||||||
beginner to programming.
|
|
||||||
</Typography>
|
|
||||||
<Typography>Example script using NS1:</Typography>
|
|
||||||
<Editor
|
|
||||||
loading={<></>}
|
|
||||||
defaultLanguage="javascript"
|
|
||||||
defaultValue={ns1Example}
|
|
||||||
height={`${300}px`}
|
|
||||||
theme={"vs-dark"}
|
|
||||||
onMount={onMount}
|
|
||||||
options={{ fontSize: 30 }}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{value === 1 && (
|
|
||||||
<>
|
|
||||||
<Typography>
|
|
||||||
These scripts end with '.js'. Scripts using ns2 are running natively along the game. If you know any
|
|
||||||
programming language you should be using this. However if you're unfamiliar with javascript Promises you
|
|
||||||
might want to read up on them a little bit before diving in.
|
|
||||||
</Typography>
|
|
||||||
<Typography>Example script using NS2:</Typography>
|
|
||||||
<Editor
|
|
||||||
loading={<></>}
|
|
||||||
defaultLanguage="javascript"
|
|
||||||
defaultValue={ns2Example}
|
|
||||||
height={`${300}px`}
|
|
||||||
theme={"vs-dark"}
|
|
||||||
options={{ fontSize: 30 }}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user