// ███╗░░░███╗██████╗░███████╗██╗░░██╗ // ████╗░████║██╔══██╗██╔════╝╚██╗██╔╝ // ██╔████╔██║██████╔╝█████╗░░░╚███╔╝░ // ██║╚██╔╝██║██╔══██╗██╔══╝░░░██╔██╗░ // ██║░╚═╝░██║██║░░██║███████╗██╔╝╚██╗ // ╚═╝░░░░░╚═╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝ const Discord = require("discord.js") const intents = new Discord.IntentsBitField(3276799) const bot = new Discord.Client({intents, partials: [Discord.Partials.Message]}) const loadComands = require("./Loaders/loadCommands") const loadEvents = require("./Loaders/loadEvents") const config = require("./config") const { EmbedBuilder, time } = require("discord.js"); bot.commands = new Discord.Collection() bot.snipe = new Map() bot.login(config.token) loadComands(bot) loadEvents(bot) bot.color = "#0066ff" bot.bans = new Map(); // Map pour stocker les bans (ID utilisateur → { reason, date }) bot.function = { createId: require("./Fonctions/createId"), calculXp: require("./Fonctions/calculXp"), generateCaptcha: require("./Fonctions/generateCaptcha") } const voiceTimes = new Map(); // Pour stocker l'heure d'entrée en vocal bot.on('voiceStateUpdate', (oldState, newState) => { const logChannelId = '1361356351158354030'; // Ton salon de logs vocaux const user = newState.member || oldState.member; if (!user || user.user.bot) return; const logChannel = user.guild.channels.cache.get(logChannelId); if (!logChannel) return; const tag = user.user.tag; const avatarURL = user.user.displayAvatarURL({ dynamic: true }); const userMention = `<@${user.id}>`; let embed; let color = null; let emoji = null; let title = null; let description = null; // Connexion if (!oldState.channel && newState.channel) { emoji = '🔊'; title = 'Connexion vocale'; description = `**${userMention}** a rejoint le salon : \`${newState.channel.name}\``; color = 0x3BA55D; voiceTimes.set(user.id, Date.now()); // Stocke l'heure d'entrée } // Déconnexion else if (oldState.channel && !newState.channel) { const joinTime = voiceTimes.get(user.id); const duration = joinTime ? formatDuration(Date.now() - joinTime) : 'Inconnu'; emoji = '🔇'; title = 'Déconnexion vocale'; description = `**${userMention}** a quitté le salon : \`${oldState.channel.name}\`\n**Durée passée :** ${duration}`; color = 0xED4245; voiceTimes.delete(user.id); } // Changement de salon (déplacement forcé ou volontaire) else if (oldState.channelId !== newState.channelId) { const joinTime = voiceTimes.get(user.id); const duration = joinTime ? formatDuration(Date.now() - joinTime) : 'Inconnu'; // Update du temps de début dans le nouveau salon voiceTimes.set(user.id, Date.now()); emoji = '🔁'; title = 'Changement de salon vocal'; description = `**${userMention}** est passé de \`${oldState.channel.name}\` à \`${newState.channel.name}\`\n**Durée passée :** ${duration}`; color = 0xFAA61A; // Détection du déplacement forcé (si un administrateur ou modérateur déplace l'utilisateur) if (oldState.channelId && !newState.channelId) { description += `\nCe déplacement peut avoir été forcé.`; } } // Mute / Unmute micro else if (oldState.selfMute !== newState.selfMute) { emoji = newState.selfMute ? '🎙️❌' : '🎙️✅'; title = newState.selfMute ? 'Micro désactivé' : 'Micro activé'; description = `**${userMention}** a ${newState.selfMute ? 'coupé' : 'réactivé'} son micro.`; color = newState.selfMute ? 0x808080 : 0x57F287; } // Deaf / Undeaf (casque) else if (oldState.selfDeaf !== newState.selfDeaf) { emoji = newState.selfDeaf ? '🎧❌' : '🎧✅'; title = newState.selfDeaf ? 'Casque désactivé' : 'Casque activé'; description = `**${userMention}** a ${newState.selfDeaf ? 'désactivé' : 'activé'} le son.`; color = newState.selfDeaf ? 0x808080 : 0x57F287; } // Stream ON / OFF else if (oldState.streaming !== newState.streaming) { emoji = newState.streaming ? '📺' : '📺❌'; title = newState.streaming ? 'Stream activé' : 'Stream désactivé'; description = `**${userMention}** a ${newState.streaming ? 'lancé' : 'arrêté'} un stream.`; color = newState.streaming ? 0x0099ff : 0xED4245; } // Caméra ON / OFF else if (oldState.selfVideo !== newState.selfVideo) { emoji = newState.selfVideo ? '📷' : '📷❌'; title = newState.selfVideo ? 'Caméra activée' : 'Caméra désactivée'; description = `**${userMention}** a ${newState.selfVideo ? 'activé' : 'désactivé'} sa caméra.`; color = newState.selfVideo ? 0x0099ff : 0xED4245; } // Si aucune action détectée if (!title || !description) return; embed = new EmbedBuilder() .setAuthor({ name: tag, iconURL: avatarURL }) .setTitle(`${emoji} ${title}`) .setDescription(description) .setColor(color) .setThumbnail(avatarURL) .setFooter({ text: `ID utilisateur : ${user.id}`, iconURL: avatarURL }) .setTimestamp(); logChannel.send({ embeds: [embed] }); }); // Fonction pour formater la durée en format HH:MM:SS function formatDuration(duration) { const seconds = Math.floor((duration / 1000) % 60); const minutes = Math.floor((duration / 1000 / 60) % 60); const hours = Math.floor((duration / 1000 / 60 / 60) % 24); return `${hours > 9 ? hours : '0' + hours}:${minutes > 9 ? minutes : '0' + minutes}:${seconds > 9 ? seconds : '0' + seconds}`; } bot.on('messageCreate', message => { // Vérifier si le message contient un mot blacklist if(message.content.match(/(tg|connard|FDP|salope|pute|connasse|negro|negre|Petasse|Bouffon|Bouffonne|Bougnoul|Batard|Tana)/i)) { // Vérifier si le membre utilise un mot blacklist a un rôle à ignorer if(message.member.roles.cache.has("1360966139072483512") || message.member.roles.cache.has("1360966139072483511")){ return; }else{ // Suppression du message message.delete(); // Embed avertissant l'utilisation d'un mot blacklist const Embedblacklist = new Discord.EmbedBuilder() .setColor("#0C15CF") .setTitle("Système de protection") .setThumbnail(bot.user.displayAvatarURL({dynamic: true})) .setDescription(`Tu utilises des mots interdit ! \n\n Ton message à été envoyé à un modérateur pour vérification ! \n\n Auteur du message : ${message.author}`) message.channel.send({embeds: [Embedblacklist]}) // Envoie d'un embed dans un salon avec contenu du message const logsBlacklist = new Discord.EmbedBuilder() .setTitle(`Un Membre vient de faire usage d'un mot interdit.`) .setThumbnail(bot.user.displayAvatarURL({dynamic: true})) .setColor("#0C15CF") .setDescription(`**Le Membre : ** ${message.author} \n\n **Contenu du message :** ${message.content}`) .setFooter({ text: 'Système de Protection', iconURL: 'https://www.terre.defense.gouv.fr/sites/default/files/portail-federateur/protection%20des%20donn%C3%A9es%20perso.jpg' }) .setTimestamp(); // Salon ou envoyé le message logs bot.channels.cache.get('1361356933935665173').send({ embeds: [logsBlacklist] }) }; } }); bot.on("messageCreate", async (message) => { if (message.author.bot) return; // Ignore les messages des bots const linkRegex = /(https?:\/\/|www\.|discord\.gg\/)/i; const whitelistKeywords = ["medal", "forms", "docs", "tenor", "tiktok", "twitch", "youtube","kick"]; if (linkRegex.test(message.content)) { // Autoriser si le message contient un mot-clé whitelisté const lowerContent = message.content.toLowerCase(); const isWhitelisted = whitelistKeywords.some(keyword => lowerContent.includes(keyword)); if (isWhitelisted) return; // Vérifier si l'utilisateur a un rôle autorisé à envoyer des liens const allowedRoles = ["1361290706584600710", "1361290764105289964"]; if (message.member.roles.cache.some(role => allowedRoles.includes(role.id))) return; // Supprimer le message await message.delete(); // Embed d'avertissement const warnEmbed = new EmbedBuilder() .setColor("#ff0000") .setTitle("🚨 Anti-Link Activé") .setDescription(`⚠️ ${message.author}, les liens ne sont pas autorisés sur ce serveur !`) .setFooter({ text: "Système de Protection", iconURL: bot.user.displayAvatarURL({ dynamic: true }) }); message.channel.send({ embeds: [warnEmbed] }); // Log dans un salon spécifique const logEmbed = new EmbedBuilder() .setColor("#ff0000") .setTitle("🔍 Détection de Lien") .setDescription(`👤 **Auteur** : ${message.author}\n📜 **Message** : ${message.content}`) .setTimestamp(); const logChannel = bot.channels.cache.get("1361356967548944408"); if (logChannel) logChannel.send({ embeds: [logEmbed] }); } }); bot.on("guildMemberAdd", async (member) => { // const { EmbedBuilder, time } = require("discord.js"); const roleId = "1360966139039060093"; // 🎭 Rôle à attribuer const welcomeChannelId = "1360966139806748743"; // 👋 Salon de bienvenue const logsChannelId = "1361357003330425032"; // 📋 Salon de logs (à remplacer) const role = member.guild.roles.cache.get(roleId); const welcomeChannel = member.guild.channels.cache.get(welcomeChannelId); const logsChannel = member.guild.channels.cache.get(logsChannelId); if (!role) return console.log("❌ Le rôle spécifié n'existe pas !"); try { await member.roles.add(role); // 🎉 Embed de bienvenue (classique) const welcomeEmbed = new EmbedBuilder() .setColor("#1f4ec5") .setAuthor({ name: `Bienvenue sur ${member.guild.name} !`, iconURL: member.user.displayAvatarURL({ dynamic: true }) }) .setDescription(`**${member.user}\n N'hésite pas à visiter les salons <#1360966139806748748> et <#1360966139806748749> !**`) .setImage("https://scontent.fmpl1-1.fna.fbcdn.net/v/t1.6435-9/68426184_1500341703439003_6125285510614089728_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=127cfc&_nc_ohc=PpkhuGT3c4UQ7kNvwER0LEM&_nc_oc=Adlmmm2uJqlJNTY3FqpUMl9EZXUp9ufSKtQfayGbf6xIEH1E2LnVI91OfYdDCCtq_EIsqD62vOfgcQyrAEsz_Oph&_nc_zt=23&_nc_ht=scontent.fmpl1-1.fna&_nc_gid=WiBO4M-tyoqks2LISaw95A&oh=00_AfFz8lBnijJJdR6yYAHs0iw9Wto6-UZviBVcrOIfvTv99w&oe=6824A4B1") .setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 4096 })) .setFooter({ text: `${member.guild.members.cache.size} Membres`, iconURL: bot.user.displayAvatarURL({ dynamic: true }) }); if (welcomeChannel) { welcomeChannel.send({ embeds: [welcomeEmbed] }).catch(console.error); } // 🕵️ Infos temps réel const createdTimestamp = Math.floor(member.user.createdTimestamp / 1000); const joinedTimestamp = Math.floor(member.joinedTimestamp / 1000); const isNewAccount = Date.now() - member.user.createdTimestamp < 1000 * 60 * 60 * 24; // moins de 24h const logEmbed = new EmbedBuilder() .setColor(isNewAccount ? "Red" : "Green") .setTitle("📥 Nouveau membre détecté") .setThumbnail(member.user.displayAvatarURL({ dynamic: true })) .addFields( { name: "👤 Nom d'utilisateur", value: `${member.user.tag} (<@${member.id}>)`, inline: false }, { name: "🆔 ID", value: member.id, inline: true }, { name: "🤖 Bot ?", value: member.user.bot ? "✅ Oui" : "❌ Non", inline: true }, { name: "🎭 Rôle attribué", value: `<@&${roleId}>`, inline: true }, { name: "📅 Créé le", value: ` ()`, inline: true }, { name: "📌 A rejoint", value: ` ()`, inline: true }, { name: "⚠️ Anti-multi", value: isNewAccount ? "🔴 Compte créé il y a moins de 24h" : "🟢 OK", inline: true }, { name: "🔢 Discriminator", value: `#${member.user.discriminator}`, inline: true }, { name: "🎫 Avatar", value: `[Lien](${member.user.displayAvatarURL({ dynamic: true, size: 1024 })})`, inline: true }, { name: "🎉 Nitro ?", value: member.user.avatar?.startsWith("a_") ? "✅ Oui (GIF)" : "❌ Non", inline: true }, { name: "🔒 Niveau de sécurité du serveur", value: `${member.guild.verificationLevel}`, inline: true }, { name: "🧮 Membres totaux", value: `${member.guild.memberCount}`, inline: true }, { name: "🏠 Serveur", value: `${member.guild.name} (${member.guild.id})`, inline: false }, ) .setTimestamp() .setFooter({ text: `Suivi automatique des arrivées`, iconURL: bot.user.displayAvatarURL({ dynamic: true }) }); if (logsChannel) { logsChannel.send({ embeds: [logEmbed] }).catch(console.error); } } catch (error) { console.error("❌ Erreur lors de l'ajout du rôle :", error); } console.log() });