【发布时间】:2022-01-18 10:19:33
【问题描述】:
我需要一个命令来显示带有冷却时间的命令列表以及再次使用该命令的剩余时间。是否有可能特别将命令放在齿轮中?如果是,你能帮我如何执行命令吗?
【问题讨论】:
-
有可能吗? -- 是的。
-
@ŁukaszKwieciński 那么你能告诉我代码以及它是如何工作的吗?
标签: discord discord.py
我需要一个命令来显示带有冷却时间的命令列表以及再次使用该命令的剩余时间。是否有可能特别将命令放在齿轮中?如果是,你能帮我如何执行命令吗?
【问题讨论】:
标签: discord discord.py
创建一个显示所有冷却时间的命令是可能的。您可以使用 for 循环和 is_on_cooldown() 函数来做到这一点。
这是一个返回命令列表以及它们是否处于冷却状态的命令示例:
@client.command(pass_content=True)
async def cooldowns(ctx):
cooldown_string = ""
for command in client.commands:
if command.is_on_cooldown(ctx):
cooldown_string += f"\n{command} - **Time Left:** {command.get_cooldown_retry_after(ctx)}MS"
await ctx.send(cooldown_string)
您可以在此处添加条件语句以仅在冷却时显示命令。
【讨论】:
command.get_cooldown_retry_after(ctx)。我会将其编辑到我的回复中,以向您展示我的意思。如果这是您正在寻找的内容,您可以将回复标记为已接受。
绝对有可能让所有命令都进入冷却时间和剩余时间。然而,discord.py 并没有直接访问它,因此我们不得不滥用私有类变量来获取它们
代码:
import datetime
@client.command()
async def cooldowns(ctx: commands.Context):
string = ""
for command in client.walk_commands():
dt = ctx.message.edited_at or ctx.message.created_at
current = dt.replace(tzinfo=datetime.timezone.utc).timestamp()
bucket = command._buckets.get_bucket(ctx.message, current)
if not bucket:
continue
retry_after = bucket.update_rate_limit(current)
if retry_after:
string += f"{command.name} - {retry_after} Seconds\n"
else:
string += f"{command.name} - `READY`\n"
string = string or "No commands are on cooldown"
await ctx.send(string)
接下来是:
命令 1 - READY
命令 2 - READY
...
命令 n - READY(等等)
string = ""
我们在字符串变量中初始化一个空字符串,这是我们将添加我们的行并一次性发送的字符串。
for command in bot.walk_commands():
dt = ctx.message.edited_at or ctx.message.created_at
current = dt.replace(tzinfo=datetime.timezone.utc).timestamp()
bucket = command._buckets.get_bucket(ctx.message, current)
bot.walk_command() 是一种为我们提供生成器对象的方法,它本质上是机器人存储的所有命令对象的生成器(即:@bot.command()、@commands.command 和 @commands.group 下的所有内容)
dt 只是存储消息创建的当前时间,它是一个日期时间对象
message.created_at 是一个简单的时间偏移量,因此我们使用它的 replace 方法将时区绑定到它,然后我们使用 timestamp() 对象的 timestamp() 方法获得时间戳
我们所做的所有事情都是浪费,第三行是我们想要的肉和土豆。 command._buckets.get_bucket 是内部的,我们提供当前消息对象和我们之前创建的时间戳。
这给了我们我们的冷却对象(您使用@commands.cooldown(1, 5, commands.BucketType.user) 创建的对象,它基本上产生 () 中的内容)[这是 None 用于没有冷却时间的命令]
这是它的样子,仅供理解。
if not bucket:
continue
retry_after = bucket.update_rate_limit(current)
if retry_after:
string += f"{command.name} - {retry_after} Seconds\n"
else:
string += f"{command.name} - `READY`\n"
await ctx.send(string)
if not bucket:
continue
如果未找到存储桶,则命令没有冷却时间,这意味着我们可以跳过它。
retry_after = bucket.update_rate_limit(current)
这基本上得到了我们剩余的时间(它是一个浮动)
如果它没有处于冷却状态,则返回 None
if retry_after:
string += f"{command.name} - {retry_after} Seconds\n"
else:
string += f"{command.name} - `READY`\n"
if 语句检查它是否返回一个浮点数,如果还没有,那么命令正在冷却,我们将命令名称添加到冷却时间旁边
else 用于如果它没有冷却,那么它会在旁边添加命令名称和READY。
最后我们发送整个字符串。
就我而言,我只有一个具有冷却时间的命令,即spotify。
【讨论】: