【问题标题】:Making a command that shows all your cooldowns and the time remaining发出一个显示所有冷却时间和剩余时间的命令
【发布时间】:2022-01-18 10:19:33
【问题描述】:

我需要一个命令来显示带有冷却时间的命令列表以及再次使用该命令的剩余时间。是否有可能特别将命令放在齿轮中?如果是,你能帮我如何执行命令吗?

【问题讨论】:

  • 有可能吗? -- 是的。
  • @ŁukaszKwieciński 那么你能告诉我代码以及它是如何工作的吗?

标签: discord discord.py


【解决方案1】:

创建一个显示所有冷却时间的命令是可能的。您可以使用 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)

您可以在此处添加条件语句以仅在冷却时显示命令。

【讨论】:

  • 它只会给我错误的 idk 为什么
  • @jann 尝试运行一个有冷却时间的命令,然后立即重新运行冷却时间命令
  • 哇,它确实如此,但我想显示再次访问该命令的剩余时间.. 有可能吗?
  • @jann 是的,有可能!您可以使用command.get_cooldown_retry_after(ctx)。我会将其编辑到我的回复中,以向您展示我的意思。如果这是您正在寻找的内容,您可以将回复标记为已接受。
  • 现在可以了!谢谢!
【解决方案2】:

绝对有可能让所有命令都进入冷却时间和剩余时间。然而,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

【讨论】:

  • 我需要把 @client.command() 东西放在一边吗?如果是的话,因为它给了我一个错误...
  • @Jann,是的,让我编辑它以使其成为命令,一秒钟
  • 它对我不起作用,不知道为什么
  • Rose?#1328 请联系我
猜你喜欢
  • 2020-06-27
  • 2020-05-27
  • 2019-02-17
  • 1970-01-01
  • 2021-03-18
  • 2021-06-17
  • 1970-01-01
  • 2017-11-21
  • 2021-02-16
相关资源
最近更新 更多