goofybot/src/pterodactyl/displayer.js
2026-04-16 00:24:57 +02:00

122 lines
3.9 KiB
JavaScript

const DEFAULT_UPDATE_TEXT = "Panneau Minecraft";
const getMinecraftStatus = async () => {
const address = process.env.MINECRAFT_SERVER_ADDRESS;
if (!address) {
throw new Error("MINECRAFT_SERVER_ADDRESS manquant dans l'environnement");
}
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";
const message = new EmbedBuilder()
.setColor('#0099ff')
.setDescription('# Informations sur le Serveur \n\n## :wireless: IP :\n### goofymon.louismazin.ovh\n\n## :repeat: État :\n### '+stateText+'\n\n## :busts_in_silhouette: Joueurs :\n### '+playersText+'\n\n## :video_game: Version :\n### '+status.version+'\n\n## :speech_balloon: MOTD :\n### '+status.motd+'\n\n## :bust_in_silhouette: Liste des joueurs :\n### '+playersListText);
return message;
};
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, client) => {
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;