From 075cdf66bd2f524a6b47ec9978c5657da61d49de Mon Sep 17 00:00:00 2001 From: Louis Mazin Date: Wed, 15 Apr 2026 23:55:13 +0200 Subject: [PATCH] edit --- index.js | 56 +--------- src/pterodactyl/displayer.js | 194 +++++++++++++++++++++++++++-------- 2 files changed, 153 insertions(+), 97 deletions(-) diff --git a/index.js b/index.js index 98d0da8..884587e 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,10 @@ require('dotenv').config(); const fs = require('node:fs'); -const deepl = require('deepl-node'); const path = require('node:path'); const deploy = require('./src/discord/deploy_command.js') const update = require('./src/pterodactyl/displayer.js'); const clean = require('./src/pterodactyl/cleaner.js'); const { Client, GatewayIntentBits, Collection, Events, Partials } = require('discord.js'); -const { initDatabase, createTables, cleanExpiredCodes } = require('./src/core/database.js'); -const { startConsoleMonitoring, forceWebSocketReconnect } = require('./src/monitoring/consoleMonitor.js'); -const { initPalworldBridge } = require('./src/bridge/palworld-bridge.js'); -const { startRAMMonitoring } = require('./src/monitoring/ramMonitor.js'); const client = new Client({ intents: [ @@ -27,9 +22,7 @@ const headers = { "Content-Type": "application/json", "Authorization": "Bearer " + process.env.PTERODACTYL_API_TOKEN }; -const numbers=["๐ŸŽ","๐Ÿ","๐Ÿ","๐Ÿ‘","๐Ÿ’","๐Ÿ“","๐Ÿ”","๐Ÿ•","๐Ÿ–","๐Ÿ—","๐Ÿ๐ŸŽ","๐Ÿ๐Ÿ","๐Ÿ๐Ÿ","๐Ÿ๐Ÿ‘","๐Ÿ๐Ÿ–","๐Ÿ๐Ÿ•","๐Ÿ๐Ÿ–","๐Ÿ๐Ÿ—","๐Ÿ๐ŸŽ","๐Ÿ๐Ÿ","๐Ÿ๐Ÿ","๐Ÿ๐Ÿ‘","๐Ÿ๐Ÿ’","๐Ÿ๐Ÿ“","๐Ÿ๐Ÿ”","๐Ÿ๐Ÿ•","๐Ÿ๐Ÿ–","๐Ÿ๐Ÿ—","๐Ÿ‘๐ŸŽ","๐Ÿ‘๐Ÿ","๐Ÿ‘๐Ÿ"]; -const translator = process.env.DEEPL_TOKEN ? new deepl.Translator(process.env.DEEPL_TOKEN) : null; client.commands = new Collection(); const foldersPath = path.join(__dirname, 'commands'); @@ -51,48 +44,9 @@ for (const folder of commandFolders) { } client.once('ready', async () => { - client.user.setPresence({ activities: [{ name: 'Rygain', type: 'WATCHING' }], status: 'online' }); + client.user.setPresence({ activities: [{ name: 'ta mรจre.', type: 'WATCHING' }], status: 'online' }); console.log('Bot started !'); - try { - await initDatabase(); - await createTables(); - - // Nettoyer les codes expirรฉs au dรฉmarrage - await cleanExpiredCodes(); - console.log('๐Ÿงน Codes expirรฉs nettoyรฉs'); - - console.log('๐Ÿ“ฆ Systรจme de liaison activรฉ'); - - // Initialiser le pont Palworld-Discord - const bridgeChannelId = process.env.BRIDGE_CHANNEL_ID || '1467491354924814411'; - console.log(`๐Ÿ”ง Configuration du pont: Salon ${bridgeChannelId}`); - - // Vรฉrifier que le salon existe - try { - const bridgeChannel = await client.channels.fetch(bridgeChannelId); - if (bridgeChannel) { - console.log(`โœ… Salon du pont trouvรฉ: #${bridgeChannel.name}`); - initPalworldBridge(client, bridgeChannelId); - } else { - console.error(`โŒ Salon du pont introuvable (ID: ${bridgeChannelId})`); - } - } catch (channelError) { - console.error(`โŒ Erreur lors de la rรฉcupรฉration du salon du pont:`, channelError.message); - console.error(`โš ๏ธ Le pont Discord-Palworld est dรฉsactivรฉ`); - } - - startConsoleMonitoring(client, process.env.PTERODACTYL_API_TOKEN); - - // Dรฉmarrer la surveillance RAM avec callback de reconnexion WebSocket - startRAMMonitoring(forceWebSocketReconnect); - console.log('โœ… Surveillance RAM activรฉe (seuil: 19 Go)'); - } catch (error) { - console.error('โš ๏ธ Erreur lors de l\'initialisation de la base de donnรฉes'); - console.error('โš ๏ธ Le systรจme de liaison est dรฉsactivรฉ'); - console.error('โš ๏ธ Les autres fonctionnalitรฉs du bot restent actives'); - } - deploy(process.env.DISCORD_TOKEN); clean(client); }); @@ -116,11 +70,7 @@ client.on(Events.InteractionCreate, async interaction => { } try { - if (interaction.commandName === 'server-stats') { - await command.execute(interaction, process.env.PALWORLD_API_TOKEN); - } else if (interaction.commandName === 'trad') { - await command.execute(interaction, translator); - } else if (interaction.commandName === 'start-server' || interaction.commandName === 'reboot-server') { + if (interaction.commandName === 'start-server' || interaction.commandName === 'reboot-server') { await command.execute(interaction, headers); } else { await command.execute(interaction); @@ -137,4 +87,4 @@ client.on(Events.InteractionCreate, async interaction => { client.login(process.env.DISCORD_TOKEN); -setInterval(()=>{update(headers,numbers,client,process.env.PALWORLD_API_TOKEN)}, 300000); \ No newline at end of file +setInterval(()=>{update(headers,numbers,client,process.env.PALWORLD_API_TOKEN)}, 120000); \ No newline at end of file diff --git a/src/pterodactyl/displayer.js b/src/pterodactyl/displayer.js index 056fea7..70d7c5e 100644 --- a/src/pterodactyl/displayer.js +++ b/src/pterodactyl/displayer.js @@ -1,49 +1,155 @@ -const axios = require('axios'); +const DEFAULT_UPDATE_TEXT = "Panneau Minecraft"; +const getMinecraftStatus = async () => { + const address = process.env.MINECRAFT_SERVER_ADDRESS; -const update = async (headers,numbers,client,token) => { - try { - let state = "๐Ÿ”ด"; - let players = "0"; - let config = { - method: 'get', - maxBodyLength: Infinity, - url: 'http://play.louismazin.ovh:8212/v1/api/metrics', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Authorization': `Basic ${token}` - } - }; - - axios(config) - .then((response) => { - players = response.data["currentplayernum"]; - }) - .catch((error) => { - console.log("Erreur lors de l'appel ร  l'api palworld (serveur injoignable)"); - players = "0"; - }); + if (!address) { + throw new Error("MINECRAFT_SERVER_ADDRESS manquant dans l'environnement"); + } - const state_reponse = await fetch("https://panel.louismazin.ovh/api/client/servers/ae4a628f/resources", { method : "GET", headers }); - const state_data = await state_reponse.json(); - if(state_data["attributes"]["current_state"] === "running"){ - state = "๐ŸŸข"; - }else{ - state = "๐Ÿ”ด"; - } - const title = "๐’๐ž๐ซ๐ฏ๐ž๐ซ : "+state+" ๐‰๐จ๐ฎ๐ž๐ฎ๐ซ๐ฌ : "+numbers[parseInt(players)]; - client.channels.fetch(1263481798667796623n) - .then(channel => { - if(state !== channel.name.split(" ")[2] || numbers[parseInt(players)] !== channel.name.split(" ")[5]){ - channel.setName(title); - console.log("Channel's name changed for : "+title); - } - }) - .catch(error => {console.log("Bot : error :"+error);}); - - } catch (error) { - console.log("Bot : "+error); - } + const response = await fetch(`https://api.mcsrvstat.us/3/${encodeURIComponent(address)}`); + + if (!response.ok) { + throw new Error(`Impossible de recuperer le statut Minecraft (HTTP ${response.status})`); + } + + const data = await response.json(); + const online = Boolean(data.online); + const playersOnline = data.players?.online ?? 0; + const playersMax = data.players?.max ?? 0; + const version = data.version || "Inconnue"; + const motd = Array.isArray(data.motd?.clean) ? data.motd.clean.join("\n") : ""; + const playerList = Array.isArray(data.players?.list) ? data.players.list : []; + + return { + address, + online, + playersOnline, + playersMax, + version, + motd, + playerList + }; }; + +const getPterodactylState = async (headers) => { + const panelUrl = process.env.PTERODACTYL_PANEL_URL; + const serverId = process.env.PTERODACTYL_SERVER_ID; + + if (!headers || !panelUrl || !serverId) { + return "inconnu"; + } + + try { + const stateResponse = await fetch(`${panelUrl}/api/client/servers/${serverId}/resources`, { + method: "GET", + headers + }); + + if (!stateResponse.ok) { + return "inconnu"; + } + + const stateData = await stateResponse.json(); + return stateData?.attributes?.current_state || "inconnu"; + } catch (error) { + return "inconnu"; + } +}; + +const buildPanelEmbed = (status, panelState) => { + const stateText = status.online ? "๐ŸŸข En ligne" : "๐Ÿ”ด Hors ligne"; + const playersText = `${status.playersOnline}/${status.playersMax}`; + const playersListText = status.playerList.length > 0 ? status.playerList.join(", ") : "Aucun joueur connecte"; + + return { + color: status.online ? 0x57F287 : 0xED4245, + title: `Serveur Minecraft - ${stateText}`, + description: status.motd || DEFAULT_UPDATE_TEXT, + fields: [ + { + name: "Adresse", + value: status.address, + inline: true + }, + { + name: "Joueurs", + value: playersText, + inline: true + }, + { + name: "Version", + value: status.version, + inline: true + }, + { + name: "Etat du panel", + value: panelState, + inline: true + }, + { + name: "Joueurs connectes", + value: playersListText, + inline: false + } + ], + timestamp: new Date().toISOString(), + footer: { + text: "Actualisation automatique" + } + }; +}; + +const resolvePanelMessage = async (client, channelId, messageId) => { + const channel = await client.channels.fetch(channelId); + if (!channel || !channel.isTextBased()) { + throw new Error(`Salon non textuel ou introuvable: ${channelId}`); + } + + if (messageId) { + try { + const message = await channel.messages.fetch(messageId); + return { channel, message }; + } catch (error) { + console.log(`โš ๏ธ Message ${messageId} introuvable. Creation d'un nouveau panneau.`); + } + } + + const newMessage = await channel.send({ + content: "Initialisation du panneau Minecraft..." + }); + + console.log(`โœ… Nouveau message panneau cree: ID ${newMessage.id}`); + console.log(`๐Ÿ‘‰ Ajoute DISPLAYER_MESSAGE_ID=${newMessage.id} dans ton .env pour le lier de facon persistante.`); + + return { channel, message: newMessage }; +}; + +const update = async (headers, numbers, client, token) => { + try { + const channelId = process.env.DISPLAYER_CHANNEL_ID; + const messageId = process.env.DISPLAYER_MESSAGE_ID; + + if (!channelId) { + console.log("โš ๏ธ DISPLAYER_CHANNEL_ID non defini, mise a jour panneau ignoree."); + return; + } + + const status = await getMinecraftStatus(); + const panelState = await getPterodactylState(headers); + const embed = buildPanelEmbed(status, panelState); + + const { message } = await resolvePanelMessage(client, channelId, messageId); + + await message.edit({ + content: "", + embeds: [embed] + }); + + console.log(`๐Ÿ“Š Panneau Minecraft mis a jour (${status.playersOnline}/${status.playersMax})`); + } catch (error) { + console.log(`โŒ Erreur displayer: ${error.message}`); + } +}; + module.exports = update; \ No newline at end of file