#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 будет важен для вас