dellusofbot
Version:
💋💖crée ton propre bot discord simplement en js 💖🤍 - package de retour en développement
1,047 lines (932 loc) • 32.9 kB
JavaScript
const Discord = require('discord.js');
const path = require('path');
const fs = require('fs').promises;
const axios = require('axios');
class Dellubot {
constructor() {
this.client = new Discord.Client();
let token;
this.serverName = "";
this.token = token;
this.rootDir = process.cwd();
this.commandsDir = path.resolve(this.rootDir, 'commands');
this.initialize();
}
setActivity(status, type, text) {
const validStatuses = ['online', 'offline', 'idle', 'dnd'];
const isValidStatus = validStatuses.includes(status);
if (!isValidStatus) {
console.log(`Invalid status ${status}. Must be one of ${validStatuses.join(', ')}`);
return;
}
const validActivityTypes = ['PLAYING', 'WATCHING', 'LISTENING', 'STREAMING', 'CUSTOM_STATUS'];
const isValidActivityType = validActivityTypes.includes(type);
if (!isValidActivityType) {
console.log(`Invalid activity type ${type}. Must be one of ${validActivityTypes.join(', ')}`);
return;
}
if (type === 'CUSTOM_STATUS' && text.trim().length === 0) {
console.log('Custom status text cannot be empty');
return;
}
this.client.on('ready', () => {
const activity = type === 'CUSTOM_STATUS' ? { name: text } : { type: type, name: text };
this.client.user.setPresence({
status: status,
activity: activity,
});
console.log(`Set status to ${status} and activity to ${type} ${text}`);
});
}
BotSendMsg(channel, message) {
channel.send(message);
}
// Méthode pour gérer les messages
handleMessages(callback) {
this.bot.on('message', message => {
callback(message);
});
}
CommandsStart(trigger, commands) {
this.client.on('message', message => {
if (!message.content.startsWith(trigger)) return;
const commandBody = message.content.slice(trigger.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (commands[command]) {
commands[command](message);
}
});
}
botToken(token) {
this.token = token;
this.client
.login(this.token)
.then(() => console.log('Bot connected'))
.catch(error => console.log(error));
}
initialize() {
this.client.on('ready', () => {
console.log(`Logged in as ${this.client.user.tag}`);
});
}
botPrefix(prefix) {
this.prefix = prefix;
}
botMess() {
this.client.on('message', message => {
// Vérifie si le message commence par le préfixe défini
if (!message.content.startsWith(this.prefix) || message.author.bot) return;
const args = message.content.slice(this.prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
try {
const commandPath = path.join(this.commandsDir, `${command}.js`);
if (require.resolve(commandPath)) {
const commandHandler = require(commandPath);
commandHandler.execute(message, args);
}
} catch (error) {
// Commande non trouvée, on ignore silencieusement
return;
}
});
}
async createCommandHandler(commandName) {
// Vérifie si le répertoire des commandes existe, sinon le crée
try {
await fs.access(this.commandsDir);
} catch (error) {
if (error.code === 'ENOENT') {
await fs.mkdir(this.commandsDir);
console.log(`Created commands directory at ${this.commandsDir}`);
} else {
throw error;
}
}
}
createCommandHandler(commandName) {
// Vérifie si le répertoire des commandes existe, sinon le crée
try {
fs.access(this.commandsDir);
} catch (error) {
if (error.code === 'ENOENT') {
fs.mkdir(this.commandsDir);
console.log(`Created commands directory at ${this.commandsDir}`);
} else {
throw error;
}
}
const commandHandlerPath = path.join(this.commandsDir, `${commandName}.js`);
const commandHandlerCode = `module.exports = {
name: '${commandName}',
description: 'Description de la commande ${commandName}',
execute(message, args) {
},
};`;
fs.writeFile(commandHandlerPath, commandHandlerCode, 'utf-8');
console.log(`Created command handler for ${commandName} at ${commandHandlerPath}`);
}
BotWs() {
this.latency = Date.now() - this.client.ws.ping
return this.latency;
}
createEmbed(title, description, color, image) {
const embed = new Discord.MessageEmbed()
.setColor(color)
.setTitle(title)
.setDescription(description);
if (image) {
embed.setImage(image);
}
return embed;
}
MultiAct(activities, time, status = 'online') {
if (!['online', 'idle', 'dnd'].includes(status)) {
console.log('Status invalide. Utilisation de "online" par défaut');
status = 'online';
}
setInterval(() => {
const activity = activities[Math.floor(Math.random() * activities.length)];
this.client.user.setPresence({
status: status,
activity: activity
});
}, time);
}
NbCmd() {
return this.commands.length;
}
// Ajoute une fonction pour ajouter une commande
addCounterCmd(command) {
if (Array.isArray(this.commands)) {
this.commands.push(command);
} else {
this.commands = [command];
}
}
countServers() {
const numServers = this.client.guilds.cache.size; // obtenir le nombre de serveurs
console.log(`Le bot est pr�sent sur ${numServers} serveurs.`); // afficher le nombre de serveurs dans la console
}
randomMess(messages) {
const randomIndex = Math.floor(Math.random() * messages.length);
return messages[randomIndex];
}
BotSay(message) {
const args = message.content.slice(5).trim();
// Envoyer le message dans le m�me canal
message.channel.send(args);
}
YourAvatar(message) {
return message.author.avatarURL();
}
async BotPp(channel) {
// R�cup�rer l'URL de la photo de profil du bot
const botAvatarUrl = await this.client.user.displayAvatarURL();
// Envoyer un message avec la photo de profil du bot dans le channel
await channel.send({
files: [botAvatarUrl],
embed: {
image: {
url: botAvatarUrl,
},
},
});
}
async serveurMembres(message) {
const guild = message.guild;
if (!guild) {
message.reply("Impossible d'obtenir le serveur.");
return;
}
const fetchResult = await guild.members.fetch();
const nbMembres = fetchResult.size;
message.reply(`Le serveur contient ${nbMembres} membres.`);
}
async getBotOwner() {
const application = await this.client.fetchApplication();
const owner = await this.client.users.fetch(application.owner.id);
return `${owner.username}#${owner.discriminator}`;
}
async ajouterReactions(message, reactions) {
try {
for (let reaction of reactions) {
await message.react(reaction);
}
} catch (error) {
console.error(`Erreur lors de l'ajout des r�actions : ${error}`);
}
}
write(channel) {
channel.startTyping();
setTimeout(() => {
channel.stopTyping();
}, 20000); // Stoppe l'�criture apr�s 20 secondes
}
BotCreationAnnée() {
const creationDate = this.client.user.createdAt;
return creationDate.getFullYear();
}
async afficherListeEmojis(message) {
const guild = message.guild;
const emojis = guild.emojis.cache.array();
const embed = {
color: Math.floor(Math.random() * 16777215), // Couleur random
title: `Liste des emojis de ${guild.name}`,
description: emojis.join(' '),
};
await message.channel.send({ embed });
}
MentionUser(message) {
const user = message.mentions.users.first();
if (user) {
return user;
} else {
return null;
}
}
BotServerList(channel) {
let serverList = "";
this.client.guilds.cache.forEach((guild) => {
serverList += `${guild.name} (${guild.id})\n`;
});
channel.send(serverList);
}
async BotLeaveByID(serverID, userID) {
// V�rifier si l'utilisateur est autoris� � utiliser cette fonction
if (userID !== userID) {
throw new Error('la personne qui a utiliser cette commande sur le serveur nest pas autorisé a l/excutée❗');
}
// R�cup�rer l'objet du serveur par son ID
const server = this.client.guilds.cache.get(serverID);
// V�rifier si le bot est pr�sent sur ce serveur
if (!server) {
throw new Error('Le bot n\'est pas present sur ce serveur.');
}
// Faire quitter le bot du serveur
await server.leave();
}
async createTempVoc(message, channelName) {
// R�cup�rer la cat�gorie parente
const parentCategory = message.channel.parent;
// Cr�er le salon vocal temporaire
const createdChannel = await message.guild.channels.create(channelName, {
type: 'voice',
parent: parentCategory,
permissionOverwrites: [
{
id: message.guild.roles.everyone,
deny: [Discord.Permissions.FLAGS.VIEW_CHANNEL],
},
{
id: message.author.id,
allow: [Discord.Permissions.FLAGS.VIEW_CHANNEL],
},
],
});
// D�placer l'utilisateur dans le salon vocal temporaire
await message.member.voice.setChannel(createdChannel);
}
async ServerCreateInvit(message) {
try {
const invite = await message.channel.createInvite({ maxAge: 86400, maxUses: 1 });
message.channel.send(`Voici le lien pour rejoindre le serveur : ${invite.url}`);
} catch (error) {
console.error(`Impossible de créer une invitation : ${error}`);
message.channel.send(`Désolé, une erreur est survenue lors de la création de l'invitation.`);
}
}
async MessageEdit(channel, time, message, newText) {
// Envoi du message initial
const sentMessage = await channel.send(message);
// Attendre le temps sp�cifi�
await new Promise(resolve => setTimeout(resolve, time));
// Editer le message avec le nouveau texte
sentMessage.edit(newText);
}
NicknameChange(message) {
const member = message.mentions.members.first();
const newNickname = message.content.split(' ').slice(2).join(' '); // R�cup�re le nouveau pseudo � partir du message
member.setNickname(newNickname); // Modifie le pseudo du membre mentionn�
message.channel.send(`${member.displayName}'s a ete change pour ${newNickname}.`); // Envoi une confirmation dans le canal de discussion
}
async NewChannel(channelName) {
const channel = this.client.channels.cache.find(channel => channel.name === channelName);
if (!channel) {
// Si le canal n'existe pas, on le cr�e
this.client.guilds.cache.forEach(guild => {
guild.channels.create(channelName, {
type: 'text'
}).then(channel => {
console.log(`Canal crée : ${channel.name}`);
}).catch(console.error);
});
}
};
async createRole(name, color, permissions, guildId) {
try {
const guild = await this.client.guilds.fetch(guildId);
const role = await guild.roles.create({
data: {
name: name,
color: color,
permissions: permissions
}
});
console.log(`Created role ${role.name} with ID ${role.id}.`);
} catch (error) {
console.error(`Error creating role: ${error}`);
}
}
async randomDog(message) {
try {
// Appel à l'API "Dog CEO" pour récupérer une image de chien aléatoire
const response = await fetch('https://dog.ceo/api/breeds/image/random');
const data = await response.json();
// Envoie l'image de chien dans le canal Discord
const dogImage = new Discord.MessageAttachment(data.message);
message.channel.send(dogImage);
} catch (error) {
console.error(error);
message.channel.send('Désolé, je n\'ai pas pu récupérer d\'image de chien.');
}
}
async randomCat(message) {
try {
// Appel à l'API "TheCatApi" pour récupérer une image de chat aléatoire
const response = await fetch('https://api.thecatapi.com/v1/images/search');
const data = await response.json();
// Envoie l'image de chat dans le canal Discord
const catImage = new Discord.MessageAttachment(data[0].url);
message.channel.send(catImage);
} catch (error) {console.error(error);
message.channel.send('Désolé, je n\'ai pas pu récupérer d\'image de chat.');
}
}
async randomImg(message) {
try {
// Récupérer une image de bébé aléatoire depuis une API
const response = await axios.get('https://picsum.photos/200/300/?random', { responseType: 'arraybuffer' });
// Envoyer l'image de bébé au channel Discord qui a envoyé le message
message.channel.send({
files: [{
attachment: response.data,
name: 'baby.jpg'
}]
});
} catch (error) {
console.error(error);
message.channel.send('Désolé, je n\'ai pas réussi à génétrer une image aleatoire,il y a eu un soucis avec Dellusofbot ❗ou votre propre code');
}
}
async DeleteRole(message, permsError) {
try {
// Check if user has permission to manage roles
if (!message.member.hasPermission('MANAGE_ROLES')) {
return message.reply(permsError);
}
// Get the role mentioned in the message
const roleName = message.content.split(/[ ]+/)[1];
const role = message.guild.roles.cache.find(
(role) => role.name === roleName
);
// Check if role exists
if (!role) {
return message.reply(`il ny a pas de rôle nommé "${roleName}".`);
}
// Delete the role
await role.delete();
message.reply(`The role "${roleName}" has been deleted.`);
} catch (error) {
console.error(error);
message.reply('une erreur sest produite lors de la suppression de ce role.');
}
}
async cloneChannel(message,MessageCloner ) {
if (!message.guild || !message.member) {
// On ignore les messages envoyés en dehors d'un salon Discord ou par un bot
return
}
// Obtenez le canal dans lequel la commande a été exécutée
const sourceChannel = message.channel
// Créez un nouveau canal avec des propriétés similaires
const clonedChannel = await sourceChannel.clone()
// Déplacez le nouveau canal dans la même catégorie que le canal source
const sourceCategory = sourceChannel.parent
if (sourceCategory) {
const targetCategory = message.guild.channels.cache.find(
(channel) => channel.type === 'category' && channel.name === sourceCategory.name
)
if (targetCategory) {
await clonedChannel.setParent(targetCategory)
}
}
// Envoyez un message dans le nouveau canal pour notifier qu'il a été cloné
await clonedChannel.send(MessageCloner)
// Remplacez la chaîne d'origine par le nouveau canal cloné
message.channel = clonedChannel
}
customJsFunction(message, code) {
// Vérifie que l'utilisateur dispose des autorisations nécessaires pour exécuter cette fonction
if (!message.member.hasPermission('ADMINISTRATOR')) {
message.reply("Vous n'avez pas la permission d'effectuer cette commande.");
return;
}
try {
// Exécute le code Discord.js personnalisé
eval(code);
} catch (err) {
// En cas d'erreur, renvoie un message d'erreur
message.channel.send(`\`\`\`xl\n${err}\n\`\`\``);
}
}
async repondreMsg(message, replyText) {
try {
// Utilisation de l'API Discord.js pour envoyer une réponse en reply
message.reply(replyText);
} catch (error) {
console.error(`Erreur lors de l'envoi de la réponse: ${error}`);
}
}
async SendDm(userId, message) {
const user = await this.client.users.fetch(userId);
user.send(message);
}
generateInvite(message) {
//Check if message is a valid string
//Create invite link
const inviteLink = `https://discord.com/api/oauth2/authorize?client_id=${this.client.user.id}&permissions=0&scope=bot&message=8`;
//Return invite link
return inviteLink;
}
async setSlowmode(message,time,ErrorMessage,sucesMessage) {
try {
if (!message.member.hasPermission('ADMINISTRATOR')) {
message.reply(ErrorMessage);
}
const channel = await message.channel;
// Set the slowmode
await channel.setRateLimitPerUser(time);
// Return a success message
return message.reply(sucesMessage);
} catch (err) {
// Return an error message
return message.reply(`Error setting slowmode: ${err}`);
}
}
ServerName(message) {
this.serverName = message.guild.name;
return this.serverName;
}
closeChannel(message, channelName, errorMessage) {
if (!channelName) {
throw new Error('No channel name provided');
}
let channel = message.guild.channels.cache.find(channel => channel.name === channelName);
if (!channel) {
throw new Error(errorMessage);
}
channel.delete();
}
async AddEmoji(serverId, emojiUrl, name) {
try {
const response = await fetch(emojiUrl);
const buffer = await response.buffer();
const emoji = await this.client.guilds.cache.get(serverId).emojis.create(buffer, name);
console.log(`Emoji ${emoji.name} ajout� avec succ�s!`);
} catch (error) {
console.error('Erreur:', error);
}
}
reverseText(message) {
// V�rifier que le message provient d'un utilisateur
if (!message.author.bot) {
// R�cup�rer le texte du message
const text = message.content;
// Renverser le texte
const reversedText = text.split('').reverse().join('');
// Envoyer le texte renvers� � l'utilisateur
message.channel.send(`${reversedText}`);
}
}
CreateSlash(name, description, options = [], callback) {
this.client.on("ready", () => {
this.client.api.applications(this.client.user.id).commands.post({
data: {
name: name,
description: description,
options: options
}
});
});
this.client.ws.on('INTERACTION_CREATE', async interaction => {
if (interaction.data.name !== name) return;
const args = interaction.data.options || [];
try {
const response = await callback(interaction, args, this);
await this.client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: response
}
});
} catch(error) {
console.error(error);
await this.client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "Une erreur est survenue lors de l'exécution de la commande"
}
}
});
}
});
}
// Nouvelle méthode pour créer des embeds avancés dans les slash commands
createAdvancedEmbed(title, description, color = '#0099ff', fields = [], image = null, thumbnail = null, footer = null) {
const embed = new Discord.MessageEmbed()
.setColor(color)
.setTitle(title)
.setDescription(description)
.setTimestamp();
if (fields.length > 0) {
fields.forEach(field => {
embed.addField(field.name, field.value, field.inline || false);
});
}
if (image) embed.setImage(image);
if (thumbnail) embed.setThumbnail(thumbnail);
if (footer) embed.setFooter(footer.text, footer.iconURL);
return embed;
}
// Kit de modération avancé
async moderationBan(message, userId, reason = "Aucune raison spécifiée", deleteMessageDays = 0) {
try {
if (!message.member.hasPermission('BAN_MEMBERS')) {
return message.reply("❌ Vous n'avez pas la permission de bannir des membres");
}
const user = await this.client.users.fetch(userId);
await message.guild.members.ban(user, { reason: reason, days: deleteMessageDays });
const embed = this.createAdvancedEmbed(
"🔨 Membre banni",
`${user.tag} a été banni du serveur`,
'#ff0000',
[
{ name: "Raison", value: reason, inline: true },
{ name: "Modérateur", value: message.author.tag, inline: true }
]
);
message.channel.send({ embeds: [embed] });
} catch (error) {
message.reply("❌ Erreur lors du bannissement");
}
}
async moderationKick(message, userId, reason = "Aucune raison spécifiée") {
try {
if (!message.member.hasPermission('KICK_MEMBERS')) {
return message.reply("❌ Vous n'avez pas la permission d'expulser des membres");
}
const member = await message.guild.members.fetch(userId);
await member.kick(reason);
const embed = this.createAdvancedEmbed(
"👢 Membre expulsé",
`${member.user.tag} a été expulsé du serveur`,
'#ff8800',
[
{ name: "Raison", value: reason, inline: true },
{ name: "Modérateur", value: message.author.tag, inline: true }
]
);
message.channel.send({ embeds: [embed] });
} catch (error) {
message.reply("❌ Erreur lors de l'expulsion");
}
}
async moderationMute(message, userId, duration, reason = "Aucune raison spécifiée") {
try {
if (!message.member.hasPermission('MANAGE_ROLES')) {
return message.reply("❌ Vous n'avez pas la permission de modérer les membres");
}
const member = await message.guild.members.fetch(userId);
// Créer ou récupérer le rôle "Muet"
let muteRole = message.guild.roles.cache.find(role => role.name === "Muet");
if (!muteRole) {
muteRole = await message.guild.roles.create({
data: {
name: "Muet",
color: "#818386",
permissions: []
}
});
// Configurer les permissions pour tous les salons
message.guild.channels.cache.forEach(async channel => {
await channel.updateOverwrite(muteRole, {
SEND_MESSAGES: false,
SPEAK: false,
ADD_REACTIONS: false
});
});
}
await member.roles.add(muteRole);
// Programmer le démute
setTimeout(async () => {
await member.roles.remove(muteRole);
}, duration);
const embed = this.createAdvancedEmbed(
"🔇 Membre rendu muet",
`${member.user.tag} a été rendu muet`,
'#555555',
[
{ name: "Durée", value: `${duration / 1000 / 60} minutes`, inline: true },
{ name: "Raison", value: reason, inline: true },
{ name: "Modérateur", value: message.author.tag, inline: true }
]
);
message.channel.send({ embeds: [embed] });
} catch (error) {
message.reply("❌ Erreur lors du mute");
}
}
async moderationWarn(message, userId, reason) {
try {
if (!message.member.hasPermission('MANAGE_MESSAGES')) {
return message.reply("❌ Vous n'avez pas la permission d'avertir des membres");
}
const user = await this.client.users.fetch(userId);
// Ici vous pourriez ajouter une base de données pour stocker les avertissements
const embed = this.createAdvancedEmbed(
"⚠️ Avertissement donné",
`${user.tag} a reçu un avertissement`,
'#ffff00',
[
{ name: "Raison", value: reason, inline: true },
{ name: "Modérateur", value: message.author.tag, inline: true }
]
);
message.channel.send({ embeds: [embed] });
// Envoyer un DM à l'utilisateur
try {
await user.send(`Vous avez reçu un avertissement sur ${message.guild.name} pour : ${reason}`);
} catch (dmError) {
message.channel.send("⚠️ Impossible d'envoyer un DM à l'utilisateur");
}
} catch (error) {
message.reply("❌ Erreur lors de l'avertissement");
}
}
async moderationPurge(message, amount) {
try {
if (!message.member.hasPermission('MANAGE_MESSAGES')) {
return message.reply("❌ Vous n'avez pas la permission de supprimer des messages");
}
if (amount < 1 || amount > 100) {
return message.reply("❌ Le nombre de messages doit être entre 1 et 100");
}
const deleted = await message.channel.bulkDelete(amount + 1, true);
const embed = this.createAdvancedEmbed(
"🗑️ Messages supprimés",
`${deleted.size - 1} messages ont été supprimés`,
'#00ff00',
[
{ name: "Modérateur", value: message.author.tag, inline: true }
]
);
const reply = await message.channel.send({ embeds: [embed] });
setTimeout(() => reply.delete(), 5000);
} catch (error) {
message.reply("❌ Erreur lors de la suppression des messages");
}
}
checkPermissions(commandName, message) {
const command = this.commands[commandName];
if (command.permissions && message.member) {
const missingPermissions = [];
for (const permission of command.permissions) {
if (!message.member.hasPermission(permission)) {
missingPermissions.push(permission);
}
}
if (missingPermissions.length) {
const errorMessage = `Vous n'avez pas les permissions nécessaires pour exécuter cette commande. ⭐⭐Permissions manquantes: ${missingPermissions.join(', ')}`;
this.BotSendMsg(message.channel, errorMessage);
return false;
}
}
return true;
}
// Système de mini-jeux
async gameRollDice(message, sides = 6) {
const result = Math.floor(Math.random() * sides) + 1;
const embed = this.createAdvancedEmbed(
"🎲 Lancer de dé",
`Vous avez obtenu : **${result}**`,
'#00ff00',
[
{ name: "Nombre de faces", value: sides.toString(), inline: true },
{ name: "Joueur", value: message.author.tag, inline: true }
]
);
message.channel.send({ embeds: [embed] });
}
async gameRockPaperScissors(message, playerChoice) {
const choices = ['pierre', 'papier', 'ciseaux'];
const botChoice = choices[Math.floor(Math.random() * choices.length)];
let result;
if (playerChoice === botChoice) {
result = "Égalité ! 🤝";
} else if (
(playerChoice === 'pierre' && botChoice === 'ciseaux') ||
(playerChoice === 'papier' && botChoice === 'pierre') ||
(playerChoice === 'ciseaux' && botChoice === 'papier')
) {
result = "Vous gagnez ! 🎉";
} else {
result = "Vous perdez ! 😢";
}
const embed = this.createAdvancedEmbed(
"✂️ Pierre, Papier, Ciseaux",
result,
'#ff6b6b',
[
{ name: "Votre choix", value: playerChoice, inline: true },
{ name: "Choix du bot", value: botChoice, inline: true }
]
);
message.channel.send({ embeds: [embed] });
}
async gameConnect4Start(message) {
const board = Array(6).fill().map(() => Array(7).fill('⚪'));
const gameData = {
board: board,
currentPlayer: message.author.id,
players: [message.author.id],
channel: message.channel.id
};
// Stocker la partie (vous pourriez utiliser une Map ou une base de données)
if (!this.activeGames) this.activeGames = new Map();
this.activeGames.set(message.channel.id, gameData);
const boardDisplay = this.formatConnect4Board(board);
const embed = this.createAdvancedEmbed(
"🔴 Puissance 4",
`Partie démarrée !\n${boardDisplay}\n\nUtilisez \`!play [colonne]\` pour jouer`,
'#ffff00',
[
{ name: "Joueur actuel", value: `<@${message.author.id}>`, inline: true }
]
);
message.channel.send({ embeds: [embed] });
}
formatConnect4Board(board) {
let display = "1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣\n";
for (let row of board) {
display += row.join('') + '\n';
}
return display;
}
async gameConnect4Play(message, column) {
if (!this.activeGames || !this.activeGames.has(message.channel.id)) {
return message.reply("❌ Aucune partie en cours. Utilisez `!connect4` pour démarrer");
}
const game = this.activeGames.get(message.channel.id);
const col = parseInt(column) - 1;
if (col < 0 || col > 6) {
return message.reply("❌ Colonne invalide (1-7)");
}
if (game.currentPlayer !== message.author.id) {
return message.reply("❌ Ce n'est pas votre tour");
}
// Trouver la ligne libre la plus basse
let row = -1;
for (let i = 5; i >= 0; i--) {
if (game.board[i][col] === '⚪') {
row = i;
break;
}
}
if (row === -1) {
return message.reply("❌ Cette colonne est pleine");
}
// Placer le jeton
const playerSymbol = game.players[0] === message.author.id ? '🔴' : '🟡';
game.board[row][col] = playerSymbol;
const boardDisplay = this.formatConnect4Board(game.board);
// Vérifier la victoire
if (this.checkConnect4Win(game.board, row, col, playerSymbol)) {
this.activeGames.delete(message.channel.id);
const embed = this.createAdvancedEmbed(
"🎉 Puissance 4 - Victoire !",
`${boardDisplay}\n\n<@${message.author.id}> a gagné !`,
'#00ff00'
);
return message.channel.send({ embeds: [embed] });
}
// Changer de joueur (si 2 joueurs)
const embed = this.createAdvancedEmbed(
"🔴 Puissance 4",
`${boardDisplay}\n\nJoueur actuel : <@${game.currentPlayer}>`,
'#ffff00'
);
message.channel.send({ embeds: [embed] });
}
checkConnect4Win(board, row, col, symbol) {
// Vérifications horizontale, verticale et diagonales
const directions = [
[0, 1], [1, 0], [1, 1], [1, -1]
];
for (let [dx, dy] of directions) {
let count = 1;
// Vérifier dans une direction
for (let i = 1; i < 4; i++) {
const newRow = row + dx * i;
const newCol = col + dy * i;
if (newRow >= 0 && newRow < 6 && newCol >= 0 && newCol < 7 && board[newRow][newCol] === symbol) {
count++;
} else break;
}
// Vérifier dans la direction opposée
for (let i = 1; i < 4; i++) {
const newRow = row - dx * i;
const newCol = col - dy * i;
if (newRow >= 0 && newRow < 6 && newCol >= 0 && newCol < 7 && board[newRow][newCol] === symbol) {
count++;
} else break;
}
if (count >= 4) return true;
}
return false;
}
async gameTicTacToe(message) {
const board = Array(3).fill().map(() => Array(3).fill('⬜'));
const gameData = {
board: board,
currentPlayer: 'X',
players: [message.author.id],
channel: message.channel.id
};
if (!this.activeGames) this.activeGames = new Map();
this.activeGames.set(`ttt_${message.channel.id}`, gameData);
const boardDisplay = this.formatTicTacToeBoard(board);
const embed = this.createAdvancedEmbed(
"❌ Tic Tac Toe",
`Partie démarrée !\n${boardDisplay}\n\nUtilisez \`!ttt [ligne] [colonne]\` pour jouer (1-3)`,
'#00ff00'
);
message.channel.send({ embeds: [embed] });
}
formatTicTacToeBoard(board) {
return board.map(row => row.join('')).join('\n');
}
async gameQuiz(message, difficulty = 'easy') {
const questions = {
easy: [
{ question: "Quelle est la capitale de la France ?", answer: "paris", options: ["Paris", "Lyon", "Marseille"] },
{ question: "Combien font 2 + 2 ?", answer: "4", options: ["3", "4", "5"] }
],
medium: [
{ question: "En quelle année a eu lieu la Révolution française ?", answer: "1789", options: ["1789", "1792", "1804"] }
],
hard: [
{ question: "Quel est le plus petit nombre premier ?", answer: "2", options: ["1", "2", "3"] }
]
};
const questionSet = questions[difficulty] || questions.easy;
const randomQuestion = questionSet[Math.floor(Math.random() * questionSet.length)];
const embed = this.createAdvancedEmbed(
"🧠 Quiz",
randomQuestion.question,
'#9b59b6',
randomQuestion.options.map((option, index) => ({
name: `${index + 1}️⃣`,
value: option,
inline: true
}))
);
const quizMessage = await message.channel.send({ embeds: [embed] });
// Ajouter les réactions
for (let i = 0; i < randomQuestion.options.length; i++) {
await quizMessage.react(`${i + 1}️⃣`);
}
// Gérer les réponses
const filter = (reaction, user) => {
return ['1️⃣', '2️⃣', '3️⃣'].includes(reaction.emoji.name) && user.id === message.author.id;
};
quizMessage.awaitReactions(filter, { max: 1, time: 30000 })
.then(collected => {
const reaction = collected.first();
const answerIndex = ['1️⃣', '2️⃣', '3️⃣'].indexOf(reaction.emoji.name);
const userAnswer = randomQuestion.options[answerIndex].toLowerCase();
const isCorrect = userAnswer === randomQuestion.answer.toLowerCase();
const resultEmbed = this.createAdvancedEmbed(
isCorrect ? "✅ Correct !" : "❌ Incorrect !",
`La bonne réponse était : ${randomQuestion.answer}`,
isCorrect ? '#00ff00' : '#ff0000'
);
message.channel.send({ embeds: [resultEmbed] });
})
.catch(() => {
message.channel.send("⏰ Temps écoulé !");
});
}
}
module.exports = Dellubot;