This commit is contained in:
Louis Mazin 2026-02-01 13:28:04 +01:00
parent be3cfeb081
commit b49fdb56cf
5 changed files with 121 additions and 9 deletions

22
.env.example Normal file
View File

@ -0,0 +1,22 @@
# Configuration Discord
DISCORD_TOKEN=votre_token_discord
GUILD_ID=votre_guild_id
BRIDGE_CHANNEL_ID=1467491354924814411
# Configuration Pterodactyl
PTERODACTYL_API_URL=https://votre-panel.com
PTERODACTYL_API_TOKEN=votre_token_pterodactyl
PTERODACTYL_SERVER_ID=votre_server_id
# Configuration Palworld
PALWORLD_API_TOKEN=votre_token_palworld_api
# Configuration Base de données
DB_HOST=localhost
DB_PORT=3306
DB_USER=votre_utilisateur
DB_PASSWORD=votre_mot_de_passe
DB_NAME=nom_de_la_base
# Configuration DeepL (optionnel)
DEEPL_TOKEN=votre_token_deepl

View File

@ -1,2 +1,58 @@
# rygain_bot
Bot Discord pour la gestion du serveur Palworld Rygainland.
## Fonctionnalités
### 🔗 Système de liaison Discord-Palworld
- Liaison automatique des comptes Discord et Palworld via code à 6 chiffres
- Gestion automatique des rôles lors de la liaison/déliaison
- Suivi des dernières connexions
### 🌉 Pont Discord-Palworld
- Messages Discord → Palworld (broadcast)
- Messages Palworld → Discord (avec avatar et pseudo Discord pour les comptes liés)
- Salon dédié : `1467491354924814411`
### 📊 Statistiques serveur
- Affichage des joueurs connectés
- Statistiques du serveur Palworld
### 🔧 Commandes disponibles
- `/lier-rygainland` - Lier votre compte Discord à Palworld
- `/delier-rygainland` - Délier votre compte
- `/lier` (Admin) - Lier manuellement un compte
- `/delier` (Admin) - Délier manuellement un compte
- `/server-stats` - Afficher les stats du serveur
- `/trad` - Traduire un message
## Installation
1. Cloner le repo
2. Copier `.env.example` vers `.env`
3. Configurer les variables d'environnement
4. Installer les dépendances : `npm install`
5. Lancer le bot : `node index.js`
## Configuration
Voir le fichier `.env.example` pour la liste complète des variables d'environnement.
Variables importantes :
- `BRIDGE_CHANNEL_ID` - ID du salon Discord pour le pont Palworld (défaut: 1467491354924814411)
- `GUILD_ID` - ID du serveur Discord
- `PALWORLD_API_TOKEN` - Token API REST de Palworld
- `PTERODACTYL_API_TOKEN` - Token API Pterodactyl
## Débogage
Le bot affiche des logs détaillés préfixés par :
- `[BRIDGE]` - Logs du pont Discord-Palworld
- `[CONSOLE]` - Logs du monitoring de la console Pterodactyl
- `[LIER-RYGAINLAND]` - Logs de la commande de liaison
Si le pont ne fonctionne pas, vérifiez :
1. Que le `BRIDGE_CHANNEL_ID` est correct dans `.env`
2. Que le bot a les permissions d'envoyer des messages et créer des webhooks dans le salon
3. Les logs pour voir si les messages sont détectés
4. Que l'API Palworld est accessible (http://play.louismazin.ovh:8212)

View File

@ -339,7 +339,12 @@ const connectWebSocket = async (pterodactylToken, serverId) => {
}
// Transférer le message de chat vers Discord via le bridge
await handlePalworldChat(log);
console.log(`📋 [CONSOLE] Traitement du log pour le bridge...`);
try {
await handlePalworldChat(log);
} catch (bridgeError) {
console.error('❌ [CONSOLE] Erreur lors du transfert vers le bridge:', bridgeError);
}
const linkData = parseLogMessage(log);

View File

@ -64,8 +64,22 @@ client.once('ready', async () => {
console.log('📦 Système de liaison activé');
// Initialiser le pont Palworld-Discord
const bridgeChannelId = '1467491354924814411';
initPalworldBridge(client, bridgeChannelId);
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);
} catch (error) {

View File

@ -3,15 +3,13 @@ const { getUserLink, getAllLinks } = require('./database.js');
let bridgeClient = null;
let bridgeChannelId = null;
let wsInstance = null;
// Initialiser le bridge
const initPalworldBridge = (client, channelId, ws) => {
const initPalworldBridge = (client, channelId) => {
bridgeClient = client;
bridgeChannelId = channelId;
wsInstance = ws;
console.log('🌉 Pont Palworld-Discord initialisé');
console.log(`🌉 Pont Palworld-Discord initialisé (Salon: ${channelId})`);
// Écouter les messages du salon Discord
client.on('messageCreate', async (message) => {
@ -21,18 +19,24 @@ const initPalworldBridge = (client, channelId, ws) => {
// Vérifier que c'est bien le salon du pont
if (message.channelId !== bridgeChannelId) return;
console.log(`📨 [BRIDGE] Message Discord détecté de ${message.author.tag}: ${message.content}`);
try {
// Récupérer le pseudo Palworld lié
const userLink = await getUserLink(message.author.id);
console.log(`🔍 [BRIDGE] Liaison trouvée pour ${message.author.tag}:`, userLink);
if (!userLink) {
// L'utilisateur n'est pas lié
console.log(`⚠️ [BRIDGE] ${message.author.tag} n'est pas lié`);
await message.reply('❌ Vous devez lier votre compte Palworld pour envoyer des messages. Utilisez `/lier-rygainland`');
return;
}
// Envoyer le message vers Palworld via broadcast
console.log(`🚀 [BRIDGE] Envoi vers Palworld: ${userLink.palworld_username}: ${message.content}`);
await sendToPalworld(userLink.palworld_username, message.content);
console.log(`✅ [BRIDGE] Message envoyé avec succès vers Palworld`);
} catch (error) {
console.error('Erreur lors de l\'envoi du message vers Palworld:', error);
@ -84,7 +88,10 @@ const sendToPalworld = async (palworldUsername, content) => {
// Parser les messages de chat Palworld et les envoyer sur Discord
const parsePalworldChatAndSend = async (log) => {
if (!bridgeClient || !bridgeChannelId) return;
if (!bridgeClient || !bridgeChannelId) {
console.log('⚠️ [BRIDGE] Bridge non initialisé, impossible de traiter le message');
return;
}
// Format: [2026-02-01 13:08:02] [CHAT] <Lili Asuna> coucou
const chatRegex = /\[.*?\]\s*\[CHAT\]\s*<(.+?)>\s*(.+)/i;
@ -92,14 +99,22 @@ const parsePalworldChatAndSend = async (log) => {
if (!match) return;
console.log(`📥 [BRIDGE] Message Palworld détecté dans les logs`);
const palworldUsername = match[1].trim();
const messageContent = match[2].trim();
console.log(`📥 [BRIDGE] Palworld: ${palworldUsername}: ${messageContent}`);
// Ignorer les messages de commande !lier
if (messageContent.toLowerCase().startsWith('!lier')) return;
if (messageContent.toLowerCase().startsWith('!lier')) {
console.log(`⏭️ [BRIDGE] Commande !lier ignorée`);
return;
}
try {
// Récupérer le salon
console.log(`🔍 [BRIDGE] Récupération du salon ${bridgeChannelId}...`);
const channel = await bridgeClient.channels.fetch(bridgeChannelId).catch(() => null);
if (!channel) {
console.error('❌ Impossible de trouver le salon du pont');