const { Events } = require('discord.js'); const db = require('../functions/database/db.js'); const { addXP, isChannelExcluded, getUserXP, getXPMultiplier } = require('../functions/xp/xp.js'); // Fonction pour détecter les bumps (Disboard, etc.) async function detectBump(message) { // Vérifier si le message vient d'un bot de bump (Disboard, etc.) // Disboard a l'ID: 302050872383242240 // On peut aussi détecter par le nom du bot ou le contenu du message const bumpBots = ['302050872383242240']; // Disboard bot ID if (!message.author.bot) return null; if (!bumpBots.includes(message.author.id)) return null; // Détecter les messages de bump (Disboard envoie généralement un embed avec "Bump done!") const content = message.content?.toLowerCase() || ''; const hasEmbed = message.embeds.length > 0; // Vérifier si c'est un message de bump // Disboard envoie généralement un embed avec "Bump done!" ou similaire if (hasEmbed) { const embed = message.embeds[0]; const embedDescription = embed.description?.toLowerCase() || ''; const embedTitle = embed.title?.toLowerCase() || ''; // Mots-clés pour détecter un bump const bumpKeywords = ['bump done', 'bump réussi', 'bump réalisé', 'bump effectué', 'serv bump', 'server bump']; const isBumpMessage = bumpKeywords.some(keyword => embedDescription.includes(keyword) || embedTitle.includes(keyword) || content.includes(keyword) ); if (isBumpMessage) { // Chercher l'utilisateur qui a fait le bump dans les mentions ou dans l'embed // Disboard mentionne généralement l'utilisateur dans l'embed let bumpedUserId = null; // Essayer de trouver l'utilisateur dans les mentions if (message.mentions.users.size > 0) { bumpedUserId = message.mentions.users.first().id; } // Si pas de mention, chercher dans l'embed (format: "User bumped the server!") if (!bumpedUserId && embedDescription) { // Chercher un ID utilisateur dans l'embed (format: <@userId>) const userIdMatch = embedDescription.match(/<@!?(\d+)>/); if (userIdMatch) { bumpedUserId = userIdMatch[1]; } } // Si toujours pas trouvé, chercher dans le footer ou les fields if (!bumpedUserId && embed.footer) { const footerMatch = embed.footer.text?.match(/<@!?(\d+)>/); if (footerMatch) { bumpedUserId = footerMatch[1]; } } return bumpedUserId; } } return null; } // Fonction pour détecter les messages de bienvenue function detectWelcomeMessage(message) { // Ignorer les bots if (message.author.bot) return false; // Mots-clés pour détecter les messages de bienvenue const welcomeKeywords = ['bienvenue', 'welcome', 'bvn', 'salut', 'hey', 'bonjour']; const content = message.content.toLowerCase(); // Vérifier si le message contient un mot de bienvenue const hasWelcomeKeyword = welcomeKeywords.some(keyword => content.includes(keyword)); // Vérifier si le message mentionne un utilisateur (généralement pour accueillir quelqu'un) const hasMention = message.mentions.users.size > 0; // Vérifier si le message est assez court (pour éviter les faux positifs) const isShortMessage = message.content.length < 100; return hasWelcomeKeyword && hasMention && isShortMessage; } module.exports = { name: Events.MessageCreate, async execute(message) { // Ignorer les messages qui ne sont pas dans un canal de texte if (!message.channel.isTextBased() || message.channel.isDMBased()) return; try { // Détecter les bumps (AVANT d'ignorer les bots, car Disboard est un bot) const bumpedUserId = await detectBump(message); if (bumpedUserId) { try { // Enregistrer le bump dans la DB await db.query( 'INSERT INTO bumps (userId, guildId, bumpTime, reminderSent) VALUES (?, ?, ?, ?)', [bumpedUserId, message.guild.id, Date.now(), false] ); // Donner de l'XP pour le bump const member = await message.guild.members.fetch(bumpedUserId).catch(() => null); if (member) { const multiplier = getXPMultiplier(member); // Gain d'XP pour bump : 50-100 XP (plus que les messages normaux) const xpGained = Math.floor(Math.random() * 51) + 50; // 50-100 XP const result = await addXP(bumpedUserId, message.guild.id, xpGained, 'bump', multiplier); if (result && result.levelUp) { const { EmbedBuilder } = require('discord.js'); const { colors } = require('../utils/constants'); const { getXPProgress } = require('../functions/xp/xp.js'); const progress = getXPProgress(result.newXP, result.newLevel); const embed = new EmbedBuilder() .setTitle('🎉 Level Up !') .setDescription(`Félicitations ${member.toString()} ! Tu as atteint le niveau **${result.newLevel}** !`) .setColor(colors.success) .addFields( { name: '📊 XP', value: `${result.newXP} XP`, inline: true }, { name: '⭐ Niveau', value: `${result.newLevel}`, inline: true }, { name: '📈 Progression', value: `${progress.current}/${progress.needed} XP (${progress.percentage}%)`, inline: true } ) .setThumbnail(member.user.displayAvatarURL({ dynamic: true })) .setTimestamp(); await message.channel.send({ embeds: [embed] }); } } // Le reminder sera géré automatiquement par bumpReminder.js (vérifie toutes les minutes) // Pas besoin de setTimeout ici, le système de reminder s'en occupe } catch (err) { console.error('Erreur lors de la détection du bump:', err); } // Ne pas continuer le traitement pour les messages de bump return; } // Ignorer les messages du bot (après la détection des bumps) if (message.author.bot) return; // Vérifier si ce canal est un ticket (logique existante pour les tickets) const [tickets] = await db.query( 'SELECT * FROM tickets WHERE channelId = ? AND status = ?', [message.channel.id, 'Ouvert'] ); if (tickets.length > 0) { // C'est un ticket, traiter la logique des tickets const ticket = tickets[0]; // Enregistrer le message dans la DB const attachments = message.attachments.size > 0 ? message.attachments.map(a => a.url).join(', ') : null; // Troncature des champs pour respecter les limites SQL const maxTag = 100; const maxText = 65535; const safeUserTag = (message.author.tag && message.author.tag.length > maxTag) ? message.author.tag.substring(0, maxTag) : message.author.tag; const safeContent = (message.content && message.content.length > maxText) ? message.content.substring(0, maxText) : message.content; const safeAttachments = (attachments && attachments.length > maxText) ? attachments.substring(0, maxText) : attachments; await db.query( `INSERT INTO ticket_messages (ticketId, messageId, userId, userTag, content, attachments, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)`, [ ticket.ticketId, message.id, message.author.id, safeUserTag, safeContent || null, safeAttachments, message.createdTimestamp ] ); // Ne pas donner d'XP dans les tickets return; } // Système XP : Gagner de l'XP pour les messages (pas dans les tickets) // Vérifier si le salon est exclus de l'XP const excluded = await isChannelExcluded(message.channel.id, message.guild.id); if (!excluded) { // Récupérer les données de l'utilisateur const userXP = await getUserXP(message.author.id, message.guild.id); // Cooldown : 15 secondes entre chaque gain d'XP par message const cooldown = 15 * 1000; // 15 secondes const now = Date.now(); // Convertir lastMessageTime en nombre (peut être string depuis la DB) let lastMessageTime = 0; if (userXP.lastMessageTime) { lastMessageTime = parseInt(userXP.lastMessageTime, 10); // Si lastMessageTime est dans le futur (erreur de données) ou trop ancien (plus de 1 an), on le réinitialise if (lastMessageTime > now || lastMessageTime < (now - 365 * 24 * 60 * 60 * 1000)) { lastMessageTime = 0; } } const timeSinceLastMessage = now - lastMessageTime; // Si lastMessageTime est 0 (premier message) ou si le cooldown est passé if (lastMessageTime === 0 || timeSinceLastMessage >= cooldown) { // Récupérer le membre pour calculer le multiplicateur const member = await message.guild.members.fetch(message.author.id).catch(() => null); const multiplier = member ? getXPMultiplier(member) : 1.0; // Gain d'XP : 15-25 XP aléatoire par message const xpGained = Math.floor(Math.random() * 11) + 15; // 15-25 XP // Ajouter l'XP const result = await addXP(message.author.id, message.guild.id, xpGained, 'message', multiplier); if (result && result.levelUp) { // Niveau supérieur atteint ! const { EmbedBuilder } = require('discord.js'); const { colors } = require('../utils/constants'); const { getXPProgress } = require('../functions/xp/xp.js'); const progress = getXPProgress(result.newXP, result.newLevel); const embed = new EmbedBuilder() .setTitle('🎉 Level Up !') .setDescription(`Félicitations ${message.author.toString()} ! Tu as atteint le niveau **${result.newLevel}** !`) .setColor(colors.success) .addFields( { name: '📊 XP', value: `${result.newXP} XP`, inline: true }, { name: '⭐ Niveau', value: `${result.newLevel}`, inline: true }, { name: '📈 Progression', value: `${progress.current}/${progress.needed} XP (${progress.percentage}%)`, inline: true } ) .setThumbnail(message.author.displayAvatarURL({ dynamic: true })) .setTimestamp(); await message.channel.send({ embeds: [embed] }); } // Mettre à jour lastMessageTime et totalMessages (AVANT le gain d'XP pour éviter les problèmes) await db.query( 'UPDATE user_xp SET lastMessageTime = ?, totalMessages = totalMessages + 1 WHERE userId = ? AND guildId = ?', [now, message.author.id, message.guild.id] ); } else { // Cooldown actif, mettre à jour seulement totalMessages (sans XP) await db.query( 'UPDATE user_xp SET totalMessages = totalMessages + 1 WHERE userId = ? AND guildId = ?', [message.author.id, message.guild.id] ); } } // Détecter les messages de bienvenue if (detectWelcomeMessage(message)) { try { // Réagir avec un emoji de bienvenue await message.react('👋').catch(() => null); await message.react('🎉').catch(() => null); // Donner de l'XP pour avoir dit bienvenue const member = await message.guild.members.fetch(message.author.id).catch(() => null); if (member) { const multiplier = getXPMultiplier(member); // Gain d'XP pour bienvenue : 20-40 XP const xpGained = Math.floor(Math.random() * 21) + 20; // 20-40 XP const result = await addXP(message.author.id, message.guild.id, xpGained, 'welcome', multiplier); if (result && result.levelUp) { const { EmbedBuilder } = require('discord.js'); const { colors } = require('../utils/constants'); const { getXPProgress } = require('../functions/xp/xp.js'); const progress = getXPProgress(result.newXP, result.newLevel); const embed = new EmbedBuilder() .setTitle('🎉 Level Up !') .setDescription(`Félicitations ${message.author.toString()} ! Tu as atteint le niveau **${result.newLevel}** !`) .setColor(colors.success) .addFields( { name: '📊 XP', value: `${result.newXP} XP`, inline: true }, { name: '⭐ Niveau', value: `${result.newLevel}`, inline: true }, { name: '📈 Progression', value: `${progress.current}/${progress.needed} XP (${progress.percentage}%)`, inline: true } ) .setThumbnail(message.author.displayAvatarURL({ dynamic: true })) .setTimestamp(); await message.channel.send({ embeds: [embed] }); } } } catch (err) { console.error('Erreur lors de la détection du message de bienvenue:', err); } } } catch (err) { console.error('Erreur lors de l\'enregistrement du message:', err); } }, };