From 44eefeac6c681e25aeaa88aa971ceba75c01ef88 Mon Sep 17 00:00:00 2001 From: Mathis Date: Sat, 3 Jan 2026 01:15:10 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20syst=C3=A8me=20de=20r=C3=A8glement?= =?UTF-8?q?=20dans=20le=20menu=20principal=20de=20Kuby=20(test=C3=A9=20?= =?UTF-8?q?=C2=A7=20fonctionnel)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 1 + commandes/modules_security/rules.py | 498 ++++++++++++++++++++++++++++ commandes/security.py | 234 ++++++++++++- data/security_settings.json | 27 +- 4 files changed, 735 insertions(+), 25 deletions(-) create mode 100644 commandes/modules_security/rules.py mode change 100755 => 100644 data/security_settings.json diff --git a/bot.py b/bot.py index ecac70f..352b000 100755 --- a/bot.py +++ b/bot.py @@ -61,6 +61,7 @@ class MyBot(commands.Bot): "commandes.modules_security.antispam", "commandes.modules_security.antiraid", "commandes.modules_security.logs_manager", + "commandes.modules_security.rules", ] for extension in extensions: diff --git a/commandes/modules_security/rules.py b/commandes/modules_security/rules.py new file mode 100644 index 0000000..e123653 --- /dev/null +++ b/commandes/modules_security/rules.py @@ -0,0 +1,498 @@ +import discord +from discord import app_commands +from discord.ext import commands +import json +import os +from typing import Optional + +# Chemins des fichiers +SETTINGS_FILE = "data/security_settings.json" + + +def load_settings(guild_id: int) -> dict: + """Charge les paramètres de sécurité pour un serveur""" + if not os.path.exists(SETTINGS_FILE): + return {} + try: + with open(SETTINGS_FILE, "r", encoding='utf-8') as f: + return json.load(f).get(str(guild_id), {}) + except (json.JSONDecodeError, FileNotFoundError): + return {} + + +def save_settings(guild_id: int, settings: dict) -> None: + """Sauvegarde les paramètres de sécurité""" + data = {} + if os.path.exists(SETTINGS_FILE): + try: + with open(SETTINGS_FILE, "r", encoding='utf-8') as f: + data = json.load(f) + except (json.JSONDecodeError, FileNotFoundError): + pass + + data[str(guild_id)] = settings + + os.makedirs(os.path.dirname(SETTINGS_FILE), exist_ok=True) + with open(SETTINGS_FILE, "w", encoding='utf-8') as f: + json.dump(data, f, indent=4, ensure_ascii=False) + + +# --- MODALS DE CONFIGURATION DU RÈGLEMENT (BACK-END) --- + +class RulesTitleModal(discord.ui.Modal, title="📜 Titre du Règlement"): + """Modal pour configurer le titre du règlement""" + title_input = discord.ui.TextInput( + label="Titre du règlement", + placeholder="Ex: 📜 Règlement de [Nom du Serveur]", + min_length=1, + max_length=100, + required=True + ) + + def __init__(self, guild_id: int, settings: dict, on_update_callback=None): + super().__init__() + self.guild_id = guild_id + self.settings = settings + self.on_update_callback = on_update_callback + + async def on_submit(self, interaction: discord.Interaction): + self.settings["rules_title"] = self.title_input.value + save_settings(self.guild_id, self.settings) + + if self.on_update_callback: + await self.on_update_callback(interaction, self.settings) + else: + await interaction.response.edit_message(view=self._create_view(interaction)) + + await interaction.followup.send( + f"✅ Titre du règlement mis à jour.", + ephemeral=True + ) + + def _create_view(self, interaction): + """Crée la vue mise à jour""" + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + view = SecurityView(interaction, self.settings, category="rules", bot=bot) + return view + + +class RulesContentModal(discord.ui.Modal, title="📝 Contenu du Règlement"): + """Modal pour configurer le contenu du règlement""" + content_input = discord.ui.TextInput( + label="Contenu du règlement", + placeholder="Entrez les règles de votre serveur...", + style=discord.TextStyle.paragraph, + min_length=10, + max_length=4000, + required=True + ) + + def __init__(self, guild_id: int, settings: dict, on_update_callback=None): + super().__init__() + self.guild_id = guild_id + self.settings = settings + self.on_update_callback = on_update_callback + + async def on_submit(self, interaction: discord.Interaction): + self.settings["rules_content"] = self.content_input.value + save_settings(self.guild_id, self.settings) + + if self.on_update_callback: + await self.on_update_callback(interaction, self.settings) + else: + await interaction.response.edit_message(view=self._create_view(interaction)) + + await interaction.followup.send( + f"✅ Contenu du règlement mis à jour.", + ephemeral=True + ) + + def _create_view(self, interaction): + """Crée la vue mise à jour""" + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + view = SecurityView(interaction, self.settings, category="rules", bot=bot) + return view + + +class RulesChannelModal(discord.ui.Modal, title="📌 Salon du Règlement"): + """Modal pour sélectionner le salon du règlement""" + channel_input = discord.ui.TextInput( + label="ID du salon", + placeholder="Entrez l'ID du salon où envoyer le règlement", + min_length=15, + max_length=20, + required=True + ) + + def __init__(self, guild_id: int, settings: dict, on_update_callback=None): + super().__init__() + self.guild_id = guild_id + self.settings = settings + self.on_update_callback = on_update_callback + + async def on_submit(self, interaction: discord.Interaction): + if not self.channel_input.value.isdigit(): + return await interaction.response.send_message( + "❌ Erreur : ID invalide.", + ephemeral=True + ) + + channel_id = int(self.channel_input.value) + channel = interaction.guild.get_channel(channel_id) + + if not channel: + return await interaction.response.send_message( + "❌ Salon non trouvé. Vérifiez l'ID.", + ephemeral=True + ) + + self.settings["rules_channel_id"] = channel_id + save_settings(self.guild_id, self.settings) + + if self.on_update_callback: + await self.on_update_callback(interaction, self.settings) + else: + await interaction.response.edit_message(view=self._create_view(interaction)) + + await interaction.followup.send( + f"✅ Salon du règlement défini sur {channel.mention}.", + ephemeral=True + ) + + def _create_view(self, interaction): + """Crée la vue mise à jour""" + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + view = SecurityView(interaction, self.settings, category="rules", bot=bot) + return view + + +class RulesRoleModal(discord.ui.Modal, title="✅ Rôle d'Acceptation"): + """Modal pour configurer le rôle attribué à l'acceptation""" + role_input = discord.ui.TextInput( + label="ID du rôle", + placeholder="Entrez l'ID du rôle à attribuer", + min_length=15, + max_length=20, + required=True + ) + + def __init__(self, guild_id: int, settings: dict, on_update_callback=None): + super().__init__() + self.guild_id = guild_id + self.settings = settings + self.on_update_callback = on_update_callback + + async def on_submit(self, interaction: discord.Interaction): + if not self.role_input.value.isdigit(): + return await interaction.response.send_message( + "❌ Erreur : ID invalide.", + ephemeral=True + ) + + role_id = int(self.role_input.value) + role = interaction.guild.get_role(role_id) + + if not role: + return await interaction.response.send_message( + "❌ Rôle non trouvé. Vérifiez l'ID.", + ephemeral=True + ) + + self.settings["rules_accept_role_id"] = role_id + save_settings(self.guild_id, self.settings) + + if self.on_update_callback: + await self.on_update_callback(interaction, self.settings) + else: + await interaction.response.edit_message(view=self._create_view(interaction)) + + await interaction.followup.send( + f"✅ Rôle d'acceptation défini sur **{role.name}**.", + ephemeral=True + ) + + def _create_view(self, interaction): + """Crée la vue mise à jour""" + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + view = SecurityView(interaction, self.settings, category="rules", bot=bot) + return view + + +class RulesMessageTypeModal(discord.ui.Modal, title="📝 Type de Message"): + """Modal pour choisir le type de message du règlement""" + message_type = discord.ui.TextInput( + label="Type de message", + placeholder="Tapez 'embed' pour embed ou 'simple' pour message simple", + min_length=5, + max_length=6, + required=True + ) + + def __init__(self, guild_id: int, settings: dict, on_update_callback=None): + super().__init__() + self.guild_id = guild_id + self.settings = settings + self.on_update_callback = on_update_callback + + async def on_submit(self, interaction: discord.Interaction): + msg_type = self.message_type.value.lower().strip() + + if msg_type not in ["embed", "simple"]: + return await interaction.response.send_message( + "❌ Erreur : Tapez 'embed' ou 'simple'.", + ephemeral=True + ) + + self.settings["rules_message_type"] = msg_type + save_settings(self.guild_id, self.settings) + + if self.on_update_callback: + await self.on_update_callback(interaction, self.settings) + else: + await interaction.response.edit_message(view=self._create_view(interaction)) + + type_name = "Embed" if msg_type == "embed" else "Message simple" + await interaction.followup.send( + f"✅ Type de message défini sur **{type_name}**.", + ephemeral=True + ) + + def _create_view(self, interaction): + """Crée la vue mise à jour""" + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + view = SecurityView(interaction, self.settings, category="rules", bot=bot) + return view + + +class ToggleRulesButton(discord.ui.Button): + """Bouton de bascule pour activer/désactiver le règlement""" + + def __init__(self, is_enabled: bool): + style = discord.ButtonStyle.green if is_enabled else discord.ButtonStyle.red + status = "✅" if is_enabled else "❌" + super().__init__( + label=f"Règlement [{status}]", + style=style, + custom_id="rules_enabled", + emoji="📜" + ) + + async def callback(self, interaction: discord.Interaction): + view = self.view + settings = view.settings + guild = interaction.guild + + # Basculer le paramètre + settings["rules_enabled"] = not settings.get("rules_enabled", False) + save_settings(guild.id, settings) + + # Reconstruire la vue + from commandes.security import SecurityView + # Essayer d'obtenir le bot depuis l'interaction + bot = getattr(interaction, 'client', None) + new_view = SecurityView(interaction, settings, category="rules", bot=bot) + + # Recréer l'embed + embed = new_view.create_category_embed( + "Configuration Règlement", + "Créez et envoyez un règlement pour votre serveur.\n\n" + "• **Titre** : Personnalisez le titre du règlement\n" + "• **Contenu** : Rédigez vos règles\n" + "• **Salon** : Choisissez où l'envoyer\n" + "• **Rôle** : Rôle attribué à l'acceptation\n\n" + "Les membres devront accepter le règlement pour accéder au serveur." + ) + + await interaction.response.edit_message(embed=embed, view=new_view) + + +class RulesAcceptButton(discord.ui.View): + """Bouton persistant pour accepter le règlement""" + + def __init__(self, guild_id: int, accept_role_id: int): + super().__init__(timeout=None) # Pas de timeout - bouton persistant + self.guild_id = guild_id + self.accept_role_id = accept_role_id + + @discord.ui.button( + label="J'accepte le règlement", + emoji="✅", + style=discord.ButtonStyle.green, + custom_id="rules_accept_button" + ) + async def accept_rules(self, interaction: discord.Interaction, button: discord.ui.Button): + """Gère le clic sur le bouton d'acceptation""" + guild = interaction.guild + + # Vérifier si le bouton est toujours activé (activé dans les paramètres) + settings = load_settings(guild.id) + if not settings.get("rules_enabled", False): + return await interaction.response.send_message( + "❌ Cette fonctionnalité a été désactivée.", + ephemeral=True + ) + + # Vérifier si l'utilisateur a déjà le rôle + role = guild.get_role(self.accept_role_id) + if not role: + return await interaction.response.send_message( + "❌ Le rôle d'acceptation n'est plus configuré sur ce serveur.", + ephemeral=True + ) + + member = interaction.user + + if role in member.roles: + return await interaction.response.send_message( + "✅ Vous avez déjà accepté le règlement !", + ephemeral=True + ) + + # Attribuer le rôle à l'utilisateur + try: + await member.add_roles(role) + + # Envoyer une confirmation éphémère + await interaction.response.send_message( + f"✅ {member.mention}, vous avez accepté le règlement !\n" + f"Le rôle **{role.name}** vous a été attribué.", + ephemeral=True + ) + except discord.Forbidden: + await interaction.response.send_message( + "❌ Je n'ai pas les permissions pour attribuer ce rôle.", + ephemeral=True + ) + except Exception as e: + await interaction.response.send_message( + f"❌ Une erreur est survenue: {e}", + ephemeral=True + ) + + +class RulesCog(commands.Cog): + """Cog pour la gestion du règlement""" + + def __init__(self, bot): + self.bot = bot + self.persistent_views_added = False + + async def setup_persistent_views(self): + """Configure les views persistantes pour les règlements existants""" + if self.persistent_views_added: + return + + # Charger les paramètres de tous les serveurs + if not os.path.exists(SETTINGS_FILE): + return + + try: + with open(SETTINGS_FILE, "r", encoding='utf-8') as f: + all_settings = json.load(f) + + # Pour chaque serveur avec le règlement activé + for guild_id_str, settings in all_settings.items(): + if settings.get("rules_enabled", False) and settings.get("rules_accept_role_id"): + # Ajouter la view persistente + view = RulesAcceptButton(int(guild_id_str), settings["rules_accept_role_id"]) + self.bot.add_view(view) + + self.persistent_views_added = True + except (json.JSONDecodeError, FileNotFoundError): + pass + + @commands.Cog.listener() + async def on_ready(self): + """Appelé quand le bot est prêt""" + await self.setup_persistent_views() + + async def send_rules_message(self, channel: discord.TextChannel, settings: dict) -> Optional[discord.Message]: + """Envoie le message du règlement dans un salon""" + title = settings.get("rules_title", "📜 Règlement du Serveur") + content = settings.get("rules_content", "") + accept_role_id = settings.get("rules_accept_role_id") + message_type = settings.get("rules_message_type", "embed") # Par défaut embed + + if not accept_role_id: + return None + + # Créer la view avec le bouton persistant + view = RulesAcceptButton(channel.guild.id, accept_role_id) + + if message_type == "simple": + # Message simple + text_message = ( + f"📜 **{title}**\n\n" + f"{content}\n\n" + "Bienvenue ! Pour accéder à l'ensemble des canaux du serveur, " + "vous devez accepter le règlement en cliquant sur le bouton ci-dessous.\n\n" + "En acceptant, vous confirmez avoir lu et compris les règles du serveur." + ) + + # Envoyer le message simple + try: + message = await channel.send( + content=text_message, + view=view + ) + return message + except Exception as e: + print(f"Erreur lors de l'envoi du règlement simple: {e}") + return None + + else: # embed + # Créer l'embed + embed = discord.Embed( + title=title, + description=content, + color=0x2b2d31 + ) + + embed.set_footer(text="Cliquez sur le bouton ci-dessous pour accepter le règlement") + + # Envoyer seulement l'embed + try: + message = await channel.send( + embed=embed, + view=view + ) + return message + except Exception as e: + print(f"Erreur lors de l'envoi du règlement embed: {e}") + return None + + def format_default_rules(self, guild_name: str) -> tuple: + """Retourne le titre et contenu par défaut du règlement""" + title = f"📜 Règlement de {guild_name}" + content = ( + "Bienvenue sur notre serveur ! Avant de commencer à interagir avec la communauté, " + "veuille lire et accepter notre règlement.\n\n" + "**📌 Règles à respecter :**\n\n" + "1. **Respectez les autres membres** - Pas d'insultes, de harcèlement ou de discrimination.\n" + "2. **Pas de contenu inapproprié** - Aucun contenu NSFW, violent ou choquant.\n" + "3. **Pas de spam ou de flood** - Évitez les messages répétitifs ou les emojis excessifs.\n" + "4. **Pas de publicité** - Ne partagez pas de liens vers d'autres serveurs sans autorisation.\n" + "5. **Restez dans les salons appropriés** - Respectez la thématique de chaque canal.\n\n" + "**⚠️ Sanctions :**\n" + "Le non-respect de ces règles peut entraîner des avertissements, des mute temporaires, " + "ou un banissement définitif selon la gravité des infractions.\n\n" + "*En cliquant sur \"J'accepte\", vous confirmez avoir lu et accepter ce règlement.*" + ) + return title, content + + +async def setup(bot): + """Setup du cog de règlement""" + cog = RulesCog(bot) + await bot.add_cog(cog) + diff --git a/commandes/security.py b/commandes/security.py index de4aa4e..6305efa 100755 --- a/commandes/security.py +++ b/commandes/security.py @@ -152,6 +152,8 @@ class RaidThresholdModal(discord.ui.Modal, title="⚔️ Seuil Anti-Raid"): ephemeral=True ) +# --- MODALS DE CONFIGURATION WHITELIST --- + class WhitelistModal(discord.ui.Modal, title="👤 Ajouter à la Whitelist"): """Modal pour ajouter un utilisateur à la whitelist""" user_input = discord.ui.TextInput( @@ -214,12 +216,13 @@ class WhitelistModal(discord.ui.Modal, title="👤 Ajouter à la Whitelist"): class SecurityView(discord.ui.View): """Vue principale du panneau de sécurité""" - def __init__(self, interaction: discord.Interaction, settings: dict, category: Optional[str] = None): + def __init__(self, interaction: discord.Interaction, settings: dict, category: Optional[str] = None, bot=None): super().__init__(timeout=300) # 5 minutes timeout self.interaction = interaction self.guild = interaction.guild self.settings = settings self.category = category + self.bot = bot self.whitelist_count = len(load_whitelist(self.guild.id)) self.build_view() @@ -240,6 +243,8 @@ class SecurityView(discord.ui.View): self.build_logs_view() elif self.category == "whitelist": self.build_whitelist_view() + elif self.category == "rules": + self.build_rules_view() def build_spam_view(self): """Construit la vue Anti-Spam""" @@ -434,6 +439,108 @@ class SecurityView(discord.ui.View): btn_back.callback = self.back_to_main self.add_item(btn_back) + def build_rules_view(self): + """Construit la vue Règlement""" + from commandes.modules_security.rules import ( + RulesTitleModal, RulesContentModal, RulesChannelModal, + RulesRoleModal, ToggleRulesButton, save_settings + ) + + # Toggle Activer/Désactiver + rules_enabled = self.settings.get("rules_enabled", False) + btn_toggle = ToggleButton( + label="Règlement", + emoji="📜", + is_enabled=rules_enabled, + custom_id="rules_enabled" + ) + + + + # Bouton pour modifier le titre + btn_title = discord.ui.Button( + label="Éditer le titre", + style=discord.ButtonStyle.blurple, + emoji="📝" + ) + btn_title.callback = self.open_rules_title_modal + self.add_item(btn_title) + + # Bouton pour modifier le contenu + btn_content = discord.ui.Button( + label="Éditer le contenu", + style=discord.ButtonStyle.blurple, + emoji="📄" + ) + btn_content.callback = self.open_rules_content_modal + self.add_item(btn_content) + + # Bouton pour choisir le salon + rules_channel_id = self.settings.get("rules_channel_id") + if rules_channel_id: + channel = self.guild.get_channel(int(rules_channel_id)) + btn_channel = discord.ui.Button( + label=f"Salon: {channel.name if channel else 'Invalide'}", + style=discord.ButtonStyle.green, + custom_id="rules_channel" + ) + else: + btn_channel = discord.ui.Button( + label="Aucun salon configuré", + style=discord.ButtonStyle.red, + custom_id="rules_channel" + ) + btn_channel.callback = self.open_rules_channel_modal + self.add_item(btn_channel) + + # Bouton pour choisir le rôle d'acceptation + rules_role_id = self.settings.get("rules_accept_role_id") + if rules_role_id: + role = self.guild.get_role(int(rules_role_id)) + btn_role = discord.ui.Button( + label=f"Rôle: {role.name if role else 'Invalide'}", + style=discord.ButtonStyle.green, + custom_id="rules_role" + ) + else: + btn_role = discord.ui.Button( + label="Aucun rôle configuré", + style=discord.ButtonStyle.red, + custom_id="rules_role" + ) + btn_role.callback = self.open_rules_role_modal + self.add_item(btn_role) + + # Bouton pour choisir le type de message + message_type = self.settings.get("rules_message_type", "embed") + type_label = "Embed" if message_type == "embed" else "Message simple" + btn_message_type = discord.ui.Button( + label=f"Type: {type_label}", + style=discord.ButtonStyle.blurple, + emoji="📝", + custom_id="rules_message_type" + ) + btn_message_type.callback = self.open_rules_message_type_modal + self.add_item(btn_message_type) + + # Bouton pour envoyer le règlement + btn_send = discord.ui.Button( + label="Envoyer le règlement", + style=discord.ButtonStyle.green, + emoji="🚀" + ) + btn_send.callback = self.send_rules + self.add_item(btn_send) + + # Bouton retour + btn_back = discord.ui.Button( + label="Retour", + style=discord.ButtonStyle.gray, + emoji="⬅️" + ) + btn_back.callback = self.back_to_main + self.add_item(btn_back) + async def toggle_setting(self, interaction: discord.Interaction, key: str): """Bascule un paramètre""" self.settings[key] = not self.settings.get(key, False) @@ -459,6 +566,110 @@ class SecurityView(discord.ui.View): WhitelistModal(self.guild.id, self) ) + async def open_rules_title_modal(self, interaction: discord.Interaction): + """Ouvre le modal de configuration du titre du règlement""" + from .modules_security.rules import RulesTitleModal + await interaction.response.send_modal( + RulesTitleModal(self.guild.id, self.settings) + ) + + async def open_rules_content_modal(self, interaction: discord.Interaction): + """Ouvre le modal de configuration du contenu du règlement""" + from .modules_security.rules import RulesContentModal + await interaction.response.send_modal( + RulesContentModal(self.guild.id, self.settings) + ) + + async def open_rules_channel_modal(self, interaction: discord.Interaction): + """Ouvre le modal de sélection du salon du règlement""" + from .modules_security.rules import RulesChannelModal + await interaction.response.send_modal( + RulesChannelModal(self.guild.id, self.settings) + ) + + async def open_rules_role_modal(self, interaction: discord.Interaction): + """Ouvre le modal de configuration du rôle d'acceptation""" + from .modules_security.rules import RulesRoleModal + await interaction.response.send_modal( + RulesRoleModal(self.guild.id, self.settings) + ) + + async def open_rules_message_type_modal(self, interaction: discord.Interaction): + """Ouvre le modal de sélection du type de message""" + from .modules_security.rules import RulesMessageTypeModal + await interaction.response.send_modal( + RulesMessageTypeModal(self.guild.id, self.settings) + ) + + async def send_rules(self, interaction: discord.Interaction): + """Envoie le règlement dans le salon configuré""" + from commandes.modules_security.rules import RulesCog + + # Vérifier que tous les paramètres sont configurés + rules_channel_id = self.settings.get("rules_channel_id") + rules_accept_role_id = self.settings.get("rules_accept_role_id") + + if not rules_channel_id: + return await interaction.response.send_message( + "❌ Aucun salon configuré pour l'envoi du règlement.", + ephemeral=True + ) + + if not rules_accept_role_id: + return await interaction.response.send_message( + "❌ Aucun rôle d'acceptation configuré.", + ephemeral=True + ) + + # Vérifier le salon + channel = self.guild.get_channel(int(rules_channel_id)) + if not channel: + return await interaction.response.send_message( + "❌ Le salon configuré n'existe plus.", + ephemeral=True + ) + + # Vérifier le rôle + role = self.guild.get_role(int(rules_accept_role_id)) + if not role: + return await interaction.response.send_message( + "❌ Le rôle d'acceptation n'existe plus.", + ephemeral=True + ) + + # Envoyer le règlement + try: + rules_cog = self.bot.get_cog("RulesCog") + if rules_cog: + message = await rules_cog.send_rules_message(channel, self.settings) + if message: + # Activer le règlement + self.settings["rules_enabled"] = True + save_settings(self.guild.id, self.settings) + self.settings = load_settings(self.guild.id) + self.build_view() + + await interaction.response.edit_message(view=self) + await interaction.followup.send( + f"✅ Règlement envoyé avec succès dans {channel.mention} !", + ephemeral=True + ) + else: + await interaction.followup.send( + "❌ Erreur lors de l'envoi du règlement.", + ephemeral=True + ) + else: + await interaction.followup.send( + "❌ Le cog Rules n'est pas chargé.", + ephemeral=True + ) + except Exception as e: + await interaction.followup.send( + f"❌ Erreur: {e}", + ephemeral=True + ) + async def back_to_main(self, interaction: discord.Interaction): """Retour au menu principal""" self.category = None @@ -471,7 +682,7 @@ class SecurityView(discord.ui.View): embed = discord.Embed( title="🛡️ Centre de Sécurité Kuby", description="Gérez la protection de votre serveur", - color=0x2b2d31 + color=0x7289DA ) if self.guild.icon: @@ -520,7 +731,7 @@ class SecurityView(discord.ui.View): embed = discord.Embed( title=title, description=description, - color=0x2b2d31 + color=0x7289DA ) if self.guild.icon: @@ -589,6 +800,12 @@ class MainCategorySelect(discord.ui.Select): value="logs", description="Journalisation des événements" ), + discord.SelectOption( + label="Règlement", + emoji="📜", + value="rules", + description="Créer et envoyer un règlement" + ), discord.SelectOption( label="Whitelist", emoji="👥", @@ -634,6 +851,15 @@ class MainCategorySelect(discord.ui.Select): "• **Logs Serveur** : Active la journalisation\n" "• **Channel** : Salon où seront envoyés les logs" ), + "rules": view.create_category_embed( + "Configuration Règlement", + "Créez et envoyez un règlement pour votre serveur.\n\n" + "• **Titre** : Personnalisez le titre du règlement\n" + "• **Contenu** : Rédigez vos règles\n" + "• **Salon** : Choisissez où l'envoyer\n" + "• **Rôle** : Rôle attribué à l'acceptation\n\n" + "Les membres devront accepter le règlement pour accéder au serveur." + ), "whitelist": view.create_category_embed( "Gestion Whitelist", "Gérez les utilisateurs immunisés aux protections.\n\n" @@ -750,7 +976,7 @@ class Security(commands.Cog): settings = load_settings(interaction.guild.id) # Création de la vue - view = SecurityView(interaction, settings) + view = SecurityView(interaction, settings, bot=self.bot) embed = view.create_main_embed(interaction.user) if interaction.response.is_done(): diff --git a/data/security_settings.json b/data/security_settings.json old mode 100755 new mode 100644 index bf003a5..7801857 --- a/data/security_settings.json +++ b/data/security_settings.json @@ -1,27 +1,12 @@ { "1369669999345537145": { "anti_spam": true, - "anti_perm": true, - "anti_salon": true, - "anti_raid": true, - "anti_nuke": true, "anti_link": true, - "anti_mention": true, - "verification_enabled": true, - "spam_threshold": 5, - "raid_threshold": 3, - "nuke_threshold": 3, - "log_channel_id": 1396088860412346428, - "lockdown_enabled": false, - "auto_ban": true, - "webhook_protection": true, - "mass_delete_protection": true, - "invite_filter": true, - "file_scanning": true, - "ai_moderation": true, - "channel_block_enabled": false, - "server_logs": true, - "anti_channel_delete": true, - "anti_role_create": true + "rules_enabled": true, + "rules_title": "Test", + "rules_content": "vfkj,oejfrsknezfrijugn,krvjgfinkrze,fgjin,", + "rules_channel_id": 1369669999677145101, + "rules_accept_role_id": 1369769836028231730, + "rules_message_type": "embed" } } \ No newline at end of file