From c7d3ebb400cadd685cff4943397f8101c9cc51ec Mon Sep 17 00:00:00 2001 From: BluePhoenixGame <38372706+BluePhoenixGame@users.noreply.github.com> Date: Mon, 12 Aug 2019 00:44:16 +0200 Subject: [PATCH] [commands] Add role cooldown bucket --- discord/ext/commands/cooldowns.py | 9 +++++++++ discord/ext/commands/core.py | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/discord/ext/commands/cooldowns.py b/discord/ext/commands/cooldowns.py index 5cd305f6f..57577a07c 100644 --- a/discord/ext/commands/cooldowns.py +++ b/discord/ext/commands/cooldowns.py @@ -27,6 +27,8 @@ DEALINGS IN THE SOFTWARE. from discord.enums import Enum import time +from ...abc import PrivateChannel + __all__ = ( 'BucketType', 'Cooldown', @@ -40,6 +42,7 @@ class BucketType(Enum): channel = 3 member = 4 category = 5 + role = 6 class Cooldown: __slots__ = ('rate', 'per', 'type', '_window', '_tokens', '_last') @@ -127,6 +130,12 @@ class CooldownMapping: return ((msg.guild and msg.guild.id), msg.author.id) elif bucket_type is BucketType.category: return (msg.channel.category or msg.channel).id + elif bucket_type is BucketType.role: + # we return the channel id of a private-channel as there are only roles in guilds + # and that yields the same result as for a guild with only the @everyone role + # NOTE: PrivateChannel doesn't actually have an id attribute but we assume we are + # recieving a DMChannel or GroupChannel which inherit from PrivateChannel and do + return (msg.channel if isinstance(msg.channel, PrivateChannel) else msg.author.top_role).id def _verify_cache_integrity(self, current=None): # we want to delete all cache objects that haven't been used diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index ead83c729..e6c0ba27c 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -1592,7 +1592,7 @@ def cooldown(rate, per, type=BucketType.default): 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. + either on a per-guild, per-channel, per-user, per-role or global basis. Denoted by the third argument of ``type`` which must be of enum type ``BucketType`` which could be either: @@ -1602,6 +1602,7 @@ def cooldown(rate, per, type=BucketType.default): - ``BucketType.channel`` for a per-channel basis. - ``BucketType.member`` for a per-member basis. - ``BucketType.category`` for a per-category basis. + - ``BucketType.role`` for a per-role basis. If a cooldown is triggered, then :exc:`.CommandOnCooldown` is triggered in :func:`.on_command_error` and the local error handler.