【问题标题】:Adding a timer to giveaway command discord.py向赠品命令 discord.py 添加计时器
【发布时间】:2021-05-02 17:48:26
【问题描述】:

我试图创建一个带有赠品命令的不和谐机器人,该命令在赠品嵌入中每 1-2 分钟更新一次剩余时间。自 3 天以来我一直在尝试它,但无法找到解决方案。我设法让它更新秒数,但如果我指定时间超过 1m 即 60 秒,它会自动将其转换为秒并开始赠品,剩余时间为 just seconds 。我希望它保持给定单位的时间并以--days、--hours、--minutes、--seconds 为单位更新时间。

这里有几张图片我的意思:

目前在做什么:

我想要它做什么:

它只是结束或剩余时间我想要改变的!

我当前的代码:

@commands.command()
    @commands.guild_only()
    async def gstart(self, ctx, duration, *, prize):
        time = self.convert(duration)
        if time == -1:
            await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
            return
        elif time == -2:
            await ctx.send(f'Time Must Be A Integer!')
            return
        giveawayembed = discord.Embed(
            title="???? New Giveaway! ????",
            description=f"**Prize:** {prize}\n"
                        f"**Hosted By:** {ctx.author.mention}\n"
                        f"**Ends In:** {time} Seconds",
            colour=discord.Color.green()
        )

        msg = await ctx.send(embed=giveawayembed)

        reactions = await msg.add_reaction("????")

        while time:
            await sleep(10)
            time -= 10
            giveawayembed.description= f"**Prize:** {prize}\n**Hosted By:** {ctx.author.mention}\n**Ends In:** {time} Seconds"
            await msg.edit(embed=giveawayembed)

        new_msg = await ctx.fetch_message(msg.id)

        users = await new_msg.reactions[0].users().flatten()
        users.pop(users.index(self.client.user))

        winner = random.choice(users)

        endembed = discord.Embed(
            title="Giveaway ended!",
            description=f"Prize: {prize}\nWinner: {winner.mention}")

        await msg.edit(embed=endembed)
        await ctx.send(f"???? Giveaway Winner: {winner.mention} | Prize: {prize}")

为了转换我拥有的时间:

class Giveaway(commands.Cog):
    def __init__(self, client):
        self.client = client

    def convert(self, time):
        pos = ["s", "m", "h", "d"]
        time_dict = {"s" : 1, "m" : 60, "h" : 3600, "d" : 3600*24}
        unit = time[-1]

        if unit not in pos:
            return -1
        try:
            val = int(time[:-1])
        except:
            return -2

        return val * time_dict[unit]

非常感谢任何帮助! ??? 如果我不能让你理解我的问题,我很抱歉。 ????

