This commit is contained in:
Louis Mazin 2026-04-15 23:55:13 +02:00
parent 986191c273
commit 075cdf66bd
2 changed files with 153 additions and 97 deletions

View File

@ -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);
setInterval(()=>{update(headers,numbers,client,process.env.PALWORLD_API_TOKEN)}, 120000);

View File

@ -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;