diff --git a/discord/ext/commands/cooldowns.py b/discord/ext/commands/cooldowns.py index 08f36b604..c530bb120 100644 --- a/discord/ext/commands/cooldowns.py +++ b/discord/ext/commands/cooldowns.py @@ -91,6 +91,15 @@ class Cooldown: tokens = self.rate return tokens + def get_retry_after(self, current=None): + current = current or time.time() + tokens = self.get_tokens(current) + + if tokens == 0: + return self.per - (current - self._window) + + return 0.0 + def update_rate_limit(self, current=None): current = current or time.time() self._last = current diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index a1f215638..5b0971aef 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -805,7 +805,8 @@ class Command(_BaseCommand): return False bucket = self._buckets.get_bucket(ctx.message) - return bucket.get_tokens() == 0 + current = ctx.message.created_at.replace(tzinfo=datetime.timezone.utc).timestamp() + return bucket.get_tokens(current) == 0 def reset_cooldown(self, ctx): """Resets the cooldown on this command. @@ -819,6 +820,29 @@ class Command(_BaseCommand): bucket = self._buckets.get_bucket(ctx.message) bucket.reset() + def get_cooldown_retry_after(self, ctx): + """Retrieves the amount of seconds before this command can be tried again. + + .. versionadded:: 1.4 + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context to retrieve the cooldown from. + + Returns + -------- + :class:`float` + The amount of time left on this command's cooldown in seconds. + If this is ``0.0`` then the command isn't on cooldown. + """ + if self._buckets.valid: + bucket = self._buckets.get_bucket(ctx.message) + current = ctx.message.created_at.replace(tzinfo=datetime.timezone.utc).timestamp() + return bucket.get_retry_after(current) + + return 0.0 + async def invoke(self, ctx): await self.prepare(ctx)