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.
Plugins are loaded when the bot is starting and lasts for its entire life-cycle. Restarting the bot also restarts all plugins.
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 find the list of plugin examples in the plugin examples section.
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);
onConnected()
Fires when the bot connects to a server or when the plugin loadsonDisconnected()
Fires when the bot disconnects from a serveronEntityChanged(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 (seePayload
below)
- obj.entityId:
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
- obj.message:
onMessageSend(obj)
Fires when a team chat message is sent- obj.message:
string
The outgoing team chat message
- obj.message:
onNotification(obj)
Fires when there is a bot notification (including server events)- obj.notification:
object
The notification data of the event (see allNotification
below)
- obj.notification:
onTeamChanged(obj)
Fires when the team leader changes, or a team member is added or removed from the team
The app
object exists in the plugin's scope this
, and exposes the following properties and methods:
bmData
object
An object containing the BattleMetrics data of the server (seeBattleMetrics Data
below)cameras
array
An array containing all camera indentifiers saved from the Camera Stationcfg
object
An object containing the configuration settings for the bot (seeConfig
below)devices
Map
A Map object containing the bot's paired devices (key: device name (lowercase only), value: Array of devices, seeDevice
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 (seeDeviceAuto
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 (seeEvent Timers
below)guild_token
string
The unique token representing the Discord serverguild_name
string
The name of the Discord serveritemIds
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, seePoint
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 playerplayer_name
string
The steam name of the bot's connected playerserver_ip
string
The IP address of the bot's connected serverserver_name
string
The name of the bot's connected serverserver_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);
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); });
- playerName:
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); });
- playerId:
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 anarray
of player names andplayersDistances
is anarray
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'); } });
- id:
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 anarray
of player names andplayersDistances
is anarray
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'); } });
- id:
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));
- returns:
getCrateTimer()
Get the configured crate unlock timer- returns:
int
value
// getCrateTimer example var timer = await this.app.getCrateTimer(); this.app.sendTeamMessage('Crate unlock timer is set to: ' + getTimeDisplay(timer));
- returns:
getDetailedInfo(callback)
Get detailed information about the server- callback(data):
function
The function to execute after getting the detailed info (data
isDetailedInfo
) - 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); } });
- callback(data):
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
containsEntityInfo
) - 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'); } });
- id:
getEvents(type)
Get the most recent server events (ordered by newest to oldest)- type:
string
The event type (optional)heli
Patrol Helicoptercargo
Cargo Shipcrate
Locked Cratech47
CH-47 Chinookoil_rig_small
Oil Rig (Small)large_oil_rig
Oil Rig (Large)vendor
Travelling Vendor
- returns:
array
Event
array
// getEvents example var e = await this.app.getEvents(); console.log(e);
- type:
getInfo(callback)
Get information about the server- callback(message):
function
The function to execute after getting the info (message.response
containsInfo
) - 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)' : '')); } });
- callback(message):
getMapInfo(callback)
Get information about the server's map- callback(message):
function
The function to execute after getting the map info (message
isMapInfo
) - 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); } });
- callback(message):
getMapMarkers(callback)
Get information about all map markers- callback(message):
function
The function to execute after getting the map markers (message.response
containsMapMarkers
) - 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); } });
- callback(message):
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 totrue
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)));
- x:
getPrefix(type)
Get the command prefix for the bot- type:
string
The command type (optional)all
All Commandsdevice
Device Commands
- returns:
string
The selected prefix if it's required
// getPrefix example var prefix = await this.app.getPrefix('all');
- type:
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 theemoji
bool
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 });
- items:
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
⚠️ Unfortunately this plugin method no longer works since Steamrep has shutdown at the end of 2024- steamId:
getTeamChat(callback)
Get recent team chat messages- callback(message):
function
The function to execute after getting the team chat messages (message.response
containsTeamChat
) - 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); } } });
- callback(message):
getTeamData(callback)
Get detailed information about the team (leader, members)- callback(data):
function
The function to execute after getting the team data (data
isTeamData
) - 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); } });
- callback(data):
getTeamInfo(callback)
Get information about the team (leader, members)- callback(message):
function
The function to execute after getting the team info (message.response
containsTeamInfo
) - 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); } });
- callback(message):
getTeamMemberDeaths(steamId)
Gets the last 5 snapshots for a specific team member taken when they died- steamId:
string
The player's steamId - returns:
array
Members
array of team member death snapshots
// getTeamMemberDeaths example var app = this.app, deaths = await app.getTeamMemberDeaths(obj.steamId), idx = 1; if (deaths && deaths.length > 0) { for (var i = 0; i < deaths.length; i++) { app.sendTeamMessage('Team member \'' + cmdFormat(deaths[i].name) + '\' death #' + idx + ' was ' + ((deaths[i].deathTime > 0) ? getFriendlyDate(deaths[i].deathTime * 1000).replace('less than one', '< 1').replace('about an', '1') : 'unknown') + ' and is located ' + cmdFormat('@ ' + (await app.util.getMapCoords(deaths[i].x, deaths[i].y)))); idx++; } } else app.sendTeamMessage('No death info found for team member: ' + cmdFormat(obj.name));
- steamId:
getTime(callback)
Get information about the server time- callback(message):
function
The function to execute after getting the time (message.response
containsTime
) - 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))); } });
- callback(message):
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))); } });
- 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 themessage
string
andchannel
string
, optionaltts
bool
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 });- msg:
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; seeNotificationList
below)
// postDiscordNotification example var app = this.app; app.postDiscordNotification('Plugin Alert Title', 'Plugin Alert Message');
- title:
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');
- url:
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');
- cmd:
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!');
- msg:
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 totrue
to disable message translation (optional) - sendVoice:
bool
Set totrue
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');
- msg:
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'); });
- id:
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 thefrom
string
andto
string
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); });- msg:
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); });
- url:
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); });
- url:
interactiveMap.addMarker(markerId
Returnsstring
, steamIdstring
, namestring
, msgstring
, xint
, yint
)true
if the custom map marker is addedRefer to the mapmarkers plugin example to see the correct usage for addMarker
interactiveMap.setMarkerColor(markerId
Returnsstring
, colorstring
)true
if the custom map marker's color is updatedinteractiveMap.removeMarker(markerId
Returnsstring
)true
if the custom map marker matching markerId is removedinteractiveMap.clearMarkers(steamId
Returnsstring
)true
if all custom map markers are removed for steamIdinteractiveMap.getHeatmapData()
Returns an object containing the heatmap data (seeHeatmapData
below)util.collides(x
Returnsint
, yint
, rotationint
, x1int
, y1int
, x2int
, y2int
)true
if angled point x,y collides with rectangle x1,y1,x2,y2util.direction(x1
Get the direction from the first point facing the secondint
, y1int
, x2int
, y2int
)util.distance(x1
Get the distance between two points in metersint
, y1int
, x2int
, y2int
)util.getMapCoords(x
Get the map coordinates for a pointint
, yint
)util.inRect(x
Returnsint
, yint
, x1int
, y1int
, x2int
, y2int
)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)));
Note: The following methods exist in the plugin's scope this
(instead of in app
).
registeredHandlers.add(type
Add a handler for a specific update event type:string
, handlerfunction
)camera
Fires when the camera list has changedconfig
Fires when the configuration settings have changeddevice
Fires when the paired devices has changedwipe
Fires when the server has wiped
registeredHandlers.remove(type
Remove a handler for a specific update event type (seestring
, handlerfunction
)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);
-
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,ch47b,vendor", "subEventsDisplay": "heli_lootable,brad_lootable,cargo_docked,oil_lootable,oil_cams" }
-
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": 7200, "spread": 7200 }, "crate": { "spawn": 7200, "spread": 3600 }, "heli": { "spawn": 7200, "spread": 3600 }, "oilrig": { "spawn": 2700, "spread": 2700 }, "vendor": { "spawn": 7200, "spread": 7200 } }
-
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 // 9 = TravellingVendor
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 }
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);
- str:
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));
- str:
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); });
- data:
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); }); } } });
- items:
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); }
- str:
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)); } });
- date:
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'));
- timestr:
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))));
- date:
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)))));
- time:
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); }); } } });
- msg:
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.
- alarmchannel
- This plugin example demonstrates how to use the activation of a Smart Alarm to post a Discord message in a specific channel and ping a role.
- announcements
- This plugin example demonstrates how to automatically send pre-defined team chat announcements.
- autopop
- This plugin example demonstrates how to automatically run the
!pop
command every 5 minutes.
- This plugin example demonstrates how to automatically run the
- autotime
- This plugin example demonstrates how to automatically send until daytime / until nighttime team chat announcements.
- hotelfloors
- This plugin example demonstrates how to automatically activate multiple similarly named Smart Switches with a single command. This is the same plugin seen in the MikeTheVike YouTube video here: https://www.youtube.com/watch?v=ijdQ31TP0hk
- macro
- This plugin example demonstrates how to use a single team chat command to execute multiple chat commands.
- mapmarker
- This plugin example demonstrates how to pin a custom map marker to the Interactive Map.
- messagerouting
- This plugin example demonstrates how to route team chat messages to custom Discord channels. You can specify wildcard matches for the messages and have them posted to their own Discord channels.
- mirrormessages
- This plugin example demonstrates how to mirror all team chat messages by posting them to another Discord server via a webhook.
- teamvoice
- This plugin example demonstrates how to send voice messages to the RustPlusBot voice client. You can invite the voice client to your active voice channel using Discord command:
rp!voice_join
.
- This plugin example demonstrates how to send voice messages to the RustPlusBot voice client. You can invite the voice client to your active voice channel using Discord command:
- timedfireworks
- This plugin example demonstrates how to activate multiple Smart Switches with different delays, allowing you to create a timed firework show. The Smart Switches should be directly wired to Igniters near the fireworks.
- turretrotation
- The plugins works by rotating turret segments, or sections, with a total of 9 segments supported. Each turret segment is controlled by a single smart switch. Each turret in the segment has their Has Target output combined to a single smart alarm. When a turret segment is active, and if its related smart alarm is activated from the combined Has Target output, then the turret segment timer is reset keeping the segment active for longer.
- vendingitems
- This plugin example demonstrates how to output all vending machine items in CSV or JSON format.
- vendinglog
- This plugin example demonstrates how to log all vending machine item changes on the server to the Notifications Discord Channel (or the Plugin Notification channel if set in the bot's config).
- Website: https://bot.rustplus.io/
- Help & Documentation: https://bot.rustplus.io/help/
- Plugin Examples: https://github.com/javajuice1337/RustPlusBot/blob/main/plugin%20examples