From 4499339b29d789c552942087747dbec4cc679eff Mon Sep 17 00:00:00 2001 From: Louis Mazin Date: Tue, 3 Feb 2026 22:00:54 +0100 Subject: [PATCH] test --- commands/utility/panel.js | 270 ++++++++++++++++++++++++++++++++++++++ database.js | 53 +++++++- ramMonitor.js | 26 ++-- 3 files changed, 340 insertions(+), 9 deletions(-) create mode 100644 commands/utility/panel.js diff --git a/commands/utility/panel.js b/commands/utility/panel.js new file mode 100644 index 0000000..c32aa8d --- /dev/null +++ b/commands/utility/panel.js @@ -0,0 +1,270 @@ +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } = require('discord.js'); +const { getConfig, updateConfig, getAllConfig } = require('../../database'); +const { getMonitoringStatus } = require('../../ramMonitor'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('panel') + .setDescription('Panneau de configuration du bot'), + + async execute(interaction) { + // Vérifier les permissions + if (!interaction.member.roles.cache.has('1444684935632912394')) { + await interaction.reply({ + content: '❌ Il faut avoir le rôle Rygainland pour accéder au panneau de configuration.', + flags: 64 + }); + return; + } + + await showPanel(interaction); + } +}; + +async function showPanel(interaction) { + const config = await getAllConfig(); + const monitoringStatus = getMonitoringStatus(); + + const autoRebootEnabled = config.auto_reboot_enabled === 'true'; + const ramThreshold = parseInt(config.ram_threshold_gb); + const consoleMonitorEnabled = config.console_monitor_enabled === 'true'; + + const embed = new EmbedBuilder() + .setColor(0x0099FF) + .setTitle('⚙️ Panneau de Configuration') + .setDescription('Gérez les paramètres du bot et du serveur') + .addFields( + { + name: '🔄 Redémarrage Automatique', + value: `**État:** ${autoRebootEnabled ? '✅ Activé' : '❌ Désactivé'}\n**Seuil RAM:** ${ramThreshold} Go\n**Surveillance:** ${monitoringStatus.isMonitoring ? '🟢 Active' : '🔴 Inactive'}`, + inline: true + }, + { + name: '📊 Surveillance Console', + value: `**État:** ${consoleMonitorEnabled ? '✅ Activée' : '❌ Désactivée'}`, + inline: true + }, + { + name: '📈 Statistiques', + value: `**En redémarrage:** ${monitoringStatus.isRebooting ? 'Oui' : 'Non'}\n**Intervalle:** ${monitoringStatus.checkInterval / 1000}s`, + inline: false + } + ) + .setTimestamp() + .setFooter({ text: 'Panneau de Configuration' }); + + const row1 = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('toggle_auto_reboot') + .setLabel(autoRebootEnabled ? 'Désactiver Auto-Reboot' : 'Activer Auto-Reboot') + .setStyle(autoRebootEnabled ? ButtonStyle.Danger : ButtonStyle.Success) + .setEmoji(autoRebootEnabled ? '⏹️' : '▶️'), + new ButtonBuilder() + .setCustomId('toggle_console_monitor') + .setLabel(consoleMonitorEnabled ? 'Désactiver Console' : 'Activer Console') + .setStyle(consoleMonitorEnabled ? ButtonStyle.Danger : ButtonStyle.Success) + .setEmoji(consoleMonitorEnabled ? '📵' : '📱') + ); + + const row2 = new ActionRowBuilder() + .addComponents( + new StringSelectMenuBuilder() + .setCustomId('change_ram_threshold') + .setPlaceholder(`Seuil RAM actuel: ${ramThreshold} Go`) + .addOptions([ + { + label: '15 Go', + description: 'Redémarrage à 15 Go de RAM', + value: '15', + emoji: '🔵' + }, + { + label: '17 Go', + description: 'Redémarrage à 17 Go de RAM', + value: '17', + emoji: '🟢' + }, + { + label: '19 Go (défaut)', + description: 'Redémarrage à 19 Go de RAM', + value: '19', + emoji: '🟡', + default: ramThreshold === 19 + }, + { + label: '21 Go', + description: 'Redémarrage à 21 Go de RAM', + value: '21', + emoji: '🟠' + }, + { + label: '23 Go', + description: 'Redémarrage à 23 Go de RAM', + value: '23', + emoji: '🔴' + }, + { + label: '25 Go', + description: 'Redémarrage à 25 Go de RAM', + value: '25', + emoji: '🔴' + } + ]) + ); + + const row3 = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('refresh_panel') + .setLabel('Actualiser') + .setStyle(ButtonStyle.Secondary) + .setEmoji('🔄'), + new ButtonBuilder() + .setCustomId('view_stats') + .setLabel('Voir Stats Détaillées') + .setStyle(ButtonStyle.Primary) + .setEmoji('📊') + ); + + if (interaction.replied || interaction.deferred) { + await interaction.editReply({ embeds: [embed], components: [row1, row2, row3] }); + } else { + await interaction.reply({ embeds: [embed], components: [row1, row2, row3] }); + } + + // Créer un collector pour les interactions + const collector = interaction.channel.createMessageComponentCollector({ + time: 300000 // 5 minutes + }); + + collector.on('collect', async i => { + if (!i.member.roles.cache.has('1444684935632912394')) { + await i.reply({ + content: '❌ Vous n\'avez pas la permission d\'utiliser ce panneau.', + flags: 64 + }); + return; + } + + try { + if (i.customId === 'toggle_auto_reboot') { + const currentState = (await getConfig('auto_reboot_enabled')) === 'true'; + const newState = !currentState; + await updateConfig('auto_reboot_enabled', newState.toString()); + + await i.deferUpdate(); + await i.editReply({ + content: `✅ Redémarrage automatique ${newState ? 'activé' : 'désactivé'}`, + }); + + // Refresh panel + setTimeout(async () => { + await showPanel(i); + }, 1000); + } + else if (i.customId === 'toggle_console_monitor') { + const currentState = (await getConfig('console_monitor_enabled')) === 'true'; + const newState = !currentState; + await updateConfig('console_monitor_enabled', newState.toString()); + + await i.deferUpdate(); + await i.editReply({ + content: `✅ Surveillance console ${newState ? 'activée' : 'désactivée'}`, + }); + + // Refresh panel + setTimeout(async () => { + await showPanel(i); + }, 1000); + } + else if (i.customId === 'change_ram_threshold') { + const newThreshold = i.values[0]; + await updateConfig('ram_threshold_gb', newThreshold); + + await i.deferUpdate(); + await i.editReply({ + content: `✅ Seuil RAM changé à ${newThreshold} Go`, + }); + + // Refresh panel + setTimeout(async () => { + await showPanel(i); + }, 1000); + } + else if (i.customId === 'refresh_panel') { + await i.deferUpdate(); + await showPanel(i); + } + else if (i.customId === 'view_stats') { + await showDetailedStats(i); + } + } catch (error) { + console.error('Erreur lors de l\'interaction avec le panel:', error); + if (i.deferred || i.replied) { + await i.editReply({ content: '❌ Une erreur est survenue', components: [] }); + } else { + await i.reply({ content: '❌ Une erreur est survenue', flags: 64 }); + } + } + }); + + collector.on('end', () => { + console.log('⏰ [Panel] Collector expiré'); + }); +} + +async function showDetailedStats(interaction) { + const config = await getAllConfig(); + const monitoringStatus = getMonitoringStatus(); + const { checkRAMUsage } = require('../../ramMonitor'); + + const ramData = await checkRAMUsage(); + + const embed = new EmbedBuilder() + .setColor(0x00FF00) + .setTitle('📊 Statistiques Détaillées du Monitoring') + .setDescription('Informations en temps réel sur le serveur') + .addFields( + { + name: '🎮 État du Serveur', + value: ramData ? `**État:** ${ramData.currentState}\n**RAM:** ${ramData.ramUsedGB} Go / ${config.ram_threshold_gb} Go` : 'Impossible de récupérer les données', + inline: true + }, + { + name: '⚙️ Configuration', + value: `**Auto-Reboot:** ${config.auto_reboot_enabled === 'true' ? 'Oui' : 'Non'}\n**Seuil:** ${config.ram_threshold_gb} Go\n**Console:** ${config.console_monitor_enabled === 'true' ? 'Active' : 'Inactive'}`, + inline: true + }, + { + name: '🔄 Surveillance', + value: `**Active:** ${monitoringStatus.isMonitoring ? 'Oui' : 'Non'}\n**En reboot:** ${monitoringStatus.isRebooting ? 'Oui' : 'Non'}\n**Intervalle:** ${monitoringStatus.checkInterval / 1000}s`, + inline: false + } + ) + .setTimestamp() + .setFooter({ text: 'Statistiques en temps réel' }); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('back_to_panel') + .setLabel('Retour au Panel') + .setStyle(ButtonStyle.Secondary) + .setEmoji('◀️') + ); + + await interaction.update({ embeds: [embed], components: [row] }); + + // Attendre le clic sur le bouton retour + const collector = interaction.channel.createMessageComponentCollector({ + time: 60000 + }); + + collector.on('collect', async i => { + if (i.customId === 'back_to_panel') { + await i.deferUpdate(); + await showPanel(i); + } + }); +} diff --git a/database.js b/database.js index 3394b26..a7501be 100644 --- a/database.js +++ b/database.js @@ -66,6 +66,25 @@ const createTables = async () => { INDEX idx_player_id (player_id) ) `); + + // Table pour la configuration du bot + await connection.execute(` + CREATE TABLE IF NOT EXISTS bot_config ( + id INT AUTO_INCREMENT PRIMARY KEY, + config_key VARCHAR(50) NOT NULL UNIQUE, + config_value VARCHAR(255) NOT NULL, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_config_key (config_key) + ) + `); + + // Initialiser les valeurs par défaut + await connection.execute(` + INSERT IGNORE INTO bot_config (config_key, config_value) VALUES + ('auto_reboot_enabled', 'true'), + ('ram_threshold_gb', '19'), + ('console_monitor_enabled', 'true') + `); }; const generateLinkCode = async (discordId) => { @@ -177,6 +196,35 @@ const updateLastConnection = async (steamId) => { return { success: true, changes: result.affectedRows }; }; +const getConfig = async (key) => { + const connection = getConnection(); + const [rows] = await connection.execute( + 'SELECT config_value FROM bot_config WHERE config_key = ?', + [key] + ); + return rows.length > 0 ? rows[0].config_value : null; +}; + +const getAllConfig = async () => { + const connection = getConnection(); + const [rows] = await connection.execute( + 'SELECT config_key, config_value FROM bot_config' + ); + const config = {}; + rows.forEach(row => { + config[row.config_key] = row.config_value; + }); + return config; +}; + +const updateConfig = async (key, value) => { + const connection = getConnection(); + await connection.execute( + 'UPDATE bot_config SET config_value = ? WHERE config_key = ?', + [value, key] + ); +}; + module.exports = { initDatabase, getConnection, @@ -190,5 +238,8 @@ module.exports = { getPendingPlayer, hasActiveLinkCodes, cleanExpiredCodes, - updateLastConnection + updateLastConnection, + getConfig, + getAllConfig, + updateConfig }; diff --git a/ramMonitor.js b/ramMonitor.js index 33dcb2d..e8b7b05 100644 --- a/ramMonitor.js +++ b/ramMonitor.js @@ -1,11 +1,11 @@ const axios = require('axios'); +const { getConfig } = require('./database'); let isMonitoring = false; let checkInterval = null; let isRebooting = false; let reconnectCallback = null; // Callback pour resync le WebSocket -const RAM_THRESHOLD_MB = 19 * 1024; // 19 Go en MB const CHECK_INTERVAL_MS = 60 * 1000; // Vérifier toutes les 60 secondes /** @@ -31,12 +31,19 @@ const checkRAMUsage = async () => { console.log(`🔍 [RAM Monitor] Utilisation RAM: ${ramUsedGB} Go / État: ${currentState}`); - // Vérifier si on dépasse le seuil ET que le serveur est en cours d'exécution - if (ramUsedMB > RAM_THRESHOLD_MB && currentState === 'running' && !isRebooting) { - console.log(`⚠️ [RAM Monitor] SEUIL DÉPASSÉ ! ${ramUsedGB} Go > 19 Go`); + // Récupérer la configuration depuis la base de données + const autoRebootEnabled = (await getConfig('auto_reboot_enabled')) === 'true'; + const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19; + const RAM_THRESHOLD_MB = ramThresholdGB * 1024; + + // Vérifier si on dépasse le seuil ET que le serveur est en cours d'exécution ET que l'auto-reboot est activé + if (autoRebootEnabled && ramUsedMB > RAM_THRESHOLD_MB && currentState === 'running' && !isRebooting) { + console.log(`⚠️ [RAM Monitor] SEUIL DÉPASSÉ ! ${ramUsedGB} Go > ${ramThresholdGB} Go`); console.log(`🔄 [RAM Monitor] Déclenchement du redémarrage automatique...`); await rebootServer(); + } else if (!autoRebootEnabled && ramUsedMB > RAM_THRESHOLD_MB) { + console.log(`⚠️ [RAM Monitor] Seuil dépassé mais auto-reboot désactivé (${ramUsedGB} Go > ${ramThresholdGB} Go)`); } return { ramUsedMB, ramUsedGB, currentState }; @@ -137,7 +144,7 @@ const rebootServer = async () => { /** * Démarre la surveillance de la RAM */ -const startRAMMonitoring = (websocketReconnectCallback = null) => { +const startRAMMonitoring = async (websocketReconnectCallback = null) => { if (isMonitoring) { console.log('⚠️ [RAM Monitor] Surveillance déjà active'); return; @@ -145,7 +152,9 @@ const startRAMMonitoring = (websocketReconnectCallback = null) => { reconnectCallback = websocketReconnectCallback; - console.log(`🚀 [RAM Monitor] Démarrage de la surveillance RAM (seuil: 19 Go)`); + const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19; + + console.log(`🚀 [RAM Monitor] Démarrage de la surveillance RAM (seuil: ${ramThresholdGB} Go)`); console.log(`⏱️ [RAM Monitor] Intervalle de vérification: ${CHECK_INTERVAL_MS / 1000}s`); isMonitoring = true; @@ -182,11 +191,12 @@ const stopRAMMonitoring = () => { /** * Obtenir le statut de la surveillance */ -const getMonitoringStatus = () => { +const getMonitoringStatus = async () => { + const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19; return { isMonitoring, isRebooting, - threshold: RAM_THRESHOLD_MB, + threshold: ramThresholdGB * 1024, // En MB checkInterval: CHECK_INTERVAL_MS }; };