diff --git a/bot.py b/bot.py index f9cfe5d..3670617 100644 --- a/bot.py +++ b/bot.py @@ -283,6 +283,8 @@ class DiscordBot(commands.Bot): color=0xE02B2B, ) await context.send(embed=embed) + elif isinstance(error, commands.CheckFailure): + return else: raise error diff --git a/cogs/fun/__init__.py b/cogs/fun/__init__.py index a08fc44..18420de 100644 --- a/cogs/fun/__init__.py +++ b/cogs/fun/__init__.py @@ -31,6 +31,16 @@ class Fun(commands.GroupCog, name="fun"): else: await context.send(f"Unknown fun command: {name}") + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + @fun_group.command(name="coinflip") async def fun_group_coinflip(self, context: Context): await self._invoke_hybrid(context, "coinflip") @@ -51,6 +61,7 @@ class Fun(commands.GroupCog, name="fun"): async def fun_group_rps(self, context: Context): await self._invoke_hybrid(context, "rps") + @commands.check(_require_group_prefix) @commands.hybrid_command( name="coinflip", description="Make a coin flip, but give your bet before." @@ -58,6 +69,7 @@ class Fun(commands.GroupCog, name="fun"): async def coinflip(self, context): return await coinflip_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="8ball", description="Ask any question to the bot.", @@ -65,6 +77,7 @@ class Fun(commands.GroupCog, name="fun"): async def eight_ball(self, context, *, question: str): return await eightball_command()(self, context, question=question) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="minesweeper", description="Play a buttoned minesweeper mini-game." @@ -72,10 +85,12 @@ class Fun(commands.GroupCog, name="fun"): async def minesweeper(self, context): return await minesweeper_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command(name="randomfact", description="Get a random fact.") async def randomfact(self, context): return await randomfact_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="rps", description="Play the rock paper scissors game against the bot." ) diff --git a/cogs/general/__init__.py b/cogs/general/__init__.py index 6e92d77..e37c04c 100644 --- a/cogs/general/__init__.py +++ b/cogs/general/__init__.py @@ -8,6 +8,17 @@ from .botinfo import botinfo_command from .serverinfo import serverinfo_command from .feedback import feedback_command + +def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + class General(commands.GroupCog, name="general"): def __init__(self, bot) -> None: self.bot = bot @@ -51,6 +62,7 @@ class General(commands.GroupCog, name="general"): async def general_group_feedback(self, context: Context): await self._invoke_hybrid(context, "feedback") + @commands.check(_require_group_prefix) @commands.hybrid_command( name="ping", description="Check if the bot is alive.", @@ -58,6 +70,7 @@ class General(commands.GroupCog, name="general"): async def ping(self, context): return await ping_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="uptime", description="Check how long the bot has been running.", @@ -65,6 +78,7 @@ class General(commands.GroupCog, name="general"): async def uptime(self, context): return await uptime_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="botinfo", description="Get some useful (or not) information about the bot.", @@ -72,6 +86,7 @@ class General(commands.GroupCog, name="general"): async def botinfo(self, context): return await botinfo_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="serverinfo", description="Get some useful (or not) information about the server.", @@ -79,6 +94,7 @@ class General(commands.GroupCog, name="general"): async def serverinfo(self, context): return await serverinfo_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="feedback", description="Submit a feedback for the owners of the bot" diff --git a/cogs/idevice/__init__.py b/cogs/idevice/__init__.py index 2f3cf5e..de3ad81 100644 --- a/cogs/idevice/__init__.py +++ b/cogs/idevice/__init__.py @@ -43,6 +43,16 @@ class Idevice(commands.GroupCog, name="idevice"): else: await context.send(f"Unknown idevice command: {name}") + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + @idevice_group.command(name="errorcodes") async def idevice_group_errorcodes(self, context: Context): await self._invoke_hybrid(context, "errorcodes") @@ -73,6 +83,7 @@ class Idevice(commands.GroupCog, name="idevice"): view = ideviceView(self.bot) await interaction.response.send_message(embed=embed, view=view, ephemeral=True) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="errorcodes", description="Look up error codes and their meanings." @@ -80,6 +91,7 @@ class Idevice(commands.GroupCog, name="idevice"): async def errorcodes(self, context, *, error_code: str = None): return await errorcodes_command()(self, context, error_code=error_code) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="developermode", description="How to turn on developer mode" @@ -87,6 +99,7 @@ class Idevice(commands.GroupCog, name="idevice"): async def developermode(self, context): return await developermode_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="noapps", description="Help when apps aren't showing in installed apps view" @@ -94,6 +107,7 @@ class Idevice(commands.GroupCog, name="idevice"): async def noapps(self, context): return await noapps_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="mountddi", description="How to manually mount DDI" diff --git a/cogs/miscellaneous/__init__.py b/cogs/miscellaneous/__init__.py index da7828c..1314059 100644 --- a/cogs/miscellaneous/__init__.py +++ b/cogs/miscellaneous/__init__.py @@ -31,6 +31,16 @@ class Miscellaneous(commands.GroupCog, name="misc"): else: await context.send(f"Unknown miscellaneous command: {name}") + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + @miscellaneous_group.command(name="rr") async def miscellaneous_group_rr(self, context: Context): await self._invoke_hybrid(context, "rr") @@ -51,6 +61,7 @@ class Miscellaneous(commands.GroupCog, name="misc"): async def miscellaneous_group_keanu(self, context: Context): await self._invoke_hybrid(context, "keanu") + @commands.check(_require_group_prefix) @commands.hybrid_command( name="rr", description="Rickroll" @@ -58,6 +69,7 @@ class Miscellaneous(commands.GroupCog, name="misc"): async def rr(self, context): return await rr_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="labubu", description="Labubu ASCII art" @@ -65,6 +77,7 @@ class Miscellaneous(commands.GroupCog, name="misc"): async def labubu(self, context): return await labubu_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="tryitandsee", description="Try it and see" @@ -72,6 +85,7 @@ class Miscellaneous(commands.GroupCog, name="misc"): async def tryitandsee(self, context): return await tryitandsee_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="piracy", description="FBI Anti Piracy Warning" @@ -79,6 +93,7 @@ class Miscellaneous(commands.GroupCog, name="misc"): async def piracy(self, context): return await piracy_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="keanu", description="Reeves" diff --git a/cogs/moderation/__init__.py b/cogs/moderation/__init__.py index 0553ba1..459ae0d 100644 --- a/cogs/moderation/__init__.py +++ b/cogs/moderation/__init__.py @@ -15,6 +15,62 @@ class Moderation(commands.GroupCog, name="moderation"): self.bot = bot super().__init__() + @commands.group(name="moderation", invoke_without_command=True) + async def moderation_group(self, context: Context): + embed = discord.Embed( + title="Moderation Commands", + description="Use `.moderation ` or `/moderation `.", + color=0x7289DA + ) + embed.add_field(name="Available", value="ban, kick, purge, warnings, archive, hackban, nick", inline=False) + await context.send(embed=embed) + + async def _invoke_hybrid(self, context: Context, name: str, **kwargs): + command = self.bot.get_command(name) + if command is not None: + await context.invoke(command, **kwargs) + else: + await context.send(f"Unknown moderation command: {name}") + + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + + @moderation_group.command(name="ban") + async def moderation_group_ban(self, context: Context, user: discord.User, *, reason: str = "Not specified", delete_messages: str = "none"): + await self._invoke_hybrid(context, "ban", user=user, reason=reason, delete_messages=delete_messages) + + @moderation_group.command(name="kick") + async def moderation_group_kick(self, context: Context, user: discord.User, *, reason: str = "Not specified"): + await self._invoke_hybrid(context, "kick", user=user, reason=reason) + + @moderation_group.command(name="purge") + async def moderation_group_purge(self, context: Context, amount: int): + await self._invoke_hybrid(context, "purge", amount=amount) + + @moderation_group.command(name="warnings") + async def moderation_group_warnings(self, context: Context): + await self._invoke_hybrid(context, "warnings") + + @moderation_group.command(name="archive") + async def moderation_group_archive(self, context: Context, limit: int = 10): + await self._invoke_hybrid(context, "archive", limit=limit) + + @moderation_group.command(name="hackban") + async def moderation_group_hackban(self, context: Context, user_id: int, *, reason: str = "Not specified"): + await self._invoke_hybrid(context, "hackban", user_id=user_id, reason=reason) + + @moderation_group.command(name="nick") + async def moderation_group_nick(self, context: Context, user: discord.User, *, nickname: str = None): + await self._invoke_hybrid(context, "nick", user=user, nickname=nickname) + + @commands.check(_require_group_prefix) @commands.hybrid_command( name="ban", description="Bans a user from the server." @@ -22,6 +78,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def ban(self, context, user: discord.User, *, reason: str = "Not specified", delete_messages: str = "none"): return await ban_command()(self, context, user=user, reason=reason, delete_messages=delete_messages) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="kick", description="Kicks a user from the server." @@ -29,6 +86,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def kick(self, context, user: discord.User, *, reason: str = "Not specified"): return await kick_command()(self, context, user=user, reason=reason) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="purge", description="Delete a number of messages." @@ -36,6 +94,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def purge(self, context, amount: int): return await purge_command()(self, context, amount=amount) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="warnings", description="Manage warnings of a user on a server." @@ -43,6 +102,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def warnings(self, context): return await warnings_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="archive", description="Archives in a text file the last messages with a chosen limit of messages." @@ -50,6 +110,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def archive(self, context, limit: int = 10): return await archive_command()(self, context, limit=limit) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="hackban", description="Bans a user without the user having to be in the server." @@ -57,6 +118,7 @@ class Moderation(commands.GroupCog, name="moderation"): async def hackban(self, context, user_id: int, *, reason: str = "Not specified"): return await hackban_command()(self, context, user_id=user_id, reason=reason) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="nick", description="Change the nickname of a user on a server." diff --git a/cogs/sidestore/__init__.py b/cogs/sidestore/__init__.py index b9c1f26..6c28437 100644 --- a/cogs/sidestore/__init__.py +++ b/cogs/sidestore/__init__.py @@ -48,6 +48,16 @@ class Sidestore(commands.GroupCog, name="sidestore"): else: await context.send(f"Unknown SideStore command: {name}") + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + @sidestore_group.command(name="refresh") async def sidestore_group_refresh(self, context: Context): await self._invoke_hybrid(context, "refresh") @@ -100,6 +110,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): await interaction.response.send_message(embed=embed, view=view, ephemeral=True) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="refresh", description="Help with refreshing or installing apps" @@ -107,6 +118,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def refresh(self, context): return await refresh_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="code", description="No code received when signing in with Apple ID" @@ -114,6 +126,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def code(self, context): return await code_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="crash", description="Help with SideStore crashing issues" @@ -121,6 +134,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def crash(self, context): return await crash_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="pairing", description="Help with pairing file issues" @@ -128,6 +142,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def pairing(self, context): return await pairing_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="server", description="Help with anisette server issues" @@ -135,6 +150,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def server(self, context): return await server_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="afc", description="Help with AFC Connection Failure issues" @@ -142,6 +158,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def afc(self, context): return await afc_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="udid", description="SideStore could not determine device UDID" @@ -149,6 +166,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def udid(self, context): return await udid_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="half", description="Help with half-installed apps" @@ -156,6 +174,7 @@ class Sidestore(commands.GroupCog, name="sidestore"): async def half(self, context): return await half_command()(self, context) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="sparse", description="Help with sparse bundle issues" diff --git a/cogs/utilities/__init__.py b/cogs/utilities/__init__.py index 3364dce..dd23422 100644 --- a/cogs/utilities/__init__.py +++ b/cogs/utilities/__init__.py @@ -27,10 +27,21 @@ class Utilities(commands.GroupCog, name="utils"): else: await context.send(f"Unknown utilities command: {name}") + def _require_group_prefix(context: Context) -> bool: + if getattr(context, "interaction", None): + return True + group = getattr(getattr(context, "cog", None), "qualified_name", "").lower() + if not group: + return True + prefix = context.prefix or "" + content = context.message.content.strip().lower() + return content.startswith(f"{prefix}{group} ") + @utilities_group.command(name="translate") async def utilities_group_translate(self, context: Context, text: str = None, to_lang: str = "en", from_lang: str = None): await self._invoke_hybrid(context, "translate", text=text, to_lang=to_lang, from_lang=from_lang) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="translate", description="Translate text to another language"