private void StartDowngrade(bool selectApk = true)
        {
            bool highRam = false; //Keyboard.IsKeyDown(Key.LeftShift);

            if (!CheckVersions(false, true))
            {
                return;
            }
            try
            {
                Stopwatch s = Stopwatch.StartNew();
                Decrypter d = new Decrypter();
                if (!Directory.Exists(exe + "DowngradedAPKs"))
                {
                    Directory.CreateDirectory(exe + "DowngradedAPKs");
                }
                String outputAPK = exe + "DowngradedAPKs\\" + appid + "_" + TV.Text + ".apk";
                if (CreateFiles)
                {
                    txtbox.AppendText("\n\nCreating downgrade file");

                    string[]         files     = APKPath.Text.Split('|');
                    Version          v         = new Version();
                    MessageBoxResult res       = MessageBox.Show("Do you want to use XDelta3 to create the downgrade file (smaller end file; yes) or the old XOR method (big file size; no)", "APK Downgrader", MessageBoxButton.YesNo, MessageBoxImage.Question);
                    bool             useXDelta = res == MessageBoxResult.Yes;
                    txtbox.AppendText("\nCreating Version info");
                    txtbox.ScrollToEnd();
                    v.SV             = SV.Text;
                    v.TV             = TV.Text;
                    v.SourceByteSize = (int)new FileInfo(files[0]).Length;
                    v.TargetByteSize = (int)new FileInfo(files[1]).Length;
                    txtbox.AppendText("\nCalculating SHA256 hashes for apks");
                    txtbox.ScrollToEnd();
                    v.SSHA256   = CalculateSHA256(files[0]);
                    v.TSHA256   = CalculateSHA256(files[1]);
                    v.isXDelta3 = useXDelta;
                    v.appid     = appid;
                    String downgrFile = exe + "DowngradeFiles\\" + v.GetDecrName();
                    if (useXDelta)
                    {
                        if (!XDeltaPresent())
                        {
                            return;
                        }
                        txtbox.AppendText("\n\nRunning cmd.exe /c \"\"" + exe + "xdelta3.exe\" -c -s \"" + files[0] + "\" " + "\"" + files[1] + "\" > \"" + downgrFile + "\"\"\nPlease be patient");
                        txtbox.ScrollToEnd();
                        if (File.Exists(downgrFile))
                        {
                            File.Delete(downgrFile);
                        }
                        Process p = Process.Start("cmd.exe", "/c \"\"" + exe + "xdelta3.exe\" -c -s \"" + files[0] + "\" " + "\"" + files[1] + "\" > \"" + downgrFile + "\"\"");
                        p.WaitForExit();
                        //File.WriteAllText(downgrFile, p.StandardOutput.ReadToEnd());
                        if (!File.Exists(downgrFile) || new FileInfo(downgrFile).Length <= 0)
                        {
                            MessageBox.Show("XDelta3 was unable to create a downgrade. This isn't supposed to happen.", "APK Downgrader", MessageBoxButton.OK, MessageBoxImage.Error);
                            txtbox.AppendText("\n\nAn Error occurred");
                            txtbox.ScrollToEnd();
                            return;
                        }
                    }
                    else
                    {
                        txtbox.AppendText("\nXOR-ing " + SV.Text + " with " + TV.Text);
                        txtbox.ScrollToEnd();
                        if (v.SourceByteSize < v.TargetByteSize)
                        {
                            txtbox.AppendText("\n\nI'm sorry. Due to the source file having to be as big as the target one or bigger to not distribute game code I can't do that for you");
                            txtbox.ScrollToEnd();
                            FreeConsole();
                            return;
                        }
                        if (v.SourceByteSize != v.TargetByteSize)
                        {
                            txtbox.AppendText("\n\nCopying and adjusting File size.");
                            Random r      = new Random();
                            byte[] random = new byte[v.SourceByteSize - v.TargetByteSize];
                            r.NextBytes(random);
                            File.Copy(files[1], exe + "tmp_APKAppended.apk", true);
                            FileStream fs = new FileStream(exe + "tmp_APKAppended.apk", FileMode.Append);
                            files[1] = exe + "tmp_APKAppended.apk";
                            fs.Write(random, 0, random.Length);
                            fs.Flush();
                            fs.Close();
                            txtbox.AppendText("\nAdjusted File size. Appended " + random.Length + " bytes to Target APK copy");
                        }
                        AllocConsole();
                        if (File.Exists(exe + "DowngradeFiles\\" + v.GetDecrName()))
                        {
                            File.Delete(exe + "DowngradeFiles\\" + v.GetDecrName());
                        }
                        d.DecryptOTPFile(files[0], files[1], exe + "DowngradeFiles\\" + v.GetDecrName(), !highRam);
                    }
                    txtbox.AppendText("\nCalculating SHA256 for downgrade file");
                    txtbox.ScrollToEnd();
                    v.DSHA256 = CalculateSHA256(exe + "DowngradeFiles\\" + v.GetDecrName());
                    versions.versions.Add(v);
                    File.WriteAllText(exe + "versions.json", JsonSerializer.Serialize(versions, new JsonSerializerOptions {
                        WriteIndented = true
                    }));
                    txtbox.AppendText("\nFeel free to add a download link to the json.");
                    txtbox.ScrollToEnd();
                    FreeConsole();
                }
                else
                {
                    txtbox.AppendText("\n\nDowngrading APK");
                    txtbox.ScrollToEnd();
                    if (!File.Exists(APKPath.Text))
                    {
                        txtbox.AppendText("\nThe APK you put in doesn't exist.");
                        txtbox.ScrollToEnd();
                        return;
                    }
                    appid = GetAPKPackageName(APKPath.Text);
                    Version v         = versions.GetVersion(SV.Text, TV.Text, appid);
                    String  hash      = CalculateSHA256(exe + "DowngradeFiles\\" + v.GetDecrName());
                    bool    otherhash = false;
                    if (hash != v.DSHA256 && v.DSHA256 != "")
                    {
                        MessageBoxResult r = MessageBox.Show("Your Downloaded downgrade file doesn't match the hash (hashes are a unique ideifier for files which can be clculated. Same content = same hash) from the downgrade file the person who made the it has. Do you want to continue (in worst case the downgraded file just won't work or not exist)?", "APK Downgrader", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                        if (r == MessageBoxResult.No)
                        {
                            txtbox.AppendText("\n\nAborted");
                            txtbox.ScrollToEnd();
                            return;
                        }
                        otherhash = true;
                    }
                    hash = CalculateSHA256(APKPath.Text);
                    if (hash.ToLower() != v.SSHA256.ToLower() && v.SSHA256 != "")
                    {
                        if (v.isXDelta3)
                        {
                            MessageBox.Show("Your APK doesn't match the hash (hashes are a unique ideifier for files which can be clculated. Same content = same hash) from the apk the person who made the downgrade file has. Since it uses XDelta3 to downgrade your APK I can't continue.", "APK Downgrader", MessageBoxButton.OK, MessageBoxImage.Warning);
                            txtbox.AppendText("\n\nAborted");
                            txtbox.ScrollToEnd();
                            return;
                        }
                        MessageBoxResult r = MessageBox.Show("Your APK doesn't match the hash (hashes are a unique ideifier for files which can be clculated. Same content = same hash) from the apk the person who made the downgrade file has. Do you want to continue (in worst case the downgraded file just won't work)?", "APK Downgrader", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                        if (r == MessageBoxResult.No)
                        {
                            txtbox.AppendText("\n\nAborted");
                            txtbox.ScrollToEnd();
                            return;
                        }
                        otherhash = true;
                    }
                    if (v.isXDelta3)
                    {
                        if (!XDeltaPresent())
                        {
                            return;
                        }
                        txtbox.AppendText("\nExecuting cmd.exe /c \"\"" + exe + "xdelta3.exe\" -d -f -s \"" + APKPath.Text + "\" \"" + exe + "DowngradeFiles\\" + v.GetDecrName() + "\" \"" + outputAPK + "\"\"");
                        txtbox.ScrollToEnd();
                        Process p = Process.Start("cmd.exe", "/c \"\"" + exe + "xdelta3.exe\" -d -f -s \"" + APKPath.Text + "\" \"" + exe + "DowngradeFiles\\" + v.GetDecrName() + "\" \"" + outputAPK + "\"\"");
                        p.WaitForExit();
                        if (!File.Exists(outputAPK) || File.Exists(outputAPK) && new FileInfo(outputAPK).Length <= 0)
                        {
                            MessageBox.Show("XDelta3 was unable to downgrade your APK. This isn't supposed to happen.", "APK Downgrader", MessageBoxButton.OK, MessageBoxImage.Error);
                            txtbox.AppendText("\n\nAn Error occurred");
                            txtbox.ScrollToEnd();
                            return;
                        }
                    }
                    else
                    {
                        txtbox.AppendText("\nXOR-ing APK with downgrade file");
                        txtbox.ScrollToEnd();
                        AllocConsole();
                        d.DecryptOTPFile(APKPath.Text, exe + "DowngradeFiles\\" + v.GetDecrName(), outputAPK, !highRam);
                        FreeConsole();
                        txtbox.AppendText("\nRemoving tailing bytes");
                        txtbox.ScrollToEnd();
                        FileInfo   fi = new FileInfo(outputAPK);
                        FileStream fs = fi.Open(FileMode.Open);

                        fs.SetLength(v.TargetByteSize);
                        fs.Close();
                    }
                    txtbox.AppendText("\nChecking hash");
                    txtbox.ScrollToEnd();
                    hash = CalculateSHA256(outputAPK);
                    if (hash.ToLower() != v.TSHA256.ToLower() && v.TSHA256 != "")
                    {
                        if (otherhash)
                        {
                            txtbox.AppendText("\nAgain the downgraded APK has another hash as the person who created the downgrade file. Hope for the best.");
                            txtbox.ScrollToEnd();
                        }
                        else
                        {
                            MessageBox.Show("Apparently an error occurred. The downgrade apk doesn't match the hash (hashes are a unique ideifier for files which can be clculated. Same content = same hash) of the person who created the downgrade files. Hope for the best.", "APK Downgrader", MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                    }
                    if (selectApk)
                    {
                        txtbox.AppendText("\nSelecting downgraded APK in explorer");
                        txtbox.ScrollToEnd();
                        Process.Start("explorer.exe", "/select," + outputAPK);
                    }
                }
                s.Stop();
                txtbox.AppendText("\n\nFinished in " + s.ElapsedMilliseconds + " ms");
                txtbox.ScrollToEnd();
            }
            catch (Exception e)
            {
                txtbox.AppendText("\n\nAn Error occurred:\n" + e.ToString());
                txtbox.ScrollToEnd();
            }
        }
        public bool CheckVersions(bool ignoreSV = false, bool showDownload = false)
        {
            try
            {
                foreach (String f in APKPath.Text.Split('|'))
                {
                    if (!ignoreSV && !File.Exists(f))
                    {
                        txtbox.AppendText("\n\nPlease put in/choose your apk");
                        txtbox.ScrollToEnd();
                        return(false);
                    }
                }
                if (SV.Text == "" && !ignoreSV)
                {
                    txtbox.AppendText("\n\nPlease put in your APK Version");
                    txtbox.ScrollToEnd();
                    return(false);
                }
                if (TV.Text == "")
                {
                    txtbox.AppendText("\n\nPlease put in your target Version");
                    txtbox.ScrollToEnd();
                    return(false);
                }
                if (!CreateFiles && !versions.IsPresent(SV.Text, TV.Text, appid) && !ignoreSV || ignoreSV && !versions.IsPresent(TV.Text, appid))
                {
                    txtbox.AppendText("\n\nThe Version downgrade isn't available for those versions. Please check that your versions are following the version names. e. g. 1.14.0 or 1.13.2 for Beat Saber\n\nTo see supported versions click Show available downgrades");
                    txtbox.ScrollToEnd();
                    return(false);
                }
                Version v = versions.GetVersion(SV.Text, TV.Text, appid);
                if (!CreateFiles && !ignoreSV && !File.Exists(exe + "DowngradeFiles\\" + v.GetDecrName()))
                {
                    if (!showDownload || v.download == "")
                    {
                        txtbox.AppendText("\n\nYou haven't got " + v.GetDecrName() + " to downgrade your App. " + (v.download == "" ? "No download link has been provided." : "You can download it once you click Start Downgrade"));
                        txtbox.ScrollToEnd();
                    }
                    else
                    {
                        if (!Directory.Exists(exe + "DowngradeFiles"))
                        {
                            Directory.CreateDirectory(exe + "DowngradeFiles");
                        }
                        MessageBoxResult r = MessageBox.Show("You haven't got " + v.GetDecrName() + " to downgrade your App. Do you want to download it?", "APK Downgrader", MessageBoxButton.YesNo, MessageBoxImage.Question);
                        switch (r)
                        {
                        case MessageBoxResult.Yes:
                            if (v.isDirectDownload)
                            {
                                txtbox.AppendText("\n\nDownloading File. Press Start Downgrade again once the download finished");
                                txtbox.ScrollToEnd();
                                Downloadprogress DP = new Downloadprogress();
                                DP.Show();
                                DP.Download(v.download, v.GetDecrName(), exe + "DowngradeFiles\\" + v.GetDecrName());
                            }
                            else
                            {
                                MessageBox.Show("I'll open the download page in your webbrowser once you clicked ok. Please download the files there and then put it in the folder named \"DowngradeFiles\" (I'll open that folder for you too). Once you finished click Start Downgrade again", "APK Downgrader");
                                Process.Start(exe + "DowngradeFiles");
                                Process.Start(v.download);
                                txtbox.AppendText("\n\nPress Start Downgrade once you downloaded and moved the downgrade file intoy \"DowngradeFiles\".");
                                txtbox.ScrollToEnd();
                            }
                            break;

                        case MessageBoxResult.No:
                            txtbox.AppendText("\n\nYou can't continue without the files. Aborting.");
                            txtbox.ScrollToEnd();
                            break;
                        }
                    }

                    return(false);
                }
                return(true);
            } catch (Exception e)
            {
                txtbox.AppendText("An Error occurred while checking if you can downgrade. Please contact ComputerElite:\n" + e.ToString());
                txtbox.ScrollToEnd();
                return(false);
            }
        }