【问题标题】:How to save command cooldown?如何保存命令冷却时间?
【发布时间】:2018-12-09 14:09:41
【问题描述】:

下面的代码为命令添加了冷却时间,但是当机器人重新启动时,冷却时间会重置。那么我怎样才能让机器人记住以前的用法呢?如果冷却时间限制是每天 5 次,并且如果成员使用了 3 次,并且如果机器人重新启动,它应该从所有成员离开的位置开始。

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))

【问题讨论】:

  • 您必须保存ping._buckets 的状态,然后在您的on_ready 事件中将该状态加载回ping._buckets。我会先尝试pickleing 该对象,如果这不起作用,您将不得不深入研究the code 以了解它是如何组合在一起的。看起来所有相关代码都在core.pycooldowns.py 之间拆分。

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


【解决方案1】:

与 Patrick Haugh 建议的类似,冷却映射存储在 Command._buckets 中。您可以在机器人启动之前腌制存储桶,并在机器人完成后保存。为方便起见,请将 Bot 类替换为以下内容(也称为“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)

这将在机器人正确注销时将冷却数据保存到“cd.pkl”。

【讨论】:

  • 如果我使用多个 cog 文件,我需要在所有文件中添加这个,还是应该通过在单独的文件中添加这个代码来使用 import
  • @Demotry 你可以使用导入。我建议也许将该类保存在 objects.py (似乎是 discord.py 机器人的约定)然后 from objects import Bot 或者它是一个项目 from .objects import Bot,从哪个文件中需要使用它。
  • 理论上它会起作用。您应该发布您的代码,以便我可以查看代码的问题所在。
  • 不工作到底是什么意思?如果您的意思是AttributeError,那是因为您忘记了self 作为ping 的参数。 async def ping(self, ctx):
  • 不工作意味着如果我重新启动机器人冷却不保存 cog 文件中的命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 2017-11-21
  • 2021-03-11
  • 2019-03-11
  • 1970-01-01
  • 2020-05-27
  • 2021-04-06
相关资源
最近更新 更多