Как сделать систему восстановления с помощью discord.py? - PullRequest
0 голосов
/ 05 августа 2020

Допустим, у меня есть две команды ...

  • hi 1, которая отправляет привет один раз пользователю и запускает перезарядку в 500 секунд
  • hi 2, которая отправляет привет дважды пользователю и запускает перезарядку в 1000 секунд

Теперь, когда я набираю hi 1, он не должен отвечать мне, когда я набираю hi 2. Что-то вроде общей системы восстановления!

Как я могу это сделать?

В настоящее время я использую это:

@commands.cooldown(1, 5, commands.BucketType.user)

Что позволяет мне использовать несколько команд без остановки для восстановления по предыдущей команде.

1 Ответ

1 голос
/ 05 августа 2020

Вы можете использовать пользовательскую проверку , чтобы убедиться, что команды не используются, пока они находятся на перезарядке. ./q63262849/cooldowns.py

import datetime
from discord.ext import commands

on_cooldown = {}  # A dictionary mapping user IDs to cooldown ends


def cooldown(seconds):
    def predicate(context):
        if (cooldown_end := on_cooldown.get(context.author.id)) is None or cooldown_end < datetime.datetime.now():  # If there's no cooldown or it's over
            if context.valid and context.invoked_with in (*context.command.aliases, context.command.name):  # If the command is being run as itself (not by help, which runs checks and would end up creating more cooldowns if this didn't exist)
                on_cooldown[context.author.id] = datetime.datetime.now() + datetime.timedelta(seconds=seconds)  # Add the datetime of the cooldown's end to the dictionary
            return True  # And allow the command to run
        else:
            raise commands.CommandOnCooldown(commands.BucketType.user, (cooldown_end - datetime.datetime.now()).seconds)  # Otherwise, raise the cooldown error to say the command is on cooldown

    return commands.check(predicate)

Затем его можно импортировать

./main.py

from q63262849 import cooldowns

и использовать в качестве декоратора для команд

./main.py

@bot.command()
@cooldowns.cooldown(10)
async def cooldown1(ctx):
    await ctx.send("Ran cooldown 1")


@bot.command()
@cooldowns.cooldown(20)
async def cooldown2(ctx):
    await ctx.send("Ran cooldown 2")

Примечательно, что у этого подхода все еще есть некоторые проблемы, в частности, если другая более поздняя проверка не удалась, эта проверка все равно приведет к перезарядке команды, однако это можно решить, поставив эту проверку так, чтобы она запустится после всех остальных проверок.

...