VisionApp/features/security.py

105 lines
4 KiB
Python
Raw Normal View History

from __future__ import annotations
import logging
from datetime import datetime, timedelta, timezone
import discord
from discord import app_commands
from discord.ext import commands
from features import shared
logger = logging.getLogger("vision")
_raids: dict[int, list[tuple[datetime, str]]] = {}
class Security(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
@commands.Cog.listener()
async def on_member_join(self, member: discord.Member):
cfg = shared.section(member.guild.id, "security")
if not cfg.get("antiraid"):
return
now = datetime.now(timezone.utc)
raids = _raids.setdefault(member.guild.id, [])
raids.append((now, str(member.id)))
cutoff = now - timedelta(seconds=cfg.get("antiraid_window", 10))
_raids[member.guild.id] = [(t, uid) for t, uid in raids if t > cutoff]
threshold = cfg.get("antiraid_threshold", 5)
if len(_raids[member.guild.id]) >= threshold:
try:
await member.guild.edit(verification_level=discord.VerificationLevel.highest)
embed = discord.Embed(
title="🛡️ Alerte Antiraid",
description=f"**{len(_raids[member.guild.id])}** membres en {cfg.get('antiraid_window', 10)}s.\n"
f"**Verification_level** augmenté automatiquement.",
color=discord.Color.red(),
)
if cfg.get("log_channel_id"):
ch = member.guild.get_channel(cfg["log_channel_id"])
if ch:
await ch.send(embed=embed)
except discord.HTTPException:
pass
_raids[member.guild.id] = []
@commands.Cog.listener()
async def on_member_ban(self, guild: discord.Guild, user: discord.User | discord.Member):
cfg = shared.section(guild.id, "security")
if not cfg.get("ban_protection"):
return
embed = discord.Embed(
title="🔨 Protection Ban",
description=f"**{user}** a été banni de **{guild.name}**",
color=discord.Color.orange(),
)
if cfg.get("log_channel_id"):
ch = guild.get_channel(cfg["log_channel_id"])
if ch:
await ch.send(embed=embed)
@commands.Cog.listener()
async def on_member_remove(self, member: discord.Member):
cfg = shared.section(member.guild.id, "security")
if not cfg.get("join_leave_log"):
return
embed = discord.Embed(
title="📥 Départ",
description=f"**{member}** a quitté **{member.guild.name}**",
color=discord.Color.grey(),
timestamp=datetime.now(timezone.utc),
)
if cfg.get("log_channel_id"):
ch = member.guild.get_channel(cfg["log_channel_id"])
if ch:
await ch.send(embed=embed)
@app_commands.command(name="security_setup", description="Configurer la sécurité")
@app_commands.describe(log_channel="Canal de logs", antiraid_threshold="Seuil antiraid (membres/10s)")
@app_commands.checks.has_permissions(manage_guild=True)
async def security_setup(
self, interaction: discord.Interaction, log_channel: discord.TextChannel, antiraid_threshold: int = 5
):
cfg = shared.get(interaction.guild_id, "security")
cfg["enabled"] = True
cfg["log_channel_id"] = log_channel.id
cfg["antiraid"] = True
cfg["antiraid_threshold"] = antiraid_threshold
cfg["antiraid_window"] = 10
cfg["ban_protection"] = True
cfg["join_leave_log"] = True
shared.set(interaction.guild_id, "security", cfg)
await interaction.response.send_message(
f"Sécurité activée. Logs dans {log_channel.mention}. Seuil antiraid : {antiraid_threshold} membres / 10s.",
ephemeral=True,
)
async def setup(bot: commands.Bot):
await bot.add_cog(Security(bot))