Skip to content

javajuice1337/RustPlusBot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RustPlusBot plugins reference and examples

RustPlusBot plugins allow you to develop your own commands to add functionality to the bot. The plugin itself exposes many events for a programmer to attach to and execute code.

The plugins are written in JavaScript and run in a NodeJS environment after they are published. During development, you host the plugin on your client machine and in your web-browser. Your plugin interfaces with the bot via a WebSocket connection and communicates using the RustPlusBot api.

You can load any of the official plugins and use them as a template for getting started in the Plugin Studio. The Plugin Studio can be accessed via a link in the Plugin settings tab on the RustPlusBot settings page for your Discord server.

You can also find complete plugin examples on github in the plugin examples folder.

Plugins are loaded when the bot is starting and lasts for its entire life-cycle. Restarting the bot also restarts all plugins.

Plugin Storage

For data that persists beyond the bot's instance, use this.storage. This object loads with the bot and saves when it stops or restarts.

// store the myData variable
if (!this.storage.myData) this.storage.myData = 'Hello World!';
console.log(this.storage.myData);

Plugin Events

  • onConnected() Fires when the bot connects to a server or when the plugin loads
  • onDisconnected() Fires when the bot disconnects from a server
  • onEntityChanged(obj) Fires when a paired Smart Device is changed
    • obj.entityId: int The entity ID of the Smart device
    • obj.payload: object The payload data of the event (see Payload below)
  • onMessageReceive(obj) Fires when a team chat message is received
    • obj.message: string The incoming team chat message
    • obj.name: string The steam name of the sender
    • obj.steamId: string The steam ID of the sender
  • onMessageSend(obj) Fires when a team chat message is sent
    • obj.message: string The outgoing team chat message
  • onNotification(obj) Fires when there is a bot notification (including server events)
    • obj.notification: object The notification data of the event (see all Notification below)
  • onTeamChanged(obj) Fires when the team leader changes, or a team member is added or removed from the team
    • obj.leaderSteamId: object The steam ID of the team leader
    • obj.leaderMapNotes: object The leader map notes data of the event (see MapNotes below)
    • obj.members: object The members list data of the event (see Members below)

Plugin Interface

The app object exists in the plugin's scope this, and exposes the following properties and methods:

Properties

  • bmData object An object containing the BattleMetrics data of the server (see BattleMetrics Data below)
  • cameras array An array containing all camera indentifiers saved from the Camera Station
  • cfg object An object containing the configuration settings for the bot (see Config below)
  • devices Map A Map object containing the bot's paired devices (key: device name (lowercase only), value: Array of devices, see Device below)
  • devices_auto Map A Map object containing the bot's automatic paired devices function (key: device name, value: An object containing the automatic function config (see DeviceAuto below))
  • devices_icons Map A Map object containing the bot's paired device icons (key: device name, value: The icon name of the device)
  • devices_map Map A Map object containing the bot's paired device names (key: device ID, value: Array of lowercased device names)
  • event_types Map A Map object containing server event names (key: event ID, value: event name)
  • eventTimers object An object containing the respawn timers for server events in seconds (see Event Timers below)
  • guild_token string The unique token representing the Discord server
  • guild_name string The name of the Discord server
  • itemIds Map A Map object containing the item names for all item IDs (key: item ID, value: item name)
  • itemShortnames Map A Map object containing the item shortnames for all item IDs (key: item ID, value: item shortname)
  • monuments Map A Map object containing all monument tokens and locations (key: monument token, value: Array of monument locations, see Point below)
  • tokenMap Map A Map object containing the monument names for all monument tokens (key: monument token, value: monument name)
  • player_id string The steam ID of the bot's connected player
  • player_name string The steam name of the bot's connected player
  • server_ip string The IP address of the bot's connected server
  • server_name string The name of the bot's connected server
  • server_port string The port of the bot's connected server (Rust+ app port)
  • server_tags string Internal tags used to describe this server
// get the bot's language setting
console.log(this.app.cfg.lang);

