Kuby/commandes/blacklist.py

299 lines
13 KiB
Python
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import discord
from discord.ext import commands, tasks
from discord import app_commands
import json
import os
import asyncio
from datetime import datetime, timedelta
BLACKLIST_FILE = "data/blacklist.json"
AGENTS_FILE = "data/agents.json"
TICKETS_FILE = "data/tickets_blacklist.json"
MAIN_GUILD_ID = 1369669999345537145 # ID serveur principal
TICKET_CATEGORY_ID = 1369669999677145104 # Catégorie tickets
# --------- Utils JSON ---------
def load_json(path, default):
if not os.path.exists(path):
with open(path, "w") as f:
json.dump(default, f, indent=4)
with open(path, "r") as f:
return json.load(f)
def save_json(path, data):
with open(path, "w") as f:
json.dump(data, f, indent=4)
# --------- Cog ---------
class Blacklist(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.check_ban_expiry.start() # boucle auto pour bannir après 7j
def cog_unload(self):
self.check_ban_expiry.cancel()
async def cog_load(self):
"""Enregistrer les vues persistantes au démarrage"""
await self._register_persistent_views()
async def _register_persistent_views(self):
"""Enregistre les vues pour les tickets ouverts"""
try:
tickets = load_json(TICKETS_FILE, {})
for user_id_str, data in tickets.items():
user_id = int(user_id_str)
# Enregistrer le bouton d'ouverture de ticket
view = TicketButton(user_id)
self.bot.add_view(view)
# Enregistrer le bouton de fermeture
close_view = CloseTicketView(user_id)
self.bot.add_view(close_view)
print(f"[Blacklist] {len(tickets)} vues de tickets enregistrées")
except Exception as e:
print(f"[Blacklist] Erreur lors de l'enregistrement des vues: {e}")
def is_agent(self, user_id: int):
agents = load_json(AGENTS_FILE, {"agents": []})
return str(user_id) in agents["agents"]
@app_commands.command(name="blacklist", description="Blacklist un utilisateur")
async def blacklist(self, interaction: discord.Interaction, user: discord.User, reason: str = "Aucune raison fournie"):
if not self.is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
blacklist = load_json(BLACKLIST_FILE, {})
blacklist[str(user.id)] = {
"reason": reason,
"timestamp": datetime.utcnow().isoformat()
}
save_json(BLACKLIST_FILE, blacklist)
# Préparer l'embed pro
embed = discord.Embed(
title="🚫 Mise en blacklist - Réseau Omega Kube",
description=(
f"Bonjour {user.mention},\n\n"
f"Vous avez été **blacklisté** du **Réseau Omega Kube**.\n\n"
f"**Raison :** {reason}\n\n"
"⚠️ Vous êtes banni de tous nos serveurs partenaires. "
"Cependant, vous restez présent sur le **serveur principal**, "
"mais tu ne peux pas interagir avec la communauté.\n\n"
"📩 Vous disposez de **7 jours** pour contester cette décision en ouvrant un ticket via le bouton ci-dessous.\n\n"
"⏳ Passé ce délai, vous serez **définitivement banni de tout le réseau**, sans autre recours possible."
),
color=discord.Color.red()
)
embed.set_footer(text="Omega Kube - Nixfix06 & Mgstudios")
view = TicketButton(user.id)
# Envoyer MP avant action
try:
await user.send(embed=embed, view=view)
await asyncio.sleep(2)
except:
pass
# Bannir de tous les serveurs sauf principal
for guild in self.bot.guilds:
if guild.id == MAIN_GUILD_ID:
member = guild.get_member(user.id)
if member:
try:
# Supprime la permission d'écrire partout
for channel in guild.channels:
overwrite = channel.overwrites_for(member)
overwrite.send_messages = False
overwrite.add_reactions = False
await channel.set_permissions(member, overwrite=overwrite)
except:
pass
else:
member = guild.get_member(user.id)
if member:
try:
await member.ban(reason=f"Blacklisté : {reason}")
except:
pass
await interaction.response.send_message(
f"{user.mention} blacklisté, banni des partenaires et restreint sur le serveur principal.",
ephemeral=True
)
@app_commands.command(name="unblacklist", description="Retirer un utilisateur de la blacklist")
async def unblacklist(self, interaction: discord.Interaction, user: discord.User):
if not self.is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
blacklist = load_json(BLACKLIST_FILE, {})
if str(user.id) in blacklist:
del blacklist[str(user.id)]
save_json(BLACKLIST_FILE, blacklist)
await interaction.response.send_message(f"{user.mention} retiré de la blacklist.", ephemeral=True)
else:
await interaction.response.send_message("❌ Cet utilisateur nest pas blacklisté.", ephemeral=True)
@tasks.loop(hours=1)
async def check_ban_expiry(self):
"""Boucle qui vérifie si 7 jours sont écoulés → ban total."""
blacklist = load_json(BLACKLIST_FILE, {})
to_remove = []
for user_id, data in blacklist.items():
try:
ts = datetime.fromisoformat(data["timestamp"])
if datetime.utcnow() > ts + timedelta(days=7):
# Ban définitif partout
user = await self.bot.fetch_user(int(user_id))
for guild in self.bot.guilds:
member = guild.get_member(int(user_id))
if member:
try:
await member.ban(reason="Blacklist définitive (7j écoulés)")
except:
pass
to_remove.append(user_id)
except:
continue
for uid in to_remove:
del blacklist[uid]
save_json(BLACKLIST_FILE, blacklist)
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author.bot:
return
tickets = load_json(TICKETS_FILE, {})
if isinstance(message.channel, discord.DMChannel):
user_id = str(message.author.id)
if user_id in tickets:
guild = self.bot.get_guild(MAIN_GUILD_ID)
ticket_channel = guild.get_channel(tickets[user_id]["channel_id"])
if ticket_channel:
embed = discord.Embed(
description=message.content,
color=discord.Color.blue()
).set_author(name=message.author, icon_url=message.author.display_avatar.url)
await ticket_channel.send(embed=embed)
else:
for user_id, data in tickets.items():
if message.channel.id == data["channel_id"] and self.is_agent(message.author.id):
user = await self.bot.fetch_user(int(user_id))
try:
embed = discord.Embed(
description=message.content,
color=discord.Color.green()
).set_author(name=f"Agent {message.author}", icon_url=message.author.display_avatar.url)
await user.send(embed=embed)
except:
pass
# --------- Boutons ---------
class TicketButton(discord.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=None)
self.user_id = user_id
@discord.ui.button(label="📩 Ouvrir une demande de révision", style=discord.ButtonStyle.primary, custom_id="blacklist_open_ticket")
async def open_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user.id != self.user_id:
return await interaction.response.send_message("❌ Ce bouton ne tappartient pas.", ephemeral=True)
tickets = load_json(TICKETS_FILE, {})
if str(self.user_id) in tickets:
return await interaction.response.send_message("❌ Tu as déjà un ticket ouvert.", ephemeral=True)
guild = interaction.client.get_guild(MAIN_GUILD_ID)
category = guild.get_channel(TICKET_CATEGORY_ID)
ticket_channel = await guild.create_text_channel(
name=f"ticket-{self.user_id}",
category=category,
topic=f"Ticket de l'utilisateur {self.user_id}"
)
tickets[str(self.user_id)] = {"channel_id": ticket_channel.id}
save_json(TICKETS_FILE, tickets)
view_close = CloseTicketView(self.user_id)
embed = discord.Embed(
title="📩 Ticket ouvert",
description=f"Un utilisateur blacklisté (<@{self.user_id}>) a ouvert une demande de révision.\n\nUn agent Omega Kube prendra en charge ce dossier.",
color=discord.Color.blurple()
)
await ticket_channel.send(embed=embed, view=view_close)
await interaction.response.send_message("✅ Ton ticket a bien été créé.", ephemeral=True)
button.disabled = True
self.stop()
class CloseTicketView(discord.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=None)
self.user_id = user_id
@discord.ui.button(label="❌ Fermer le ticket", style=discord.ButtonStyle.danger, custom_id="blacklist_close_ticket")
async def close_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
if not interaction.client.get_cog("Blacklist").is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Seuls les agents peuvent fermer ce ticket.", ephemeral=True)
view = ConfirmCloseView(self.user_id)
await interaction.response.send_message("⚠️ Veux-tu vraiment fermer ce ticket ?", view=view, ephemeral=True)
class ConfirmCloseView(discord.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=30)
self.user_id = user_id
@discord.ui.button(label="✅ Oui", style=discord.ButtonStyle.success, custom_id="blacklist_confirm_close")
async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
if not interaction.client.get_cog("Blacklist").is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
tickets = load_json(TICKETS_FILE, {})
if str(self.user_id) in tickets:
channel_id = tickets[str(self.user_id)]["channel_id"]
guild = interaction.guild
channel = guild.get_channel(channel_id)
if channel:
await channel.delete()
del tickets[str(self.user_id)]
save_json(TICKETS_FILE, tickets)
user = await interaction.client.fetch_user(int(self.user_id))
try:
embed = discord.Embed(
title="🔒 Ticket fermé",
description="Ton ticket a été examiné et fermé.\n\n⚠️ Après analyse, la sanction est confirmée et tu restes blacklisté de lensemble du réseau.",
color=discord.Color.orange()
)
await user.send(embed=embed)
await asyncio.sleep(2)
except:
pass
for guild in interaction.client.guilds:
member = guild.get_member(self.user_id)
if member:
try:
await member.ban(reason="Ticket blacklist fermé")
except:
pass
await interaction.response.send_message("✅ Ticket fermé avec succès.", ephemeral=True)
@discord.ui.button(label="❌ Non", style=discord.ButtonStyle.secondary, custom_id="blacklist_cancel_close")
async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
# --------- Setup ---------
async def setup(bot: commands.Bot):
await bot.add_cog(Blacklist(bot))