using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Media;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace LocalPSM_
{
    public partial class PSMKeyGen : Form
    {
        public PSMKeyGen()
        {
            InitializeComponent();
        }

        public String UnityURL = "https://nsx.sec.np.dl.playstation.net/nsx/sec/Xz78TMQ1Uf31VCYr/c/NSXVID/NSXVID-PSM.UNITY.WW-GLOBAL.xml";
        public String PsmDevURL = "https://nsx.sec.np.dl.playstation.net/nsx/sec/Xz78TMQ1Uf31VCYr/c/NSXVID/NSXVID-PSS.VT.WW-GLOBAL.xml";


        private void PSMKeyGen_Load(object sender, EventArgs e)
        {
            Stream BGM = Properties.Resources.BGM;
            SoundPlayer snd = new SoundPlayer(BGM);
            snd.PlayLooping();
        }

        private void Unpack()
        {
            File.WriteAllBytes("cygwin1.dll", Properties.Resources.cygwin1);
            File.WriteAllBytes("cygz.dll", Properties.Resources.cygz);
            File.WriteAllBytes("cygcrypto-1.0.0.dll", Properties.Resources.cygcrypto_1_0_0);
            File.WriteAllBytes("kconsole_sign.exe", Properties.Resources.kconsole_sign);
            File.WriteAllBytes("revoke_sign.exe", Properties.Resources.revoke_sign);
            File.WriteAllBytes("reverse.exe", Properties.Resources.reverse);
        }
        private void DownloadXML(string path)
        {
            try
            {
                WebClient wc = new WebClient();
                if (Unity.Checked)
                {
                    byte[] XML = wc.DownloadData(UnityURL);
                    File.WriteAllBytes(path, XML);
                }
                else
                {
                    byte[] XML = wc.DownloadData(PsmDevURL);
                    File.WriteAllBytes(path, XML);
                }
            }
            catch
            {
                if (Unity.Checked)
                {
                    File.WriteAllText(path, Properties.Resources.NSXVID_PSM_UNITY_WW_GLOBAL);
                }
                else
                {
                    File.WriteAllText(path, Properties.Resources.NSXVID_PSS_VT_WW_GLOBAL);
                }
            }
        }

        private void SignXML(string path)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = "revoke_sign.exe";
            proc.StartInfo.Arguments = path + " " + "psmdrmboot.dat";
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.StartInfo.CreateNoWindow = true;
            proc.Start();
            proc.WaitForExit();
            moveToCache("psmdrmboot.dat");
        }

        private void CreateKConsole(string path)
        {
            if(Unity.Checked)
            {
                File.WriteAllBytes(path, Properties.Resources.unity_kconsole_dat);
            }
            else
            {
                File.WriteAllBytes(path, Properties.Resources.psm_kconsole_dat);
            }
            
        }

        private void SignKConsole(string path)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = "kconsole_sign.exe";
            proc.StartInfo.Arguments = path + " " + "protected_kconsole_cache.dat";
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.StartInfo.CreateNoWindow = true;
            proc.Start();
            proc.WaitForExit();
            moveToCache("protected_kconsole_cache.dat");
        }

        private void Cleanup()
        {
            File.Delete("reverse.exe");
            File.Delete("revoke_sign.exe");
            File.Delete("kconsole_sign.exe");
            File.Delete("cygz.dll");
            File.Delete("cygwin1.dll");
            File.Delete("cygcrypto-1.0.0.dll");
        }
        
        private void CreateCache()
        {
            if(Unity.Checked)
            {
                if (!Directory.Exists("cache/PCSI0009/_System/"))
                {
                    Directory.CreateDirectory("cache/PCSI00009/_System/");
                }
            }
            else
            {
                if (!Directory.Exists("cache/PCSI00007/_System/"))
                {
                    Directory.CreateDirectory("cache/PCSI00007/_System/");
                }
            }

        }

        private void moveToCache(string file)
        {
            if (Unity.Checked)
            {
                if (File.Exists("cache/PCSI00009/_System/" + file))
                {
                    File.Delete("cache/PCSI00009/_System/" + file);
                }
                File.Move(file, "cache/PCSI00009/_System/" + file);
            }
            else
            {
                if (File.Exists("cache/PCSI00007/_System/" + file))
                {
                    File.Delete("cache/PCSI00007/_System/" + file);
                }
                File.Move(file, "cache/PCSI00007/_System/" + file);
            }

        }
        private void LicenseGen_Click(object sender, EventArgs e)
        {
            KeyGen.Enabled = false;
            DevName.Enabled = false;
            Unity.Enabled = false;
            LicenseGen.Enabled = false;
            
            CreateCache();

            Unpack();

            DownloadXML("temp.xml");
            SignXML("temp.xml");

            CreateKConsole("kconsole.dat");
            SignKConsole("kconsole.dat");

            File.Delete("temp.xml");
            File.Delete("kconsole.dat");

            Cleanup();

            KeyGen.Enabled = true;
            DevName.Enabled = true;
            Unity.Enabled = true;
            LicenseGen.Enabled = true;

            MessageBox.Show("Refreshed License Created!", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private void CreateKeys()
        {
            if (Unity.Checked)
            {
                if (!Directory.Exists("keys/unity/"+DevName.Text))
                {
                    Directory.CreateDirectory("keys/unity/" + DevName.Text);
                }
            }
            else
            {
                if (!Directory.Exists("keys/psm/" + DevName.Text))
                {
                    Directory.CreateDirectory("keys/psm/" + DevName.Text);
                }
            }
        }

        private void moveToKeys(string file)
        {
            if (Unity.Checked)
            {
                if (File.Exists("keys/unity/" + DevName.Text + "/" + file))
                {
                    File.Delete("keys/unity/" + DevName.Text + "/" + file);
                }
                File.Move(file, "keys/unity/" + DevName.Text + "/" + file);
            }
            else
            {
                if (File.Exists("keys/psm/" + DevName.Text + "/" + file))
                {
                    File.Delete("keys/psm/" + DevName.Text + "/" + file);
                }
                File.Move(file, "keys/psm/" + DevName.Text + "/" + file);
            }

        }

        private void GenKeys()
        {
            if(Unity.Checked)
            {
                byte[] krng = Properties.Resources.UnityDev;

                for (int i = 0x454; i != 0x465; i++)
                {
                    krng[i] = (byte)DevName.Text[i - 0x454];
                }

                File.WriteAllBytes("_PSM_DEFAULT_.krng", krng);

                File.WriteAllBytes("kdev.p12", Properties.Resources.UnityDev_private);

                byte[] Seed = Properties.Resources.UnityDev_seed;

                for (int i = 0x0C; i != 0x1D; i++)
                {
                    Seed[i] = (byte)DevName.Text[i - 0x0C];
                }

                for (int i = 0x2C; i != 0x3D; i++)
                {
                    Seed[i] = (byte)DevName.Text[i - 0x2C];
                }

                File.WriteAllBytes(DevName.Text + ".seed", Seed);

                moveToKeys(DevName.Text + ".seed");
                moveToKeys("_PSM_DEFAULT_.krng");
                moveToKeys("kdev.p12");
            }
            else
            {

                byte[] krng = Properties.Resources.psmdev;

                for (int i = 0x454; i != 0x465; i++)
                {
                    krng[i] = (byte)DevName.Text[i - 0x454];
                }

                File.WriteAllBytes("+asterisk+.krng", krng);

                File.WriteAllBytes("kdev.p12", Properties.Resources.psmdev_private);

                byte[] Seed = Properties.Resources.psmdev_seed;

                for (int i = 0x0C; i != 0x1D; i++)
                {
                    Seed[i] = (byte)DevName.Text[i - 0x0C];
                }

                for (int i = 0x2C; i != 0x3D; i++)
                {
                    Seed[i] = (byte)DevName.Text[i - 0x2C];
                }

                File.WriteAllBytes(DevName.Text + ".seed", Seed);

                moveToKeys(DevName.Text + ".seed");
                moveToKeys("+asterisk+.krng");
                moveToKeys("kdev.p12");
            }

        }

        private void GenCache()
        {
            if(Unity.Checked)
            {
                File.WriteAllBytes("Code", Properties.Resources.unity_Code);
                File.WriteAllBytes("protected_kconsole_cache.dat", Properties.Resources.unity_protected_kconsole_cache);
                File.WriteAllBytes("target_kdbg_list.dat", Properties.Resources.unity_target_kdbg_list);
                File.WriteAllBytes("vseed.dat", Properties.Resources.unity_vseed);

                moveToCache("Code");
                moveToCache("protected_kconsole_cache.dat");
                moveToCache("target_kdbg_list.dat");
                moveToCache("vseed.dat");
            }
            else
            {
                File.WriteAllBytes("activever.dat", Properties.Resources.psm_activever);
                File.WriteAllBytes("Code", Properties.Resources.psm_Code);
                File.WriteAllBytes("protected_kconsole_cache.dat", Properties.Resources.psm_protected_kconsole_cache);
                File.WriteAllBytes("target_kdbg_list.dat", Properties.Resources.psm_target_kdbg_list);
                File.WriteAllBytes("vseed.dat", Properties.Resources.psm_vseed);

                moveToCache("activever.dat");
                moveToCache("Code");
                moveToCache("protected_kconsole_cache.dat");
                moveToCache("target_kdbg_list.dat");
                moveToCache("vseed.dat");
            }

        }

        private void KeyGen_Click(object sender, EventArgs e)
        {
            KeyGen.Enabled = false;
            DevName.Enabled = false;
            Unity.Enabled = false;
            LicenseGen.Enabled = false;

            CreateCache();
            CreateKeys();
            GenKeys();
            GenCache();

            KeyGen.Enabled = true;
            DevName.Enabled = true;
            Unity.Enabled = true;
            LicenseGen.Enabled = true;

            MessageBox.Show("Keypair & License for "+DevName.Text+" Created!", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void DevName_TextChanged(object sender, EventArgs e)
        {
            if(DevName.TextLength == 17)
            {
                KeyGen.Enabled = true;
            }
            else
            {
                KeyGen.Enabled = false;
            }
            int i = DevName.SelectionStart;
            DevName.Text = new String(DevName.Text.Where(char.IsDigit).ToArray());
            DevName.SelectionStart = i;
        }

    }
}
