diff --git a/banners/banner_1369669999345537145.png b/banners/banner_1369669999345537145.png new file mode 100644 index 0000000..cddf163 Binary files /dev/null and b/banners/banner_1369669999345537145.png differ diff --git a/bot.py b/bot.py index 352b000..253467e 100755 --- a/bot.py +++ b/bot.py @@ -51,7 +51,6 @@ class MyBot(commands.Bot): "commandes.sendbotmessages", "commandes.goodbye", "commandes.welcome", - "commandes.fun", "commandes.security", "commandes.snipe", "commandes.scan", diff --git a/commandes/fun.py b/commandes/fun.py deleted file mode 100755 index 62e9a76..0000000 --- a/commandes/fun.py +++ /dev/null @@ -1,17 +0,0 @@ -import discord -from discord import app_commands -from discord.ext import commands -import random - -class FunCommands(commands.Cog): - def __init__(self, bot): - self.bot = bot - self.emojis = ['😀', '😂', '😎', '😍', '😡', '🤖', '👻', '🎉', '🔥', '🌈', '🍕', '🍔', '🍟', '🚀', '🌟'] - - @app_commands.command(name="fun", description="Envoie 10 emojis fun aléatoires") - async def fun(self, interaction: discord.Interaction): - chosen_emojis = random.sample(self.emojis, 10) - await interaction.response.send_message(" ".join(chosen_emojis)) - -async def setup(bot): - await bot.add_cog(FunCommands(bot)) diff --git a/commandes/welcome.py b/commandes/welcome.py index a6bc48b..92f899e 100644 --- a/commandes/welcome.py +++ b/commandes/welcome.py @@ -23,13 +23,29 @@ class Welcome(commands.Cog): server_id INTEGER PRIMARY KEY, welcome_channel INTEGER, goodbye_channel INTEGER, - welcome_dm_message TEXT + welcome_dm_message TEXT, + welcome_server_name TEXT, + welcome_banner_background TEXT, + welcome_channel_message TEXT ) ''') + # Migration pour ajouter les colonnes si elles n'existent pas + cursor.execute("PRAGMA table_info(server_configs)") + columns = [col[1] for col in cursor.fetchall()] + + if 'welcome_server_name' not in columns: + cursor.execute('ALTER TABLE server_configs ADD COLUMN welcome_server_name TEXT') + + if 'welcome_banner_background' not in columns: + cursor.execute('ALTER TABLE server_configs ADD COLUMN welcome_banner_background TEXT') + + if 'welcome_channel_message' not in columns: + cursor.execute('ALTER TABLE server_configs ADD COLUMN welcome_channel_message TEXT') + conn.commit() conn.close() - async def create_welcome_image(self, username, avatar_url): + async def create_welcome_image(self, username, avatar_url, server_name=None, banner_background=None): current_dir = os.path.dirname(__file__) base_dir = os.path.abspath(os.path.join(current_dir, "..")) @@ -38,16 +54,24 @@ class Welcome(commands.Cog): async with session.get(avatar_url) as resp: avatar_bytes = await resp.read() - background = Image.open(os.path.join(base_dir, 'background_template.png')) + # Utiliser le fond personnalisé ou celui par défaut + if banner_background and os.path.exists(banner_background): + background = Image.open(banner_background) + else: + background = Image.open(os.path.join(base_dir, 'background_template.png')) + draw = ImageDraw.Draw(background) font_large = ImageFont.truetype(os.path.join(base_dir, 'custom_font_large.otf'), 70) font_small = ImageFont.truetype(os.path.join(base_dir, 'custom_font_small.otf'), 50) - font_large_omega = ImageFont.truetype(os.path.join(base_dir, 'custom_font_large.otf'), 55) draw.text((325, 70), "Bienvenue", font=font_large, fill=(255,255,255)) - draw.text((325, 135), f"{username} chez", font=font_small, fill=(255,255,255)) - draw.text((325, 195), "OMEGA KUBE", font=font_large_omega, fill=(255,255,255)) + draw.text((325, 135), f"{username}", font=font_small, fill=(255,255,255)) + + # Afficher le nom du serveur uniquement si configuré + if server_name: + font_server = ImageFont.truetype(os.path.join(base_dir, 'custom_font_large.otf'), 55) + draw.text((325, 195), server_name, font=font_server, fill=(255,255,255)) avatar = Image.open(io.BytesIO(avatar_bytes)).convert("RGBA").resize((224, 224), Image.LANCZOS) mask = Image.new('L', avatar.size, 0) @@ -67,50 +91,114 @@ class Welcome(commands.Cog): async def on_member_join(self, member): conn = sqlite3.connect(self.db_path) cursor = conn.cursor() - # On récupère 2 colonnes : index 0 et 1 - cursor.execute('SELECT welcome_channel, welcome_dm_message FROM server_configs WHERE server_id = ?', (member.guild.id,)) + cursor.execute('SELECT welcome_channel, welcome_dm_message, welcome_server_name, welcome_banner_background, welcome_channel_message FROM server_configs WHERE server_id = ?', (member.guild.id,)) result = cursor.fetchone() conn.close() - # 1. Gestion du DM (Index 1) - welcome_dm_text = result[1] if result and result[1] else "Bienvenue {username} sur le serveur {servername} ! 🎉\n\nNous sommes ravis de t'accueillir parmi nous." + welcome_channel = result[0] if result else None + welcome_dm_text = result[1] if result and result[1] else None + server_name = result[2] if result and result[2] else None + banner_background = result[3] if result and result[3] else None + welcome_channel_message = result[4] if result and result[4] else None - try: - formatted_message = welcome_dm_text.format( - username=member.name, - servername=member.guild.name, - member_count=member.guild.member_count - ) - await member.send(formatted_message) - await member.send("https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXV1NW02NTk0bGF2ZHcyMGFna2F6amRrbGpobGpsMHowOW5xa2E5eCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZtFuW4rsUbfrRzPauJ/giphy.gif") - except Exception as e: - logging.warning(f"Impossible d'envoyer le DM à {member.name}: {e}") + # 1. Gestion du DM + if welcome_dm_text: + try: + formatted_message = welcome_dm_text.format( + username=member.name, + servername=member.guild.name, + member_count=member.guild.member_count + ) + await member.send(formatted_message) + await member.send("https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXV1NW02NTk0bGF2ZHcyMGFna2F6amRrbGpobGpsMHowOW5xa2E5eCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZtFuW4rsUbfrRzPauJ/giphy.gif") + except Exception as e: + logging.warning(f"Impossible d'envoyer le DM à {member.name}: {e}") - # 2. Gestion du salon de bienvenue (Index 0) - if result and result[0]: - channel = member.guild.get_channel(result[0]) + # 2. Gestion du salon de bienvenue + if welcome_channel: + channel = member.guild.get_channel(welcome_channel) if channel: - img = await self.create_welcome_image(member.name, member.avatar.url if member.avatar else member.default_avatar.url) + img = await self.create_welcome_image( + member.name, + member.avatar.url if member.avatar else member.default_avatar.url, + server_name=server_name, + banner_background=banner_background + ) if img: + # Utiliser le message personnalisé ou un message par défaut + channel_description = welcome_channel_message.format( + username=member.name, + servername=member.guild.name, + member_count=member.guild.member_count + ) if welcome_channel_message else "Bienvenue dans le serveur !\nSi vous cherchez des RolePlay de qualité,\nVous êtes au bon endroit. " + embed = discord.Embed(title=f"Merci d'accueillir {member} 🤝", - description="Bienvenue dans le serveur Omega Kube !\nSi vous cherchez des RolePlay de qualité,\nVous êtes au bon endroit. ", + description=channel_description, color=discord.Color.dark_purple()) embed.set_image(url="attachment://welcome.png") await channel.send(content=member.mention, embed=embed, file=discord.File(img, filename="welcome.png")) - @app_commands.command(name="setwelcome", description="Définit le salon et le message DM de bienvenue") + async def save_banner_attachment(self, attachment: discord.Attachment, guild_id: int) -> str: + """Sauvegarde l'attachment et retourne le chemin du fichier""" + base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "banners")) + os.makedirs(base_dir, exist_ok=True) + + # Vérifier que c'est une image + if not attachment.content_type or not attachment.content_type.startswith('image/'): + raise ValueError("Le fichier doit être une image.") + + # Vérifier le format PNG + if not attachment.filename.lower().endswith('.png'): + raise ValueError("Le fichier doit être au format PNG.") + + # Vérifier les dimensions + banner_path = os.path.join(base_dir, f"banner_{guild_id}.png") + + async with aiohttp.ClientSession() as session: + async with session.get(attachment.url) as resp: + if resp.status == 200: + # Vérifier les dimensions avant de sauvegarder + img_data = await resp.read() + from io import BytesIO + with Image.open(BytesIO(img_data)) as img: + width, height = img.size + if width != 1000 or height != 300: + raise ValueError(f"Les dimensions doivent être 1000x300 pixels (votre image: {width}x{height})") + + with open(banner_path, 'wb') as f: + f.write(img_data) + + return banner_path + + @app_commands.command(name="setwelcome", description="Définit le salon, les messages de bienvenue et le fond de la bannière") @app_commands.checks.has_permissions(administrator=True) - async def set_welcome(self, interaction: discord.Interaction, channel: discord.TextChannel, message_dm: str = None): + async def set_welcome(self, interaction: discord.Interaction, channel: discord.TextChannel, message_dm: str, message_salon: str, server_name: str, banner_file: discord.Attachment = None): + banner_path = None + + # Si un fichier est uploadé, le sauvegarder + if banner_file: + try: + banner_path = await self.save_banner_attachment(banner_file, interaction.guild_id) + except Exception as e: + await interaction.response.send_message(f"❌ Erreur avec le fichier: {e}", ephemeral=True) + return + conn = sqlite3.connect(self.db_path) cursor = conn.cursor() - cursor.execute('''INSERT INTO server_configs (server_id, welcome_channel, welcome_dm_message) - VALUES (?, ?, ?) ON CONFLICT(server_id) + cursor.execute('''INSERT INTO server_configs (server_id, welcome_channel, welcome_dm_message, welcome_server_name, welcome_banner_background, welcome_channel_message) + VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(server_id) DO UPDATE SET welcome_channel=excluded.welcome_channel, - welcome_dm_message=COALESCE(excluded.welcome_dm_message, welcome_dm_message)''', - (interaction.guild_id, channel.id, message_dm)) + welcome_dm_message=excluded.welcome_dm_message, + welcome_server_name=excluded.welcome_server_name, + welcome_banner_background=COALESCE(excluded.welcome_banner_background, welcome_banner_background), + welcome_channel_message=excluded.welcome_channel_message''', + (interaction.guild_id, channel.id, message_dm, server_name, banner_path, message_salon)) conn.commit() conn.close() - await interaction.response.send_message("Configuration de bienvenue enregistrée !", ephemeral=True) + + bg_used = "background_template.png" if not banner_path else (banner_path.split('/')[-1]) + await interaction.response.send_message(f"✅ Configuration de bienvenida enregistrée !\nFond utilisé: {bg_used}", ephemeral=True) async def setup(bot): - await bot.add_cog(Welcome(bot)) \ No newline at end of file + await bot.add_cog(Welcome(bot)) + diff --git a/config.db b/config.db index a98dafe..e23f846 100644 Binary files a/config.db and b/config.db differ diff --git a/data/logs/member_events_2026-01-03.json b/data/logs/member_events_2026-01-03.json new file mode 100644 index 0000000..a9007a8 --- /dev/null +++ b/data/logs/member_events_2026-01-03.json @@ -0,0 +1,58 @@ +[ + { + "timestamp": "2026-01-03T21:25:17.730927", + "event_type": "member_leave", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null, + "roles": { + "role_ids": [ + 1369669999366770721 + ], + "role_names": [ + "Faux banquier" + ], + "permissions": [ + 8192 + ] + }, + "joined_at": "2026-01-01T21:00:26.074000+00:00" + }, + { + "timestamp": "2026-01-03T21:25:28.894683", + "event_type": "member_join", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null + }, + { + "timestamp": "2026-01-03T21:49:33.975462", + "event_type": "member_leave", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null, + "roles": { + "role_ids": [ + 1369669999366770721 + ], + "role_names": [ + "Faux banquier" + ], + "permissions": [ + 8192 + ] + }, + "joined_at": "2026-01-03T20:25:28.737000+00:00" + }, + { + "timestamp": "2026-01-03T21:49:55.375389", + "event_type": "member_join", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null + } +] \ No newline at end of file diff --git a/data/member_logs/1456390746167967932.json b/data/member_logs/1456390746167967932.json new file mode 100644 index 0000000..a9cc32a --- /dev/null +++ b/data/member_logs/1456390746167967932.json @@ -0,0 +1,42 @@ +[ + { + "timestamp": "2026-01-03T21:25:17.730927", + "event_type": "member_leave", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null, + "roles": { + "role_ids": [ + 1369669999366770721 + ], + "role_names": [ + "Faux banquier" + ], + "permissions": [ + 8192 + ] + }, + "joined_at": "2026-01-01T21:00:26.074000+00:00" + }, + { + "timestamp": "2026-01-03T21:49:33.975462", + "event_type": "member_leave", + "member_id": 1456390746167967932, + "member_name": "juibu_66388", + "member_discriminator": "0", + "member_avatar": null, + "roles": { + "role_ids": [ + 1369669999366770721 + ], + "role_names": [ + "Faux banquier" + ], + "permissions": [ + 8192 + ] + }, + "joined_at": "2026-01-03T20:25:28.737000+00:00" + } +] \ No newline at end of file