Advertisement
Trash_GOTY

serverMaster.js

Mar 6th, 2024 (edited)
325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** @param {NS} ns */
  2. export async function main(ns) {
  3.  
  4.     /**
  5.      * SERVER MANAGER
  6.      * ---------------------------------------------------------
  7.      * THIS SCRIPT HANDLES BUYING AND UPGRADING SERVERS
  8.      * ITS MAIN FUNCTION IS FINDING SPACE FOR A GIVEN SCRIPT AND STARTING IT THERE
  9.      * ---------------------------------------------------------
  10.      * IT LISTENS ON PORT 1, TAKING:
  11.      *    
  12.      * 1. The Script you want to run    ex. string  "hack.js"
  13.      * 2. The amount of wanted threads  ex. int      2                  default: 1
  14.      * 3. The Structure Name            ex. string  "sv_TestServer_"    default: "sv_StandardServer_"
  15.      * 4. The location of the script    ex. string  "home"              default: "home"
  16.      *
  17.      * EVERYTHING AFTER 4 IS PASSED AS AN ARGUMENT TO THE SCRIPT
  18.      * ---------------------------------------------------------
  19.      */
  20.  
  21.     //Only change things here.
  22.  
  23.     const portNum   = 1;    //Port Number. Ranges from 1-20
  24.     const maxServer = 8;    //Maxmimum Servers that are purchased for a single network.
  25.  
  26.     //Script starts here. Looping endlessly.
  27.  
  28.     while (true) {
  29.  
  30.         /**
  31.          *  VARIABLE MANAGEMENT
  32.          *  This means reading Port 1 and getting variables that change more regularly.
  33.          *  -----------------------------------------
  34.          * 1. Get next argument in Port Queue 1.
  35.          * 2. If port is empty, pause and wait for a write operation.
  36.          * 3. Parse variables
  37.          * 4. Check for errors
  38.          * 5. Set additional variables
  39.          * 5. Toast the host of current request.
  40.          *  -----------------------------------------
  41.          */
  42.  
  43.         //Part 1 / 2 - Read Port
  44.         //-----------------------------------------
  45.        
  46.                 var args = ns.readPort(portNum);  //Read from port
  47.        
  48.         if (args == "NULL PORT DATA") {
  49.             await ns.nextPortWrite(portNum);      //Wait for PortWrite. See step 2.
  50.             var args = ns.readPort(portNum);      //Read the new content.
  51.         }
  52.         var splitArgs = args.split(",");          //Split Arguments
  53.  
  54.         ns.print (args)
  55.  
  56.         //Part 3 - Parse Variables
  57.         //-----------------------------------------
  58.  
  59.         if (splitArgs[0]== null) {
  60.             ns.alert("serverMaster wasn't passed any arguments. How did you even manage this. Breaking...");
  61.             continue;
  62.         }                                                                    // Set Name
  63.         else { var name = splitArgs[0] }
  64.  
  65.         if (splitArgs[1] == null || splitArgs[1] == "0") { var threads = 1 } // Set Threads
  66.         else { var threads = Math.ceil(splitArgs[1]) }
  67.  
  68.         if (splitArgs[2] == null) { var host = "sv_StandardServer_" }        // Set Server Name
  69.         else { var host = splitArgs[2] }
  70.  
  71.         if (splitArgs[3] == null) { var scriptLoc = "home" }                 // Set Script Location
  72.         else { var scriptLoc = splitArgs[3] }
  73.  
  74.         var restArgs = [];                                                   // Set script Arguments
  75.         for (let i = 4; i < splitArgs.length; i++) { restArgs.push(splitArgs[i]) }
  76.  
  77.         ns.print(restArgs.toString())
  78.        
  79.         //Part 4 - Check for problems
  80.         //-----------------------------------------
  81.  
  82.            if (!ns.fileExists(name, scriptLoc)) {
  83.             ns.alert("The file " + name + " does not exist at " + scriptLoc + ". Breaking...")
  84.             continue;
  85.            }
  86.  
  87.         //Part 5 - Set additional variables
  88.         //-----------------------------------------
  89.  
  90.         var actualWeight    = ns.getScriptRam(name, scriptLoc) * threads;        // Set total Ram Cost
  91.         var roundedWeight   = Math.ceil(actualWeight/2) * 2;                     // Sets Ram cost to the next higher, even int
  92.         let player          = ns.getPlayer();                                    // Get Player
  93.         var availableServers= [];                                                // Prepare for wanted servers
  94.         var currentServers  = ns.getPurchasedServers();                          // Get already purchased servers
  95.                
  96.         ns.print ("Needed Ram = " + roundedWeight + " for " + threads + " threads.")
  97.        
  98.         //Get already established Servers and their Ram
  99.         for (const server of currentServers) {
  100.             if (server.includes(host)) {
  101.                 availableServers.push   (server)
  102.  
  103.                 ns.print ("Added " + server + " to available")
  104.             }
  105.         }
  106.  
  107.         ns.print(availableServers.toString())
  108.  
  109.         /**
  110.          * MAIN FUNCTION
  111.          * ---------------------------------------------------------
  112.          * Automatically assigns script to a server.
  113.          * If no server has enough space, automatically upgrades or buys new ones.
  114.          * ---------------------------------------------------------
  115.          * 1. Checks through already established servers and returns name if it finds enough space.
  116.          * 2. Checks if any available server can be upgraded enough and chooses the cheapest.
  117.          * 3. Checks if it can buy a new server with enough capacity. This has a maximum of 8 by default, more can be set above.
  118.          * 4. If player doesn't have enough money to purchase anything, puts request back into queue.
  119.          * ---------------------------------------------------------
  120.          */
  121.  
  122.         var success = false;
  123.  
  124.         //Part 1 - Check for space
  125.         //-----------------------------------------
  126.  
  127.         for (const server of availableServers) {
  128.  
  129.             //Check if server has enough space.
  130.             //If yes, start script and end cycle.
  131.             if ((ns.getServerMaxRam(server) - ns.getServerUsedRam(server)) > actualWeight) {
  132.                 await startScript(server, name, threads, restArgs, scriptLoc);
  133.                 success = true;
  134.                 break;
  135.             }
  136.         }
  137.  
  138.         if (success) { continue }       // Move onto next cycle
  139.  
  140.         //  Part 2 - Check for Upgrades
  141.         //  Check if an upgrade can be afforded and puts out the cheapest option.
  142.         //  --------------------------------------------------------------------------
  143.  
  144.         var cheapestPrice = -1;
  145.  
  146.         for (const server of availableServers) {
  147.  
  148.             //Calculates how much Ram needs to be bought
  149.             var freeRam     =  Math.floor((ns.getServerMaxRam(server) - ns.getServerUsedRam(server)));
  150.             var neededRam =  Math.pow(2, Math.ceil(Math.log2(roundedWeight + ns.getServerMaxRam(server) - freeRam)))        //Set to next power of 2
  151.  
  152.             //Get the price.
  153.             var price     = ns.getPurchasedServerUpgradeCost(server, neededRam);
  154.            
  155.             //Check if Cheapest / First Server
  156.             if (price < cheapestPrice || cheapestPrice == -1) {
  157.                 var cheapestPrice   = price;
  158.                 var cheapestServer  = server;
  159.                 var cheapestNeeded  = ns.getServerMaxRam(server) + neededRam;
  160.  
  161.             }
  162.         }
  163.  
  164.         //Check if Cheapest Price is affordable
  165.  
  166.         if (cheapestPrice < player.money && !cheapestPrice == -1) {
  167.  
  168.             ns.print("Cheapest Server is " + cheapestServer + " at " + cheapestPrice)
  169.                        
  170.             //Is affordable. Purchase, run and continue
  171.  
  172.             ns.upgradePurchasedServer(cheapestServer, cheapestNeeded);
  173.             await startScript(cheapestServer, name, threads, restArgs, scriptLoc);
  174.             continue;
  175.         }
  176.  
  177.         //  Part 3 - Buy a new Server
  178.         //  Check if you can buy a new Server and does so. Last line of defense.
  179.         //  --------------------------------------------------------------------------
  180.  
  181.         if (player.money > ns.getPurchasedServerCost(Math.pow(2, Math.ceil(Math.log2(roundedWeight)))) && availableServers.length < maxServer){
  182.  
  183.             //Can purchase server.
  184.  
  185.             var newName = host + availableServers.length.toString()
  186.  
  187.             await ns.purchaseServer(newName, Math.pow(2, Math.ceil(Math.log2(roundedWeight))));
  188.             await startScript(newName, name, threads, restArgs, scriptLoc);
  189.             continue;
  190.         }
  191.         else {
  192.  
  193.             //Can't purchase new server. Returning request to end of queue.
  194.             ns.writePort(portNum, args);
  195.             await ns.sleep(10000)
  196.             continue;
  197.  
  198.         }
  199.     }
  200.    
  201.     async function startScript(host, name, threads, args, fileLoc) {
  202.         ns.scp  (name, host, fileLoc);
  203.         ns.exec (name, host, threads, args.toString());
  204.     }
  205. }
Tags: Bitburner
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement