首页 > 解决方案 > discord.py 机器人命令 - 如何为不同的用户设置不同的冷却时间

问题描述

我正在尝试编写一个不和谐的机器人,它为每个用户针对相同的命令具有不同的冷却时间。例如,当用户 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")

标签: pythondiscorddiscord.py

解决方案


听起来您正在寻找一种方法来让您的机器人创建许多仅在运行时才知道的独特冷却时间。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.


推荐阅读