diff --git a/cogs/help.py b/cogs/help.py index e6fdfdf..161f846 100644 --- a/cogs/help.py +++ b/cogs/help.py @@ -21,6 +21,7 @@ class Help(commands.Cog, name="help"): "sidestore", "idevice", "melonx", + "livecontainer", "media", "miscellaneous", "utilities", @@ -51,6 +52,7 @@ class Help(commands.Cog, name="help"): "fun": "fun", "idevice": "idevice", "melonx": "melonx", + "livecontainer": "livecontainer", "media": "media", "misc": "miscellaneous", "miscellaneous": "miscellaneous", @@ -77,6 +79,7 @@ class Help(commands.Cog, name="help"): "sidestore": "SideStore troubleshooting commands", "idevice": "idevice troubleshooting commands", "melonx": "MeloNX troubleshooting commands", + "livecontainer": "LiveContainer troubleshooting commands", "media": "Media commands", "utilities": "Utility commands", "miscellaneous": "Miscellaneous commands", diff --git a/cogs/livecontainer/__init__.py b/cogs/livecontainer/__init__.py new file mode 100644 index 0000000..c654a36 --- /dev/null +++ b/cogs/livecontainer/__init__.py @@ -0,0 +1,91 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context + +from .livecontainer import LivecontainerView +from .jit26 import jit26_command + + +@app_commands.allowed_contexts(guilds=True, dms=True, private_channels=True) +@app_commands.allowed_installs(guilds=True, users=True) +class Livecontainer(commands.GroupCog, name="livecontainer"): + def __init__(self, bot) -> None: + self.bot = bot + super().__init__() + + @commands.group(name="livecontainer", invoke_without_command=True) + async def livecontainer_group(self, context: Context): + embed = discord.Embed( + title="LiveContainer Commands", + description="Choose a command from the dropdown below to get help with specific issues:", + color=0x0169FF, + ) + embed.set_author( + name="LiveContainer", icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png" + ) + view = LivecontainerView(self.bot) + await context.send(embed=embed, view=view) + + @livecontainer_group.command(name="help") + async def livecontainer_group_help(self, context: Context): + embed = discord.Embed( + title="LiveContainer Commands", + description="Choose a command from the dropdown below to get help with specific issues:", + color=0x0169FF, + ) + embed.set_author( + name="LiveContainer", icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png" + ) + view = LivecontainerView(self.bot) + await context.send(embed=embed, view=view) + + @livecontainer_group.command(name="26jit") + async def livecontainer_group_26jit(self, context: Context): + await self._invoke_hybrid(context, "26jit") + + async def _invoke_hybrid(self, context: Context, name: str): + command = self.bot.get_command(name) + if command is not None: + await context.invoke(command) + else: + await context.send(f"Unknown LiveContainer 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} ") + + @app_commands.command(name="help", description="LiveContainer troubleshooting help") + async def help(self, interaction: discord.Interaction): + embed = discord.Embed( + title="LiveContainer Commands", + description="Choose a command from the dropdown below to get help with specific issues:", + color=0x0169FF, + ) + embed.set_author( + name="LiveContainer", icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png" + ) + view = LivecontainerView(self.bot) + await interaction.response.send_message(embed=embed, view=view, ephemeral=True) + + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="26jit", description="Walkthrough for iOS 26 JIT and sideloading" + ) + async def jit26(self, context): + return await jit26_command()(self, context) + + +async def setup(bot) -> None: + cog = Livecontainer(bot) + await bot.add_cog(cog) + + bot.logger.info("Loaded extension 'livecontainer.help'") + bot.logger.info("Loaded extension 'livecontainer.26jit'") + diff --git a/cogs/livecontainer/jit26.py b/cogs/livecontainer/jit26.py new file mode 100644 index 0000000..adc958a --- /dev/null +++ b/cogs/livecontainer/jit26.py @@ -0,0 +1,27 @@ +import discord +from discord.ext.commands import Context + + +def jit26_command(): + async def command(self, context: Context): + embed = discord.Embed( + color=0x0169FF, + description=( + "# iOS 26 JIT & Sideloading Walkthrough\n\n---\n\n" + "Click the [button below](https://github.com/CelloSerenity/iOS-26-Sideloading-and-JIT-Complete-Walkthrough) to get started with iOS 26 JIT and sideloading." + ), + ) + embed.set_author( + name="LiveContainer", icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png" + ) + embed.set_footer(icon_url="https://yes.nighty.works/raw/2PPWd3.webp", text="Made By CelloSerenity") + + view = discord.ui.View() + view.add_item(discord.ui.Button(label="Get Started", url="https://github.com/CelloSerenity/iOS-26-Sideloading-and-JIT-Complete-Walkthrough", style=discord.ButtonStyle.primary, emoji="<:githubicon:1417717356846776340>")) + + if context.interaction: + await context.interaction.response.send_message(embed=embed, view=view) + else: + await context.send(embed=embed, view=view) + + return command diff --git a/cogs/livecontainer/livecontainer.py b/cogs/livecontainer/livecontainer.py new file mode 100644 index 0000000..2177d27 --- /dev/null +++ b/cogs/livecontainer/livecontainer.py @@ -0,0 +1,88 @@ +import discord + + +class LivecontainerSelect(discord.ui.Select): + def __init__(self, bot): + self.bot = bot + options = [ + discord.SelectOption( + label="iOS 26 JIT & Sideloading", + value="26jit", + description="Walkthrough for iOS 26 JIT and sideloading", + ), + ] + super().__init__(placeholder="Choose a LiveContainer command...", options=options) + + async def callback(self, interaction: discord.Interaction): + command_name = self.values[0] + command = self.bot.get_command(command_name) + + if command: + try: + ctx = await self.bot.get_context(interaction.message) + if ctx: + await ctx.invoke(command) + embed = discord.Embed( + title="Command Executed", + description=f"Successfully executed `/{command_name}`", + color=0x00FF00, + ) + embed.set_author( + name="LiveContainer", + icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png", + ) + await interaction.response.edit_message(embed=embed, view=None) + except discord.Forbidden: + guild_info = ( + f"server {interaction.guild.name} (ID: {interaction.guild.id})" + if interaction.guild + else "DM or private channel" + ) + self.bot.logger.warning( + f"Bot missing permissions in {guild_info} - cannot execute {command_name} command" + ) + + if interaction.guild is None: + embed = discord.Embed( + title="Error", + description="This command cannot be executed in DMs.", + color=0xFF0000, + ) + else: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xFF0000, + ) + embed.set_author( + name="LiveContainer", + icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png", + ) + await interaction.response.edit_message(embed=embed, view=None) + except Exception as e: + self.bot.logger.error(f"Error executing {command_name} command: {e}") + embed = discord.Embed( + title="Error", + description="An error occurred while executing the command.", + color=0xFF0000, + ) + embed.set_author( + name="LiveContainer", + icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png", + ) + await interaction.response.edit_message(embed=embed, view=None) + else: + embed = discord.Embed( + title="Error", description="Command not found!", color=0xFF0000 + ) + embed.set_author( + name="LiveContainer", + icon_url="https://raw.githubusercontent.com/LiveContainer/LiveContainer/main/screenshots/livecontainer_icon.png", + ) + await interaction.response.edit_message(embed=embed, view=None) + + +class LivecontainerView(discord.ui.View): + def __init__(self, bot): + super().__init__() + self.add_item(LivecontainerSelect(bot))