如何在discord.User cog中添加角色层级,同时支持封禁非服务器用户?
Discord封禁命令同时支持跨服封禁与角色层级校验方案
核心逻辑
角色层级校验不需要依赖discord.User对象的属性,仅需针对两个关联对象做校验即可,完全可以同时实现两个需求:
- 首先校验命令调用者的权限与角色层级:调用者属于当前服务器成员,本身就是
discord.Member类型,天然持有角色属性,这块校验是无论被封禁用户是否在服务器都必须执行的前置校验 - 其次仅当被封禁用户在当前服务器内时,才需要额外校验二者的角色层级;如果被封禁用户不在服务器内,不存在本服务器的角色,自然没有层级冲突的可能,无需额外校验
实现步骤
- 前置校验调用者基础权限:首先确认调用者持有
ban_members服务器权限,服务器所有者可直接跳过后续所有层级校验 - 尝试获取被封禁用户的服务器成员对象:调用
ctx.guild.get_member(user.id),如果返回非空则说明用户在当前服务器内 - 若用户在服务器内,校验调用者的最高角色位置必须高于被封禁用户的最高角色位置,同时禁止封禁服务器所有者
- 所有校验通过后,直接调用
guild.ban()方法传入discord.User对象即可完成封禁,即使该用户不在服务器内也可正常执行
参考代码示例(discord.py/pycord环境)
@commands.command(name="ban") @commands.has_permissions(ban_members=True) async def ban_user(self, ctx, user: discord.User, *, reason="未指定原因"): # 服务器所有者直接跳过层级校验 if ctx.author != ctx.guild.owner: # 检查被封禁用户是否在当前服务器 target_member = ctx.guild.get_member(user.id) if target_member: # 校验角色层级 if ctx.author.top_role.position <= target_member.top_role.position: await ctx.send("操作失败:你无法封禁角色等级高于或等于你的用户") return # 禁止封禁服务器所有者 if target_member == ctx.guild.owner: await ctx.send("操作失败:你无法封禁服务器所有者") return # 执行封禁 await ctx.guild.ban(user, reason=reason, delete_message_days=0) await ctx.send(f"已成功封禁用户:{user.mention},原因:{reason}")
注意事项
如果你设置了自定义的封禁权限最低角色阈值,可以在校验调用者权限的步骤额外增加调用者最高角色位置与阈值的对比逻辑,进一步收紧权限。
内容的提问来源于stack exchange,提问作者MrPie
相关产品推荐
相关产品推荐

