首页 > 解决方案 > 在 discord.py 中添加一个开机定时器

问题描述

我正在制作一个基于汽车的不和谐机器人,我想添加电源,其中一个包括 Nitrous。Nitrous 会增加你的力量 30 分钟,然后恢复正常,但由于某种原因,它会忘记计时器并永久增加用户的力量。我尝试使用await asyncio.sleep(1800),但它似乎不起作用,如您所见(1800 秒是 30 分钟)。也没有显示错误。

这是代码...

@client.command()
async def use(ctx, option = None):

    global nit

    await open_account(ctx.author)

    user = ctx.author

    users = await get_bank_data()

    car = users[str(user.id)]["car"]

    hp = users[str(user.id)]["hp"]
    hpn = hp*1.5

    nos = users[str(user.id)]["nit"]


    if option == None:
        await ctx.send('You forgot to type an option!')

    elif option == 'nos' or option == 'Nitrous':
        if nit == True:
            await ctx.send('Nitrous is already enabled!')
            return

        if nos>0:
            await ctx.send('Are you sure you want to enable it? This will increase your HP by 50 percent for 30min, Type Y or N')
            msg = await client.wait_for('message',timeout = 20.0, check=lambda message: not message.author.bot)
            if msg.content.lower() == 'y' or msg.content.lower() == 'Y':
                await change_bank(ctx.author, "nitn", car)
                await change_bank(ctx.author, "nithp", hp)
                await change_bank(ctx.author, "hp", hpn)
                await update_bank(ctx.author, -1, "nit")

                nit = True

                await ctx.send('You have used Nitrous , your timer will start now!')

                await asyncio.sleep(1800)

                user = ctx.author

                users = await get_bank_data()

                car = users[str(user.id)]["car"]
                carn = users[str(user.id)]["nitn"]
                hp = users[str(user.id)]["nithp"]
                nit = False

                if carn == car:
                    await change_bank(ctx.author, "hp", hp)
                    await change_bank(ctx.author, "nithp", 0)
                    await change_bank(ctx.author, "nitn", 0)
                    await ctx.send(f"{ctx.author.name}'s 30min of Nitrous is finish!")
                else:
                    await change_bank(ctx.author, "hp2", hp)
                    await change_bank(ctx.author, "nithp", 0)
                    await change_bank(ctx.author, "nitn", 0)
                    await ctx.send(f"{ctx.author.name}'s 30min of Nitrous is finish!")
            else:
                await ctx.send('Either you chose "N" or you didnt type in time!')
        else:
            await ctx.send('You dont have enough nitrous bottles!')

标签: pythondiscorddiscord.py

解决方案


您已经发现了使用任何类型的睡眠功能来管理未来事件所涉及的重大问题之一。有效的方式asyncio.sleep是它记录了一个未来。未来就像一个尚未返回的函数的占位符。您不必等待该函数,直到您真正想要读取结果,但该函数仍在后台处理。期货是异步处理的基础元素之一。

技术上asyncio.sleep应该在这种情况下工作。我不完全确定发生了什么,但很可能discord.py图书馆有某种管理器,如果它们被暂停超过一定时间,就会放弃这些期货。如果我找到更多关于这个的信息,那么我会编辑这个答案。

总而言之,你不应该对像这样的长事件使用睡眠调用。相反,您应该创建一个全局(或公会级别)数据库并有一个循环任务,该任务从该数据库中读取并调用一个函数来运行asyncio.sleep. 您可以通过创建一个字典来存储用户 nitro 何时完成以及其他一些信息(如作者和频道)来做到这一点。

您可以在此处找到有关 discord.py 库中任务的更多信息


推荐阅读