【问题标题】:Blacklisting bot commands with role?将具有角色的机器人命令列入黑名单?
【发布时间】:2018-10-16 08:09:33
【问题描述】:

您好,您可以简单地将某人按角色使用所有机器人命令列入黑名单吗?我目前正在寻找一种方法来为我在 Discord 重写分支上的机器人执行此操作。

谢谢

【问题讨论】:

    标签: python python-3.x discord discord.py discord.py-rewrite


    【解决方案1】:

    如果可能使用global check,最简单的方法是使用bot.check 装饰器。以下基于角色name 操作,但您可以使用id 编写等效版本:

    from discord.utils import get
    
    @bot.check
    async def globally_blacklist_roles(self, ctx):
        blacklist = ["BAD_ROLE_1", "BAD_ROLE_2"]  # Role names
        return not any(get(ctx.guild.roles, name=name) in ctx.author.roles for name in blacklist)
    

    例如,您可以通过缓存列入黑名单的角色的 Role 对象来实现一些加速。

    如果您使用的是 cogs,您可以通过为协程指定一个特殊名称来表明您希望协程成为全局检查,__global_check_once__global_check。这是documented here。看起来 __global_check_once 是您正在寻找的东西,但您可能想尝试一下。我认为唯一的区别是当您使用带有子命令的命令组时调用了多少次

    class Blacklisted(commands.CheckFailure): pass
    
    class YourCog:
        def __init__(self, bot):
            self.bot = bot
    
        def __global_check_once(self, ctx):
            blacklist = ["BAD_ROLE_1", "BAD_ROLE_2"]  # Role names
            if any(get(ctx.guild.roles, name=name) in ctx.author.roles for name in blacklist):
                raise Blacklisted()
            else:
                return True
    
        async def on_command_error(self, ctx, error):
            if isinstance(error, Blacklisted):
                await ctx.send("You cannot use this command.")
    

    【讨论】:

    • 我是否需要删除 @bot.check,因为我的机器人是模块化的,并且会将其创建为一个模块。
    • @ShanJameson 查看我的编辑。使用此处记录的 cogs 内置的全局检查:discordpy.readthedocs.io/en/rewrite/migrating.html#cog-changes
    • 我想在这个“命令被阻止”中添加一条消息raise 可以接受吗?如果我使用 ctx.send() 会引发语法错误?
    • 您可以尝试将其设为async def 协程。真正应该做的是子类CheckFailure,然后引发该错误而不是返回False。然后,写一个error handler 来处理该错误并发送消息。见this example
    • 嗨@Patrick 我在为error handler 添加错误处理程序时有点卡住了,我添加了一个答案,向您展示我在下面尝试做的事情。不知道我哪里出错了。
    【解决方案2】:
    def __global_check_once(self, ctx):
        blacklist = ["Blacklisted", "Blacklist"]  # Role names
        return not any(get(ctx.guild.roles, name=name) in ctx.author.roles for name in blacklist)
    
    async def __global_check_once_error(ctx, error):
        if isinstance(error, __global_check_once):
            await ctx.send('You cannot use that command!')
    

    【讨论】:

    • 请解释你的答案以提高它的质量
    猜你喜欢
    • 2021-06-30
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2021-04-08
    • 2021-02-21
    • 2021-11-24
    • 2016-12-30
    • 2021-03-01
    相关资源
    最近更新 更多