test
This commit is contained in:
parent
7d7121269a
commit
4499339b29
270
commands/utility/panel.js
Normal file
270
commands/utility/panel.js
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
53
database.js
53
database.js
@ -66,6 +66,25 @@ const createTables = async () => {
|
|||||||
INDEX idx_player_id (player_id)
|
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) => {
|
const generateLinkCode = async (discordId) => {
|
||||||
@ -177,6 +196,35 @@ const updateLastConnection = async (steamId) => {
|
|||||||
return { success: true, changes: result.affectedRows };
|
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 = {
|
module.exports = {
|
||||||
initDatabase,
|
initDatabase,
|
||||||
getConnection,
|
getConnection,
|
||||||
@ -190,5 +238,8 @@ module.exports = {
|
|||||||
getPendingPlayer,
|
getPendingPlayer,
|
||||||
hasActiveLinkCodes,
|
hasActiveLinkCodes,
|
||||||
cleanExpiredCodes,
|
cleanExpiredCodes,
|
||||||
updateLastConnection
|
updateLastConnection,
|
||||||
|
getConfig,
|
||||||
|
getAllConfig,
|
||||||
|
updateConfig
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
const { getConfig } = require('./database');
|
||||||
|
|
||||||
let isMonitoring = false;
|
let isMonitoring = false;
|
||||||
let checkInterval = null;
|
let checkInterval = null;
|
||||||
let isRebooting = false;
|
let isRebooting = false;
|
||||||
let reconnectCallback = null; // Callback pour resync le WebSocket
|
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
|
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}`);
|
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
|
// Récupérer la configuration depuis la base de données
|
||||||
if (ramUsedMB > RAM_THRESHOLD_MB && currentState === 'running' && !isRebooting) {
|
const autoRebootEnabled = (await getConfig('auto_reboot_enabled')) === 'true';
|
||||||
console.log(`⚠️ [RAM Monitor] SEUIL DÉPASSÉ ! ${ramUsedGB} Go > 19 Go`);
|
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...`);
|
console.log(`🔄 [RAM Monitor] Déclenchement du redémarrage automatique...`);
|
||||||
|
|
||||||
await rebootServer();
|
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 };
|
return { ramUsedMB, ramUsedGB, currentState };
|
||||||
@ -137,7 +144,7 @@ const rebootServer = async () => {
|
|||||||
/**
|
/**
|
||||||
* Démarre la surveillance de la RAM
|
* Démarre la surveillance de la RAM
|
||||||
*/
|
*/
|
||||||
const startRAMMonitoring = (websocketReconnectCallback = null) => {
|
const startRAMMonitoring = async (websocketReconnectCallback = null) => {
|
||||||
if (isMonitoring) {
|
if (isMonitoring) {
|
||||||
console.log('⚠️ [RAM Monitor] Surveillance déjà active');
|
console.log('⚠️ [RAM Monitor] Surveillance déjà active');
|
||||||
return;
|
return;
|
||||||
@ -145,7 +152,9 @@ const startRAMMonitoring = (websocketReconnectCallback = null) => {
|
|||||||
|
|
||||||
reconnectCallback = websocketReconnectCallback;
|
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`);
|
console.log(`⏱️ [RAM Monitor] Intervalle de vérification: ${CHECK_INTERVAL_MS / 1000}s`);
|
||||||
|
|
||||||
isMonitoring = true;
|
isMonitoring = true;
|
||||||
@ -182,11 +191,12 @@ const stopRAMMonitoring = () => {
|
|||||||
/**
|
/**
|
||||||
* Obtenir le statut de la surveillance
|
* Obtenir le statut de la surveillance
|
||||||
*/
|
*/
|
||||||
const getMonitoringStatus = () => {
|
const getMonitoringStatus = async () => {
|
||||||
|
const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19;
|
||||||
return {
|
return {
|
||||||
isMonitoring,
|
isMonitoring,
|
||||||
isRebooting,
|
isRebooting,
|
||||||
threshold: RAM_THRESHOLD_MB,
|
threshold: ramThresholdGB * 1024, // En MB
|
||||||
checkInterval: CHECK_INTERVAL_MS
|
checkInterval: CHECK_INTERVAL_MS
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user