feat: Enhance ban system with interaction checks for slash commands

This commit is contained in:
Slipstream 2025-05-20 20:07:52 -06:00
parent dd334c5f24
commit b8248ee7a9
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD

View File

@ -41,9 +41,15 @@ class BanSystemCog(commands.Cog):
# Setup database table when the cog is loaded
self.bot.loop.create_task(self._setup_database())
# Register the global check
# Register the global check for prefix commands
self.bot.add_check(self.check_if_user_banned)
# Store the original interaction check if it exists
self.original_interaction_check = getattr(self.bot.tree, 'interaction_check', None)
# Register our interaction check for slash commands
self.bot.tree.interaction_check = self.interaction_check
async def _setup_database(self):
"""Create the banned_users table if it doesn't exist."""
# Wait for the bot to be ready to ensure the database pool is available
@ -97,8 +103,30 @@ class BanSystemCog(commands.Cog):
except Exception as e:
log.error(f"Error loading banned users: {e}")
@commands.Cog.listener()
async def on_interaction(self, interaction: discord.Interaction):
"""Listener for all interactions to check if the user is banned."""
# Skip check for the bot owner
if interaction.user.id == self.bot.owner_id:
return
# Check if the user is banned
if interaction.user.id in self.banned_users_cache:
# Get the ban info
ban_info = self.banned_users_cache[interaction.user.id]
# If the interaction hasn't been responded to yet, respond with the ban message
if not interaction.response.is_done():
await interaction.response.send_message(ban_info['message'], ephemeral=True)
# Log the blocked interaction
log.warning(f"Blocked interaction from banned user {interaction.user.id}: {ban_info['message']}")
# Raise the exception to prevent further processing
raise UserBannedError(interaction.user.id, ban_info['message'])
async def check_if_user_banned(self, ctx):
"""Global check to prevent banned users from using commands."""
"""Global check to prevent banned users from using prefix commands."""
# Skip check for DMs
if not isinstance(ctx, commands.Context) and not hasattr(ctx, 'guild'):
return True
@ -115,6 +143,33 @@ class BanSystemCog(commands.Cog):
# User is not banned, allow the command
return True
async def interaction_check(self, interaction: discord.Interaction) -> bool:
"""Global check for slash commands to prevent banned users from using them."""
# Skip check for the bot owner
if interaction.user.id == self.bot.owner_id:
return True
# Check if the user is banned
if interaction.user.id in self.banned_users_cache:
ban_info = self.banned_users_cache[interaction.user.id]
# If the interaction hasn't been responded to yet, respond with the ban message
if not interaction.response.is_done():
try:
await interaction.response.send_message(ban_info['message'], ephemeral=True)
except Exception as e:
log.error(f"Error sending ban message to user {interaction.user.id}: {e}")
# Raise the custom exception with the ban message
raise UserBannedError(interaction.user.id, ban_info['message'])
# If there was an original interaction check, call it
if self.original_interaction_check is not None:
return await self.original_interaction_check(interaction)
# User is not banned, allow the interaction
return True
def register_commands(self):
"""Register all commands for this cog"""
@ -297,6 +352,13 @@ class BanSystemCog(commands.Cog):
await interaction.response.send_message(embed=embed, ephemeral=ephemeral)
def cog_unload(self):
"""Cleanup when the cog is unloaded."""
# Restore the original interaction check if it exists
if hasattr(self, 'original_interaction_check'):
self.bot.tree.interaction_check = self.original_interaction_check
log.info("Restored original interaction check on cog unload.")
# Setup function for loading the cog
async def setup(bot):
"""Add the BanSystemCog to the bot."""