diff --git a/README.md b/README.md index 0997e35..ca49d59 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ | moderation | `kick`, `ban`, `nick`, `purge`, `hackban`, `warnings`, `archive` | | sidestore | `sidestore`, `refresh`, `code`, `crash`, `pairing`, `server`, `half`, `sparse`, `afc`, `udid` | | idevice | `idevice`, `noapps`, `errorcode`, `developermode`, `mountddi` | -| melonx | `melonx`, `transfer` | +| melonx | `melonx`, `transfer`, `mods`, `gamecrash`, `requirements`, `error`, `26` | | miscellaneous | `keanu`, `labubu`, `piracy`, `tryitandsee`, `rickroll`, `dontasktoask`, `support`| | utilities | `translate`, `codepreview`, `dictionary` | | media | `download` | diff --git a/cogs/melonx/__init__.py b/cogs/melonx/__init__.py index e5dc66a..8b3a753 100644 --- a/cogs/melonx/__init__.py +++ b/cogs/melonx/__init__.py @@ -5,6 +5,11 @@ from discord.ext.commands import Context from .melonx import MelonxView from .transfer import transfer_command +from .mods import mods_command +from .gamecrash import crash_command +from .requirements import requirements_command +from .error import error_command +from .ios26 import ios26_command class Melonx(commands.GroupCog, name="melonx"): def __init__(self, bot) -> None: @@ -37,6 +42,26 @@ class Melonx(commands.GroupCog, name="melonx"): async def melonx_group_transfer(self, context: Context): await self._invoke_hybrid(context, "transfer") + @melonx_group.command(name="mods") + async def melonx_group_mods(self, context: Context): + await self._invoke_hybrid(context, "mods") + + @melonx_group.command(name="gamecrash") + async def melonx_group_gamecrash(self, context: Context): + await self._invoke_hybrid(context, "gamecrash") + + @melonx_group.command(name="requirements") + async def melonx_group_requirements(self, context: Context): + await self._invoke_hybrid(context, "requirements") + + @melonx_group.command(name="error") + async def melonx_group_error(self, context: Context): + await self._invoke_hybrid(context, "error") + + @melonx_group.command(name="26") + async def melonx_group_26(self, context: Context): + await self._invoke_hybrid(context, "26") + async def _invoke_hybrid(self, context: Context, name: str): command = self.bot.get_command(name) if command is not None: @@ -44,6 +69,16 @@ class Melonx(commands.GroupCog, name="melonx"): else: await context.send(f"Unknown MeloNX 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="MeloNX troubleshooting help" @@ -58,6 +93,7 @@ class Melonx(commands.GroupCog, name="melonx"): view = MelonxView(self.bot) await interaction.response.send_message(embed=embed, view=view, ephemeral=True) + @commands.check(_require_group_prefix) @commands.hybrid_command( name="transfer", description="How to transfer save files from other emulators or platforms" @@ -65,9 +101,54 @@ class Melonx(commands.GroupCog, name="melonx"): async def transfer(self, context): return await transfer_command()(self, context) + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="mods", + description="How to install mods within MeloNX (Limited Support)" + ) + async def mods(self, context): + return await mods_command()(self, context) + + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="gamecrash", + description="Why does my game crash?" + ) + async def gamecrash(self, context): + return await crash_command()(self, context) + + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="requirements", + description="What does MeloNX require?" + ) + async def requirements(self, context): + return await requirements_command()(self, context) + + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="error", + description="What does this error message mean?" + ) + async def error(self, context): + return await error_command()(self, context) + + @commands.check(_require_group_prefix) + @commands.hybrid_command( + name="26", + description="How can I run MeloNX on iOS 26?" + ) + async def ios26(self, context): + return await ios26_command()(self, context) + async def setup(bot) -> None: cog = Melonx(bot) await bot.add_cog(cog) bot.logger.info("Loaded extension 'melonx.help'") bot.logger.info("Loaded extension 'melonx.transfer'") + bot.logger.info("Loaded extension 'melonx.mods'") + bot.logger.info("Loaded extension 'melonx.gamecrash'") + bot.logger.info("Loaded extension 'melonx.requirements'") + bot.logger.info("Loaded extension 'melonx.error'") + bot.logger.info("Loaded extension 'melonx.26'") diff --git a/cogs/melonx/error.py b/cogs/melonx/error.py new file mode 100644 index 0000000..f9c802f --- /dev/null +++ b/cogs/melonx/error.py @@ -0,0 +1,41 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context +import time + + +def error_command(): + @commands.hybrid_command( + name="error", description="What does this error message mean?" + ) + async def error(self, context): + embed = discord.Embed( + color=0x963155, + description=( + '# What does this error message mean?\n\n---\n\n' + + '**1. "MeloNX Crashed! System.SystemException: Cannot allocate memory"**' + + 'You likely don\'t have the increased memory limit entitlement enabled, are using an a12 chipset, and have 4GB or less of memory. You can see the status of the entitlement for MeloNX under the Settings tab.\n\n' + + '**2. "MeloNX Crashed! LibHac.Common.HorizonResultException: ResultLoaderInvalidNso (2009-0005)"**' + + 'This is likely a bad game / update / or DLC dump. redump your files and try again.' + ) + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + embed.set_footer(text=f'Last Edited by neoarz') + embed.timestamp = discord.utils.utcnow() + + view = discord.ui.View() + view.add_item(discord.ui.Button( + label="Edit Command", + style=discord.ButtonStyle.secondary, + url="https://github.com/neoarz/Syntrel/blob/main/cogs/melonx/error.py", + 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 error diff --git a/cogs/melonx/gamecrash.py b/cogs/melonx/gamecrash.py new file mode 100644 index 0000000..b2b1821 --- /dev/null +++ b/cogs/melonx/gamecrash.py @@ -0,0 +1,46 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context +import time + + +def crash_command(): + @commands.hybrid_command( + name="gamecrash", description="Why does my game crash?" + ) + async def crash(self, context): + embed = discord.Embed( + color=0x963155, + description=( + '# "Why does my game crash?"\n\n---\n\n' + + '**This can be caused by multiple reasons:**\n' + + '- Not enough available ram\n' + + '- You may have tried to update your firmware without updating your keys\n' + + '- Game file is corrupted/broken\n' + + '- Game requires a higher firmware+keys combination than you currently have\n' + + '- In rare cases some games also crash when not having the resolution set to 1x\n' + + '- The a12 chipset have a lot of issues at the moment\n' + + '- Shader cache isn\'t cleared after updating MeloNX\n' + + '- iOS 15 and 16 are known to have some compatibility issues' + ) + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + embed.set_footer(text=f'Last Edited by neoarz') + embed.timestamp = discord.utils.utcnow() + + view = discord.ui.View() + view.add_item(discord.ui.Button( + label="Edit Command", + style=discord.ButtonStyle.secondary, + url="https://github.com/neoarz/Syntrel/blob/main/cogs/melonx/crash.py", + 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 crash diff --git a/cogs/melonx/ios26.py b/cogs/melonx/ios26.py new file mode 100644 index 0000000..cec73af --- /dev/null +++ b/cogs/melonx/ios26.py @@ -0,0 +1,47 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context +import time + + +def ios26_command(): + @commands.hybrid_command( + name="26", description="How can I run MeloNX on iOS 26?" + ) + async def ios26(self, context): + embed = discord.Embed( + color=0x963155, + description=( + '# "How can I run MeloNX on iOS 26?"\n\n---\n\n' + + '### StikDebug\n' + + '1. Make sure StikDebug is on the latest version.\n' + + '2. Turn on "Picture in Picture" in StikDebug\'s settings.\n\n' + + '### MeloNX\n' + + 'Make sure you\'re on the latest public beta.\n' + + '#prerelease-betas\n\n' + + '## Disclaimer:\n\n' + + 'If you\'re on iOS 18 or below, and emulation is essential to you:\n\n' + + '## <:error:1424007141768822824> DO NOT UPDATE <:error:1424007141768822824> \n\n' + + 'iOS 26 has many issues related to emulation.' + ) + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + embed.set_footer(text=f'Last Edited by neoarz') + embed.timestamp = discord.utils.utcnow() + + view = discord.ui.View() + view.add_item(discord.ui.Button( + label="Edit Command", + style=discord.ButtonStyle.secondary, + url="https://github.com/neoarz/Syntrel/blob/main/cogs/melonx/ios26.py", + 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 ios26 diff --git a/cogs/melonx/melonx.py b/cogs/melonx/melonx.py index e0f249e..9285210 100644 --- a/cogs/melonx/melonx.py +++ b/cogs/melonx/melonx.py @@ -13,6 +13,31 @@ class MelonxSelect(discord.ui.Select): value="transfer", description="How to transfer save files from other emulators or platforms", ), + discord.SelectOption( + label="Mods", + value="mods", + description="How to install mods within MeloNX (Limited Support)", + ), + discord.SelectOption( + label="Game Crash", + value="gamecrash", + description="Why does my game crash?", + ), + discord.SelectOption( + label="Requirements", + value="requirements", + description="What does MeloNX require?", + ), + discord.SelectOption( + label="Error", + value="error", + description="What does this error message mean?", + ), + discord.SelectOption( + label="iOS 26", + value="26", + description="How can I run MeloNX on iOS 26?", + ), ] super().__init__(placeholder="Choose a MeloNX command...", options=options) diff --git a/cogs/melonx/mods.py b/cogs/melonx/mods.py new file mode 100644 index 0000000..0c353a8 --- /dev/null +++ b/cogs/melonx/mods.py @@ -0,0 +1,47 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context +import time + + +def mods_command(): + @commands.hybrid_command( + name="mods", description="How to install mods within MeloNX (Limited Support)" + ) + async def mods(self, context): + embed = discord.Embed( + color=0x963155, + description=( + '# How do I install mods within MeloNX? (Limited Support)\n\n---\n\n' + + '### **romFS/exeFS mods**:\n' + + '1. Obtain your title ID of your game by copying it from MeloNX, Hold down on the game and click game info.\n' + + '2. Copy it and then go to Files-> MeloNX-> mods-> contents\n' + + '3. In the contents folder create a new folder and name it the title ID you copied earlier.\n' + + '4. Now place all your mods for that game in the folder you just made (these should be folders with the mod name, do not mess with the file structure of the mod after unzipping it.)\n\n' + + '### **Atmosphere mods**: \n' + + '1. Obtain your title ID of your game by copying it from MeloNX, Hold down on the game and click game info.\n' + + '2. Copy it and then go to Files-> MeloNX-> sdcard-> atmosphere-> contents\n' + + '3. In the contents folder create a new folder and name it the title ID you copied earlier.\n' + + '4. Now place all your mods for that game in the folder you just made (these should be folders with the mod name, do not mess with the file structure of the mod after unzipping it.)' + ) + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + embed.set_footer(text=f'Last Edited by neoarz') + embed.timestamp = discord.utils.utcnow() + + view = discord.ui.View() + view.add_item(discord.ui.Button( + label="Edit Command", + style=discord.ButtonStyle.secondary, + url="https://github.com/neoarz/Syntrel/blob/main/cogs/melonx/mods.py", + 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 mods diff --git a/cogs/melonx/requirements.py b/cogs/melonx/requirements.py new file mode 100644 index 0000000..61f3a71 --- /dev/null +++ b/cogs/melonx/requirements.py @@ -0,0 +1,42 @@ +import discord +from discord import app_commands +from discord.ext import commands +from discord.ext.commands import Context +import time + + +def requirements_command(): + @commands.hybrid_command( + name="requirements", description="What does MeloNX require?" + ) + async def requirements(self, context): + embed = discord.Embed( + color=0x963155, + description=( + '# "What does MeloNX require?"\n\n---\n\n' + + '- JIT is **Mandatory**, because of this MeloNX will never be on the App Store / TestFlight\n' + + '- A Modded Nintendo Switch\n' + + '- The Increased Memory Limit Entitlement\n' + + '- A device with a **A12/M1** chip and **4GB Ram** or higher\n' + + '- TrollStore is supported with limited functionality for iOS 15' + ) + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + embed.set_footer(text=f'Last Edited by neoarz') + embed.timestamp = discord.utils.utcnow() + + view = discord.ui.View() + view.add_item(discord.ui.Button( + label="Edit Command", + style=discord.ButtonStyle.secondary, + url="https://github.com/neoarz/Syntrel/blob/main/cogs/melonx/requirements.py", + 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 requirements