คูลดาวน์การแก้ไข discord.py ของฉันไม่ทำงาน

ฉันพยายามเปลี่ยน lib (core.py) และเปลี่ยนคำสั่งคูลดาวน์เป็นดังนั้นคำสั่งทั้งหมดจะแชร์ 1 คูลดาวน์ เช่น หลังจากใช้ !hi แล้ว !bye ก็จะถูกคูลดาวน์แทนเพียง !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

แทนสิ่งนี้:

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

ในโค้ดบอทของฉัน ฉันเพิ่มบรรทัดนี้: my_cooldown = commands.shared_cooldown(1, 600, commands.shared_cooldown) และ 2 คำสั่ง:

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

ตอนนี้ ปัญหาคือคูลดาวน์ของฉันใช้ได้กับทุกคำสั่ง แต่ผู้ใช้ทุกคนจะได้รับคูลดาวน์หากมีคนคนหนึ่งใช้คำสั่ง ฉันพยายามเปลี่ยน def shared_cooldown(rate, per, type=BucketType.default): cooldown = Cooldown(rate, per, type=BucketType.default) เป็น def shared_cooldown(rate, per, type=BucketType.user): cooldown = Cooldown(rate, per, type=BucketType.user) แต่แล้วผู้คนก็คูลดาวน์สำหรับคำสั่งเดียวที่พวกเขาใช้ แทนที่จะเป็นคำสั่งทั้งหมด ฉันจะทำให้เฉพาะผู้ใช้ที่ใช้คำสั่งแทนทุกคน แต่ยังคงคูลดาวน์คำสั่งทั้งหมดสำหรับผู้ใช้รายนั้นได้อย่างไร


person BabyCoder20    schedule 08.09.2019    source แหล่งที่มา


คำตอบ (1)


ดูเหมือนว่าเราต้องบังคับให้คำสั่งแชร์อ็อบเจ็กต์ CooldownMapping เสมอ มันค่อนข้างง่าย แต่หมายความว่ามัณฑนากรจะต้องออกไปนอก commandมัณฑนากร เนื่องจากเราไม่สามารถติดคูลดาวน์กับฟังก์ชันได้อีกต่อไป และต้องใช้กลไก command เพื่อสร้างการแมป

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

สิ่งนี้เกิดขึ้นได้เนื่องจากประเภทบัคเก็ตเริ่มต้นจะจัดเก็บข้อมูลทั้งหมดไว้ในคูลดาวน์นั่นเอง ที่เก็บข้อมูลที่มีรายละเอียดมากขึ้นจะจัดเก็บข้อมูลในการแมปซึ่งจะถูกสร้างใหม่ทุกครั้ง จริงๆ แล้วฉันตรวจสอบบัคเก็ตประเภทต่างๆ เมื่อฉันเขียนต้นฉบับ แต่เนื่องจากมีฉันเพียงคนเดียว ฉันจึงไม่สังเกตว่าจริงๆ แล้วมีการใช้บัคเก็ตเริ่มต้นทุกครั้ง

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