104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
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=0x2F3136,
|
|
)
|
|
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=0x2F3136,
|
|
)
|
|
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=0x2F3136,
|
|
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))
|