【问题讨论】:

    标签: python python-3.x discord discord.py discord.py-rewrite


    【解决方案1】:

    我理解你的问题,因为它实际上是一个非常简单的修复,你可以导入时间,或者使用await asyncio.sleep(time)

    在使用我提供的代码之前,请确保在您的导入中使用import asyncio

    您的代码:

        @commands.command()
        @commands.guild_only()
        async def gstart(self, ctx, duration, *, prize):
            time = self.convert(duration)
            if time == -1:
                await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
                return
            elif time == -2:
                await ctx.send(f'Time Must Be A Integer!')
                return
            giveawayembed = discord.Embed(
                title="? New Giveaway! ?",
                description=f"**Prize:** {prize}\n"
                            f"**Hosted By:** {ctx.author.mention}\n"
                            f"**Ends In:** {time} Seconds",
                colour=discord.Color.green()
            )
    
            msg = await ctx.send(embed=giveawayembed)
    
            reactions = await msg.add_reaction("?")
    
            while time:
                await sleep(10)
                time -= 10
                giveawayembed.description= f"**Prize:** {prize}\n**Hosted By:** {ctx.author.mention}\n**Ends In:** {time} Seconds"
                await msg.edit(embed=giveawayembed)
    
            new_msg = await ctx.fetch_message(msg.id)
    
            users = await new_msg.reactions[0].users().flatten()
            users.pop(users.index(self.client.user))
    
            winner = random.choice(users)
    
            endembed = discord.Embed(
                title="Giveaway ended!",
                description=f"Prize: {prize}\nWinner: {winner.mention}")
    
            await msg.edit(embed=endembed)
            await ctx.send(f"? Giveaway Winner: {winner.mention} | Prize: {prize}")
    

    在这两个修复中,我将修复一个很容易修复的小问题,你有它,所以一段时间后,它会下降 10,我建议这样做,它会显示 while time > 0:,这样一旦它达到 0,它就不会继续倒计时。

    使用await asyncio.sleep(time) 轻松修复:

        @commands.command()
        @commands.guild_only()
        async def gstart(self, ctx, duration, *, prize):
            time = self.convert(duration)
            if time == -1:
                await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
                return
            elif time == -2:
                await ctx.send(f'Time Must Be A Integer!')
                return
            giveawayembed = discord.Embed(
                title="? New Giveaway! ?",
                description=f"**Prize:** {prize}\n"
                            f"**Hosted By:** {ctx.author.mention}\n"
                            f"**Ends In:** {time} Seconds",
                colour=discord.Color.green()
            )
    
            msg = await ctx.send(embed=giveawayembed)
    
            reactions = await msg.add_reaction("?")
    
                    while time >= 0:
                if time <= 60:
                    giveaway.remove_field(index=1)
                    giveaway.insert_field_at(index=1, name='Ends:', value=f'{time} second(s) from now')
                    await my_msg.edit(embed=giveaway)
                    time -= 10
                    await asyncio.sleep(10)
                elif 60 <= time < 3600:
                    giveaway.remove_field(index=1)
                    giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/60} minute(s) from now')
                    await my_msg.edit(embed=giveaway)
                    time -= 6
                    await asyncio.sleep(6)
                elif 3600 <= time < 86400:
                    giveaway.remove_field(index=1)
                    giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/3600} hour(s) from now')
                    await my_msg.edit(embed=giveaway)
                    time -= 360
                    await asyncio.sleep(360)
                elif time >= 86400:
                    giveaway.remove_field(index=1)
                    giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/86400} day(s) from now')
                    await my_msg.edit(embed=giveaway)
                    time -= 8640
                    await asyncio.sleep(8640)
            if time <= 0:
                giveaway.remove_field(index=1)
                giveaway.insert_field_at(index=1, name='Ends:', value=f'Ended at {datetime.datetime.now().strftime("%B %d, %I:%M %p")}') # noqa
                await my_msg.edit(embed=giveaway)
    
            await asyncio.sleep(time)
    
            new_msg = await ctx.fetch_message(msg.id)
    
            users = await new_msg.reactions[0].users().flatten()
            users.pop(users.index(self.client.user))
    
            winner = random.choice(users)
    
            endembed = discord.Embed(
                title="Giveaway ended!",
                description=f"Prize: {prize}\nWinner: {winner.mention}")
    
            await msg.edit(embed=endembed)
            await ctx.send(f"? Giveaway Winner: {winner.mention} | Prize: {prize}")
    

    如果您仍然感到困惑或有任何其他问题,您可以通过killrebeest#7187 与我联系,或对此答案发表评论。祝你有美好的一天!

    【讨论】:

    • 它仍然以秒为单位进行转换,并且计时器再次以秒为单位开始。我希望它显示像这样的计时器:如果我输入 2m(分钟),它应该嵌入为 2m 并像 ... 1m 50s ....1m 30s,,,,1m 10....以秒为单位转换,例如 120 秒 ...而不是 ...120 秒 ....100 秒 ...80 秒 ...
    • @Nucleo__ 我刚刚编辑了它,试试看!也很抱歉,我已经离开我的电脑了。
    猜你喜欢
    • 2021-03-20
    • 2021-06-02
    • 2021-11-01
    • 2021-07-20
    • 2021-05-25
    • 2020-04-17
    • 2020-03-17
    • 2021-04-02
    • 2021-04-18
    相关资源
    最近更新 更多