### Initialize ReforgerServer and Handle Game Events (JavaScript) Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Initializes the ReforgerServer with configuration for RCON, log parsing, and Discord/MySQL connectors. It demonstrates listening to 'playerJoined' and 'satPlayerKilled' events, and starting RCON player updates. ```javascript const ReforgerServer = require('./reforger-server/main'); const config = { server: { id: 1, name: "My Server", host: "192.168.1.100", queryPort: 2001, rconPort: 2002, rconPassword: "password123", logReaderMode: "tail", logDir: "/path/to/reforger/logs" }, connectors: { discord: { token: "YOUR_DISCORD_TOKEN", clientId: "YOUR_CLIENT_ID", guildId: "YOUR_GUILD_ID" }, mysql: { enabled: true, host: "localhost", port: 3306, username: "reforger", password: "dbpass", database: "reforgerjs" } }, plugins: [] }; const serverInstance = new ReforgerServer(config); await serverInstance.initialize(); // Listen to player events serverInstance.on('playerJoined', (data) => { console.log(`Player ${data.playerName} joined from ${data.playerIP}`); console.log(`UUID: ${data.steamID}, Device: ${data.device}`); }); // Listen to kill events serverInstance.on('satPlayerKilled', (data) => { console.log(`${data.instigatorName} killed ${data.playerName}`); if (data.friendlyFire) { console.log('Friendly fire incident!'); } }); // Start RCON player updates serverInstance.startSendingPlayersCommand(30000); ``` -------------------------------- ### Discord Channel Integration and Messaging in JavaScript Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md This snippet shows how to integrate with Discord, fetch a specific text channel, and send messages to it. It includes configuration checks, permission validation, and event handler setup. Requires a configured Discord client and guild ID. ```javascript async prepareToMount(serverInstance, discordClient) { this.serverInstance = serverInstance; this.discordClient = discordClient; // Get plugin config const pluginConfig = this.config.plugins.find( plugin => plugin.plugin === "YourPluginName" ); if (!pluginConfig || !pluginConfig.channel) { logger.warn(`[${this.name}] No channel configured`); return; } // Get the Discord channel try { const guild = await this.discordClient.guilds.fetch( this.config.connectors.discord.guildId, { cache: true, force: true } ); const channel = await guild.channels.fetch(pluginConfig.channel); if (!channel || !channel.isTextBased()) { logger.error(`[${this.name}] Channel is not a text channel`); return; } this.channel = channel; // Check permissions if (!this.channel.permissionsFor(this.discordClient.user).has("SendMessages")) { logger.error(`[${this.name}] Bot cannot send messages in channel`); return; } // Setup event handlers this.serverInstance.on("playerJoined", this.handlePlayerJoined.bind(this)); } catch (error) { logger.error(`[${this.name}] Discord setup error: ${error.message}`); } } // Send a message to Discord async sendDiscordMessage(content) { if (!this.channel) return; try { await this.channel.send(content); } catch (error) { logger.error(`[${this.name}] Discord message error: ${error.message}`); } } ``` -------------------------------- ### MySQL Database Integration and Operations in JavaScript Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md This snippet demonstrates how to prepare the MySQL database connection, create tables if they don't exist, and save data to the database. It includes checks for configuration and pool availability, error handling, and logging. Requires a configured MySQL connection pool (process.mysqlPool). ```javascript async prepareToMount(serverInstance) { this.serverInstance = serverInstance; // Check if MySQL is enabled if ( !this.config.connectors || !this.config.connectors.mysql || !this.config.connectors.mysql.enabled ) { logger.warn(`[${this.name}] MySQL is not enabled in config`); return; } // Get the MySQL pool const pool = process.mysqlPool; if (!pool) { logger.error(`[${this.name}] MySQL pool is not available`); return; } // Create tables if needed try { const createTableQuery = ` CREATE TABLE IF NOT EXISTS your_table ( id INT AUTO_INCREMENT PRIMARY KEY, playerName VARCHAR(255) NULL, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `; const connection = await pool.getConnection(); await connection.query(createTableQuery); connection.release(); logger.info(`[${this.name}] Database schema ready`); } catch (error) { logger.error(`[${this.name}] Database setup error: ${error.message}`); } } // Example of saving data to database async saveToDatabase(data) { try { await process.mysqlPool.query( "INSERT INTO your_table (playerName) VALUES (?)", [data.playerName] ); logger.info(`[${this.name}] Data saved to database`); } catch (error) { logger.error(`[${this.name}] Database error: ${error.message}`); } } ``` -------------------------------- ### Configure ReforgerJS Plugin in JSON Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md Defines plugin configuration structure in config.json. Specifies plugin name, enable status, Discord channel mapping, and custom options. Used by the server to load and initialize plugins with their specific settings. ```json "plugins": [ { "plugin": "YourPluginName", "enabled": true, "channel": "discord-channel-id", "custom-option": "value" } ] ``` -------------------------------- ### Create ReforgerJS Plugin Class in JavaScript Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md Provides a complete JavaScript plugin template for ReforgerJS that implements required lifecycle methods including constructor, prepareToMount, event handlers, and cleanup. Demonstrates event subscription, configuration access, and proper resource management with player join event handling and server console logging. This template serves as the foundation for creating custom server plugins. ```javascript class YourPluginName { constructor(config) { this.config = config; this.name = "Your Plugin Name"; this.serverInstance = null; this.discordClient = null; } async prepareToMount(serverInstance, discordClient) { // Store references to server and Discord client this.serverInstance = serverInstance; this.discordClient = discordClient; // Get plugin-specific config const pluginConfig = this.config.plugins.find(plugin => plugin.plugin === "YourPluginName"); // Subscribe to events this.serverInstance.on("playerJoined", this.handlePlayerJoined.bind(this)); logger.info(`[${this.name}] Plugin initialized successfully`); } handlePlayerJoined(data) { // Handle player joined event logger.info(`[${this.name}] Player joined: ${data.playerName}`); } async cleanup() { // Remove event listeners if (this.serverInstance) { this.serverInstance.removeListener("playerJoined", this.handlePlayerJoined); } logger.info(`[${this.name}] Cleanup complete`); } } module.exports = YourPluginName; ``` -------------------------------- ### RCON Command Execution in JavaScript Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md This snippet provides a function to send RCON commands to the server, specifically demonstrated with kicking a player. It includes checks for RCON availability and connection status before sending the command. Assumes the server instance has an RCON object with a sendCustomCommand method. ```javascript // Example: kicking a player via RCON kickPlayer(playerName) { if (!this.serverInstance || !this.serverInstance.rcon) { logger.warn(`[${this.name}] RCON not available`); return; } if (!this.serverInstance.rcon.isConnected) { logger.warn(`[${this.name}] RCON not connected`); return; } const kickCommand = `#kick ${playerName}`; this.serverInstance.rcon.sendCustomCommand(kickCommand); logger.info(`[${this.name}] Sent kick command for ${playerName}`); } ``` -------------------------------- ### DBLogStats Plugin TableName Configuration Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md This example shows the 'tableName' configuration option for the DBLogStats plugin. It specifies the table name used by the plugin to store or retrieve data. The default value is an empty string. ```plaintext tableName: "" ``` -------------------------------- ### Configure Log Parser and Handle Game Events (JavaScript) Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Sets up the LogParser to monitor Arma Reforger server logs using specified modes (e.g., 'tail'). It demonstrates registering event handlers for various game events like 'playerJoined', 'voteKickStart', 'serverHealth', and 'chatMessage', and starting log watching. ```javascript const LogParser = require('./reforger-server/log-parser/index'); const options = { logReaderMode: 'tail', logDir: '/path/to/reforger/logs', filename: 'console.log', backfill: true }; const logParser = new LogParser('console.log', options); // Register event handlers logParser.on('playerJoined', (data) => { console.log(`Player joined: ${data.playerName} (#${data.playerNumber})`); console.log(`IP: ${data.playerIP}, BE GUID: ${data.beGUID}`); }); logParser.on('voteKickStart', (data) => { console.log(`Vote kick initiated by ${data.voteOffenderName} against ${data.voteVictimName}`); }); logParser.on('serverHealth', (data) => { console.log(`Server FPS: ${data.fps}, Memory: ${data.memory} kB, Players: ${data.player}`); }); logParser.on('chatMessage', (data) => { console.log(`[${data.channelType}] ${data.playerName}: ${data.message}`); }); // Start watching logs logParser.watch(); // Stop watching // await logParser.unwatch(); ``` -------------------------------- ### Implementing Event Logging with EventLogger in JavaScript Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/reforger-server/plugins/README.md The EventLogger class sets up event listeners for playerJoined, satPlayerKilled, and chatMessage events on a ReforgerJS server instance, logging details using a logger utility. It requires a config object in the constructor and a serverInstance for mounting, with event data as inputs for logging outputs. Limitations include dependency on specific server events and manual listener removal during cleanup. ```javascript class EventLogger { constructor(config) { this.config = config; this.name = "EventLogger Plugin"; this.serverInstance = null; } async prepareToMount(serverInstance) { this.serverInstance = serverInstance; // Track multiple events this.serverInstance.on("playerJoined", this.handlePlayerJoined.bind(this)); this.serverInstance.on("satPlayerKilled", this.handlePlayerKilled.bind(this)); this.serverInstance.on("chatMessage", this.handleChatMessage.bind(this)); logger.info(`[${this.name}] Initialized and tracking events`); } handlePlayerJoined(data) { logger.info(`[${this.name}] Player joined: ${data.playerName} from IP ${data.playerIP}`); } handlePlayerKilled(data) { logger.info(`[${this.name}] Player ${data.playerName} was killed by ${data.instigatorName}`); } handleChatMessage(data) { logger.info(`[${this.name}] [${data.channelType}] ${data.playerName}: ${data.message}`); } async cleanup() { if (this.serverInstance) { this.serverInstance.removeListener("playerJoined", this.handlePlayerJoined); this.serverInstance.removeListener("satPlayerKilled", this.handlePlayerKilled); this.serverInstance.removeListener("chatMessage", this.handleChatMessage); } } } module.exports = EventLogger; ``` -------------------------------- ### DBLog Plugin for Player Data Logging Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt The DBLog plugin automatically logs player information to a MySQL database. It prepares the database schema, starts a logging interval, and logs player details such as name, IP, and unique identifiers. If a player exists, their record is updated; otherwise, a new record is inserted. ```javascript class DBLog { constructor(config) { this.config = config; this.interval = 5; // minutes } async prepareToMount(serverInstance) { this.serverInstance = serverInstance; await this.setupSchema(); this.startLogging(); } async logPlayers() { const players = this.serverInstance.players; for (const player of players) { const [existing] = await pool.query( 'SELECT * FROM players WHERE playerUID = ?', [player.uid] ); if (existing.length > 0) { await pool.query( 'UPDATE players SET playerName = ?, playerIP = ?, beGUID = ?, steamID = ?, device = ? WHERE playerUID = ?', [player.name, player.ip, player.beGUID, player.steamID, player.device, player.uid] ); } else { await pool.query( 'INSERT INTO players (playerName, playerIP, playerUID, beGUID, steamID, device) VALUES (?, ?, ?, ?, ?, ?)', [player.name, player.ip, player.uid, player.beGUID, player.steamID, player.device] ); } } } } module.exports = DBLog; ``` -------------------------------- ### Discord /whois Slash Command Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Implements a Discord slash command '/whois' to query player information from the database. Users can search by BattlEye GUID, UUID, Name, or IP. The command returns an embed with the player's details or a 'not found' message. ```javascript // Command definition const { SlashCommandBuilder } = require('discord.js'); const whoisCommand = { data: new SlashCommandBuilder() .setName('whois') .setDescription('Reforger player information') .addStringOption(option => option .setName('identifier') .setDescription('The type of identifier') .setRequired(true) .addChoices( { name: 'beGUID', value: 'beguid' }, { name: 'UUID', value: 'uuid' }, { name: 'Name', value: 'name' }, { name: 'IP', value: 'ip' } ) ) .addStringOption(option => option .setName('value') .setDescription('The value to search for') .setRequired(true) ) }; // Usage in Discord: /whois identifier:UUID value:12345678-1234-1234-1234-123456789abc // Returns embed with player name, IP, UUID, beGUID, SteamID, device // Command handler implementation const pool = process.mysqlPool; const identifier = interaction.options.getString('identifier'); const value = interaction.options.getString('value'); const fieldMap = { 'beguid': 'beGUID', 'uuid': 'playerUID', 'name': 'playerName', 'ip': 'playerIP' }; const [rows] = await pool.query( `SELECT playerName, playerIP, playerUID, beGUID, steamID, device FROM players WHERE ${fieldMap[identifier]} = ?`, [value] ); if (rows.length === 0) { await interaction.reply(`No player found with ${identifier}: ${value}`); } else { const player = rows[0]; await interaction.reply({ embeds: [{ title: 'Player Information', fields: [ { name: 'Name', value: player.playerName }, { name: 'UUID', value: player.playerUID }, { name: 'IP', value: player.playerIP }, { name: 'beGUID', value: player.beGUID || 'N/A' }, { name: 'SteamID', value: player.steamID || 'N/A' }, { name: 'Device', value: player.device || 'Unknown' } ] }] }); } ``` -------------------------------- ### Integrate and Mount ReforgerJS Plugins Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt This code demonstrates how to load and mount plugins for ReforgerJS. It defines a configuration object for plugins, loads enabled plugins using `loadPlugins`, and then mounts them with server and Discord client instances. It also includes cleanup logic for graceful shutdown. ```javascript const { loadPlugins, mountPlugins } = require('./reforger-server/pluginLoader'); // Define plugin configuration const config = { plugins: [ { plugin: "DBLog", enabled: true, interval: 5 }, { plugin: "ServerStatus", enabled: true, channel: "1234567890123456789", interval: 1, showFPS: true, discordBotStatus: true, embed: { title: "Server Status", color: "#00FF00", footer: "ReforgerJS" } }, { plugin: "AltChecker", enabled: true, channel: "9876543210987654321", logAlts: true, logOnlyOnline: false } ] }; // Load all enabled plugins const loadedPlugins = await loadPlugins(config); console.log(`Loaded ${loadedPlugins.length} plugins`); // Mount plugins with server and Discord client await mountPlugins(loadedPlugins, serverInstance, discordClient); // Cleanup on shutdown process.on('SIGINT', async () => { for (const plugin of loadedPlugins) { if (typeof plugin.cleanup === 'function') { await plugin.cleanup(); } } }); ``` -------------------------------- ### Factory Pattern for Startup Validation in JavaScript Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Validates configuration and performs essential startup checks for the application. It imports validation and startup functions, loads configuration from 'config.json', and initializes the Discord client. Dependencies include custom factory functions and 'discord.js'. It returns an authenticated Discord client and potentially sets up global variables for database connections. ```javascript const { validateConfig, performStartupChecks } = require('./reforger-server/factory'); const { Client, GatewayIntentBits } = require('discord.js'); // Load and validate config const config = require('./config.json'); if (!validateConfig(config)) { console.error('Invalid configuration'); process.exit(1); } // Perform startup checks - connects Discord, MySQL, verifies log directory const discordClient = await performStartupChecks(config); // discordClient is now authenticated and ready // process.mysqlPool is now available globally if MySQL enabled // process.battlemetricsAPI is available if BattleMetrics enabled discordClient.on('ready', () => { console.log(`Logged in as ${discordClient.user.tag}`); }); // Access MySQL connection pool if (config.connectors.mysql.enabled) { const [rows] = await process.mysqlPool.query('SELECT * FROM players LIMIT 10'); console.log(`Found ${rows.length} players in database`); } ``` -------------------------------- ### Configure ReforgerJS Server Settings in JSON Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md Defines the server configuration for ReforgerJS, including server identification, connection details, and logging preferences. Essential for setting up the framework to interact with the Arma Reforger server. ```json "server": { "id": 1, "name": "SERVER NAME", "host": "xxx.xxx.xxx.xxx", "queryPort": 00000, "rconPort": 00000, "rconPassword": "password", "logReaderMode": "tail", "logDir": "C:/path/to/reforger/log/folder" }, "consoleLogLevel": "info", "outputLogLevel": "info" ``` -------------------------------- ### Configure MySQL Database Connection in ReforgerJS Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md Sets up MySQL database connectivity for ReforgerJS, allowing data persistence for plugins. Includes host, port, credentials, and database dialect configuration. ```json "mysql": { "enabled": false, "host": "host", "port": 3306, "username": "", "password": "", "database": "", "dialect": "" } ``` -------------------------------- ### Set Up Discord Connector in ReforgerJS Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md Configures the Discord connector for ReforgerJS, enabling communication between the framework and Discord. Requires bot token, client ID, and guild ID for authentication and connection. ```json "connectors": { "discord": { "token": "", "clientId":"", "guildId": "" } } ``` -------------------------------- ### Deploy Discord Slash Commands in JavaScript Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Registers slash commands with the Discord API. It loads command files from a specified directory, filters them based on configuration, and deploys them to a specific guild. Dependencies include 'discord.js', 'fs', and 'path'. It takes configuration, a logger, and a Discord client instance as input. ```javascript const { REST, Routes } = require('discord.js'); const fs = require('fs'); const path = require('path'); async function deployCommands(config, logger, discordClient) { try { const rest = new REST({ version: '10' }).setToken(config.connectors.discord.token); // Clear existing commands await rest.put( Routes.applicationGuildCommands(config.connectors.discord.clientId, config.connectors.discord.guildId), { body: [] } ); // Load command files const commandsPath = path.resolve('./reforger-server/commands'); const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); const commands = []; for (const file of commandFiles) { const command = require(path.join(commandsPath, file)); const commandConfig = config.commands.find(cmd => cmd.command === command.data.name); if (commandConfig && commandConfig.enabled) { commands.push(command.data.toJSON()); logger.info(`Command '/${command.data.name}' loaded`); } } // Deploy commands if (commands.length > 0) { await rest.put( Routes.applicationGuildCommands(config.connectors.discord.clientId, config.connectors.discord.guildId), { body: commands } ); logger.info(`Deployed ${commands.length} commands`); } return true; } catch (error) { logger.error(`Error deploying commands: ${error.message}`); return false; } } // Usage await deployCommands(config, logger, discordClient); ``` -------------------------------- ### Execute RCON Commands and Handle RCON Events (JavaScript) Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt Establishes an RCON connection to the Arma Reforger server and demonstrates sending custom commands like kick, ban, and shutdown. It also shows how to handle 'connect', 'players', and 'error' events from the RCON client. ```javascript const Rcon = require('./reforger-server/rcon'); const rcon = new Rcon({ server: { host: "192.168.1.100", rconPort: 2002, rconPassword: "password123" } }); rcon.on('connect', () => { console.log('RCON connected'); // Send custom commands rcon.sendCustomCommand('#kick 5'); rcon.sendCustomCommand('#ban 12345678-1234-1234-1234-123456789abc'); rcon.sendCustomCommand('#shutdown 60'); }); rcon.on('players', (players) => { console.log('Current players:', players); players.forEach(player => { console.log(`ID: ${player.id}, Name: ${player.name}, UID: ${player.uid}`); }); }); rcon.on('error', (err) => { console.error('RCON error:', err.message); }); rcon.start(); rcon.startSendingPlayersCommand(30000); ``` -------------------------------- ### Retrieve Player Information with /whois Command Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md The /whois command retrieves player information from the database using a specified identifier (beGUID, UUID, Name, or IP). It requires the DBLog plugin and can function as an alt checker when an IP address is provided. ```command /whois ``` -------------------------------- ### Enable Discord Slash Commands in ReforgerJS Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md Configures individual Discord slash commands for ReforgerJS, including enabling/disabling and setting permission levels. Commands must match those in the commands folder. ```json "commands": [ { "command": "whois", "enabled": false, "commandLevel": 3 } ] ``` -------------------------------- ### Configure ReforgerJS Plugins Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md This JSON snippet demonstrates how to configure plugins in ReforgerJS. The 'plugins' array lists active plugins, each with a 'plugin' name and a 'disabled' boolean flag. 'disabled' can be set to true or false to enable or disable a plugin, respectively. ```json { "plugins": [ { "plugin": "DBLog", "disabled": false } ] } ``` -------------------------------- ### Discord Player Stats Command (JavaScript) Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt This JavaScript code snippet implements a Discord slash command '/stats' that retrieves and displays comprehensive player statistics from a MySQL database. It handles both UUID and player name inputs, calculates the K/D ratio, and formats the data into an embed for Discord. Dependencies include 'discord.js' for Discord interactions and a MySQL connection pool ('process.mysqlPool'). ```javascript const { EmbedBuilder } = require('discord.js'); const identifier = interaction.options.getString('identifier'); const pool = process.mysqlPool; // Check if UUID or name const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier); let playerUID; if (isUUID) { playerUID = identifier; } else { const [matches] = await pool.query( 'SELECT playerUID FROM players WHERE playerName LIKE ?', [`%${identifier}%`] ); if (matches.length === 0) { return await interaction.reply('Player not found'); } playerUID = matches[0].playerUID; } const [stats] = await pool.query( 'SELECT * FROM player_stats WHERE playerUID = ?', [playerUID] ); if (stats.length === 0) { return await interaction.reply('No stats found for this player'); } const s = stats[0]; const kdRatio = s.deaths > 0 ? (s.kills / s.deaths).toFixed(2) : s.kills; const embed = new EmbedBuilder() .setTitle('📊 Player Stats') .setColor('#FFA500') .addFields( { name: '🔸Infantry', value: `Points: ${s.sppointss0}\nKills: ${s.kills}\nDeaths: ${s.deaths}\nK/D: ${kdRatio}\nAI Kills: ${s.ai_kills}` }, { name: '🔸Logistics', value: `Points: ${s.sppointss1}\nRoadkills: ${s.roadkills}\nDistance: ${(s.distance_driven/1000).toFixed(2)} km` }, { name: '🔸Medical', value: `Points: ${s.sppointss2}\nBandages: ${s.bandage_friendlies}\nTourniquets: ${s.tourniquet_friendlies}` }, { name: '❗Warcrimes', value: `Value: ${s.warcrime_harming_friendlies}\nTeamkills: ${s.friendly_kills}` } ); await interaction.reply({ embeds: [embed] }); ``` -------------------------------- ### Retrieve Player Statistics with /stats Command Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md The /stats command fetches detailed player statistics by UUID, requiring both DBLog and DBLogStats plugins. It returns a comprehensive set of metrics including infantry, logistics, medical, and warcrime data. ```command /stats ``` -------------------------------- ### Define Discord Command Permissions in ReforgerJS Source: https://github.com/zsu-gg-reforger/reforgerjs/blob/main/README.md Configures role-based permissions for Discord commands in ReforgerJS. Maps Discord roles to permission levels, enabling fine-grained access control for server administration commands. ```json "roleLevels": { "1": [ "roleName", "roleName1" ], "2": [ "roleName2" ], "3": [ "roleName3" ] } ``` -------------------------------- ### Discord Server Status Embed Updates (JavaScript) Source: https://context7.com/zsu-gg-reforger/reforgerjs/llms.txt This JavaScript class, 'ServerStatus', facilitates the display of live server information within Discord using automatically updating embeds. It connects to a server instance and a Discord client, fetches or creates a message in a specified channel, and periodically updates the embed with player count, FPS, and memory usage. It also updates the bot's activity status. Dependencies include 'discord.js'. ```javascript const { EmbedBuilder, ActivityType } = require('discord.js'); class ServerStatus { constructor(config) { this.config = config; this.interval = null; } async prepareToMount(serverInstance, discordClient) { this.serverInstance = serverInstance; this.discordClient = discordClient; const pluginConfig = this.config.plugins.find(p => p.plugin === "ServerStatus"); const guild = await discordClient.guilds.fetch(this.config.connectors.discord.guildId); this.channel = await guild.channels.fetch(pluginConfig.channel); // Create or fetch message if (pluginConfig.messageID) { this.message = await this.channel.messages.fetch(pluginConfig.messageID); } else { this.message = await this.channel.send({ embeds: [this.createEmbed()] }); pluginConfig.messageID = this.message.id; } // Update every N minutes this.interval = setInterval(() => this.updateEmbed(), pluginConfig.interval * 60 * 1000); } createEmbed() { const playerCount = global.serverPlayerCount || 0; const fps = global.serverFPS || 0; const memoryMB = ((global.serverMemoryUsage || 0) / 1024).toFixed(2); return new EmbedBuilder() .setTitle('Server Status') .setColor('#00FF00') .addFields( { name: 'Player Count', value: `${playerCount}`, inline: true }, { name: 'FPS', value: `${fps}`, inline: true }, { name: 'Memory', value: `${memoryMB} MB`, inline: true } ) .setTimestamp(); } async updateEmbed() { await this.message.edit({ embeds: [this.createEmbed()] }); // Update bot status this.discordClient.user.setActivity({ type: ActivityType.Custom, name: `${global.serverPlayerCount} Players | ${global.serverFPS} FPS`, state: `${global.serverPlayerCount} Players | ${global.serverFPS} FPS` }); } } module.exports = ServerStatus; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.