mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
Use a SnowflakeList for Command disable instead of checks (#5552)
This commit is contained in:
parent
edb3369169
commit
f47d1dffb3
@ -92,7 +92,6 @@ RESERVED_COMMAND_NAMES = (
|
||||
)
|
||||
|
||||
_ = Translator("commands.commands", __file__)
|
||||
DisablerDictType = MutableMapping[discord.Guild, Callable[["Context"], Awaitable[bool]]]
|
||||
|
||||
|
||||
class RedUnhandledAPI(Exception):
|
||||
@ -311,6 +310,7 @@ class Command(CogCommandMixin, DPYCommand):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.ignore_optional_for_conversion = kwargs.pop("ignore_optional_for_conversion", False)
|
||||
self._disabled_in: discord.utils.SnowflakeList = discord.utils.SnowflakeList([])
|
||||
self._help_override = kwargs.pop("help_override", None)
|
||||
self.translator = kwargs.pop("i18n", None)
|
||||
super().__init__(*args, **kwargs)
|
||||
@ -461,10 +461,20 @@ class Command(CogCommandMixin, DPYCommand):
|
||||
if not change_permission_state:
|
||||
ctx.permission_state = original_state
|
||||
|
||||
def is_enabled(self, ctx) -> bool:
|
||||
if not self.enabled:
|
||||
return False
|
||||
if ctx.guild:
|
||||
if self._disabled_in.has(ctx.guild.id):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def prepare(self, ctx, /):
|
||||
ctx.command = self
|
||||
|
||||
if not self.enabled:
|
||||
cmd_enabled = self.is_enabled(ctx)
|
||||
if not cmd_enabled:
|
||||
raise DisabledCommand(f"{self.name} command is disabled")
|
||||
|
||||
if not await self.can_run(ctx, change_permission_state=True):
|
||||
@ -533,12 +543,11 @@ class Command(CogCommandMixin, DPYCommand):
|
||||
``True`` if the command wasn't already disabled.
|
||||
|
||||
"""
|
||||
disabler = get_command_disabler(guild)
|
||||
if disabler in self.checks:
|
||||
if self._disabled_in.has(guild.id):
|
||||
return False
|
||||
else:
|
||||
self.checks.append(disabler)
|
||||
return True
|
||||
|
||||
self._disabled_in.add(guild.id)
|
||||
return True
|
||||
|
||||
def enable_in(self, guild: discord.Guild) -> bool:
|
||||
"""Enable this command in the given guild.
|
||||
@ -554,13 +563,12 @@ class Command(CogCommandMixin, DPYCommand):
|
||||
``True`` if the command wasn't already enabled.
|
||||
|
||||
"""
|
||||
disabler = get_command_disabler(guild)
|
||||
try:
|
||||
self.checks.remove(disabler)
|
||||
self._disabled_in.remove(guild.id)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
return True
|
||||
|
||||
def allow_for(self, model_id: Union[int, str], guild_id: int) -> None:
|
||||
super().allow_for(model_id, guild_id=guild_id)
|
||||
@ -1151,28 +1159,6 @@ def group(name=None, cls=Group, **attrs):
|
||||
return dpy_command_deco(name, cls, **attrs)
|
||||
|
||||
|
||||
__command_disablers: DisablerDictType = weakref.WeakValueDictionary()
|
||||
|
||||
|
||||
def get_command_disabler(guild: discord.Guild) -> Callable[["Context"], Awaitable[bool]]:
|
||||
"""Get the command disabler for a guild.
|
||||
|
||||
A command disabler is a simple check predicate which returns
|
||||
``False`` if the context is within the given guild.
|
||||
"""
|
||||
try:
|
||||
return __command_disablers[guild.id]
|
||||
except KeyError:
|
||||
|
||||
async def disabler(ctx: "Context") -> bool:
|
||||
if ctx.guild is not None and ctx.guild.id == guild.id:
|
||||
raise DisabledCommand()
|
||||
return True
|
||||
|
||||
__command_disablers[guild.id] = disabler
|
||||
return disabler
|
||||
|
||||
|
||||
# The below are intentionally left out of `__all__`
|
||||
# as they are not intended for general use
|
||||
class _AlwaysAvailableMixin:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user