mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-20 09:56:05 -05:00
[Core] Make Requires.verify() wait until rules are loaded (#2857)
* Make Requires.verify() wait until rules are loaded Also ensures `Requires` objects are reset when unloaded, particularly in case a `Command` object manages to stay in memory between cog unload and load, and its permissions rules change between those events. Also, this PR re-ordered some of the event loop policy stuff, because it was required that the event loop policy be set before creating any `Requires` objects. This may or may not have an effect on other `get_event_loop()` calls elsewhere (either in our code, a dependency's, or asyncio's). Either way, these effects would be a *correction*, and any bugs that arise from it are likely to have been occurring silently beforehand. Signed-off-by: Toby Harradine <tobyharradine@gmail.com> * Remove calls to `remove_listener()` in permissions Signed-off-by: Toby Harradine <tobyharradine@gmail.com> * Fix adding rules for permissions cog/commands itself Also addresses feedback Signed-off-by: Toby Harradine <tobyharradine@gmail.com> * Clean up indentation when setting uvloop policy Signed-off-by: Toby Harradine <tobyharradine@gmail.com> * Use `set(walk_commands())` to traverse `Group` subcommands Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
committed by
Michael H
parent
21a6384ebf
commit
f83f378528
@@ -4,10 +4,9 @@ from .permissions import Permissions
|
||||
async def setup(bot):
|
||||
cog = Permissions(bot)
|
||||
await cog.initialize()
|
||||
# It's important that these listeners are added prior to load, so
|
||||
# the permissions commands themselves have rules added.
|
||||
# Automatic listeners being added in add_cog happen in arbitrary
|
||||
# order, so we want to circumvent that.
|
||||
bot.add_listener(cog.red_cog_added, "on_cog_add")
|
||||
bot.add_listener(cog.red_command_added, "on_command_add")
|
||||
# We should add the rules for the Permissions cog and its own commands *before* adding the cog.
|
||||
# The actual listeners ought to skip the ones we're passing here.
|
||||
await cog._on_cog_add(cog)
|
||||
for command in cog.__cog_commands__:
|
||||
await cog._on_command_add(command)
|
||||
bot.add_cog(cog)
|
||||
|
||||
@@ -436,31 +436,41 @@ class Permissions(commands.Cog):
|
||||
await self._clear_rules(guild_id=ctx.guild.id)
|
||||
await ctx.tick()
|
||||
|
||||
async def red_cog_added(self, cog: commands.Cog) -> None:
|
||||
@commands.Cog.listener()
|
||||
async def on_cog_add(self, cog: commands.Cog) -> None:
|
||||
"""Event listener for `cog_add`.
|
||||
|
||||
This loads rules whenever a new cog is added.
|
||||
|
||||
Do not convert to using Cog.listener decorator !!
|
||||
This *must* be added manually prior to cog load, and removed at unload
|
||||
"""
|
||||
if cog is self:
|
||||
# This cog has its rules loaded manually in setup()
|
||||
return
|
||||
await self._on_cog_add(cog)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_command_add(self, command: commands.Command) -> None:
|
||||
"""Event listener for `command_add`.
|
||||
|
||||
This loads rules whenever a new command is added.
|
||||
"""
|
||||
if command.cog is self:
|
||||
# This cog's commands have their rules loaded manually in setup()
|
||||
return
|
||||
await self._on_command_add(command)
|
||||
|
||||
async def _on_cog_add(self, cog: commands.Cog) -> None:
|
||||
self._load_rules_for(
|
||||
cog_or_command=cog,
|
||||
rule_dict=await self.config.custom(COG, cog.__class__.__name__).all(),
|
||||
)
|
||||
cog.requires.ready_event.set()
|
||||
|
||||
async def red_command_added(self, command: commands.Command) -> None:
|
||||
"""Event listener for `command_add`.
|
||||
|
||||
This loads rules whenever a new command is added.
|
||||
|
||||
Do not convert to using Cog.listener decorator !!
|
||||
This *must* be added manually prior to cog load, and removed at unload
|
||||
"""
|
||||
async def _on_command_add(self, command: commands.Command) -> None:
|
||||
self._load_rules_for(
|
||||
cog_or_command=command,
|
||||
rule_dict=await self.config.custom(COMMAND, command.qualified_name).all(),
|
||||
)
|
||||
command.requires.ready_event.set()
|
||||
|
||||
async def _add_rule(
|
||||
self, rule: bool, cog_or_cmd: CogOrCommand, model_id: int, guild_id: int
|
||||
@@ -708,8 +718,6 @@ class Permissions(commands.Cog):
|
||||
cog_or_command.deny_to(model_id, guild_id=guild_id)
|
||||
|
||||
def cog_unload(self) -> None:
|
||||
self.bot.remove_listener(self.red_cog_added, "on_cog_add")
|
||||
self.bot.remove_listener(self.red_command_added, "on_command_add")
|
||||
self.bot.loop.create_task(self._unload_all_rules())
|
||||
|
||||
async def _unload_all_rules(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user