discord.py v2 Kick命令权限问题:需禁止踢自身及同角色成员
解决discord.py v2中Kick命令的权限校验问题
问题说明
当前Kick命令存在两个权限校验漏洞:
- 允许用户踢自己
- 允许用户踢拥有相同角色(如Moderator)的成员
需要在触发这两种场景时抛出错误提示。
原代码
from __future__ import annotations from typing import Optional from .. import Plugin from core import Bot from discord import app_commands, Interaction, Member def can_moderate(): async def predicate(interaction: Interaction): target: Member = interaction.namespace.member or interaction.namespace.target if not target: return True assert interaction.guild is not None and isinstance(interaction.user, Member) if ( target.top_role.position > interaction.user.top_role.position or target.guild_permissions.kick_members or target.guild_permissions.ban_members or target.guild_permissions.administrator or target.guild_permissions.manage_guild ): raise app_commands.CheckFailure(f"You can't kick **{target}**") return True return app_commands.check(predicate) class Moderation(Plugin): def __init__(self, bot: Bot) -> None: self.bot = bot @app_commands.command(name = "kick", description = "Kick a member") @app_commands.default_permissions(kick_members = True) @app_commands.describe(member = "Select a member", reason = "Specify a reason for the kick") async def kick_command(self, interaction: Interaction, member: Member, reason: Optional[str]): if not reason: reason = "not specified" try: await member.kick(reason = reason) except: await self.bot.error(f"I'm sorry, but I can't kick **{member}**", interaction) else: await self.bot.success(f"**{member}** has been kicked 👢 from the server.", interaction) async def setup(bot: Bot): await bot.add_cog(Moderation(bot))
你尝试的修改
if ( target.top_role.position >= interaction.user.top_role.position or target.guild_permissions.kick_members or target.guild_permissions.ban_members or target.guild_permissions.administrator or target.guild_permissions.manage_guild or target.id == interaction.user.id ): raise app_commands.CheckFailure(f"You can't kick **{target}**") return True
最终解决方案
你的修改方向是对的,但核心问题是你定义的can_moderate检查器没有绑定到Kick命令上,导致所有权限校验逻辑根本没执行。同时可以优化判断逻辑,补充服务器所有者的特殊权限(按需保留):
- 给Kick命令添加
@can_moderate()装饰器 - 完善检查器中的判断条件
修改后的完整代码:
from __future__ import annotations from typing import Optional from .. import Plugin from core import Bot from discord import app_commands, Interaction, Member def can_moderate(): async def predicate(interaction: Interaction): target: Member = interaction.namespace.member or interaction.namespace.target if not target: return True assert interaction.guild is not None and isinstance(interaction.user, Member) # 禁止踢自己 if target.id == interaction.user.id: raise app_commands.CheckFailure("你不能踢自己!") # 服务器所有者拥有最高权限,允许踢任何人(可按需移除) if interaction.user.id == interaction.guild.owner_id: return True # 禁止踢角色位置不低于自己的成员,或拥有管理权限的成员 if ( target.top_role.position >= interaction.user.top_role.position or target.guild_permissions.kick_members or target.guild_permissions.ban_members or target.guild_permissions.administrator or target.guild_permissions.manage_guild ): raise app_commands.CheckFailure(f"You can't kick **{target}**") return True return app_commands.check(predicate) class Moderation(Plugin): def __init__(self, bot: Bot) -> None: self.bot = bot @app_commands.command(name = "kick", description = "Kick a member") @app_commands.default_permissions(kick_members = True) @can_moderate() # 关键:添加这个检查器装饰器,让校验逻辑生效 @app_commands.describe(member = "Select a member", reason = "Specify a reason for the kick") async def kick_command(self, interaction: Interaction, member: Member, reason: Optional[str]): if not reason: reason = "not specified" try: await member.kick(reason = reason) except: await self.bot.error(f"I'm sorry, but I can't kick **{member}**", interaction) else: await self.bot.success(f"**{member}** has been kicked 👢 from the server.", interaction) async def setup(bot: Bot): await bot.add_cog(Moderation(bot))
关键修改点
- 给
kick_command添加@can_moderate()装饰器,让权限校验逻辑真正生效 - 单独判断禁止踢自己的场景,给出明确提示
- 新增服务器所有者的特殊判断,避免限制所有者的操作(可根据需求移除)
- 使用
>=判断目标角色位置,禁止踢同角色或角色层级更高的成员
内容的提问来源于stack exchange,提问作者FacelessFiore
相关产品推荐
相关产品推荐

