Запретить выполнение команды в каналах

#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??
 

Это событие работает нормально, за исключением того факта, что бот не отменяет выполнение команды после или до, он отправляет сообщение «использовать #команды», и это потому, что я понятия не имею, как бы я это сделал.

Я пробовал несколько разных методов, которые не могу вспомнить, но они не сработали, поэтому я надеюсь, что кто-нибудь здесь знает, как бы я выполнил то, что пытаюсь сделать.

РЕДАКТИРОВАТЬ: Я отказался от всего, что связано с on_command, и вместе со своим другом создал новый вызов, который отлично работает.

Комментарии:

1. Почему бы вам не провести простую глобальную проверку ?

2. Конечно, я скучаю по чему-то, что могло бы облегчить мне жизнь. Единственное, что я все еще не знаю способа остановить выполнение команды на самом деле..

3. Если глобальная проверка вернет ложное значение, команда не будет выполнена и commands.CheckFailure будет вызвана.

4. Я не часто использовал глобальные проверки, извините, если это немного раздражает, но у вас есть пример того, как это будет работать? Или как я мог бы реализовать то, что я пытаюсь сделать, в проверке?

5. Я не уверен, что вы действительно пытаетесь сделать, код действительно грязный, также в названии вы указываете «Запретить выполнение команды в каналах», код выглядит так, как будто вы пытаетесь «запретить выполнение команды определенными ролями».

Ответ №1:

Этот 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: важно, так как этот метод будет запущен, даже если команда не указана, и эта проверка пройдет только в том случае, если команда распознана.

Ответ №2:

on_message Событие вызывается до вызова команды. Так что это правильный метод для вашей проблемы. Если я правильно помню, вы должны поместить on_message событие в свой основной винтик, чтобы оно работало должным образом. В противном случае вы не переопределите 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. проблема с этим методом заключается в том, что вы не можете получить доступ к ctx, и, возможно, ctx будет важен для вас