<commit_before>import aiohttp
import asyncio
import discord
import urllib.parse

from cogs.checks import check_if_user_can_sr
from discord.ext import commands
from inspect import cleandoc


class Assistance(commands.Cog, command_attrs=dict(cooldown=commands.Cooldown(1, 30.0, commands.BucketType.channel))):
    """
    Commands that will mostly be used in the help channels.
    """
    def __init__(self, bot):
        self.bot = bot
        self.systems = ("3ds", "wiiu", "vwii", "switch", "nx", "ns", "wii", "dsi", "legacy")

    async def simple_embed(self, ctx, text, title="", color=discord.Color.default()):
        embed = discord.Embed(title=title, color=color)
        embed.description = cleandoc(text)
        await ctx.send(embed=embed)

    def check_console(self, message, channel, consoles):
        message = message.lower()
        if message in consoles:
            return True
        elif ("wii" not in consoles or channel.startswith("legacy")) and channel.startswith(consoles) and message not in self.systems:
            return True
        return False

    @check_if_user_can_sr()
    @commands.guild_only()
    @commands.command(aliases=["sr", "Sr", "sR", "SR"], cooldown=commands.Cooldown(0, 0, commands.BucketType.channel))
    async def staffreq(self, ctx, *, msg_request: str = ""):
        """Request staff, with optional additional text. Trusted, Helpers, Staff, Retired Staff, Verified only."""
        author = ctx.author
        await ctx.message.delete()
        # await ctx.send("Request sent.")
        msg = f"❗️ **Assistance requested**: {ctx.channel.mention} by {author.mention} | {str(author)} @here"
        if msg_request != "":
            # msg += "\n✏️ __Additional text__: " + msg_request
            embed = discord.Embed(color=discord.Color.gold())
            embed.description = msg_request
        await self.bot.channels['mods'].send(msg, embed=(embed if msg_request != "" else None))
        try:
            await author.send(f"✅ Online staff have been notified of your request in {ctx.channel.mention}.", embed=(embed if msg_request != "" else None))
        except discord.errors.Forbidden:
            pass

    @commands.guild_only()
    @commands.command()
    async def guide(self, ctx, *, consoles=""):
        """Links to the recommended guides."""
        consoleslist = {x for x in consoles.split() if x in self.systems}
        if not consoleslist:
            if ctx.channel.name.startswith(self.systems):
                consoleslist = ['auto']
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in self.systems])}.")
                return
        for x in consoleslist:
            if self.check_console(x, ctx.channel.name, '3ds'):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCE181E))
                embed.set_author(name="Plailect", url="https://3ds.hacks.guide/")
                embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
                embed.url = "https://3ds.hacks.guide/"
                embed.description = "A complete guide to 3DS custom firmware, from stock to boot9strap."
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('wiiu',)):
                embed = discord.Embed(title="Guide", color=discord.Color(0x009AC7))
                embed.set_author(name="NH Discord Server", url="https://wiiuguide.xyz/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://wiiuguide.xyz/"
                embed.description = "A complete Wii U custom firmware + coldboothax guide"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('vwii',)):
                embed = discord.Embed(title="Guide", color=discord.Color(0xFFFFFF))
                embed.set_author(name="NH Discord Server", url="https://wiiuguide.xyz/#/vwii/vwii-modding")
                embed.set_thumbnail(url="https://i.imgur.com/FclGzNz.png")
                embed.url = "https://wiiuguide.xyz/#/vwii/vwii-modding"
                embed.description = "A complete vWii modding guide"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('switch', 'nx', 'ns')):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="NH Discord Server", url="https://nh-server.github.io/switch-guide/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://nh-server.github.io/switch-guide/"
                embed.description = "A Switch guide from stock to Atmosphere"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('legacy', 'wii')):
                embed = discord.Embed(title="Guide", color=discord.Color(0x009AC7))
                embed.set_author(name="tj_cool", url="https://sites.google.com/site/completesg/")
                embed.set_thumbnail(url="https://i.imgur.com/KI6IXmm.png")
                embed.url = "https://sites.google.com/site/completesg/"
                embed.description = "A complete original Wii softmod guide"
                await ctx.send(embed=embed)
            if self.check_console(x, ctx.channel.name, ('legacy', 'dsi')):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="jerbear64 & emiyl", url="https://dsi.cfw.guide/")
                embed.set_thumbnail(url="https://i.imgur.com/T227BW0.png")
                embed.url = "https://dsi.cfw.guide/"
                embed.description = "A complete Nintendo DSi homebrew guide, from stock to HiyaCFW"
                await ctx.send(embed=embed)	

    @commands.command(aliases=['finalizing'])
    async def finalize(self, ctx):
        """Finalizing Setup"""
        await self.simple_embed(ctx, """
                    3DS Hacks Guide's [Finalizing Setup](https://3ds.hacks.guide/finalizing-setup)
                    """, title="Finalizing Setup")

    # Embed to Soundhax Download Website
    @commands.command()
    async def soundhax(self, ctx):
        """Links to Soundhax Website"""
        embed = discord.Embed(title="Soundhax", color=discord.Color.blue())
        embed.set_author(name="<NAME>", url="http://soundhax.com/")
        embed.set_thumbnail(url="http://i.imgur.com/lYf0jan.png")
        embed.url = "http://soundhax.com"
        embed.description = "Free 3DS Primary Entrypoint <= 11.3"
        await ctx.send(embed=embed)

    # dsp dumper command
    @commands.command()
    async def dsp(self, ctx):
        """Links to Dsp1."""
        embed = discord.Embed(title="Dsp1", color=discord.Color.green())
        embed.set_author(name="zoogie", url="https://github.com/zoogie", icon_url="https://gbatemp.net/data/avatars/l/357/357147.jpg?1426471484")
        embed.description = "Dump 3DS's DSP component to SD for homebrew audio."
        embed.set_thumbnail(url="https://raw.githubusercontent.com/Cruel/DspDump/master/icon.png")
        embed.url = "https://github.com/zoogie/DSP1/releases"
        await ctx.send(embed=embed)

    @commands.command(aliases=['snickerstream'])
    async def ntrstream(self, ctx):
        """Snickerstream/NTR streaming guide"""
        embed = discord.Embed(title="Snickerstream: NTR Streaming Client", color=discord.Color.blue())
        embed.url = "https://gbatemp.net/threads/release-snickerstream-revived-a-proper-release-with-lots-of-improvements-and-new-features.488374/"
        embed.description = "How to use NTR CFW with Snickerstream to stream your 3DS' screen"
        embed.add_field(name="Guide and Advice", value=cleandoc("""
                Easy [install guide](https://github.com/RattletraPM/Snickerstream/wiki/Streaming-with-NTR) for streaming with Snickerstream.
                Snickerstream [app download](https://github.com/RattletraPM/Snickerstream/releases/latest)
                Having issues? Check the following:
                • Are you connected to the Internet?
                • Is your antivirus program blocking the program?
                • Make sure you typed the IP correctly.
                • Make sure you are using the latest BootNTR Selector with NTR 3.6.
                More detailed troubleshooting [available here](https://github.com/RattletraPM/Snickerstream/wiki/Troubleshooting)
                Other information about Snickerstream on [Snickerstream's GitHub Wiki](https://github.com/RattletraPM/Snickerstream/wiki)
                """))
        await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def update(self, ctx, *, consoles=""):
        """Explains how to safely prepare for an update for a hacked console"""
        
        systems = ('3ds', 'nx', 'ns', 'switch')
        wanted_consoles = list(set(x for x in consoles.split() if x in systems))

        if not wanted_consoles:
            if ctx.channel.name.startswith(systems):
                wanted_consoles = ["auto"]
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}")
                return

        for console in wanted_consoles:
            if self.check_console(console, ctx.channel.name, "3ds"):
                await self.simple_embed(ctx,
                    "**Is it safe to update to current 3DS firmware?**\n\n"

                    "**Luma3DS 9.1 and above**\n"
                    "You can update safely.\n\n"
                
                    "**Luma3DS 8.0 - 9.0**\n"
                    "Follow the [manual Luma3DS update guide](https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086), then you can update safely. Being on these Luma3DS "
                    "versions on 11.8+ will cause an error screen until you update.\n\n"
                
                    "**Luma3DS 7.1**\n"
                    "Follow the [B9S upgrade guide](https://3ds.hacks.guide/updating-b9s)\n\n"
                
                    "**Luma3DS 7.0.5 and below**\n"
                    "Follow the [a9lh-to-b9s guide](https://3ds.hacks.guide/a9lh-to-b9s)\n\n"
                 
                    "**To find out your Luma3DS version, hold select on bootup and look at the top left corner of the top screen**\n"
                )
            
            elif self.check_console(console, ctx.channel.name, ("switch", "nx", "ns")):
                embed = discord.Embed(title="Updating Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="NH Discord Server", url="https://nh-server.github.io/switch-guide/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://nh-server.github.io/switch-guide/extras/updating/"
                embed.description = "A guide and general recommendations for updating your switch with emuMMC."
                await ctx.send(embed=embed)

    @commands.command(aliases=["checkluma"])
    @commands.cooldown(rate=1, per=15.0, type=commands.BucketType.channel)
    async def lumacheck(self, ctx):
        """How to check Luma version"""
        embed = discord.Embed(title="Please check your Luma version.", color=discord.Color.blue())
        embed.description = "In order to do this, you will need to load the Luma Configuration screen."
        embed.add_field(name="Steps to open Luma Configuration", value=cleandoc("""
                1. Turn your console off.
                2. Hold the SELECT button.
                3. While still holding SELECT, turn the console on.
                4. Provide a photo of your console's screens, or if you can see the version, tell us here.
                """))
        await ctx.send(embed=embed)

    @commands.command(aliases=["lowspace", "lowbackup"])
    @commands.cooldown(rate=1, per=15.0, type=commands.BucketType.channel)
    async def nospace(self, ctx):
        """Low space NAND Backup"""
        embed = discord.Embed(title="How to create a 3DS NAND backup without enough space on the SD card", color=discord.Color.blue())
        embed.add_field(name="Steps to create the backup", value=cleandoc("""
                1. Copy the Nintendo 3DS folder from the root of your SD card to your computer then delete it from **the SD card.**
                2. Boot GodMode9 by holding START on boot then preform a normal NAND backup. After that, power off the system.
                3. Copy the files in gm9/out on your SD card to a safe spot on your computer. Then, delete the files from **the SD card.**
                4. Copy the Nintendo 3DS folder to your SD card root then delete it **from your computer.**
                """))
        await ctx.send(embed=embed)

    @commands.command()
    async def cfwuses(self, ctx):
        """Links to eiphax cfw uses page"""
        await self.simple_embed(ctx, "Want to know what CFW can be used for? <https://3ds.eiphax.tech/tips.html>")

    @commands.command()
    async def updateb9s(self, ctx):
        """Links to the guide for updating b9s versions"""
        embed = discord.Embed(title="Updating B9S Guide", color=discord.Color(0xCE181E))
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/updating-b9s")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/updating-b9s"
        embed.description = "A guide for updating to new B9S versions."
        await ctx.send(embed=embed)
    
    @commands.command()
    async def updateluma(self, ctx):
        """Links to the guide for updating Luma3DS manually (8.0 or later)"""
        embed = discord.Embed(title="Manually Updating Luma3DS", color=discord.Color(0xCE181E))
        embed.set_author(name="Chenzw", url="https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086")
        embed.set_thumbnail(url="https://avatars0.githubusercontent.com/u/5243259?s=400&v=4")
        embed.url = "https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086"
        embed.description = "A guide for manually updating Luma3ds. This is necessary if you receive the \"Failed to apply 1 Firm patch(es)\" error."
        await ctx.send(embed=embed)

    @commands.command(aliases=["a9lhtob9s", "updatea9lh"])
    async def atob(self, ctx):
        """Links to the guide for updating from a9lh to b9s"""
        embed = discord.Embed(title="Upgrading a9lh to b9s", color=discord.Color(0xCE181E))
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/a9lh-to-b9s")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/a9lh-to-b9s"
        embed.description = "A guide for upgrading your device from arm9loaderhax to boot9strap."
        await ctx.send(embed=embed)

    @commands.command(aliases=["atobwhat", "a9lhhow"])
    async def a9lhrec(self, ctx):
        """Advice for b9stool with a9lh conflict"""
        embed = discord.Embed(title="arm9loaderhax Detected!", color=discord.Color.blue())
        embed.description = "A9LH + b9stool information"
        embed.add_field(name="Guide and Advice", value=cleandoc("""
                If you are seeing an "arm9loaderhax detected!" message in b9stool, you should attempt to boot into the luma configuration menu before simply pressing A. If you can access the config, you should follow the normal a9lh-to-b9s guide instead of using b9stool.
                
                If you appear to not actually have a9lh installed, you may press A to continue in b9stool. Once you do so and unlock NAND writing, one of two things will happen. If you reboot into an installer and then a luma config, you did actually have a9lh and it was successfully replaced with b9s. If you reboot to the home menu normally, you did not have a9lh and you should run b9stool again once.
                
                If you're seeing an "a9lh detected! brick avoided!" error, you are on an old version of b9stool and should update your boot.nds to the latest.
                """))
        await ctx.send(embed=embed)

    # Hardmodder pastebin list
    @commands.command()
    async def hmodders(self, ctx):
        """Links to approved hardmodder list"""
        await self.simple_embed(ctx, "Don't want to hardmod yourself? Ask one of the installers on the server! <https://pastebin.com/FAiczew4>")

    # Links to ctrtransfer guide
    @commands.command(aliases=["ctrtransfer", "ctrnandtransfer"])
    async def ctr(self, ctx):
        """Links to ctrtransfer guide"""
        embed = discord.Embed(title="Guide - ctrtransfer", color=discord.Color.orange())
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/ctrtransfer"
        embed.description = "How to do the 11.5.0-38 ctrtransfer"
        await ctx.send(embed=embed)

    @commands.command()
    async def modmoon(self, ctx):
        """Links to a tool for a mod manager"""
        await self.simple_embed(ctx, cleandoc("""
                                To install mods for Smash 3DS, and to manage other LayeredFS mods, \
[Mod-Moon](https://github.com/Swiftloke/ModMoon/releases) is recommended. Instructions for use can be found on the page.
                                """))

    @commands.command()
    async def inoriwarn(self, ctx):
        """Warns users to keep the channels on-topic - Staff & Helper Declaration Only"""
        await self.simple_embed(ctx, """
                                **Please keep the channels clean and on-topic, further derailing will result in \
intervention.  A staff or helper will be the quickest route to resolution; you can \
contact available staff by private messaging the Mod-Mail bot.** A full list of staff \
and helpers can be found in #welcome-and-rules if you don't know who they are.
                                """)
        
    @commands.command()
    async def vguides(self, ctx):
        """Information about video guides relating to custom firmware"""
        embed = discord.Embed(title="Why you should not use video guides", color=discord.Color.dark_orange())
        embed.description = cleandoc("""
                Reasons to not use video guides:
                - They get outdated quickly
                - Tough to update and give assistance for
                - Can be misinformative and dangerous for the console
                """)
        embed.add_field(name="Recommended Solution", value="Read a trusted written tutorial. Try `.guide` for a list.")
        await ctx.send(embed=embed)

    @commands.command()
    async def vguides2(self, ctx):
        """Information about video guides relating to custom firmware"""
        await ctx.send("https://www.youtube.com/watch?v=miVDKgInzyg")

    @commands.command()
    async def ip(self, ctx):
        """How to check your IP"""
        embed = discord.Embed(title="Check your 3DSs IP (CFW)", color=discord.Color.dark_orange())
        embed.description = "1. FBI\n2. Remote Install\n3. Receive URLs over the network"
        embed.add_field(name="Check your 3DSs IP (Homebrew)", value="1. Open Homebrew Launcher\n2. Press Y")
        await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def stock(self, ctx, console=None):
        """Advisory for various Nintendo systems on stock firmware"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return
        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="Running stock (unmodified) 11.4+ firmware?", color=discord.Color.dark_orange())
            embed.add_field(name="NTRBoot", value="Requires a compatible NDS flashcart and maybe an additional DS(i) or hacked 3DS console depending on the flashcart (All versions, all hardware). [Guide](https://3ds.hacks.guide/ntrboot)", inline=False)
            embed.add_field(name="Seedminer", value="Requires a working NDS mode or Pokémon Picross (free from eshop) [Guide](https://3ds.hacks.guide/seedminer)", inline=False)
            embed.add_field(name="Hardmod", value="Requires soldering **Not for beginners!**. [Guide](https://git.io/fhQk9)", inline=False)
            await ctx.send(embed=embed)
        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):
            embed = discord.Embed(title="Looking to hack your Switch?", color=0xe60012)
            embed.description = cleandoc("""
            Use [our guide](https://nh-server.github.io/switch-guide/user_guide/getting_started/) to determine if your Switch is a first-gen unit.
            **First generation consoles (RCM exploitable)**
            All of these can run [Atmosphere](https://nh-server.github.io/switch-guide/). Make sure that Atmosphere is compatible with the latest firmware version before you update.

            **Second generation consoles ("patched" units, Switch Lite, Mariko, etc.)**

            **"Old" Patched Switch (HAC-001)**: Do NOT update past 7.0.1. Units on 7.0.1 and below will eventually get CFW. Units on 8.0.0 and higher are not expected to be hacked and can be updated.
            **"New" Switch (HAC-001-01)**: Do NOT update past 8.0.1. Units on 8.0.1 and below will likely get homebrew. Units on 8.1.0 and higher are not expected to be hacked and can be updated.
            **Switch Lite (HDH-001)**: Do NOT update past 8.0.1. Units on 8.0.1 and below will likely get homebrew. Units on 8.1.0 and higher are not expected to be hacked and can be updated.

            Downgrading is **impossible** on patched consoles, and isn't worth your time on unpatched ones.
            """)
            await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def newver(self, ctx, console=None):
        """Quick advice for new versions"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return

        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="Is the new 3DS update safe?", color=0xe60012)
            embed.description = cleandoc("""
            Currently, the latest 3DS system firmware is `11.13.0-45`.
            
            If you currently have CFW installed (boot9strap/Luma):
            Is your Luma version up to date? If your Luma version is 9.1 or above, **updating is safe**.
            If it is 9.0 or below, please type `.update` in <#261581918653513729> and follow the information there.
            
            If you DO NOT currently have CFW installed (stock console):
            11.13.0-45 can be hacked with current methods. **Updating is safe**.
            *Last edited: December 3, 2019*
            """)
            await ctx.send(embed=embed)

        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):
            embed = discord.Embed(title="Is the new Switch update safe?", color=0xe60012)
            embed.description = cleandoc("""
            Currently, the latest Switch system firmware is `9.2.0`.
            
            If your Switch is **unpatched and can access RCM**:
            Atmosphere and Hekate currently support 9.2.0, and unpatched units will always be hackable.
            You should follow the precautions in our update guide, and always update Atmosphere and Hekate before updating the system firmware.
            
            If your Switch is **hardware patched and cannot access RCM**:
            Stay on the lowest possible firmware version. Any Switch that is patched and above 7.0.1 is unlikely to be hackable.
            *Last edited: March 24, 2020*
            """)
            await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def what(self, ctx, console=None):
        """Links to 'what' style pages"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return

        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="what?", color=discord.Color.purple())
            embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/250051871962562562/726ae27792fc496755805397722c1e8e.png?size=1024")
            embed.url = "https://3ds.eiphax.tech/what.html"
            embed.description = "Basic things about the 3DS and CFW"
            await ctx.send(embed=embed)

        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):<commit_msg>bump newver<commit_after>import aiohttp
import asyncio
import discord
import urllib.parse

from cogs.checks import check_if_user_can_sr
from discord.ext import commands
from inspect import cleandoc


class Assistance(commands.Cog, command_attrs=dict(cooldown=commands.Cooldown(1, 30.0, commands.BucketType.channel))):
    """
    Commands that will mostly be used in the help channels.
    """
    def __init__(self, bot):
        self.bot = bot
        self.systems = ("3ds", "wiiu", "vwii", "switch", "nx", "ns", "wii", "dsi", "legacy")

    async def simple_embed(self, ctx, text, title="", color=discord.Color.default()):
        embed = discord.Embed(title=title, color=color)
        embed.description = cleandoc(text)
        await ctx.send(embed=embed)

    def check_console(self, message, channel, consoles):
        message = message.lower()
        if message in consoles:
            return True
        elif ("wii" not in consoles or channel.startswith("legacy")) and channel.startswith(consoles) and message not in self.systems:
            return True
        return False

    @check_if_user_can_sr()
    @commands.guild_only()
    @commands.command(aliases=["sr", "Sr", "sR", "SR"], cooldown=commands.Cooldown(0, 0, commands.BucketType.channel))
    async def staffreq(self, ctx, *, msg_request: str = ""):
        """Request staff, with optional additional text. Trusted, Helpers, Staff, Retired Staff, Verified only."""
        author = ctx.author
        await ctx.message.delete()
        # await ctx.send("Request sent.")
        msg = f"❗️ **Assistance requested**: {ctx.channel.mention} by {author.mention} | {str(author)} @here"
        if msg_request != "":
            # msg += "\n✏️ __Additional text__: " + msg_request
            embed = discord.Embed(color=discord.Color.gold())
            embed.description = msg_request
        await self.bot.channels['mods'].send(msg, embed=(embed if msg_request != "" else None))
        try:
            await author.send(f"✅ Online staff have been notified of your request in {ctx.channel.mention}.", embed=(embed if msg_request != "" else None))
        except discord.errors.Forbidden:
            pass

    @commands.guild_only()
    @commands.command()
    async def guide(self, ctx, *, consoles=""):
        """Links to the recommended guides."""
        consoleslist = {x for x in consoles.split() if x in self.systems}
        if not consoleslist:
            if ctx.channel.name.startswith(self.systems):
                consoleslist = ['auto']
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in self.systems])}.")
                return
        for x in consoleslist:
            if self.check_console(x, ctx.channel.name, '3ds'):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCE181E))
                embed.set_author(name="Plailect", url="https://3ds.hacks.guide/")
                embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
                embed.url = "https://3ds.hacks.guide/"
                embed.description = "A complete guide to 3DS custom firmware, from stock to boot9strap."
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('wiiu',)):
                embed = discord.Embed(title="Guide", color=discord.Color(0x009AC7))
                embed.set_author(name="NH Discord Server", url="https://wiiuguide.xyz/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://wiiuguide.xyz/"
                embed.description = "A complete Wii U custom firmware + coldboothax guide"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('vwii',)):
                embed = discord.Embed(title="Guide", color=discord.Color(0xFFFFFF))
                embed.set_author(name="NH Discord Server", url="https://wiiuguide.xyz/#/vwii/vwii-modding")
                embed.set_thumbnail(url="https://i.imgur.com/FclGzNz.png")
                embed.url = "https://wiiuguide.xyz/#/vwii/vwii-modding"
                embed.description = "A complete vWii modding guide"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('switch', 'nx', 'ns')):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="NH Discord Server", url="https://nh-server.github.io/switch-guide/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://nh-server.github.io/switch-guide/"
                embed.description = "A Switch guide from stock to Atmosphere"
                await ctx.send(embed=embed)
                continue
            if self.check_console(x, ctx.channel.name, ('legacy', 'wii')):
                embed = discord.Embed(title="Guide", color=discord.Color(0x009AC7))
                embed.set_author(name="tj_cool", url="https://sites.google.com/site/completesg/")
                embed.set_thumbnail(url="https://i.imgur.com/KI6IXmm.png")
                embed.url = "https://sites.google.com/site/completesg/"
                embed.description = "A complete original Wii softmod guide"
                await ctx.send(embed=embed)
            if self.check_console(x, ctx.channel.name, ('legacy', 'dsi')):
                embed = discord.Embed(title="Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="jerbear64 & emiyl", url="https://dsi.cfw.guide/")
                embed.set_thumbnail(url="https://i.imgur.com/T227BW0.png")
                embed.url = "https://dsi.cfw.guide/"
                embed.description = "A complete Nintendo DSi homebrew guide, from stock to HiyaCFW"
                await ctx.send(embed=embed)	

    @commands.command(aliases=['finalizing'])
    async def finalize(self, ctx):
        """Finalizing Setup"""
        await self.simple_embed(ctx, """
                    3DS Hacks Guide's [Finalizing Setup](https://3ds.hacks.guide/finalizing-setup)
                    """, title="Finalizing Setup")

    # Embed to Soundhax Download Website
    @commands.command()
    async def soundhax(self, ctx):
        """Links to Soundhax Website"""
        embed = discord.Embed(title="Soundhax", color=discord.Color.blue())
        embed.set_author(name="<NAME>", url="http://soundhax.com/")
        embed.set_thumbnail(url="http://i.imgur.com/lYf0jan.png")
        embed.url = "http://soundhax.com"
        embed.description = "Free 3DS Primary Entrypoint <= 11.3"
        await ctx.send(embed=embed)

    # dsp dumper command
    @commands.command()
    async def dsp(self, ctx):
        """Links to Dsp1."""
        embed = discord.Embed(title="Dsp1", color=discord.Color.green())
        embed.set_author(name="zoogie", url="https://github.com/zoogie", icon_url="https://gbatemp.net/data/avatars/l/357/357147.jpg?1426471484")
        embed.description = "Dump 3DS's DSP component to SD for homebrew audio."
        embed.set_thumbnail(url="https://raw.githubusercontent.com/Cruel/DspDump/master/icon.png")
        embed.url = "https://github.com/zoogie/DSP1/releases"
        await ctx.send(embed=embed)

    @commands.command(aliases=['snickerstream'])
    async def ntrstream(self, ctx):
        """Snickerstream/NTR streaming guide"""
        embed = discord.Embed(title="Snickerstream: NTR Streaming Client", color=discord.Color.blue())
        embed.url = "https://gbatemp.net/threads/release-snickerstream-revived-a-proper-release-with-lots-of-improvements-and-new-features.488374/"
        embed.description = "How to use NTR CFW with Snickerstream to stream your 3DS' screen"
        embed.add_field(name="Guide and Advice", value=cleandoc("""
                Easy [install guide](https://github.com/RattletraPM/Snickerstream/wiki/Streaming-with-NTR) for streaming with Snickerstream.
                Snickerstream [app download](https://github.com/RattletraPM/Snickerstream/releases/latest)
                Having issues? Check the following:
                • Are you connected to the Internet?
                • Is your antivirus program blocking the program?
                • Make sure you typed the IP correctly.
                • Make sure you are using the latest BootNTR Selector with NTR 3.6.
                More detailed troubleshooting [available here](https://github.com/RattletraPM/Snickerstream/wiki/Troubleshooting)
                Other information about Snickerstream on [Snickerstream's GitHub Wiki](https://github.com/RattletraPM/Snickerstream/wiki)
                """))
        await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def update(self, ctx, *, consoles=""):
        """Explains how to safely prepare for an update for a hacked console"""
        
        systems = ('3ds', 'nx', 'ns', 'switch')
        wanted_consoles = list(set(x for x in consoles.split() if x in systems))

        if not wanted_consoles:
            if ctx.channel.name.startswith(systems):
                wanted_consoles = ["auto"]
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}")
                return

        for console in wanted_consoles:
            if self.check_console(console, ctx.channel.name, "3ds"):
                await self.simple_embed(ctx,
                    "**Is it safe to update to current 3DS firmware?**\n\n"

                    "**Luma3DS 9.1 and above**\n"
                    "You can update safely.\n\n"
                
                    "**Luma3DS 8.0 - 9.0**\n"
                    "Follow the [manual Luma3DS update guide](https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086), then you can update safely. Being on these Luma3DS "
                    "versions on 11.8+ will cause an error screen until you update.\n\n"
                
                    "**Luma3DS 7.1**\n"
                    "Follow the [B9S upgrade guide](https://3ds.hacks.guide/updating-b9s)\n\n"
                
                    "**Luma3DS 7.0.5 and below**\n"
                    "Follow the [a9lh-to-b9s guide](https://3ds.hacks.guide/a9lh-to-b9s)\n\n"
                 
                    "**To find out your Luma3DS version, hold select on bootup and look at the top left corner of the top screen**\n"
                )
            
            elif self.check_console(console, ctx.channel.name, ("switch", "nx", "ns")):
                embed = discord.Embed(title="Updating Guide", color=discord.Color(0xCB0004))
                embed.set_author(name="NH Discord Server", url="https://nh-server.github.io/switch-guide/")
                embed.set_thumbnail(url="https://i.imgur.com/CVSu1zc.png")
                embed.url = "https://nh-server.github.io/switch-guide/extras/updating/"
                embed.description = "A guide and general recommendations for updating your switch with emuMMC."
                await ctx.send(embed=embed)

    @commands.command(aliases=["checkluma"])
    @commands.cooldown(rate=1, per=15.0, type=commands.BucketType.channel)
    async def lumacheck(self, ctx):
        """How to check Luma version"""
        embed = discord.Embed(title="Please check your Luma version.", color=discord.Color.blue())
        embed.description = "In order to do this, you will need to load the Luma Configuration screen."
        embed.add_field(name="Steps to open Luma Configuration", value=cleandoc("""
                1. Turn your console off.
                2. Hold the SELECT button.
                3. While still holding SELECT, turn the console on.
                4. Provide a photo of your console's screens, or if you can see the version, tell us here.
                """))
        await ctx.send(embed=embed)

    @commands.command(aliases=["lowspace", "lowbackup"])
    @commands.cooldown(rate=1, per=15.0, type=commands.BucketType.channel)
    async def nospace(self, ctx):
        """Low space NAND Backup"""
        embed = discord.Embed(title="How to create a 3DS NAND backup without enough space on the SD card", color=discord.Color.blue())
        embed.add_field(name="Steps to create the backup", value=cleandoc("""
                1. Copy the Nintendo 3DS folder from the root of your SD card to your computer then delete it from **the SD card.**
                2. Boot GodMode9 by holding START on boot then preform a normal NAND backup. After that, power off the system.
                3. Copy the files in gm9/out on your SD card to a safe spot on your computer. Then, delete the files from **the SD card.**
                4. Copy the Nintendo 3DS folder to your SD card root then delete it **from your computer.**
                """))
        await ctx.send(embed=embed)

    @commands.command()
    async def cfwuses(self, ctx):
        """Links to eiphax cfw uses page"""
        await self.simple_embed(ctx, "Want to know what CFW can be used for? <https://3ds.eiphax.tech/tips.html>")

    @commands.command()
    async def updateb9s(self, ctx):
        """Links to the guide for updating b9s versions"""
        embed = discord.Embed(title="Updating B9S Guide", color=discord.Color(0xCE181E))
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/updating-b9s")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/updating-b9s"
        embed.description = "A guide for updating to new B9S versions."
        await ctx.send(embed=embed)
    
    @commands.command()
    async def updateluma(self, ctx):
        """Links to the guide for updating Luma3DS manually (8.0 or later)"""
        embed = discord.Embed(title="Manually Updating Luma3DS", color=discord.Color(0xCE181E))
        embed.set_author(name="Chenzw", url="https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086")
        embed.set_thumbnail(url="https://avatars0.githubusercontent.com/u/5243259?s=400&v=4")
        embed.url = "https://gist.github.com/chenzw95/3b5b953c9c913e89fdda3c4c4d98d086"
        embed.description = "A guide for manually updating Luma3ds. This is necessary if you receive the \"Failed to apply 1 Firm patch(es)\" error."
        await ctx.send(embed=embed)

    @commands.command(aliases=["a9lhtob9s", "updatea9lh"])
    async def atob(self, ctx):
        """Links to the guide for updating from a9lh to b9s"""
        embed = discord.Embed(title="Upgrading a9lh to b9s", color=discord.Color(0xCE181E))
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/a9lh-to-b9s")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/a9lh-to-b9s"
        embed.description = "A guide for upgrading your device from arm9loaderhax to boot9strap."
        await ctx.send(embed=embed)

    @commands.command(aliases=["atobwhat", "a9lhhow"])
    async def a9lhrec(self, ctx):
        """Advice for b9stool with a9lh conflict"""
        embed = discord.Embed(title="arm9loaderhax Detected!", color=discord.Color.blue())
        embed.description = "A9LH + b9stool information"
        embed.add_field(name="Guide and Advice", value=cleandoc("""
                If you are seeing an "arm9loaderhax detected!" message in b9stool, you should attempt to boot into the luma configuration menu before simply pressing A. If you can access the config, you should follow the normal a9lh-to-b9s guide instead of using b9stool.
                
                If you appear to not actually have a9lh installed, you may press A to continue in b9stool. Once you do so and unlock NAND writing, one of two things will happen. If you reboot into an installer and then a luma config, you did actually have a9lh and it was successfully replaced with b9s. If you reboot to the home menu normally, you did not have a9lh and you should run b9stool again once.
                
                If you're seeing an "a9lh detected! brick avoided!" error, you are on an old version of b9stool and should update your boot.nds to the latest.
                """))
        await ctx.send(embed=embed)

    # Hardmodder pastebin list
    @commands.command()
    async def hmodders(self, ctx):
        """Links to approved hardmodder list"""
        await self.simple_embed(ctx, "Don't want to hardmod yourself? Ask one of the installers on the server! <https://pastebin.com/FAiczew4>")

    # Links to ctrtransfer guide
    @commands.command(aliases=["ctrtransfer", "ctrnandtransfer"])
    async def ctr(self, ctx):
        """Links to ctrtransfer guide"""
        embed = discord.Embed(title="Guide - ctrtransfer", color=discord.Color.orange())
        embed.set_author(name="Plailect", url="https://3ds.hacks.guide/")
        embed.set_thumbnail(url="https://3ds.hacks.guide/images/bio-photo.png")
        embed.url = "https://3ds.hacks.guide/ctrtransfer"
        embed.description = "How to do the 11.5.0-38 ctrtransfer"
        await ctx.send(embed=embed)

    @commands.command()
    async def modmoon(self, ctx):
        """Links to a tool for a mod manager"""
        await self.simple_embed(ctx, cleandoc("""
                                To install mods for Smash 3DS, and to manage other LayeredFS mods, \
[Mod-Moon](https://github.com/Swiftloke/ModMoon/releases) is recommended. Instructions for use can be found on the page.
                                """))

    @commands.command()
    async def inoriwarn(self, ctx):
        """Warns users to keep the channels on-topic - Staff & Helper Declaration Only"""
        await self.simple_embed(ctx, """
                                **Please keep the channels clean and on-topic, further derailing will result in \
intervention.  A staff or helper will be the quickest route to resolution; you can \
contact available staff by private messaging the Mod-Mail bot.** A full list of staff \
and helpers can be found in #welcome-and-rules if you don't know who they are.
                                """)
        
    @commands.command()
    async def vguides(self, ctx):
        """Information about video guides relating to custom firmware"""
        embed = discord.Embed(title="Why you should not use video guides", color=discord.Color.dark_orange())
        embed.description = cleandoc("""
                Reasons to not use video guides:
                - They get outdated quickly
                - Tough to update and give assistance for
                - Can be misinformative and dangerous for the console
                """)
        embed.add_field(name="Recommended Solution", value="Read a trusted written tutorial. Try `.guide` for a list.")
        await ctx.send(embed=embed)

    @commands.command()
    async def vguides2(self, ctx):
        """Information about video guides relating to custom firmware"""
        await ctx.send("https://www.youtube.com/watch?v=miVDKgInzyg")

    @commands.command()
    async def ip(self, ctx):
        """How to check your IP"""
        embed = discord.Embed(title="Check your 3DSs IP (CFW)", color=discord.Color.dark_orange())
        embed.description = "1. FBI\n2. Remote Install\n3. Receive URLs over the network"
        embed.add_field(name="Check your 3DSs IP (Homebrew)", value="1. Open Homebrew Launcher\n2. Press Y")
        await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def stock(self, ctx, console=None):
        """Advisory for various Nintendo systems on stock firmware"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return
        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="Running stock (unmodified) 11.4+ firmware?", color=discord.Color.dark_orange())
            embed.add_field(name="NTRBoot", value="Requires a compatible NDS flashcart and maybe an additional DS(i) or hacked 3DS console depending on the flashcart (All versions, all hardware). [Guide](https://3ds.hacks.guide/ntrboot)", inline=False)
            embed.add_field(name="Seedminer", value="Requires a working NDS mode or Pokémon Picross (free from eshop) [Guide](https://3ds.hacks.guide/seedminer)", inline=False)
            embed.add_field(name="Hardmod", value="Requires soldering **Not for beginners!**. [Guide](https://git.io/fhQk9)", inline=False)
            await ctx.send(embed=embed)
        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):
            embed = discord.Embed(title="Looking to hack your Switch?", color=0xe60012)
            embed.description = cleandoc("""
            Use [our guide](https://nh-server.github.io/switch-guide/user_guide/getting_started/) to determine if your Switch is a first-gen unit.
            **First generation consoles (RCM exploitable)**
            All of these can run [Atmosphere](https://nh-server.github.io/switch-guide/). Make sure that Atmosphere is compatible with the latest firmware version before you update.

            **Second generation consoles ("patched" units, Switch Lite, Mariko, etc.)**

            **"Old" Patched Switch (HAC-001)**: Do NOT update past 7.0.1. Units on 7.0.1 and below will eventually get CFW. Units on 8.0.0 and higher are not expected to be hacked and can be updated.
            **"New" Switch (HAC-001-01)**: Do NOT update past 8.0.1. Units on 8.0.1 and below will likely get homebrew. Units on 8.1.0 and higher are not expected to be hacked and can be updated.
            **Switch Lite (HDH-001)**: Do NOT update past 8.0.1. Units on 8.0.1 and below will likely get homebrew. Units on 8.1.0 and higher are not expected to be hacked and can be updated.

            Downgrading is **impossible** on patched consoles, and isn't worth your time on unpatched ones.
            """)
            await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def newver(self, ctx, console=None):
        """Quick advice for new versions"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return

        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="Is the new 3DS update safe?", color=0xe60012)
            embed.description = cleandoc("""
            Currently, the latest 3DS system firmware is `11.13.0-45`.
            
            If you currently have CFW installed (boot9strap/Luma):
            Is your Luma version up to date? If your Luma version is 9.1 or above, **updating is safe**.
            If it is 9.0 or below, please type `.update` in <#261581918653513729> and follow the information there.
            
            If you DO NOT currently have CFW installed (stock console):
            11.13.0-45 can be hacked with current methods. **Updating is safe**.
            *Last edited: December 3, 2019*
            """)
            await ctx.send(embed=embed)

        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):
            embed = discord.Embed(title="Is the new Switch update safe?", color=0xe60012)
            embed.description = cleandoc("""
            Currently, the latest Switch system firmware is `10.0.0`     
            If your Switch is **unpatched and can access RCM**:
            Atmosphere and Hekate currently **DO NOT** support 10.0.0, but unpatched units will always be hackable once they do.
            If your console is 9.2.0 or below, you are able to access CFW at the moment.
            When Atmosphere and Hekate update, update them before updating the system firmware.
            
            If your Switch is **hardware patched and cannot access RCM**:
            Stay on the lowest possible firmware version. Any Switch that is patched and above 7.0.1 is unlikely to be hackable.
            *Last edited: April 14, 2020*
            """)
            await ctx.send(embed=embed)

    @commands.guild_only()
    @commands.command()
    async def what(self, ctx, console=None):
        """Links to 'what' style pages"""
        systems = ("3ds", "nx", "ns", "switch")
        if console not in systems:
            if ctx.channel.name.startswith(systems):
                console = "auto"
            else:
                await ctx.send(f"Please specify a console. Valid options are: {', '.join([x for x in systems])}.")
                return

        if self.check_console(console, ctx.message.channel.name, '3ds'):
            embed = discord.Embed(title="what?", color=discord.Color.purple())
            embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/250051871962562562/726ae27792fc496755805397722c1e8e.png?size=1024")
            embed.url = "https://3ds.eiphax.tech/what.html"
            embed.description = "Basic things about the 3DS and CFW"
            await ctx.send(embed=embed)

        elif self.check_console(console, ctx.message.channel.name, ('nx', 'switch', 'ns')):
{'fraction_non_alphanumeric': 0.11943248532289628, 'fraction_numerical': 0.01888454011741683, 'mean_word_length': 2.4703565365025466, 'pattern_counts': {'":': 2, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 114, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2439226', 'n_tokens_mistral': 15828, 'n_tokens_neox': 14812, 'n_words': 4251}