Have ideas to improve npm?Join in the discussion! »

    astroneer-rcon-client

    2.2.7 • Public • Published

    AstroneerRconClient

    Version: 2.2.7
    A client for the Astroneer Rcon server built with Node.JS

    Table of contents

    Please take a moment to look at this list to find what you are looking for!

    How it works

    In-depth documentation on how the remote console works.

    Sending and receiving data
    Command reference
    Usage

    The documentation of this library. If you want to know how to use this library, start here!

    Quickstart
    Type definitions
    ClientOptions
    PlayerQuery
    PlayerCategory
    CreativeConfig
    Client class
    Constructor
    Functions
    Events
    AstroLauncher Link class
    Errors and Bugs

    How-it-works

    How does rcon work in the Astroneer Dedicated server?
    First to enable rcon for a server, set the ConsolePort value in the AstroServerSettings.ini in Astro/Saved/Config within the server folder.
    It is also recommended to set ConsolePassword to a random secure password, that the rcon client will use to connect.

    What is it?

    It is simply a tcp socket server that accepts one client to connect. This server will listen and respond with data depending on client requests as it is the socket continuous duplex stream.

    Before we continue...

    Here is some stuff you need to know before reading this:

    Guid = An unique identifier for each player calculated using MurMurHash x86_64-bit based on unknown arguments (perhaps Steam/Microsoft account id). This value never changes.

    RCON = Remote Console

    < x > = Anything between <> tags is a placeholder for a variable (user input) (with the <> tags marking the placeholder)

    Sending-and-receiving-data

    Commands are sent to the server as strings followed by a newline (\n), encoded into raw binary bytes. You will simply connect with a tcp socket client and start sending commands to the server.
    If the server requires a password, send the password in the same encoded format and with it a following (\n) newline to allow commands to be executed.
    The server will respond after command execution with the requested data, result of execution or with an error. For some reason, not all the commands return responses, but most of them return JSON.
    Here are some examples of basic responses after command execution:

    { _message: "Some error occurred!", status: false} // Something went wrong :/
    
    { _message: "Success!", status: true} // It worked!
    

    It's pretty easy to understand the basic structure of a response right? If the status JSON value is false, the _message value will contain an error. If the status value is true, the _message value contains a success message.
    Now it's important to understand a key difference between commands with responses and commands with data. Commands with responses, such as "DSSetPlayerCategoryForPlayerName" return a standard response JSON object. If the command "has" data, which means you're requesting some data from the server, it will contain a command specific JSON response object. As an example "DSListPlayers" will return a JSON object, which has a "playerInfo" array, which contains information about each known player with it's command specific structure.
    Because of the continuous data stream nature of the tcp socket, the rcon server can also return responses to multiple requests at once. Responses are always separated by \r\n.
    The same applies for sending commands. You can send multiple commands separated by \n.

    Command-reference

    The basic structure is this:

    <command> <arguments,...>
    

    First there is the command part, which is the command. Then there is the arguments part, which is a list of arguments separated by spaces.
    If an argument contains a space, use " in the start and the end of the argument.
    Here's a list of commands exposed to the rcon client and how to use them. Not all of these work due to bugs, or they may be disabled.
    The (?) symbol in the description means that the use case of the function is unknown.
    (The arguments format below works like this <ArgumentName>(<Type>))
    Written for server version 1.17.89.0 (9.1.2021)

    Name Arguments Description Functional? Returns
    DSRemote <ConsoleCommand>(String) (?) Execute an in-game command in the in-game console No Unknown
    DSClearFavoritesList None (?) Unknown No Unknown
    DSRemoveFavorite <ServerUrl>(String, <ip>:<port>) (?) Unknown No Unknown
    DSAddFavorite <ServerUrl>(String, <ip>:<port>) <NickName>(String) (?) Unknown No Unknown
    DSGetFavoritesList None (?) Unknown No Unknown
    DSClearRecentsList None (?) Unknown No Unknown
    DSGetRecentsList None (?) Unknown No Unknown
    DSBackupSaveGames None (?) Backup the servers saves No Unknown
    DSSetBackupSaveGamesInterval <Seconds>(Number) (?) Set the backup interval in seconds No Unknown
    DSSetPlayerCategoryForPlayerName <PlayerName>(String) <Category>(String, PlayerCategory) Set a player's category based on the player's name. See the type definition of PlayerCategory for more details on what the Category argument can be. Yes Unknown
    DSSetPlayerCategory <Player>(String?) <Category>(String, PlayerCategory) <Index>(Number?) (?) Set a player's category based on the player object? No Unknown
    DSSetPlayerCategoryGuid <PlayerGuid> <Category> Set a player's category based on the player's guid. No (Bug!) Standard:
    {"_message":"updated entry: player=<PlayerName>, playerGuid=<PlayerGuid>, category=<PlayerGuid>","status":true}
    DSSetPlayerCategoryIdx <PlayerIndex> <Category> Set a player's category based on their index in the known players list. Please not the index can change, so it's better to use the guid equivalent for this command No (Bug!) Standard:
    {"_message":"updated entry: player=<PlayerName>, playerGuid=<PlayerGuid>, category=<PlayerGuid>","status":true}
    DSSetDenyUnlisted <Boolean>(Boolean) Enable or disable the whitelist Yes Special:
    (UAstroServerCommExecutor::DSSetDenyUnlisted: SetDenyUnlistedPlayers <unchanged/changed>: <0/1>\r\n
    DSSetSaveGameInterval <Seconds>(Number) Set the autosave internal in seconds No Unknown
    DSSetActivityTimeout <Seconds>(Number) Set the afk timeout in seconds No Unknown
    DSTravelPass <ServerName>(String?) <Password>(String) (Number?) (?) No Unknown
    DSTravelName <ServerName>(String?) <Index>(Number?) <Password>(String) (?) No Unknown
    DSTravel <ServerIndex>(Number?) <Password>(String) (?) Maybe to connect to some other server? This is for clients, so I have no idea... No Unknown
    DSSetPassword <Password>(String) Set the server password No Unknown
    DSKickPlayer <PlayerIndex>(Number) Kick a player based on their index in the known players list No Unknown
    DSKickPlayerGuid <PlayerGuid>(Number) Kick a player based on their guid Yes Special:
    UAstroServerCommExecutor::DSKickPlayerGuid: request to kick player <PlayerGuid> ???\<d/ >\r\n' The variable here on the end of the data is either "d" or nothing. It is "d" for success.
    DSGetServerList None Unknown No Unknown
    DSSetBackpackPowerUnlimitedCreative <Boolean>(Boolean) (?) Disable or enable backpack power limits No Unknown
    DSSetInvisibleToHazardsCreative <Boolean>(Boolean) (?) Make the players invincible to hazards No Unknown
    DSSetInvincibleCreative <Boolean>(Boolean) (?) Make the player invincible to any damage No Unknown
    DSSetOxygenFreeCreative <Boolean>(Boolean) (?) Disable / Enable oxygen limitations No Unknown
    DSSetFuelFreeCreative <Boolean>(Boolean) (?) Disable / Enable fuel limitations No Unknown
    DSCreativeMode <Boolean>(Boolean) (?) Enable creative mode for the active save No Unknown
    DSGetProperties None Unknown No Unknown
    DSServerStatistics() None Get information about the server Yes Special: {"build":"<ServerVersion>","ownerName":"<ServerOwnerName>","maxInGamePlayers":<ServerPlayerLimit>,"playersInGame":<PlayersInGame>,"playersKnownToGame":<KnownPlayers>,"saveGameName":"<ActiveSave>","playerActivityTimeout":<AfkTimeout>,"secondsInGame":<SecondsPlayed>,"serverName":<ServerRegistryServerName>,"serverURL":<ServerUrl>,"averageFPS":<ServerFps/TickSpeed>,"hasServerPassword":<HasPassword>,"isEnforcingWhitelist":<HasWhitelistEnabled>,"creativeMode":<ActiveSaveIsCreative>,"isAchievementProgressionDisabled":<NoAchievements>}\r\n
    DSListPlayers None Get the known players list Yes Special: {"playerInfo":[{"playerGuid":"<PlayerGuid>","playerCategory":<PlayerCategory>,"playerName":<PlayerName>,"inGame":<PlayerConnected>,"index":<PlayerIndex>}, ...]}\r\n
    DSRenameGame <Oldname>(String) <NewName>(String) Rename a save No Unknown
    DSDeleteGame <SaveName>(String) Delete a save No Unknown
    DSLoadGame <SaveName>(String) Load a new save and set it as the active save for the server Yes None
    DSSaveGame <Unknown>(String, Optional) Save the game instantly Yes None
    DSNewGame <NewSaveName>(String) Create a new save and set it as active. All players will be forced to reload. Yes None
    DSServerShutdown None Shutdown the server gracefully Yes None
    DSListGames None List all the saves available Yes Special: {"activeSaveName":"<ActiveSave>","gameList":[{"name":"<SaveName>","date":"<LastEdited, YYYY.MM.DD-hh.mm.ss>9,"bHasBeenFlaggedAsCreativeModeSave":<IsCreative>}, ...]}\r\n
    DSTravelURL <ServerUrl> <Password> <Index> (?) Go to another server? Again, this is for clients usually No Unknown
    DSTravelFriend <FriendName> <Password> <Index> (?) Go/Connect to a friend? This is used to in clients to connect to a CoOp server usually No Unknown

    Usage

    This library is written in Node.Js and is to be used in Node.Js applications as a CommonJS module.
    This module exports an object which contains the client class and the link class known as the Astrolauncher link class.
    Both classes implement same functionality, but the client class connects to the actual server, while the link class uses Astrolauncher's API to send commands to the server.
    You can read more about it in the How-it-works section above.

    Quickstart

    As both exported classes implement the same functionality, but execute them in different ways. This quickstart applies for both, with minor modifications depending on what you need to use.
    In short. If you are using AstroLauncher you need to create a new instance of the Link class, if you're not using anything that already connects to the server rcon socket use, the Client class.
    In this quickstart we will be using the Client class, but you may switch it by changing the end of the first line to .link, instead of .client.

    Step 1

    First you need to download the library. You can do it with NPM (astroneer-rcon-client, clone of this repo):

    npm install astroneer-rcon-client
    

    Then you need to import the CommonJs module, you can do that with:

    const AstroneerRcon = require("astroneer-rcon-client").client
    // Tip: If we are operating in the same directory replace the variable in the file path with a dot (.), or if AstroneerRcon is in a folder in your projects working directory. You may use ./<The folder you installed this lib with>/AstroneerRcon.js
    

    If AstroneerRcon is undefined, or you get an error, make sure your filepath is correct.

    Step 2

    Now that the library has been imported, you need to connect to the server (or the AstroLauncher api, this quickstart works for both!)
    First you need to create a new instance of the client/link and call .connect() with the constructor appropriate parameters.
    AstroneerRcon is event driven. You can register listeners for multiple things happening in the server and in the client.
    There are a few good ones to include, like "connected" and "error".

    const AstroneerRcon = require("astroneer-rcon-client").client
    let myInstance = new client({
        // Here is the important part, the client configuration.
        ip: "127.0.0.1", // Your server ip
        port: 1234, // Your server port
        password: "MyVerySecureRandomPassword" // This is the server password, if required. You can make it as long as you want.
        // Always use a password for security reasons, if possible!!!
    })
    // Register event listeners
    myInstance.on("error", async error => {
        console.log("An error occurred!\n", error)
        // It is very important you handle this. All unexpected errors will trigger this function, so you can handle it in your application.
    })
    
    myInstance.on("connected", async () => {
        console.log("Connected to server!")
        // This function gets ran when the connection to the server is established.
        // Your app code should live here.
    })
    
    myInstance.connect() // Connect to the server, keep this line last if possible. At least below all the event listener registrations. As they may not be registered correctly, if the client is already connecting or connected.
    

    That's pretty much it! You can now start executing commands and gathering data from the server!

    Step 3

    To execute commands, refer to the Client class functions list. Which can be found from the "Table of contents" above.
    Here we simply get some basic data about the server.

    const AstroneerRcon = require("astroneer-rcon-client").client
    let myInstance = new client({
        // Here is the important part, the client configuration.
        ip: "127.0.0.1", // Your server ip
        port: 1234, // Your server port
        password: "MyVerySecureRandomPassword" // This is the server password, if required. You can make it as long as you want.
        // Always use a password for security reasons, if possible!!!
    })
    // Register event listeners
    myInstance.on("error", async error => {
        console.log("An error occurred!\n", error)
        // It is very important you handle this. All unexpected errors will trigger this function, so you can handle it in your application.
    })
    
    myInstance.on("connected", async () => {
        console.log("Connected to server!")
    
        let server = await myInstance.getInfo()
        console.log("Got this information about the server:\n", server)
    })
    
    myInstance.connect() // Connect to the server, keep this line last if possible. At least below all the event listener registrations. As they may not be registered correctly, if the client is already connecting or connected.
    

    That's pretty much all there is to know about the basic usage of this library.
    Refer to the Client class section for more details on what you can do with this library!

    Client-class

    The client class is where the rcon client lives. It contains all the commands you can execute against the server and it formats the data for easier usage.
    Such as handling dates better (as JavasScript Date objects) and building cleaner response objects.

    Type-definitions

    These are written using JSDoc.
    In markdown:

    ClientOptions

    {ip: String, port: Number, password?: String, timeout?: Number}

    Property: ip,
    Type: String,
    Description: The IP-address to connect to

    Property: port,
    Type: Number,
    Description: The port number the server is listening for rcon

    Property: password,
    Type: String,
    Description: The rcon password, leave empty if the server does not require an rcon password

    Property: timeout,
    Type: Number,
    Description: The timeout limit in ms. If not set, will default to 15000

    Property: delivery_delay,
    Type: Number,
    Description: The possible delay while starting and ending a "packet". A "packet" can arrive in multiple parts This value is the amount of time to wait for the next part of the "packet". By default 90(ms).

    PlayerQuery

    {guid?: String, name?: String, index?: Number}

    Property: ?guid,
    Type: String,
    Description: A player guid. This is a string id unique for each player, which never changes

    Property: ?name,
    Type: String,
    Description: The IP-address to connect to

    Property: ?index,
    Type: Number,
    Description: The player index (in the known players list)

    PlayerCategory

    "Unlisted" or "Blacklisted" or "Whitelisted" or "Admin" or "Pending" or "Owner"

    Definitions:
    - Unlisted = No permissions, blocked by whitelist if enabled
    - Blacklisted = Same as banned
    - Whitelisted = No permissions, allowed by whitelist if enabled
    - Admin = Max permissions possible for anyone but the owner
    - Pending = Not yet set, will be automatically set to Unlisted on next connect if not changed by then
    - Owner = The owner, all permissions

    CreativeConfig

    {fuel: Boolean, invincible: Boolean, hazards: Boolean, oxygen: Boolean, backpackpower: Boolean}

    Property: fuel,
    Type: Boolean,
    Description: Should fuel consumption be enabled?

    Property: invincible,
    Type: Boolean,
    Description: Should invincibility be enabled?

    Property: hazards,
    Type: Boolean,
    Description: Should hazards be enabled?

    Property: oxygen,
    Type: Boolean,
    Description: Should oxygen system be enabled?

    Property: backpackpower,
    Type: Boolean,
    Description: Should the backpack power limit be enabled?

    Constructor

    This is the constructor, which is in this case used to configure the client and to define internal variables

    Reference

    /**
     * Create a new rcon client instance
     * @param {ClientOptions} options The client options
    */
    constructor(options){...}
    

    The options object is an instance of ClientOptions. Look in the Type definitions section for more details.

    Internal variables

    Constructor parameters

    ip
    This is the IP used to connect to the server
    port
    This is the port used to connect to the server
    password
    This is the password to connect to the server with
    timeout
    This is the server timeout limit, which is by default 15 seconds

    Libraries

    net = require("net")
    This is the only used library, which is native to Node.Js

    Internal memory object

    _

    queue: [], | The request queue

    handler: null | The current response callback handler

    socket: null | The TCP socket

    General constants

    const

    permissionCategories: ["Unlisted", "Blacklisted", "Whitelisted", "Admin", "Pending", "Owner"]
    All the possible categories
    commandPrefix: "DS"
    Append this to start of every command

    Events

    This library also provides multiple events for things happening on the server. Here is a list of events and their meanings:

    • "playerjoin", Emitted when a player joins the server. Arguments: Object
    • "playerleft", Emitted when a player has left the server. Arguments: Object
    • "newplayer", Emitted when a new player joins the server. Arguments: Object
    • "save", Emitted when the game is saved. Arguments: Object
    • "setsave", Emitted when the active save changes. Arguments: Object
    • "connecting", Emitted when the client is connecting to the server. Arguments: None
    • "connected", Emitted when the client has connected to the server. Arguments: None
    • "disconnect", Emitted when the client has disconnected from the server. Arguments: None
    • "timeout", The server did not respond in time. Will also emit an error. Arguments: None This list does not include the "error" event. For more information about that see: Errors and bugs

    Functions

    List of functions in the Client class

    .connect()

    Use: Connect to the server
    Returns: Promise<\void>
    Triggers events: connecting, connected, disconnect
    Usage:

    <instance>.connect()
    

    .disconnect()

    Use: Disconnect from the server
    Returns: Promise<\void>
    Triggers events: disconnect
    Usage:

    <instance>.disconnect().then(() => {
        console.log("Disconnected!")
    }).catch((err) => {
        console.log("Failed to disconnect:", err)
    })
    

    .listPlayers()

    Use: Get the known players list
    Returns: Promise<Array>
    Triggers events: none
    Usage:

    let list = await <instance>.listPlayers()
    // "list" will be the known players list
    

    .getPlayer(player: PlayerQuery)

    Use: Get information about a specific player
    Returns: Promise<Object|Array>
    Triggers events: none
    Usage:

    let myPlayer = await <instance>.getPlayer({ guid: "<SomePlayerGuid>" })
    // This function returns an object when data is queried with precise means
    // If you query the known players list with a player name, it will return
    // an array with all matches.
    

    .kick(player: PlayerQuery)

    Use: Kick a player from the server
    Returns: Promise<void>
    Triggers events: kick
    Usage:

    <instance>.kick({ guid: "<SomePlayerGuid>"}).then(() => {
        console.log("Player kicked!)
    }).catch(err => {
        console.log("Failed to kick:", err)
    })
    

    .kickAll()

    Use: Kick all the players from the server
    Returns: Promise<void>
    Triggers events:
    Usage:

    <instance>.kickAll().then(() => {
        console.log("Players kicked!)
    }).catch(err => {
        console.log("Failed to kickAll:", err)
    })
    

    .setPlayerCategory(player: PlayerQuery, category: PlayerCategory)

    Use:
    Returns:
    Triggers events:
    Usage:

    <instance>.setPlayerCategory({guid: "<SomePlayerGuid>"}, "<SomePlayerCategory>).then(() => {
        console.log("Category set! It will be applied on next join.")
    }).catch((err) => {
        console.log("Failed to apply category:", err)
    })
    

    .listSaves()

    Use: List the saves of the server
    Returns: Promise<Object>
    Triggers events: none
    Usage:

    let savesList = await <instance>.listSaves()
    console.log(savesList) // Will contain the active save and then a saves array as a property
    

    .save(?name)

    Use: Save the game with an optional new name
    Returns: Promise<void>
    Triggers events: save
    Usage:

    <instance>.save()
    //or
    //<instance>.save("My-New-Save-Name")
    

    .shutdown(force: Boolean)

    Use: Shutdown the server while saving before complete shutdown
    Returns: Promise<void>
    Triggers events: save, disconnect
    Usage:

    <instance>.shutdown()
    //<instance>.shutdown(true)
    // ^ That won't save!
    

    .renameSave(name, newname)

    This function is not yet implemented, due to the limitations of the server.
    Use: Rename a save
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .deleteSave(name)

    This function is not yet implemented, due to the limitations of the server.
    Use: Delete a save
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .setSaveInterval(ms)

    This function is not yet implemented, due to the limitations of the server.
    Use: Set the autosave interval
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .setPassword(password)

    This function is not yet implemented, due to the limitations of the server.
    Use: Set the server password
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .setActivityTimeout()

    This function is not yet implemented, due to the limitations of the server.
    Use: Set the player activity/idle timeout
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .setCreative(options: CreativeConfig)

    This function is not yet implemented, due to the limitations of the server.
    Use: Make the active save a creative save (one time use).
    Returns: none
    Triggers events: none
    Usage:

    none
    

    .createSave(name: String, ?activate: Boolean)

    Use: Create a new save
    Returns: Promise<void>
    Triggers events: save, setsave, newsave
    Usage:

    <instance>.createSave("MyNewSave", true)
    // If you don't want the new save to become the active save, set the last parameter to false.
    

    .setWhitelist(boolean: Boolean)

    Use: Enable/Disable the whitelist. The whitelist makes users with the Unlisted category unable to connect.
    Returns: Promise<void>
    Triggers events: none
    Usage:

    <instance>.setWhitelist(true).then(() => {
        console.log("Whitelist activated")
    }).catch(err => {
        console.log("Failed to enable whitelist:", err)
    })
    

    .getInfo()

    Use: Get general information about the server
    Returns: Promise<Object>
    Triggers events: none
    Usage:

    let myServer = await <instance>.getInfo()
    console.log("My server:\n", myserver)
    

    AstroLauncher-link-class

    This is the second class exported by the library. It implements the same functionality as above, but instead connects to the AstroLauncher API to send commands to the server.
    The command reference for this class is the same instead the constructor is a bit different. Instead of taking the server port, ip and console password. It want's the ip, port and password of your AstroLauncher web-panel.
    Please note, that some features of rcon that are yet to be implemented in AstroLauncher's api, will of course not be usable.

    Errors-and-bugs

    Error handling is very important. In this library all errors are handled with the "error" event. If this event has no listeners, the error will be thrown in to global scope.
    If you encounter any bugs, or anything unexpected. Don't hesitate to create a new issue.

    Copyright

     * By: @Esinko
     * 
     * Github: https://github.com/Esinko/
     * 
     * License: SEE "LICENSE" FILE
     * (Copyright 2020 Esinko. Licensed under the Apache License, Version 2.0)
    

    Install

    npm i astroneer-rcon-client

    DownloadsWeekly Downloads

    0

    Version

    2.2.7

    License

    Apache 2.0 (see LICENSE file)

    Unpacked Size

    94.3 kB

    Total Files

    4

    Last publish

    Collaborators

    • avatar