防止命令在通道中执行

时间:2021-03-30 20:16:52

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

我试图阻止我的机器人的命令在特定渠道中运行 - 没有在机器人的每个命令的开头进行检查。

我现在有这个 on_command 事件:

    @commands.Cog.listener()
    async def on_command(self, ctx):
        aroles=ctx.author.roles
        aroles.reverse()
        blacklist=["role", "role", "role", "role", "role"] # Roles I don't want to include in the roles list.. if that makes sense
        roles=[id, id, id, id, id, id, id, id, id, id] # Roles that can run commands anywhere
        channel=get(ctx.guild.channels, id=id) # Commands channel
        
        for role in aroles:
            if role.name not in blacklist:
                if role.id in roles: # If they have one of the roles, do nothing and let the command run
                    return
                elif ctx.channel == channel: # If they are in the commands channel, do nothing and let the command run
                    return
                else:
                    # something??
                    await ctx.send(f"Commands can only be ran in {channel.mention}", delete_after=3)
                    # something??

这个事件工作正常,除了机器人不会在它发送“use #commands”消息之后或之前取消运行的命令,那是因为我不知道我会怎么做.

我尝试了一些我不记得但没有奏效的不同方法,所以我希望这里有人知道我将如何完成我正在尝试做的事情。

编辑: 我废弃了整个 on_command 的东西,并与我的朋友一起进行了一个运行良好的新调用。

2 个答案:

答案 0 :(得分:0)

在调用命令之前调用 on_message 事件。所以这是解决您问题的正确方法。如果我没记错的话,您必须将 on_message 事件放在主 Cog 中才能正常工作。否则,您将不会覆盖导致消息被处理的主 Cog 的 on_message 事件。 此外,您需要在 process_commands 方法的末尾包含 on_message,否则不会处理该命令。如果没有该行,您的所有命令都将无法正常工作(假设您能够解决问题)。假设你在没有解决问题的情况下添加了第一行,所有应该运行的命令都被执行了两次,而你想要防止发生的所有命令都只执行一次。这也应该为您确认 on_message 方法工作正常。

class MyBot(commands.Bot):
    def __init__(self):
        # initialisation stuff here 
        intents = discord.Intents.default()

        super().__init__(command_prefix="-", intents=intents) # all your other stuff here

    def run(self):
        super().run("token")

    @commands.Cog.listener()
    async def on_message(self, message):
        if your_check_here:
            return 
            # the return prevents the provess_commands from being executed and therefore the command not being executed
        
        # Make sure to include this, because otherwise the message won't be processed
        await self.process_commands(message)

答案 1 :(得分:0)

当您使用齿轮和高级前缀等时,on_message 方法实现起来有点棘手...

所以我测试了覆盖调用命令的方法。

default_invoke = bot.invoke
async def new_invoke(self, ctx: Context):
    if ctx.command:
        if 'something is wrong':
            return

    await self.default_invoke(ctx)
bot.invoke = new_invoke

仅当您要查找的条件为假时才必须返回。否则,允许默认调用触发器。

还有 if ctx.command: 很重要,因为即使未指定命令也会触发此方法,并且只有在识别到命令时才会通过此检查。