问题
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