Methods

  • getBattleMetrics(playerName, success, error) Retrieve the BattleMetrics info for a server player using their player name
    • playerName: string The name of the player
    • success(data): function The function to execute after receiving the BattleMetrics data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // getBattleMetrics example
    var app = this.app;
    app.getBattleMetrics('Rust Player 2099', (data) => {
        if (data && data.name) {
            if (data.online)
                app.sendTeamMessage('Player ' + cmdFormat(data.id) + ' \'' + cmdFormat(data.name) + '\' is ONLINE and has been connected for ' + getTimeDisplay(getTimeDifference(new Date(data.lastseen)), true));
            else
                app.sendTeamMessage('Player ' + cmdFormat(data.id) + ' \'' + cmdFormat(data.name) + '\' is OFFLINE and was last seen ' + getFriendlyDate(data.lastseen));
            app.sendTeamMessage('Player ' + cmdFormat(data.id) + ' was first seen ' + getFriendlyDate(data.firstseen) + ' and their time played is ' + getTimeDisplay(data.timeplayed, true));
        }
        else if (data && data.indexOf('unavailable') > 0) {
            app.sendTeamMessage(data);
        }
        else app.sendTeamMessage('Server player not found');
    }, (error) => {
        app.sendTeamMessage('Error obtaining the BattleMetrics data: ' + error);
    });
    

  • getBattleMetricsId(playerId, success, error) Retrieve the BattleMetrics info for a server player using their BattleMetrics ID
    • playerId: int The BattleMetrics ID of the player
    • success(data): function The function to execute after receiving the BattleMetricsId data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // getBattleMetricsId example
    var app = this.app;
    app.getBattleMetricsId(123456789, (data) => {
        if (data && data.name) {
            app.sendTeamMessage('Player ' + cmdFormat(data.id) + ' \'' + cmdFormat(data.name) + '\' is ' + ((data.online) ? 'ONLINE' : 'OFFLINE'));
            if (data.lastseen)
                app.sendTeamMessage('Player ' + cmdFormat(data.id) + ' has been connected for ' + getTimeDisplay(getTimeDifference(new Date(data.lastseen)), true));
        }
        else app.sendTeamMessage('Server player not found');
    }, (error) => {
        app.sendTeamMessage('Error obtaining the BattleMetricsId data: ' + error);
    });
    

  • getCameraPlayers(id, callback) Get all player names visible on the specified camera
    • id: string The identifier of the camera
    • callback(players, playersDistances): function The function to execute after getting the players list and players distances list (players is an array of player names and playersDistances is an array of player distances in meters)
    • returns: bool true if successful

    // getCameraPlayers example
    var app = this.app;
    app.getCameraPlayers('CAMERA_ID', (players, playersDistances) => {
        if (players && players.length > 0) {
            for (var i = 0; i < players.length; i++)
                players[i] += ' [' + playersDistances[i] + 'm]';
            app.sendTeamMessage('Detected these players: ' + players.join(', '));
        }
        else {
            app.sendTeamMessage('No players detected on camera');
        }
    });
    

  • getCameraPlayersFiltered(id, callback) Get only non-team member player names visible on the specified camera
    • id: string The identifier of the camera
    • callback(players, playersDistances): function The function to execute after getting the players list and players distances list (players is an array of player names and playersDistances is an array of player distances in meters)
    • returns: bool true if successful

    // getCameraPlayersFiltered example
    var app = this.app;
    app.getCameraPlayersFiltered('CAMERA_ID', (players, playersDistances) => {
        if (players && players.length > 0) {
            for (var i = 0; i < players.length; i++)
                players[i] += ' [' + playersDistances[i] + 'm]';
            app.sendTeamMessage('Detected these enemy players: ' + players.join(', '));
        }
        else {
            app.sendTeamMessage('No enemy players detected on camera');
        }
    });
    

  • getConnected() Get the date of the server connection
    • returns: string a Date string

    // getConnected example
    var connected = await this.app.getConnected();
    console.log(new Date(connected));
    

  • getCrateTimer() Get the configured crate unlock timer
    • returns: int value

    // getCrateTimer example
    var timer = await this.app.getCrateTimer();
    console.log('Crate unlock timer is set to: ' + getTimeDisplay(timer));
    

  • getDetailedInfo(callback) Get detailed information about the server
    • callback(data): function The function to execute after getting the detailed info (data is DetailedInfo)
    • returns: bool true if successful

    // getDetailedInfo example
    var app = this.app;
    app.getDetailedInfo((data) => {
        if (data && data.players) {
            app.sendTeamMessage('Current server population is ' + data.players);
            app.sendTeamMessage('Current server time is ' + data.time);
        }
    });
    

  • getEntityInfo(id, callback) Get data from a Smart device
    • id: int The identifier of the Smart device
    • callback(message): function The function to execute after getting the entity info (message.response contains EntityInfo)
    • returns: bool true if successful

    // getEntityInfo example
    var app = this.app;
    app.getEntityInfo(123456, (message) => {
        if (message.response && message.response.entityInfo && message.response.entityInfo.payload) {
            app.sendTeamMessage('This device is: ' + ((message.response.entityInfo.payload.value) ? 'On' : 'Off'));
        }
        else {
            app.sendTeamMessage('This device is inactive');
        }
    });
    

  • getEvents(type) Get the most recent server events (ordered by newest to oldest)
    • type: string The event type (optional)
      • heli Patrol Helicopter
      • cargo Cargo Ship
      • crate Locked Crate
      • ch47 CH-47 Chinook
      • oil_rig_small Oil Rig (Small)
      • large_oil_rig Oil Rig (Large)
    • returns: array Event array

    // getEvents example
    var e = await this.app.getEvents();
    console.log(e);
    

  • getInfo(callback) Get information about the server
    • callback(message): function The function to execute after getting the info (message.response contains Info)
    • returns: bool true if successful

    // getInfo example
    var app = this.app;
    app.getInfo((message) => {
        if (message.response && message.response.info) {
            app.sendTeamMessage('Current server population is ' + message.response.info.players + ' / ' + message.response.info.maxPlayers + ((message.response.info.queuedPlayers > 0) ? ' (' + message.response.info.queuedPlayers + ' in queue)' : ''));
        }
    });
    

  • getMapInfo(callback) Get information about the server's map
    • callback(message): function The function to execute after getting the map info (message is MapInfo)
    • returns: bool true if successful

    // getMapInfo example
    var app = this.app;
    app.getMapInfo((message) => {
        if (message && message.image) {
            app.sendTeamMessage('Link to server map: ' + message.image);
        }
    });
    

  • getMapMarkers(callback) Get information about all map markers
    • callback(message): function The function to execute after getting the map markers (message.response contains MapMarkers)
    • returns: bool true if successful

    // getMapMarkers example
    var app = this.app;
    app.getMapMarkers((message) => {
        if (message.response && message.response.mapMarkers && message.response.mapMarkers.markers) {
            var cnt = 0;
            for (var i = 0; i < message.response.mapMarkers.markers.length; i++) {
                if (message.response.mapMarkers.markers[i].type == 3) { // 'VendingMachine'
                    if (message.response.mapMarkers.markers[i].sellOrders.length > 0) cnt++;
                }
            }
            app.sendTeamMessage('There are this many active vending machines: ' + cnt);
        }
    });
    

  • getMonumentName(x, y, noSmall) Get the name of the monument at the specified coordinates
    • x: int The x-coordinate of where the monument is located
    • y: int The y-coordinate of where the monument is located
    • noSmall: bool Set to true to exclude small monuments (optional)
    • returns: string The name of the monument

    // getMonumentName example
    var app = this.app,
        x = 1000,
        y = 1000;
    app.sendTeamMessage('The monument located at ' + (await app.util.getMapCoords(x, y)) + ' is: ' + (await app.getMonumentName(x, y)));
    

  • getPrefix(type) Get the command prefix for the bot
    • type: string The command type (optional)
      • all All Commands
      • device Device Commands
    • returns: string The selected prefix if it's required

    // getPrefix example
    var prefix = await this.app.getPrefix('all');
    

  • getRecyclerItems(items, success, error, opts) Retrieve the recycled items for the input items
    • items: object An object containing the item names and item values
    • success(data): function The function to execute after receiving recycle data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • opts: object The opts object containing the emojibool property (optional)
    • returns: bool true

    // getRecyclerItems example
    var app = this.app;
    app.getRecyclerItems({'Sheet Metal Door': 1}, (data) => {
        var keys = Object.keys(data),
            recycle = [];
        for (var i = 0; i < keys.length; i++) {
            recycle.push(keys[i] + ' x ' + data[keys[i]]);
        }
        if (recycle.length > 0) app.sendTeamMessage('Recyclables: ' + recycle.join(', '));
    }, (error) => {
        app.sendTeamMessage('Error obtaining the recyle items: ' + error);
    }, { emoji: false });
    

  • getSteamrep(steamId, success, error) Retrieve the Steamrep data for a Steam member
    • steamId: string The steam ID of the Steam member
    • success(data): function The function to execute after receiving Steamrep data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // getSteamrep example
    var app = this.app;
    app.getSteamrep(123456789, (data) => {
        if (data && data.membersince) {
            app.sendTeamMessage('This player has been a member of Steam since ' + data.membersince);
            app.sendTeamMessage('This player has ' + ((data.vacbanned != 'None' || data.communitybanned != 'None' || data.tradebanstate != 'None') ? 'bans: ' + ((data.vacbanned != 'None') ? 'VAC ' : '') + ((data.communitybanned != 'None') ? 'Community ' : '') + ((data.tradebanstate != 'None') ? 'Trade ' : '') : 'NO bans'));
        }
        else app.sendTeamMessage('Unable to lookup Steamrep data');
    }, (error) => {
        app.sendTeamMessage('Error obtaining the Steamrep data: ' + error);
    });
    

  • getTeamChat(callback) Get recent team chat messages
    • callback(message): function The function to execute after getting the team chat messages (message.response contains TeamChat)
    • returns: bool true if successful

    // getTeamChat example
    const messages_max = 5;
    var app = this.app;
    app.getTeamChat((message) => {
        if (message.response && message.response.teamChat) {
            var cnt = message.response.teamChat.messages.length,
                max = (cnt > messages_max) ? messages_max : cnt;
            app.sendTeamMessage('Showing the last ' + cnt + ' team chat messages:');
            for (var i = 0; i < cnt; i++) {
                app.sendTeamMessage('(' + getFriendlyDate(new Date(message.response.teamChat.messages[cnt - i - 1].time * 1000)) + ') ' + message.response.teamChat.messages[cnt - i - 1].message);
            }
        }
    });
    

  • getTeamData(callback) Get detailed information about the team (leader, members)
    • callback(data): function The function to execute after getting the team data (data is TeamData)
    • returns: bool true if successful

    // getTeamData example
    var app = this.app;
    app.getTeamData((data) => {
        if (data && data.members) {
            var info = '';
            for (var i = 0; i < data.members.length; i++) {
                if (data.members[i].steamId == data.leader.steamId) {
                    info = data.members[i].status + '; ' + data.members[i].info;
                    break;
                }
            }
            app.sendTeamMessage('Team leader \'' + data.leader.name + '\' is ' + info);
        }
    });
    

  • getTeamInfo(callback) Get information about the team (leader, members)
    • callback(message): function The function to execute after getting the team info (message.response contains TeamInfo)
    • returns: bool true if successful

    // getTeamInfo example
    var app = this.app;
    app.getTeamInfo((message) => {
        if (message.response && message.response.teamInfo) {
            var cnt = 0;
            for (var i = 0; i < message.response.teamInfo.members.length; i++) {
                if (message.response.teamInfo.members[i].isAlive) cnt++;
            }
            app.sendTeamMessage('There are this many alive team members: ' + cnt);
        }
    });
    

  • getTime(callback) Get information about the server time
    • callback(message): function The function to execute after getting the time (message.response contains Time)
    • returns: bool true if successful

    // getTime example
    var app = this.app;
    app.getTime(async (message) => {
        if (message.response && message.response.time) {
            app.sendTeamMessage('Current Rust time is ' + (await app.getTimeInfo(message.response.time)));
        }
    });
    

  • getTimeInfo(time) Get the server time + day/night display text
    • time: object The time object from the getTime method
    • returns: string the server time + day/night display text

    // getTimeInfo example
    var app = this.app;
    app.getTime(async (message) => {
        if (message.response && message.response.time) {
            app.sendTeamMessage('Current Rust time is ' + (await app.getTimeInfo(message.response.time)));
        }
    });
    

  • postDiscordMessage(msg) Post a message to the bot's Main Discord channel or a custom channel
    • msg: string The message to post
    • msg: object The message object containing the messagestring and channelstring, optional ttsbool Note: channel is the channel ID

    // postDiscordMessage example 1
    this.app.postDiscordMessage('This is a message from a bot\'s plugin');
    // postDiscordMessage example 2
    this.app.postDiscordMessage({
        message: 'This is a message from a bot\'s plugin to a custom channel',
        channel: '966820843924466774',
        tts: false
    });
    

  • postDiscordNotification(title, description, url, img, list) Post a notification to the bot's Notification Discord channel
    • title: string The title of the notification
    • description: string The description of the notification
    • url: string The url of the notification (optional)
    • img: string The image url of the notification (optional)
    • list: array The item list data of the notification (optional; see NotificationList below)

    // postDiscordNotification example
    var app = this.app;
    app.postDiscordNotification('Plugin Alert Title', 'Plugin Alert Message');
    

  • postDiscordWebhook(url, msg) Post a message to a Discord webhook
    • url: string The url of the Discord webhook
    • msg: string The message to post to the Discord webhook

    // postDiscordWebhook example
    var app = this.app;
    app.postDiscordWebhook('webhook url', 'Webhook Message');
    

  • runCommand(cmd, steamId, steamName) Run a team chat command as a specific player
    • cmd: string The command to run
    • steamId: string The player's steamId (optional)
    • steamName: string The player's steam name (optional)
    • returns: bool true if successful

    // runCommand example
    var app = this.app,
        prefix = await app.getPrefix('all');
    app.runCommand(prefix + 'pop');
    

  • sendDiscordVoiceMessage(msg) Send a voice message to the RustPlusBot voice client
    • msg: string The voice message to send

    // sendDiscordVoiceMessage example
    var app = this.app;
    app.sendDiscordVoiceMessage('Hello, this is a test voice message!');
    

  • sendTeamMessage(msg, callback, noTranslate, sendVoice) Send a team chat message
    • msg: string The message to send
    • callback(): function The function to execute after sending (optional)
    • noTranslate: bool Set to true to disable message translation (optional)
    • sendVoice: bool Set to true to send the message to the voice client (optional)
    • returns: bool true if successful

    // sendTeamMessage example
    var app = this.app;
    app.sendTeamMessage('This is a team message');
    

  • setEntityValue(id, value, callback) Set the value of a Smart Switch
    • id: int The identifier of the Smart Switch
    • value: bool The value (true or false)
    • callback(): function The function to execute after setting the value (optional)
    • returns: bool true if successful

    // setEntityValue example
    var app = this.app;
    app.setEntityValue(123456, true, () => {
        app.sendTeamMessage('The smart switch is activated');
    });
    

  • translateMessage(msg, lang, success, error) Translate a message from English (default) to another language
    • msg: string The message to translate
    • lang: string The language code to use for translation (see: Language Codes)
    • lang: object The lang object containing the fromstring and tostring language codes
    • success(res): function The function to execute after translating (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // translateMessage example 1
    this.app.translateMessage('Hello, how are you?', 'es', (res) => {
        app.sendTeamMessage(res);
    }, (error) => {
        app.sendTeamMessage('Error: ' + error);
    });
    // translateMessage example 2
    this.app.translateMessage('Hola, como estas?', {
        from: 'es',
        to: 'en'
    }, (res) => {
        app.sendTeamMessage(res);
    }, (error) => {
        app.sendTeamMessage('Error: ' + error);
    });
    

  • webGet(url, params, headers, success, error) Retrieve data from a url
    • url: string The url to access
    • params: object The parameters of the url (optional)
    • headers: object The headers to send with the web request (optional)
    • success(data): function The function to execute after receiving data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // webGet example
    var app = this.app;
    app.webGet('https://rust.facepunch.com/rss/news', null, null, (data) => {
        var link = '',
            pos = data.indexOf('>https://');
        if (pos > 0) link = data.substr(pos + 1, data.indexOf('<', pos) - pos - 1);
        if (link != '')
            app.sendTeamMessage('The newest Rust update link: ' + link);
        else
            app.sendTeamMessage('The newest Rust update link was not found');
    }, (error) => {
        app.sendTeamMessage('Error obtaining Rust update link: ' + error);
    });
    

  • webPost(url, data, headers, success, error) Post data to a url
    • url: string The url to access
    • data: string The data to post (optional)
    • headers: object The headers to send with the web request (optional)
    • success(data): function The function to execute after receiving data (optional)
    • error(err): function The function to execute when an error occurs (optional)
    • returns: bool true

    // webPost example
    var app = this.app;
    app.webPost('https://httpbin.org/post', 'test data', null, (data) => {
        app.sendTeamMessage('Post result: ' + data);
    }, (error) => {
        app.sendTeamMessage('Error posting: ' + error);
    });
    

  • interactiveMap.addMarker(markerIdint, steamIdstring, namestring, msgstring, xint, yint) Returns true if the custom map marker is added
    Refer to the mapmarkers plugin example to see the correct usage for addMarker
  • interactiveMap.setMarkerColor(markerIdint, colorstring) Returns true if the custom map marker's color is updated
  • interactiveMap.removeMarker(markerIdint) Returns true if the custom map marker matching markerId is removed
  • interactiveMap.clearMarkers(steamIdstring) Returns true if all custom map markers are removed for steamId
  • interactiveMap.getHeatmapData() Returns an object containing the heatmap data (see HeatmapData below)
  • util.collides(xint, yint, rotationint, x1int, y1int, x2int, y2int) Returns true if angled point x,y collides with rectangle x1,y1,x2,y2
  • util.direction(x1int, y1int, x2int, y2int) Get the direction from the first point facing the second
  • util.distance(x1int, y1int, x2int, y2int) Get the distance between two points in meters
  • util.getMapCoords(xint, yint) Get the map coordinates for a point
  • util.inRect(xint, yint, x1int, y1int, x2int, y2int) Returns true if the point is inside the rectangle
// get the map coordinates of a specific location
var location = {x: 1000, y: 2000};
console.log('map coordinates: ' + (await this.app.util.getMapCoords(location.x, location.y)));

Other Methods

Note: The following methods exist in the plugin's scope this (instead of in app).

  • registeredHandlers.add(typestring, handlerfunction) Add a handler for a specific update event type:
    • camera Fires when the camera list has changed
    • config Fires when the configuration settings have changed
    • device Fires when the paired devices has changed
    • wipe Fires when the server has wiped
  • registeredHandlers.remove(typestring, handlerfunction) Remove a handler for a specific update event type (see registeredHandlers.add above)
// listen for a configuration change event
if (!this.configFunc) {
    var self = this;
    self.configFunc = function() {
        console.log(self.app.cfg);
    };
}
this.registeredHandlers.add('config', this.configFunc);

Data Types

  • BattleMetrics Data
    {     
      "Name": "Server Name",
      "Rank": "#1",
      "Player count": "1/100",
      "Address": "Server Address",
      "Status": "online",
      "Country": "US",
      "Uptime": 26522,
      "Average FPS": "60",
      "Last Wipe": "2024-02-01T18:53:55.766Z",
      "Next Wipe": "2024-02-15T20:00:00.000Z",
      "PVE": "False",
      "Website": "http://www.playrust.com/",
      "Entity Count": "265097",
      "Official Server": "True",
      "Private": "False",
      "Map": "Procedural Map",
      "Type": "official",
      "Tags": [],
      "createdAt": "2018-09-06T00:16:14.003Z",
      "updatedAt": "2024-02-08T18:25:13.509Z",
      "id": 546784,
      "time": 1640108040219
    }
  • Config
    {     
      "lang": "en",
      "gender": "male",
      "cmdPrefix": "!",
      "requirePrefix": "all",
      "teamChatIncoming": "all",
      "teamChatOutgoing": true,
      "teamChatResponses": false,
      "teamChatSilenced": false,
      "teamChatDelay": 0,
      "teamChatTTS": false,
      "teamChatMentions": true,
      "shortTime": false,
      "nextTime": false,
      "altTime": false,
      "dirAngle": true,
      "eventsDiscord": false,
      "broadcastEvents": true,
      "vendingDiscord": false,
      "broadcastVending": true,
      "broadcastVendingName": true,
      "broadcastAmount": 1,
      "respawnAmount": 1,
      "battlemetricsID": 0,
      "battlemetricsDiscord": true,
      "deathDiscord": true,
      "loginDiscord": true,
      "aliasesFullMatch": false,
      "accessOnlyCommands": false,
      "deviceTTS": false,
      "autoCleanDevices": false,
      "autoDeviceCommand": true,
      "showDevicePlayer": false,
      "alwaysPostAlarms": true,
      "alwaysPostDecay": true,
      "decayOffset": 0,
      "streamerMode": false,
      "promoteStrict": false,
      "voiceDevice": true,
      "voiceEvent": true,
      "voiceVending": true,
      "voiceTracking": true,
      "voicePlugin": true,
      "eventsDisplay": "heli,brad,cargo,oil,crate,ch47",
      "subEventsDisplay": "heli_lootable,brad_lootable,cargo_crates,oil_lootable"
    }
  • DetailedInfo
    {
      "players": "51/200",
      "playersQueue": 0,
      "playersChange": 0,
      "time": "16:23",
      "timeValue": 16.38,
      "wipe": 1147412,
      "nextDay": 1453,
      "nextNight": 775,
      "nextWipe": 22
    }
    // wipe usage: getTimeDisplay(wipe * 1000) + ' ago'
    // nextDay usage: getTimeDisplay(nextDay)
    // nextNight usage: getTimeDisplay(nextNight)
    // nextWipe usage: nextWipe + 'd'
  • Device
    {
      name: "MyDevice",
      id: 123456,
      flag: false, // true if op is inverted
      type: "Smart Switch",
      time: 0 // timestamp of last state change
    }
  • DeviceAuto
    {
      state: true, // true for ON
      time: 60 // auto time in seconds
    }
  • EntityInfo
    {
      "type": "1",
      "payload": {} // see Payload below
    }
    // entity types:
    // 1 = Smart Switch
    // 2 = Smart Alarm
    // 3 = Storage Monitor
  • Event
    {
      id: 123456789,
      type: "heli",
      name: "Patrol Helicopter @ A1",
      start: new Date(),
      stop: null // null if active
    }
  • Event Timers
    {
      "cargo": {
        "spawn": 14400,
        "spread": 7200
      },
      "crate": {
        "spawn": 7200,
        "spread": 3600
      },
      "heli": {
        "spawn": 7200,
        "spread": 3600
      },
      "oilrig": {
        "spawn": 2700,
        "spread": 2700
      }
    }
  • Heatmap Data
    {
      "deaths": [],
      "brad": [{
        "x": 2667.51416015625,
        "y": 2336.646240234375,
        "count": 1
      }],
      "heli": [{
        "x": 688.2880859375,
        "y": 922.4451904296875,
        "count": 1
      }],
      "crate": [{
        "x": 2047.0020751953125,
        "y": 2884.339111328125,
        "count": 6
      }],
      "cargo": [{
        "x": -1775,
        "y": 2098.646240234375,
        "count": 8
      },{
        "x": -1684.09814453125,
        "y": 2145.852783203125,
        "count": 2
      },{
        "x": -1608.643798828125,
        "y": 2141.641357421875,
        "count": 2
      }]
    }
  • Info
    {
      "name": "Rust Server Name",
      "headerImage": "",
      "url": "",
      "map": "Procedure Map",
      "mapSize": 4250,
      "wipeTime": 0,
      "players": 100,
      "maxPlayers": 200,
      "queuedPlayers": 0,
      "seed": 0,
      "salt": 0
    }
  • MapInfo
    {
      "width": 3125,
      "height": 3125,
      "oceanMargin": 500,
      "offset": 0,
      "background": "#12404D",
      "image": "",
      "cached": true,
      "info": {
        "name": "Rust Server Name",
        "headerImage": "",
        "url": "",
        "map": "Procedure Map",
        "mapSize": 4250,
        "wipeTime": 0,
        "players": 100,
        "maxPlayers": 200,
        "queuedPlayers": 0,
        "seed": 0,
        "salt": 0
      }
    }
  • MapMarkers
    {
      markers: [{
        "id": 123456,
        "type": 3,
        "x": 1500.958740234375,
        "y": 2551.239990234375,
        "location": "G20",
        "steamId": 0,
        "rotation": 0,
        "radius": 0,
        "name": "",
        "outOfStock": false,
        sellOrders: [{ // sellOrders when type is 3
          "itemId": 123456,
          "quantity": 1,
          "currencyId": 654321,
          "costPerItem": 1,
          "amountInStock": 10,
          "itemIsBlueprint": false,
          "currencyIsBlueprint": false,
          "itemCondition": 42.75,
          "itemConditionMax": 100
        }]
      }]
    }
    // marker types:
    // 1 = Player
    // 2 = Explosion
    // 3 = VendingMachine
    // 4 = CH47
    // 5 = CargoShip
    // 6 = Crate
    // 8 = PatrolHelicopter
    Find the item name with the itemId using itemIds
  • MapNotes
    [{
      "type": 1,
      "x": 1500.958740234375,
      "y": 2551.239990234375
    }]
  • Members
    [{
      "steamId": "123456789",
      "name": "RustPlayer1",
      "x": 1497.4344482421875,
      "y": 2522.85546875,
      "isOnline": true,
      "spawnTime": 1638768666,
      "isAlive": true,
      "deathTime": 1638768647,
      "onlineTime": 1638768660,
      "afk": {
        "value": false,
        "time": 0
      }
    }, {
      "steamId": "123456799",
      "name": "RustPlayer2",
      "x": 1487.4344482421875,
      "y": 2512.85546875,
      "isOnline": true,
      "spawnTime": 1638768866,
      "isAlive": true,
      "deathTime": 1638768847,
      "onlineTime": 1638768660,
      "afk": {
        "value": false,
        "time": 0
      }
    }]
  • Notification: Alarm
    {
      "notification: {
        "type": "alarm",
        "alarm": {
          "title": "Smart Alarm Title",
          "message": "Smart Alarm Message"
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: Decaying TC
    {
      "notification": {
        "type": "monitor",
        "monitor": {
          "title": "MyDevice",
          "message": "This monitored TC is decaying!",
          "device_name": "MyDevice",
          "device_id": "123456",
          "device_flag": false,
          "device_type": "Storage Monitor"
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: Entity Pairing
    {
      "notification": {
        "type": "entity",
        "server_name": "Rust Server Name",
        "entityName": "Smart Switch",
        "entityId": "123456",
        "entityType": "1"
      }
    }
    // entity types:
    // 1 = Smart Switch
    // 2 = Smart Alarm
    // 3 = Storage Monitor
  • Notification: Event
    {
      "notification": {
        "type": "event",
        "event": {
          "type": "heli",
          "title": "Patrol Helicopter",
          "message": "The Patrol Helicopter has exploded @ A1",
          "x": 100.543565665,
          "y": 200.345765755
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: Inactive Device
    {
      "notification": {
        "type": "inactive",
        "inactive": {
          "title": "MyDevice",
          "message": "This device is inactive.",
          "device_name": "MyDevice",
          "device_id": "123456",
          "device_flag": false,
          "device_type": "Smart Switch"
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: News
    {
      "notification: {
        "type": "news",
        "news": {
          "title": "Rust Update News",
          "url": "https://rust.facepunch.com/",
          "message": "A new Rust update blog is available!"
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: Player Death
    {
      "notification": {
        "type": "death",
        "server_name": "Rust Server Name",
        "targetName": "RustPlayer",
        "targetId": "123456789"
      }
    }
  • Notification: Player Tracking
    {
      "notification": {
        "type": "tracking",
        "tracking": {
          "bm_id": "1234",
          "player_id": "123456789",
          "name": "Tracked player \"Rust Player\" has joined the server",
          "status": "joined"
        },
        "server_name": "Rust Server Name"
      }
    }
  • Notification: Team Login
    {
      "notification": {
        "type": "login",
        "server_name": "Rust Server Name",
        "targetName": "RustPlayer",
        "targetId": "123456789"
      }
    }
  • NotificationList
    [{
      name: "Sub Item",
      value: "Sub Value",
      inline: false
    }]
  • Payload: Smart Switch, Smart Alarm
    "payload": {
      "value": false,
      "capacity": 0,
      "hasProtection": false,
      "protectionExpiry": 0
    }
    
  • Payload: Storage Monitor
    "payload": {
      "value": false,
      "items": [{
        "itemId": 317398316,
        "quantity": 95,
        "itemIsBlueprint": false
      }, {
        "itemId": -151838493,
        "quantity": 998,
        "itemIsBlueprint": false
      }],
      "capacity": 24,
      "hasProtection": true,
      "protectionExpiry": 1638790206
    }
    
    Find the item name with the itemId using itemIds
  • Point
    {
      x: 100,
      y: 200
    }
  • Time
    {
      "dayLengthMinutes": 60,
      "timeScale": 1,
      "sunrise": 7,
      "sunset": 20,
      "time": 12
    }
  • TeamChat
    {
      "messages": [{
        "steamId": "123456789",
        "name": "RustPlayer1",
        "message": "A Locked Crate has been dropped @ M13 (Airfield)",
        "color": "#5af",
        "time": 1649959932
      }]
    }
  • TeamData
    {
      "leader": {
        "name": "RustPlayer1",
        "steamId": "123456789"
      },
      "members": [{
        "name": "RustPlayer1",
        "steamId": "123456789",
        "status": "ONLINE",
        "info": "alive for 2 hours",
        "infoAlt": "online for 2 hours",
        "infoText": "alive for",
        "infoValue": 1649959932,
        "infoTextAlt": "online for",
        "infoValueAlt": 1649959932,
        "location": "G20",
        "x": 1932.2833251953125,
        "y": 2376.96240234375
      }]
    }
  • TeamInfo
    {
      "leaderSteamId": 123456789,
      "members": [], // see Members
      "leaderMapNotes": [], // see MapNotes
      "mapNotes": [] // see MapNotes
    }
  • Time
    {
      "dayLengthMinutes": 60,
      "timeScale": 1,
      "sunrise": 7,
      "sunset": 20,
      "time": 12
    }

Plugin Globals

  • cmdFormat(str) Convert a string into a non-translatable string
    • str: string The string to convert
    • returns: string a non-translatable string

    // cmdFormat example
    var app = this.app,
        msg = 'Here is the url: ' + cmdFormat('https://www.google.com');
    app.sendTeamMessage(msg);
    

  • cmdFormatUndo(str) Undo the non-translatable string conversion
    • str: string The string to undo the non-translatable string conversion
    • returns: string a string

    // cmdFormatUndo example
    var app = this.app,
        msg = 'Here is the url: ' + cmdFormat('https://www.google.com');
    console.log(cmdFormatUndo(msg));
    

  • encodeForm(data) Convert an object to form data for a webPost
    • data: object The object to convert
    • returns: string a string of encoded names and values

    // encodeForm example
    var app = this.app;
    app.webPost('https://www.iplocation.net/ip-lookup', encodeForm({ query: app.server_ip }), null, (data) => {
        var regex = new RegExp('<tr><td>' + app.server_ip + '</td><td>([^<]+)<', 'g'),
            match = regex.exec(data);
        if (match)
            app.sendTeamMessage('GeoIP location of the server: ' + match[1]);
        else
            app.sendTeamMessage('Unable to get the GeoIP location of the server');
    }, (error) => {
        app.sendTeamMessage('Error posting: ' + error);
    });
    

  • combineItems(items, itemIds) Combine the items from a Storage Monitor payload and resolve the item names
    • items: object The items from the payload
    • itemIds: Map The item ID list to lookup item names
    • returns: Map A Map object containing the combined items and item quantities

    // combineItems example
    var app = this.app,
        device = app.devices.get('BaseTC')[0];
    app.getEntityInfo(device.id, (message) => {
        if (message.response && message.response.entityInfo && message.response.entityInfo.payload && message.response.entityInfo.payload.capacity > 0 && message.response.entityInfo.payload.items) {
            var items = combineItems(message.response.entityInfo.payload.items, app.itemIds),
                sorted = [],
                list = [];
            items.forEach((value, key) => {
                sorted.push({ name: key, quantity: value });
            });
            sorted.sort(function (a, b) {
                if (a.name < b.name) return -1;
                if (a.name > b.name) return 1;
            });
            sorted.forEach((item) => {
                list.push(item.name + ' x ' + item.quantity.toLocaleString());
            });
            if (list.length > 0) {
                multiLineFormat('Device \'' + cmdFormat(device.name) + '\' contents: ', list, function(line) {
                    app.sendTeamMessage(line);
                });
            }
        }
    });
    

  • findClosestString(str, arr, threshold = 2) Find the closest match for a string in an array using a threshold
    • str: string The input string
    • arr: array The array of possible string matches
    • threshold: int The threshold used for string matching (optional)
    • returns: string The closest matched string found in the input array

    // findClosestString example
    var app = this.app,
        item = 'windturbine',
        closest = findClosestString(item, Array.from(app.itemIds.values()));
    if (closest && closest.toLowerCase() != item.toLowerCase()) {
        app.sendTeamMessage('Are you looking for this item? ' + closest);
    }
    else {
        app.sendTeamMessage('This item name is a direct match: ' + item);
    }
    

  • getFriendlyDate(date) Get a friendly representation of the date
    • date: date The date object
    • returns: string a string containing the friendly representation of the date

    // getFriendlyDate example
    var app = this.app;
    app.getTeamInfo((message) => {
        if (message.response && message.response.teamInfo) {
            var status = '',
                status_time = 0;
            for (var i = 0; i < message.response.teamInfo.members.length; i++) {
                if (message.response.teamInfo.members[i].steamId == message.response.teamInfo.leaderSteamId) {
                    status = (message.response.teamInfo.members[i].isAlive) ? 'alive' : 'dead';
                    status_time = (message.response.teamInfo.members[i].isAlive) ? message.response.teamInfo.members[i].spawnTime : message.response.teamInfo.members[i].deathTime;
                    break;
                }
            }
            app.sendTeamMessage('The team leader has been ' + status + ' since ' + getFriendlyDate(status_time * 1000));
        }
    });
    

  • getTime(timestr, max_val) Convert a time string to seconds
    • timestr: string The time string (format: 1d1h1m1s)
    • max_val: int The maximum allowed time value to return (optional)
    • returns: int the total seconds of the timestr

    // getTime example
    var app = this.app;
    app.sendTeamMessage('The time in seconds for 1d1h1m1s is ' + getTime('1d1h1m1s'));
    

  • getTimeDifference(date) Get the time difference for a date
    • date: date The date object
    • returns: int the date difference in seconds

    // getTimeDifference example
    var app = this.app,
        connected = await app.getConnected();
    app.sendTeamMessage('The time in seconds since the bot connected is ' + Math.round(getTimeDifference(new Date(connected))));
    

  • getTimeDisplay(time) Get the time display for time
    • time: int The time in seconds
    • returns: string a string representing the time

    // getTimeDisplay example
    var app = this.app,
        connected = await app.getConnected();
    app.sendTeamMessage('The bot has been connected for ' + getTimeDisplay(Math.round(getTimeDifference(new Date(connected)))));
    

  • multiLineFormat(msg, list, callback, all) Format the message + list to fit the Rust message size using multiple lines
    • msg: string The message to prepend
    • list: array The list of items to output
    • callback(line, msg, data, idx): function The function to execute for each formatted line (optional)
    • all: bool Set to true if all lines should include the msg (optional)
    • returns: array an Array containing the formatted lines

    // multiLineFormat example
    var app = this.app,
        device = app.devices.get('BaseTC')[0];
    app.getEntityInfo(device.id, (message) => {
        if (message.response && message.response.entityInfo && message.response.entityInfo.payload && message.response.entityInfo.payload.capacity > 0 && message.response.entityInfo.payload.items) {
            var items = combineItems(message.response.entityInfo.payload.items, app.itemIds),
                sorted = [],
                list = [];
            items.forEach((value, key) => {
                sorted.push({ name: key, quantity: value });
            });
            sorted.sort(function (a, b) {
                if (a.name < b.name) return -1;
                if (a.name > b.name) return 1;
            });
            sorted.forEach((item) => {
                list.push(item.name + ' x ' + item.quantity.toLocaleString());
            });
            if (list.length > 0) {
                multiLineFormat('Device \'' + cmdFormat(device.name) + '\' contents: ', list, function(line, msg, data, idx) {
                    if (idx == 0)
                        app.sendTeamMessage(msg + data);
                    else
                        app.sendTeamMessage(data);
                });
            }
        }
    });
    

Plugin Publishing

You can publish your plugin when you are done making any major changes to it by clicking the Publish tab in the Plugin Studio. You have the option of making it a public plugin for others to use with their bot. There will be a review of your plugin after submitting which could take several days. If your plugin is accepted for publishing, you will then be able to select it in the Plugin settings for your bot and install it. Duplicates of official plugins will not be accepted.

Links

About

RustPlusBot plugins reference and examples

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages