我试图阻止我的机器人的命令在特定渠道中运行 - 没有在机器人的每个命令的开头进行检查。
我现在有这个 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 的东西,并与我的朋友一起进行了一个运行良好的新调用。
答案 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:
很重要,因为即使未指定命令也会触发此方法,并且只有在识别到命令时才会通过此检查。