Cooldown saya yang diedit discord.py tidak berfungsi

Saya mencoba mengubah lib (core.py) dan mengubah perintah cooldown menjadi ini sehingga semua perintah akan berbagi 1 cooldown, misalnya setelah menggunakan !hi, juga !bye akan menjadi cooldown, bukan hanya !hi:

def shared_cooldown(rate, per, type=BucketType.default):
    cooldown = Cooldown(rate, per, type=BucketType.default)
    def decorator(func):
        if isinstance(func, Command):
            func._buckets = CooldownMapping(cooldown)
        else:
            func.__commands_cooldown__ = cooldown
        return func
    return decorator

Alih-alih ini:

def cooldown(rate, per, type=BucketType.default):
    """A decorator that adds a cooldown to a :class:`.Command`
    or its subclasses.

    A cooldown allows a command to only be used a specific amount
    of times in a specific time frame. These cooldowns can be based
    either on a per-guild, per-channel, per-user, or global basis.
    Denoted by the third argument of ``type`` which must be of enum
    type ``BucketType`` which could be either:

    - ``BucketType.default`` for a global basis.
    - ``BucketType.user`` for a per-user basis.
    - ``BucketType.guild`` for a per-guild basis.
    - ``BucketType.channel`` for a per-channel basis.
    - ``BucketType.member`` for a per-member basis.
    - ``BucketType.category`` for a per-category basis.

    If a cooldown is triggered, then :exc:`.CommandOnCooldown` is triggered in
    :func:`.on_command_error` and the local error handler.

    A command can only have a single cooldown.

    Parameters
    ------------
    rate: :class:`int`
        The number of times a command can be used before triggering a cooldown.
    per: :class:`float`
        The amount of seconds to wait for a cooldown when it's been triggered.
    type: ``BucketType``
        The type of cooldown to have.
    """

    def decorator(func):
        if isinstance(func, Command):
            func._buckets = CooldownMapping(Cooldown(rate, per, type))
        else:
            func.__commands_cooldown__ = Cooldown(rate, per, type)
        return func
    return decorator

Dalam kode bot saya, saya menambahkan baris ini: my_cooldown = commands.shared_cooldown(1, 600, commands.shared_cooldown) Dan 2 perintah:

@bot.command(name ="hi")
@my_cooldown
async def hi(ctx):
    site = ["https://google.com", "https://youtube.com"]
    chosen = random.choice(site)
    url = chosen
    embed = discord.Embed(title="Your site", description=f"[Click Here]({url})", color=0x00ff00)
    if ctx.message.guild == None:
        await ctx.author.send('You can not use this command in your DM!')
        pass
    else:
        await ctx.author.send(embed=embed)

@bot.command(name ="bye")
@my_cooldown
async def bye(ctx):
    site = ["https://google.com", "https://youtube.com"]
    chosen = random.choice(site)
    url = chosen
    embed = discord.Embed(title="Your site", description=f"[Click Here]({url})", color=0x00ff00)
    if ctx.message.guild == None:
        await ctx.author.send('You can not use this command in your DM!')
        pass
    else:
        await ctx.author.send(embed=embed)

Sekarang, masalahnya adalah cooldown saya berfungsi untuk semua perintah, tetapi SEMUA pengguna mendapat cooldown jika SATU ORANG menggunakan perintah tersebut. Saya mencoba mengubah def shared_cooldown(rate, per, type=BucketType.default): cooldown = Cooldown(rate, per, type=BucketType.default) menjadi def shared_cooldown(rate, per, type=BucketType.user): cooldown = Cooldown(rate, per, type=BucketType.user), tetapi kemudian orang-orang mendapat cooldown hanya untuk satu perintah yang mereka gunakan, bukan semua perintah. Bagaimana saya bisa membuat cooldown hanya untuk pengguna yang menggunakan perintah tersebut, bukan SEMUA ORANG, tetapi tetap melakukan cooldown semua perintah untuk satu pengguna itu?


person BabyCoder20    schedule 08.09.2019    source sumber


Jawaban (1)


Sepertinya kita harus memaksa perintah untuk selalu membagikan objek CooldownMapping. Itu cukup mudah, tetapi itu berarti dekorator harus keluar dari commanddecorator, karena kita tidak dapat lagi melampirkan cooldown ke fungsi tersebut dan mengandalkan mesin command untuk menghasilkan pemetaan.

def shared_cooldown(rate, per, type=BucketType.default):
    cooldown = Cooldown(rate, per, type=type)
    cooldown_mapping = CooldownMapping(cooldown)
    def decorator(func):
        if isinstance(func, Command):
            func._buckets = cooldown_mapping 
        else:
            raise ValueError("Decorator must be applied to command, not the function")
        return func
    return decorator

Ini lolos karena jenis keranjang default menyimpan semua informasinya di cooldown itu sendiri. Keranjang yang lebih granular menyimpan informasi dalam pemetaan, yang selalu dibuat baru. Saya sebenarnya memeriksa jenis keranjang yang berbeda ketika saya menulis yang asli, tetapi karena hanya ada satu dari saya, saya tidak menyadari bahwa itu sebenarnya menggunakan keranjang default setiap saat.

my_cooldown = shared_cooldown(1, 600, BucketType.User)  # Pass the desired bucket type

@my_cooldown  # shared cooldown has to go first now 
@bot.command(name ="bye")
async def bye(ctx):
    ...
person Patrick Haugh    schedule 08.09.2019