【问题标题】:discord.py bot commands - how to make different cooldown times for different usersdiscord.py bot 命令 - 如何为不同的用户设置不同的冷却时间
【发布时间】:2021-10-15 13:00:51
【问题描述】:

我正在尝试编写一个不和谐的机器人,它对每个用户执行相同的命令具有不同的冷却时间。例如,当用户 1 !work 时,他们的冷却时间是 5 秒,而用户 2 在他们 !work 时有 6 秒的冷却时间。阅读冷却装饰器的文档,似乎没有办法拥有多个冷却时间。此方法不起作用,因为我收到一个错误,因为 ctx 尚未定义,并且我无法在函数定义之前获取用户数据。我将如何设置它以便我可以为每个用户设置可变的冷却时间?

def fetch(self, username, column):
        self.cur.execute("SELECT %s FROM users WHERE username=?" %column, (username,))
        rows = self.cur.fetchall()
        return rows

#the call to fetch should theoretically return the cooldown for that user
@commands.cooldown(rate=1, per=fetch(str(ctx.message.author), cooldown), type=commands.BucketType.user)
@bot.command(name='example')
async def example(ctx):
    await ctx.send("hello")

【问题讨论】:

标签: python discord discord.py


【解决方案1】:

听起来您正在寻找一种方法来让您的机器人创建许多仅在运行时才知道的独特冷却时间。在这种情况下,使用 Command.add_check 可能比使用冷却装饰器更容易。

如果您的代码在继承commands.Cog 的类中,那么也许这样的东西可以满足您的需求:

def __init__(self):
    self.cooldowns = dict()
    works_command = self.bot.get_command('works')
    works_command.add_check(check_cooldown)


async def initialize_cooldowns(self):  # This function still needs to be called somewhere.
    rows = self.cur.fetchall()
    for row in rows:
        user_id = row['user_id']
        duration = row['duration']
        self.cooldowns[user_id] = commands.CooldownMapping.from_cooldown(1, duration, commands.BucketType.user)
            

async def check_cooldown(self, ctx):
    row = my_fetchrow(ctx.author)  # my_fetchrow gets one row of a table; not defined here.
    user_id = row['user_id']
    bucket = self.cooldowns[user_id].get_bucket(ctx.message)

    retry_after = bucket.update_rate_limit()
    if retry_after:
        raise commands.CommandOnCooldown(bucket, retry_after)
    return True

如果initialize_cooldowns不需要异步,可以在__init__中调用。

否则,您可能想要使用self.bot.loop.create_task,例如

def __init__(self):
    self.cooldowns = dict()
    self._task = self.bot.loop.create_task(self.initialize_cooldowns())
    works_command = self.bot.get_command('works')
    works_command.add_check(check_cooldown)


async def initialize_cooldowns(self):
    await self.bot.wait_until_ready()
    rows = self.cur.fetchall()
    ...

在这些示例中,initialize_cooldowns 在机器人启动时运行,并为您已保存信息的每个用户创建冷却时间。您可能还想创建一种在机器人运行时向冷却时间字典添加更多键的方法,并为 check_cooldown 中的 KeyErrors 使用 try/except 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 2019-12-29
    • 2020-10-11
    • 2019-02-17
    • 2022-08-02
    • 1970-01-01
    • 2021-03-11
    • 2017-11-21
    相关资源
    最近更新 更多