Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
942b23c956 | ||
|
|
3450cd031c | ||
|
|
252e169af5 |
@@ -27,7 +27,7 @@ from discordbot.moderation import (
|
||||
)
|
||||
from discordbot.welcome import sendWelcomeMessage, sendLeaveMessage, updateInviteCache
|
||||
from discordbot.youtube import checkYouTubeVideos
|
||||
from discordbot.auto_rooms import on_voice_state_update_auto_rooms, on_raw_reaction_add_auto_rooms, on_message_auto_rooms
|
||||
from discordbot.auto_rooms import on_voice_state_update_auto_rooms, on_raw_reaction_add_auto_rooms
|
||||
from protondb import searhProtonDb
|
||||
|
||||
class DiscordBot(discord.Client):
|
||||
@@ -151,10 +151,6 @@ bot = DiscordBot(intents=intents)
|
||||
async def on_message(message: Message):
|
||||
if message.author == bot.user:
|
||||
return
|
||||
|
||||
# Gestion des messages dans les auto rooms (avant le check des commandes !)
|
||||
await on_message_auto_rooms(bot, message)
|
||||
|
||||
if not message.content.startswith('!'):
|
||||
return
|
||||
command_name = message.content.split()[0]
|
||||
|
||||
+69
-294
@@ -16,14 +16,13 @@ _control_message_ids: dict[int, tuple[int, int]] = {}
|
||||
REACTIONS = [
|
||||
("🔓", "open", "Ouvert"),
|
||||
("🔒", "closed", "Fermé"),
|
||||
("🔐", "private", "Privé"),
|
||||
("🛡️", "private", "Privé"),
|
||||
("✅", "whitelist", "Liste blanche"),
|
||||
("🚫", "blacklist", "Liste noire"),
|
||||
("🧹", "purge", "Purge"),
|
||||
("👑", "transfer", "Propriété"),
|
||||
("🎤", "speak", "Micro"),
|
||||
("📹", "stream", "Vidéo"),
|
||||
("📊", "soundboards", "Soundboards"),
|
||||
("📝", "status", "Statut"),
|
||||
]
|
||||
|
||||
@@ -35,85 +34,40 @@ def _status_display(access_mode: str) -> str:
|
||||
if access_mode == "closed":
|
||||
return "🔒 Fermé"
|
||||
if access_mode == "private":
|
||||
return "🔐 Privé"
|
||||
return "🔒 Privé"
|
||||
return "🔓 Ouvert"
|
||||
|
||||
|
||||
def _status_emoji(access_mode: str) -> str:
|
||||
"""Emoji cadenas seul pour le nom du channel."""
|
||||
if access_mode == "private":
|
||||
return "🔐"
|
||||
return "🔓" if access_mode == "open" else "🔒"
|
||||
|
||||
|
||||
def _build_control_embed(owner: Member, voice_channel: discord.VoiceChannel, access_mode: str, room: dict = None) -> discord.Embed:
|
||||
"""Construit l'embed de config avec infos du salon."""
|
||||
def _build_control_embed(owner: Member, voice_channel: discord.VoiceChannel, access_mode: str) -> discord.Embed:
|
||||
"""Construit l’embed de config avec infos du salon."""
|
||||
embed = discord.Embed(
|
||||
title="⚙️ Configuration du salon",
|
||||
title="Configuration du salon",
|
||||
description=(
|
||||
"Voici l'espace de configuration de votre salon vocal temporaire. "
|
||||
"Les différentes options disponibles vous permettent de personnaliser les permissions de votre salon selon vos préférences."
|
||||
"Voici l’espace de configuration de votre salon vocal. "
|
||||
"Utilisez les réactions ci-dessous — seul le propriétaire peut réagir."
|
||||
),
|
||||
color=discord.Color.orange()
|
||||
color=discord.Color.blurple()
|
||||
)
|
||||
|
||||
# Récupération des infos
|
||||
whitelist = room.get("whitelist", set()) if room else set()
|
||||
blacklist = room.get("blacklist", set()) if room else set()
|
||||
whitelist_text = f"{len(whitelist)} membre(s)" if whitelist else "Aucun"
|
||||
blacklist_text = f"{len(blacklist)} membre(s)" if blacklist else "Aucun"
|
||||
|
||||
# Section Propriétaire
|
||||
embed.add_field(
|
||||
name=f"👤 Propriétaire du salon : {owner.display_name}",
|
||||
value="",
|
||||
inline=False
|
||||
)
|
||||
|
||||
# Section Modes d'accès
|
||||
mode_open = "🔓 **Ouvert**\nLe salon sera ouvert à tous les membres, sauf ceux figurant sur la liste noire."
|
||||
mode_closed = "🔒 **Fermé**\nLe salon sera visible de tous, mais seulement accessible à la liste blanche."
|
||||
mode_private = "🔐 **Privé**\nLe salon ne sera visible et accessible qu'aux membres de la liste blanche."
|
||||
|
||||
embed.add_field(name=mode_open, value="", inline=True)
|
||||
embed.add_field(name=mode_closed, value="", inline=True)
|
||||
embed.add_field(name=mode_private, value="", inline=True)
|
||||
|
||||
# Section Listes
|
||||
embed.add_field(
|
||||
name="📝 **Liste blanche**",
|
||||
value=f"Les membres présents dans cette liste pourront toujours rejoindre le salon.\n\n{whitelist_text}",
|
||||
inline=True
|
||||
)
|
||||
embed.add_field(
|
||||
name="🚫 **Liste noire**",
|
||||
value=f"Les membres présents dans cette liste ne pourront jamais rejoindre le salon.\n\n{blacklist_text}",
|
||||
inline=True
|
||||
)
|
||||
embed.add_field(name="\u200b", value="", inline=True) # Spacer
|
||||
|
||||
# Section Purge
|
||||
embed.add_field(
|
||||
name="🧹 **Purge**",
|
||||
value="Déconnecter tous les membres du salon vocal à l'exception de ceux présents dans la liste blanche.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
# Section Transfert
|
||||
embed.add_field(
|
||||
name="👑 **Transférer**",
|
||||
value="Transférer la gestion du salon au membre de votre choix.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
# Note importante
|
||||
embed.add_field(
|
||||
name="💡",
|
||||
value="Les membres de la liste blanche ne sont pas impactés par les permissions refusées aux membres.",
|
||||
inline=False
|
||||
)
|
||||
|
||||
embed.set_footer(text="Réagissez avec les émojis ci-dessous pour configurer votre salon")
|
||||
members_count = len(voice_channel.members)
|
||||
user_limit = voice_channel.user_limit or 0
|
||||
limit_text = f"{user_limit} max" if user_limit else "Illimitée"
|
||||
members_text = f"{members_count} / {user_limit}" if user_limit else str(members_count)
|
||||
bitrate_kbps = (voice_channel.bitrate or 0) // 1000
|
||||
|
||||
embed.add_field(name="Propriétaire", value=owner.mention, inline=True)
|
||||
embed.add_field(name="Statut du salon", value=_status_display(access_mode), inline=True)
|
||||
embed.add_field(name="Nom du salon", value=voice_channel.name, inline=True)
|
||||
embed.add_field(name="Membres", value=members_text, inline=True)
|
||||
embed.add_field(name="Limite", value=limit_text, inline=True)
|
||||
embed.add_field(name="Bitrate", value=f"{bitrate_kbps} kbps", inline=True)
|
||||
embed.add_field(name="Accès", value="🔓 Ouvert · 🔒 Fermé · 🛡️ Privé", inline=False)
|
||||
embed.add_field(name="Listes", value="✅ Liste blanche · 🚫 Liste noire", inline=False)
|
||||
embed.add_field(name="Actions", value="🧹 Purge · 👑 Propriété · 🎤 Micro · 📹 Vidéo · 📝 Statut", inline=False)
|
||||
return embed
|
||||
|
||||
|
||||
@@ -160,26 +114,11 @@ def _find_room_by_message(message_id: int) -> Optional[tuple[int, int, dict]]:
|
||||
async def _apply_access_mode(channel: discord.VoiceChannel, mode: str, whitelist: set, blacklist: set):
|
||||
guild = channel.guild
|
||||
everyone = guild.default_role
|
||||
overwrites = dict(channel.overwrites) # Récupérer les overwrites existants
|
||||
|
||||
# Préserver les permissions existantes pour everyone (stream, speak, soundboards, etc.)
|
||||
existing_everyone_ow = overwrites.get(everyone, discord.PermissionOverwrite())
|
||||
overwrites = {}
|
||||
everyone_ow = discord.PermissionOverwrite()
|
||||
|
||||
# Copier les permissions importantes qui ne doivent pas être écrasées
|
||||
everyone_ow.stream = existing_everyone_ow.stream
|
||||
everyone_ow.speak = existing_everyone_ow.speak
|
||||
everyone_ow.use_soundboard = existing_everyone_ow.use_soundboard
|
||||
|
||||
if mode == "open":
|
||||
everyone_ow.connect = True
|
||||
everyone_ow.view_channel = True
|
||||
# Retirer les overwrites des membres qui ne sont plus dans la blacklist
|
||||
for target in list(overwrites.keys()):
|
||||
if target != everyone and isinstance(target, discord.Member):
|
||||
if target.id not in blacklist:
|
||||
overwrites.pop(target, None)
|
||||
# Ajouter les overwrites pour la blacklist
|
||||
for uid in blacklist:
|
||||
m = guild.get_member(uid)
|
||||
if m:
|
||||
@@ -187,12 +126,6 @@ async def _apply_access_mode(channel: discord.VoiceChannel, mode: str, whitelist
|
||||
elif mode == "closed":
|
||||
everyone_ow.connect = False
|
||||
everyone_ow.view_channel = True
|
||||
# Retirer les overwrites des membres qui ne sont plus dans la whitelist
|
||||
for target in list(overwrites.keys()):
|
||||
if target != everyone and isinstance(target, discord.Member):
|
||||
if target.id not in whitelist:
|
||||
overwrites.pop(target, None)
|
||||
# Ajouter les overwrites pour la whitelist
|
||||
for uid in whitelist:
|
||||
m = guild.get_member(uid)
|
||||
if m:
|
||||
@@ -200,17 +133,10 @@ async def _apply_access_mode(channel: discord.VoiceChannel, mode: str, whitelist
|
||||
elif mode == "private":
|
||||
everyone_ow.connect = False
|
||||
everyone_ow.view_channel = False
|
||||
# Retirer les overwrites des membres qui ne sont plus dans la whitelist
|
||||
for target in list(overwrites.keys()):
|
||||
if target != everyone and isinstance(target, discord.Member):
|
||||
if target.id not in whitelist:
|
||||
overwrites.pop(target, None)
|
||||
# Ajouter les overwrites pour la whitelist
|
||||
for uid in whitelist:
|
||||
m = guild.get_member(uid)
|
||||
if m:
|
||||
overwrites[m] = discord.PermissionOverwrite(connect=True, view_channel=True)
|
||||
|
||||
overwrites[everyone] = everyone_ow
|
||||
await channel.edit(overwrites=overwrites)
|
||||
|
||||
@@ -219,7 +145,7 @@ async def _handle_reaction_action(bot: discord.Client, guild_id: int, owner_id:
|
||||
"""channel = salon vocal (partie texte / onglet Discussion)."""
|
||||
room = _get_room(guild_id, owner_id)
|
||||
if not room:
|
||||
await channel.send("Ce salon n'existe plus.")
|
||||
await channel.send("Ce salon n’existe plus.")
|
||||
return
|
||||
voice_channel = bot.get_channel(room["voice_channel_id"])
|
||||
if not voice_channel or not isinstance(voice_channel, discord.VoiceChannel):
|
||||
@@ -229,27 +155,36 @@ async def _handle_reaction_action(bot: discord.Client, guild_id: int, owner_id:
|
||||
if action in ("open", "closed", "private"):
|
||||
room["access_mode"] = action
|
||||
await _apply_access_mode(voice_channel, action, room.get("whitelist", set()), room.get("blacklist", set()))
|
||||
await channel.send(f"✅ Accès du salon défini sur **{_status_display(action)}**.")
|
||||
# Mettre à jour l'embed
|
||||
await _update_control_panel(bot, guild_id, owner_id, channel)
|
||||
# Mettre à jour le cadenas dans le nom du channel
|
||||
try:
|
||||
base_name = voice_channel.name.rstrip(" 🔓🔒")
|
||||
new_name = f"{base_name} {_status_emoji(action)}"
|
||||
await voice_channel.edit(name=new_name)
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
await channel.send(f"Accès du salon défini sur **{action}**.")
|
||||
# Mettre à jour uniquement le statut (cadenas) dans le message de config
|
||||
control_message_id = room.get("control_message_id")
|
||||
if control_message_id:
|
||||
try:
|
||||
msg = await channel.fetch_message(control_message_id)
|
||||
if msg.embeds:
|
||||
embed = msg.embeds[0].copy()
|
||||
for i, f in enumerate(embed.fields):
|
||||
if f.name == "Statut du salon":
|
||||
embed.set_field_at(i, name="Statut du salon", value=_status_display(action), inline=f.inline)
|
||||
break
|
||||
else:
|
||||
embed.add_field(name="Statut du salon", value=_status_display(action), inline=False)
|
||||
await msg.edit(embed=embed)
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
|
||||
elif action == "whitelist":
|
||||
whitelist = room.get("whitelist", set())
|
||||
whitelist_text = ", ".join([f"<@{uid}>" for uid in whitelist]) if whitelist else "Aucun membre"
|
||||
await channel.send(
|
||||
f"**📝 Liste blanche actuelle :** {whitelist_text}\n\n"
|
||||
f"Mentionnez un membre pour l'ajouter ou le retirer de la liste blanche."
|
||||
)
|
||||
room["awaiting_whitelist"] = True
|
||||
await channel.send("Liste blanche : mentionnez un membre pour l’ajouter/retirer.")
|
||||
|
||||
elif action == "blacklist":
|
||||
blacklist = room.get("blacklist", set())
|
||||
blacklist_text = ", ".join([f"<@{uid}>" for uid in blacklist]) if blacklist else "Aucun membre"
|
||||
await channel.send(
|
||||
f"**🚫 Liste noire actuelle :** {blacklist_text}\n\n"
|
||||
f"Mentionnez un membre pour l'ajouter ou le retirer de la liste noire."
|
||||
)
|
||||
room["awaiting_blacklist"] = True
|
||||
await channel.send("Liste noire : mentionnez un membre pour l’ajouter/retirer.")
|
||||
|
||||
elif action == "purge":
|
||||
whitelist = room.get("whitelist", set())
|
||||
@@ -262,80 +197,30 @@ async def _handle_reaction_action(bot: discord.Client, guild_id: int, owner_id:
|
||||
kicked += 1
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
await channel.send(f"🧹 Purge effectuée : {kicked} membre(s) déconnecté(s).")
|
||||
await channel.send(f"Purge effectuée : {kicked} membre(s) déconnecté(s).")
|
||||
|
||||
elif action == "transfer":
|
||||
await channel.send(
|
||||
f"**👑 Transfert de propriété**\n\n"
|
||||
f"Mentionnez le membre à qui vous souhaitez transférer la gestion du salon."
|
||||
)
|
||||
room["awaiting_transfer"] = True
|
||||
await channel.send("Transférer le salon : mentionnez le membre à qui donner la propriété.")
|
||||
|
||||
elif action in ("speak", "stream", "soundboards"):
|
||||
elif action in ("speak", "stream"):
|
||||
everyone = voice_channel.guild.default_role
|
||||
overwrites = dict(voice_channel.overwrites)
|
||||
ow = overwrites.get(everyone) or discord.PermissionOverwrite()
|
||||
|
||||
# BUG FIX : Par défaut, Discord autorise stream, speak et soundboards
|
||||
# Si la permission n'est pas explicitement définie (None), on considère qu'elle est True
|
||||
current = getattr(ow, action)
|
||||
if current is None:
|
||||
# Permission non définie = autorisée par défaut dans Discord
|
||||
# On veut la désactiver lors du premier clic
|
||||
setattr(ow, action, False)
|
||||
new_value = False
|
||||
else:
|
||||
# Permission définie, on l'inverse
|
||||
setattr(ow, action, not current)
|
||||
new_value = not current
|
||||
|
||||
setattr(ow, action, not current if current is not None else False)
|
||||
overwrites[everyone] = ow
|
||||
await voice_channel.edit(overwrites=overwrites)
|
||||
|
||||
labels = {"speak": "Micro", "stream": "Vidéo/Partage d'écran", "soundboards": "Soundboards"}
|
||||
label = labels.get(action, action.capitalize())
|
||||
await channel.send(f"{label} : {'autorisé' if new_value else 'désactivé'} pour tous.")
|
||||
label = "Micro" if action == "speak" else "Vidéo"
|
||||
await channel.send(f"{label} : {'autorisé' if getattr(ow, action) else 'désactivé'} pour tous.")
|
||||
|
||||
elif action == "status":
|
||||
current_status = voice_channel.status or "Aucun statut défini"
|
||||
await channel.send(
|
||||
f"**Statut actuel du salon :** {current_status}\n\n"
|
||||
f"Pour modifier le statut du salon (le texte affiché en haut du salon vocal), "
|
||||
f"répondez avec le nouveau statut (max 500 caractères).\n"
|
||||
f"💡 Pour supprimer le statut, répondez avec `clear` ou `effacer`."
|
||||
)
|
||||
room["awaiting_status"] = True
|
||||
status_text = _status_display(room.get("access_mode", "open"))
|
||||
await channel.send(f"Statut du salon : {status_text}\nRépondez avec le nouveau nom du salon pour le modifier.")
|
||||
|
||||
|
||||
async def _update_control_panel(bot: discord.Client, guild_id: int, owner_id: int, channel):
|
||||
"""Met à jour le panneau de contrôle avec les nouvelles informations."""
|
||||
room = _get_room(guild_id, owner_id)
|
||||
if not room:
|
||||
return
|
||||
|
||||
control_message_id = room.get("control_message_id")
|
||||
if not control_message_id:
|
||||
return
|
||||
|
||||
voice_channel = bot.get_channel(room["voice_channel_id"])
|
||||
if not voice_channel or not isinstance(voice_channel, discord.VoiceChannel):
|
||||
return
|
||||
|
||||
owner = voice_channel.guild.get_member(owner_id)
|
||||
if not owner:
|
||||
return
|
||||
|
||||
try:
|
||||
msg = await channel.fetch_message(control_message_id)
|
||||
embed = _build_control_embed(owner, voice_channel, room.get("access_mode", "open"), room)
|
||||
await msg.edit(embed=embed)
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
|
||||
|
||||
async def send_control_panel(bot: discord.Client, guild_id: int, owner: Member, voice_channel: discord.VoiceChannel, room: dict) -> Optional[int]:
|
||||
"""Envoie le message de config avec réactions dans la partie texte du salon vocal (onglet Discussion). Seul le proprio peut réagir. Retourne l'id du message."""
|
||||
embed = _build_control_embed(owner, voice_channel, "open", room)
|
||||
async def send_control_panel(bot: discord.Client, guild_id: int, owner: Member, voice_channel: discord.VoiceChannel) -> Optional[int]:
|
||||
"""Envoie le message de config avec réactions dans la partie texte du salon vocal (onglet Discussion). Seul le proprio peut réagir. Retourne l’id du message."""
|
||||
embed = _build_control_embed(owner, voice_channel, "open")
|
||||
|
||||
try:
|
||||
# Message dans la partie texte du vocal (onglet Discussion à droite)
|
||||
@@ -344,7 +229,7 @@ async def send_control_panel(bot: discord.Client, guild_id: int, owner: Member,
|
||||
await msg.add_reaction(emoji)
|
||||
return msg.id
|
||||
except discord.HTTPException as e:
|
||||
logging.error(f"Impossible d'envoyer le panneau Auto Room dans le vocal : {e}")
|
||||
logging.error(f"Impossible d’envoyer le panneau Auto Room dans le vocal : {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -360,8 +245,8 @@ async def on_voice_state_update_auto_rooms(bot: discord.Client, member: Member,
|
||||
|
||||
if after.channel and after.channel.id == trigger_channel_id:
|
||||
category = after.channel.category
|
||||
# Nom du salon (simple, sans emoji pour éviter le rate limiting)
|
||||
channel_name = f"Salon de {member.display_name}"
|
||||
# Nom du salon avec statut (cadenas) à la création
|
||||
channel_name = f"Salon de {member.display_name} {_status_emoji('open')}"
|
||||
try:
|
||||
new_channel = await guild.create_voice_channel(
|
||||
name=channel_name,
|
||||
@@ -369,22 +254,16 @@ async def on_voice_state_update_auto_rooms(bot: discord.Client, member: Member,
|
||||
reason="Auto room"
|
||||
)
|
||||
await member.move_to(new_channel)
|
||||
|
||||
# Créer la room data d'abord
|
||||
room_data = {
|
||||
control_message_id = await send_control_panel(bot, guild.id, member, new_channel)
|
||||
_set_room(guild.id, member.id, {
|
||||
"guild_id": guild.id,
|
||||
"voice_channel_id": new_channel.id,
|
||||
"control_message_id": None, # Sera mis à jour après
|
||||
"control_message_id": control_message_id,
|
||||
"owner_id": member.id,
|
||||
"whitelist": set(),
|
||||
"blacklist": set(),
|
||||
"access_mode": "open",
|
||||
}
|
||||
|
||||
control_message_id = await send_control_panel(bot, guild.id, member, new_channel, room_data)
|
||||
room_data["control_message_id"] = control_message_id
|
||||
_set_room(guild.id, member.id, room_data)
|
||||
|
||||
})
|
||||
logging.info(f"Auto room créé : {new_channel.name} pour {member.display_name}")
|
||||
except discord.HTTPException as e:
|
||||
logging.error(f"Erreur création auto room : {e}")
|
||||
@@ -408,110 +287,6 @@ async def on_voice_state_update_auto_rooms(bot: discord.Client, member: Member,
|
||||
pass
|
||||
|
||||
|
||||
async def on_message_auto_rooms(bot: discord.Client, message: discord.Message):
|
||||
"""Gère les messages dans les salons vocaux pour les actions (statut, liste blanche/noire, etc.)."""
|
||||
if message.author.bot:
|
||||
return
|
||||
if not ConfigurationHelper().getValue("auto_rooms_enable"):
|
||||
return
|
||||
|
||||
# Vérifier si c'est dans un salon vocal (partie texte)
|
||||
if not isinstance(message.channel, discord.VoiceChannel):
|
||||
return
|
||||
|
||||
# Trouver si c'est une auto room
|
||||
result = _find_room_by_channel(message.guild.id, message.channel.id)
|
||||
if not result:
|
||||
return
|
||||
|
||||
owner_id, room = result
|
||||
|
||||
# Seul le propriétaire peut interagir
|
||||
if message.author.id != owner_id:
|
||||
return
|
||||
|
||||
voice_channel = message.channel
|
||||
|
||||
# Gestion du statut de salon
|
||||
if room.get("awaiting_status"):
|
||||
room["awaiting_status"] = False
|
||||
new_status = message.content.strip()
|
||||
|
||||
try:
|
||||
if new_status.lower() in ("clear", "effacer", "supprimer", "delete"):
|
||||
await voice_channel.edit(status=None)
|
||||
await message.channel.send("✅ Le statut du salon a été supprimé.")
|
||||
elif len(new_status) > 500:
|
||||
await message.channel.send("❌ Le statut ne peut pas dépasser 500 caractères.")
|
||||
room["awaiting_status"] = True # Réessayer
|
||||
else:
|
||||
await voice_channel.edit(status=new_status)
|
||||
await message.channel.send(f"✅ Le statut du salon a été mis à jour : **{new_status}**")
|
||||
except discord.HTTPException as e:
|
||||
await message.channel.send(f"❌ Erreur lors de la modification du statut : {e}")
|
||||
return
|
||||
|
||||
# Gestion de la liste blanche (si en attente)
|
||||
if room.get("awaiting_whitelist"):
|
||||
room["awaiting_whitelist"] = False
|
||||
if message.mentions:
|
||||
target = message.mentions[0]
|
||||
whitelist = room.get("whitelist", set())
|
||||
if target.id in whitelist:
|
||||
whitelist.remove(target.id)
|
||||
await message.channel.send(f"✅ {target.mention} a été retiré de la liste blanche.")
|
||||
else:
|
||||
whitelist.add(target.id)
|
||||
await message.channel.send(f"✅ {target.mention} a été ajouté à la liste blanche.")
|
||||
room["whitelist"] = whitelist
|
||||
await _apply_access_mode(voice_channel, room.get("access_mode", "open"), whitelist, room.get("blacklist", set()))
|
||||
await _update_control_panel(bot, message.guild.id, owner_id, message.channel)
|
||||
return
|
||||
|
||||
# Gestion de la liste noire (si en attente)
|
||||
if room.get("awaiting_blacklist"):
|
||||
room["awaiting_blacklist"] = False
|
||||
if message.mentions:
|
||||
target = message.mentions[0]
|
||||
blacklist = room.get("blacklist", set())
|
||||
if target.id in blacklist:
|
||||
blacklist.remove(target.id)
|
||||
await message.channel.send(f"✅ {target.mention} a été retiré de la liste noire.")
|
||||
else:
|
||||
blacklist.add(target.id)
|
||||
await message.channel.send(f"✅ {target.mention} a été ajouté à la liste noire.")
|
||||
room["blacklist"] = blacklist
|
||||
await _apply_access_mode(voice_channel, room.get("access_mode", "open"), room.get("whitelist", set()), blacklist)
|
||||
await _update_control_panel(bot, message.guild.id, owner_id, message.channel)
|
||||
return
|
||||
|
||||
# Gestion du transfert de propriété (si en attente)
|
||||
if room.get("awaiting_transfer"):
|
||||
room["awaiting_transfer"] = False
|
||||
if message.mentions:
|
||||
new_owner = message.mentions[0]
|
||||
if new_owner.id == owner_id:
|
||||
await message.channel.send("❌ Vous êtes déjà le propriétaire du salon.")
|
||||
return
|
||||
|
||||
# Transférer la propriété
|
||||
old_owner_id = owner_id
|
||||
_del_room(message.guild.id, old_owner_id)
|
||||
room["owner_id"] = new_owner.id
|
||||
_set_room(message.guild.id, new_owner.id, room)
|
||||
|
||||
# Renommer le salon (optionnel, peut être commenté pour éviter rate limit)
|
||||
try:
|
||||
new_name = f"Salon de {new_owner.display_name}"
|
||||
await voice_channel.edit(name=new_name)
|
||||
except discord.HTTPException as e:
|
||||
logging.warning(f"Impossible de renommer le salon lors du transfert : {e}")
|
||||
|
||||
await message.channel.send(f"✅ La propriété du salon a été transférée à {new_owner.mention}.")
|
||||
await _update_control_panel(bot, message.guild.id, new_owner.id, message.channel)
|
||||
return
|
||||
|
||||
|
||||
async def on_raw_reaction_add_auto_rooms(bot: discord.Client, payload: discord.RawReactionActionEvent):
|
||||
"""Seul le propriétaire peut réagir ; on retire la réaction des autres."""
|
||||
if payload.user_id == bot.user.id:
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
{{ 'Enregistrer' if notification else 'Ajouter la notification' }}
|
||||
</button>
|
||||
{% if notification %}
|
||||
<a href="{{ url_for('openYouTube') }}"
|
||||
<a href="{{ url_for('youtube') }}"
|
||||
class="px-6 py-2.5 bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-gray-700 dark:text-gray-200 font-medium rounded-lg transition-colors">
|
||||
Annuler
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user