How to save command cooldown?

折月煮酒 提交于 2021-02-08 05:44:25

问题


The code below adds a cooldown for command, but when bot restarts, the cooldown resets. So how can I make the bot remember from previous usage? If the cooldown limit is 5 times per day and if the member used 3 times and if bot restarts it should start from where it was left for all members.

import discord
from discord.ext import commands
import random

from utils import Bot
from utils import CommandWithCooldown

class Members():
    def __init__(self, bot):
        self.bot = bot


    @commands.command(pass_context=True, cls=CommandWithCooldown)
    @commands.cooldown(1, 600, commands.BucketType.user)
    async def ping(self, ctx):
        msg = "Pong {0.author.mention}".format(ctx.message)
        await self.bot.say(msg)


def setup(bot):
    bot.add_cog(Members(bot))

回答1:


Similar to what Patrick Haugh suggested, the cooldown mapping is stored in Command._buckets. You can pickle the bucket before the bot starts and save it after the bot finishes. For your convenience, replace the Bot class with the following (a.k.a "moneypatching"):

token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
prefix = "?"
cooldown_info_path = "cd.pkl"

from discord.ext import commands


class Bot(commands.Bot):

    async def start(self, *args, **kwargs):
        import os, pickle
        if os.path.exists(cooldown_info_path):  # on the initial run where "cd.pkl" file hadn't been created yet
            with open(cooldown_info_path, 'rb') as f:
                d = pickle.load(f)
                for name, func in self.commands.items():
                    if name in d:  # if the Command name has a CooldownMapping stored in file, override _bucket
                        self.commands[name]._buckets = d[name]
        return await super().start(*args, **kwargs)

    async def logout(self):
        import pickle
        with open(cooldown_info_path, 'wb') as f:
            # dumps a dict of command name to CooldownMapping mapping
            pickle.dump({name: func._buckets for name, func in self.commands.items()}, f)
        return await super().logout()


bot = Bot(prefix)
# everything else as usual

@bot.event
async def on_ready():
    print('Logged in as')
    print(bot.user.name)
    print(bot.user.id)
    print('------')


@bot.command(pass_context=True)
@commands.cooldown(1, 3600, commands.BucketType.user)
async def hello(ctx):
    msg = "Hello... {0.author.mention}".format(ctx.message)
    await bot.say(msg)


class ACog:
    def __init__(self, bot):
        self.bot = bot

    @commands.command(pass_context=True)
    @commands.cooldown(1, 600, commands.BucketType.user)
    async def ping(self, ctx):
        msg = "Pong {0.author.mention}".format(ctx.message)
        await self.bot.say(msg)


bot.add_cog(ACog(bot))
bot.run(token)

This will save the cooldown data to "cd.pkl" when the bot is properly logged out.



来源:https://stackoverflow.com/questions/51117681/how-to-save-command-cooldown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!