예제 #1
0
        private static void TryAddPKMsFromSaveFilePath(ConcurrentBag <PKM> dbTemp, string file, string externalFilePrefix)
        {
            try
            {
                var sav = SaveUtil.GetVariantSAV(file);
                if (sav == null)
                {
                    Console.WriteLine("Unable to load SaveFile: " + file);
                    return;
                }

                var path = externalFilePrefix + Path.GetFileName(file);
                if (sav.HasBox)
                {
                    foreach (var pk in sav.BoxData)
                    {
                        addPKM(pk);
                    }
                }

                void addPKM(PKM pk)
                {
                    pk.Identifier = Path.Combine(path, pk.Identifier);
                    dbTemp.Add(pk);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Unable to load SaveFile: " + file);
                Console.WriteLine(ex.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// Finds a compatible save file that was most recently saved (by file write time).
        /// </summary>
        /// <param name="path">If this function returns true, full path of a save file or null if no path could be found. If this function returns false, this parameter will be set to the error message.</param>
        /// <param name="extra">Paths to check in addition to the default paths</param>
        /// <returns>A boolean indicating whether or not a file was detected</returns>
        public static bool DetectSaveFile(out string path, params string[] extra)
        {
            var foldersToCheck = extra.Where(f => f?.Length > 0);

            string path3DS = Path.GetPathRoot(Get3DSLocation());

            if (path3DS != null) // check for Homebrew/CFW backups
            {
                foldersToCheck = foldersToCheck.Concat(Get3DSBackupPaths(path3DS));
            }

            string pathNX = Path.GetPathRoot(GetSwitchLocation());

            if (pathNX != null) // check for Homebrew/CFW backups
            {
                foldersToCheck = foldersToCheck.Concat(GetSwitchBackupPaths(pathNX));
            }

            path = null;
            List <string> possiblePaths = new List <string>();

            foreach (var folder in foldersToCheck)
            {
                if (!SaveUtil.GetSavesFromFolder(folder, true, out IEnumerable <string> files))
                {
                    if (files != null)                                  // can be null if folder doesn't exist
                    {
                        path = string.Join(Environment.NewLine, files); // `files` contains the error message
                        return(false);
                    }
                }
                if (files != null)
                {
                    possiblePaths.AddRange(files);
                }
            }

            // return newest save file path that is valid
            foreach (var file in possiblePaths.OrderByDescending(f => new FileInfo(f).LastWriteTime))
            {
                try
                {
                    var data = File.ReadAllBytes(file);
                    var sav  = SaveUtil.GetVariantSAV(data);
                    if (sav?.ChecksumsValid != true)
                    {
                        continue;
                    }

                    path = file;
                    return(true);
                }
                catch (Exception e)
                {
                    path = e.Message + Environment.NewLine + file;
                    return(false);
                }
            }
            return(true);
        }
예제 #3
0
        private void CompareSaves()
        {
            var p1 = TB_OldSAV.Text;
            var p2 = TB_NewSAV.Text;

            var f1 = new FileInfo(p1);

            if (!SaveUtil.IsSizeValid((int)f1.Length))
            {
                return;
            }
            var f2 = new FileInfo(p1);

            if (!SaveUtil.IsSizeValid((int)f2.Length))
            {
                return;
            }

            var s1 = SaveUtil.GetVariantSAV(p1);

            if (!(s1 is SAV8SWSH w1))
            {
                return;
            }
            var s2 = SaveUtil.GetVariantSAV(p2);

            if (!(s2 is SAV8SWSH w2))
            {
                return;
            }

            var compare = new SCBlockCompare(w1, w2);

            richTextBox1.Lines = compare.Summary().ToArray();
        }
        private static List <PKM> LoadPKMSaves(string pkmdb, string savdb, string EXTERNAL_SAV, SaveFile SAV)
        {
            var dbTemp     = new ConcurrentBag <PKM>();
            var files      = Directory.EnumerateFiles(pkmdb, "*", SearchOption.AllDirectories);
            var extensions = new HashSet <string>(PKM.Extensions.Select(z => $".{z}"));

            Parallel.ForEach(files, file =>
            {
                var fi = new FileInfo(file);
                if (!extensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length))
                {
                    return;
                }
                var data   = File.ReadAllBytes(file);
                var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, SAV.Generation);
                var pk     = PKMConverter.GetPKMfromBytes(data, prefer);
                if (!(pk?.Species > 0))
                {
                    return;
                }
                pk.Identifier = file;
                dbTemp.Add(pk);
            });

#if LOADALL
            if (SaveUtil.GetSavesFromFolder(savdb, false, out IEnumerable <string> result))
            {
                Parallel.ForEach(result, file =>
                {
                    var sav  = SaveUtil.GetVariantSAV(file);
                    var path = EXTERNAL_SAV + new FileInfo(file).Name;
                    if (sav.HasBox)
                    {
                        foreach (var pk in sav.BoxData)
                        {
                            addPKM(pk);
                        }
                    }

                    void addPKM(PKM pk)
                    {
                        pk.Identifier = Path.Combine(path, pk.Identifier);
                        dbTemp.Add(pk);
                    }
                });
            }
#endif
            // Fetch from save file
            var savpkm = SAV.BoxData.Where(pk => pk.Species != 0);

            var bakpkm = dbTemp.Where(pk => pk.Species != 0).OrderBy(pk => pk.Identifier);
            var db     = bakpkm.Concat(savpkm).Where(pk => pk.ChecksumValid && pk.Sanity == 0);

            // Prepare Database
            return(new List <PKM>(db));
        }
예제 #5
0
        private void LoadDatabase()
        {
            var dbTemp = new ConcurrentBag <PKM>();
            var files  = Directory.EnumerateFiles(DatabasePath, "*", SearchOption.AllDirectories);

            Parallel.ForEach(files, file =>
            {
                FileInfo fi = new FileInfo(file);
                if (!fi.Extension.Contains(".pk") || !PKX.IsPKM(fi.Length))
                {
                    return;
                }
                var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(file), file, prefer: (fi.Extension.Last() - '0') & 0xF);
                if (pk != null)
                {
                    dbTemp.Add(pk);
                }
            });

#if LOADALL
            if (SaveUtil.GetSavesFromFolder(Main.BackupPath, false, out IEnumerable <string> result))
            {
                Parallel.ForEach(result, file =>
                {
                    var sav  = SaveUtil.GetVariantSAV(File.ReadAllBytes(file));
                    var path = EXTERNAL_SAV + new FileInfo(file).Name;
                    if (sav.HasBox)
                    {
                        foreach (var pk in sav.BoxData)
                        {
                            addPKM(pk);
                        }
                    }

                    void addPKM(PKM pk)
                    {
                        pk.Identifier = Path.Combine(path, pk.Identifier);
                        dbTemp.Add(pk);
                    }
                });
            }
#endif

            // Prepare Database
            RawDB = new List <PKM>(dbTemp.OrderBy(pk => pk.Identifier)
                                   .Concat(SAV.BoxData.Where(pk => pk.Species != 0)) // Fetch from save file
                                   .Where(pk => pk.ChecksumValid && pk.Species != 0 && pk.Sanity == 0)
                                   .Distinct());
            try
            {
                BeginInvoke(new MethodInvoker(() => SetResults(RawDB)));
            }
            catch { /* Window Closed? */ }
        }
예제 #6
0
        public static async Task <SaveFile> TryGetSaveFile()
        {
            try
            {
                var path = await PickFile().ConfigureAwait(false);

                if (path == null)
                {
                    return(null);
                }

                var  fi            = new FileInfo(path);
                var  len           = fi.Length;
                bool isPossibleSAV = SaveUtil.IsSizeValid((int)len);

                if (!isPossibleSAV)
                {
                    var  lenD           = len - 122;
                    bool isPossibleDSAV = SaveUtil.IsSizeValid((int)lenD);
                    if (isPossibleDSAV)
                    {
                        var    data1 = File.ReadAllBytes(path);
                        Byte[] dataD = new Byte[lenD];
                        Array.ConstrainedCopy(data1, 0, dataD, 0, (int)lenD);
                        var savD = SaveUtil.GetVariantSAV(data1);
                        savD?.SetFileInfo(path);
                        return(savD);
                    }
                    return(null);
                }

                var data = File.ReadAllBytes(path);
                var sav  = SaveUtil.GetVariantSAV(data);
                sav?.SetFileInfo(path);
                return(sav);
            }
            catch (FileNotFoundException ex)
            {
                await UserDialogs.Instance.AlertAsync($"The file is being passed as a URI instead of a path. Please try moving your saves to a different folder.\n\nStack Trace:\n{ex}").ConfigureAwait(false);

                return(null);
            }
            catch (Exception ex)
            {
                await UserDialogs.Instance.AlertAsync($"Exception choosing file: {ex}").ConfigureAwait(false);

                return(null);
            }
        }
        private void DiffSaves()
        {
            if (!File.Exists(TB_OldSAV.Text))
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (!File.Exists(TB_NewSAV.Text))
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }
            if (new FileInfo(TB_OldSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (new FileInfo(TB_NewSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }

            var s1 = SaveUtil.GetVariantSAV(TB_OldSAV.Text);
            var s2 = SaveUtil.GetVariantSAV(TB_NewSAV.Text);

            if (s1 == null)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (s2 == null)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }

            if (s1.GetType() != s2.GetType())
            {
                WinFormsUtil.Alert(MsgSaveDifferentTypes, $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return;
            }
            if (s1.Version != s2.Version)
            {
                WinFormsUtil.Alert(MsgSaveDifferentVersions, $"S1: {s1.Version}", $"S2: {s2.Version}"); return;
            }

            EventWorkUtil.DiffSavesFlag(((SAV7b)s1).EventWork, ((SAV7b)s2).EventWork, out var on, out var off);
            EventWorkUtil.DiffSavesWork(((SAV7b)s1).EventWork, ((SAV7b)s2).EventWork, out var changed, out var changes);

            var ew = ((SAV7b)s1).EventWork;

            var fOn = on.Select(z => new { Type = ew.GetFlagType(z, out var subIndex), Index = subIndex, Raw = z })
예제 #8
0
        public static async Task <SaveFile> TryGetSaveFile()
        {
            try
            {
                var file = await PickFile().ConfigureAwait(false);

                if (file == null)
                {
                    return(null);
                }

                await using var stream = await file.OpenReadAsync().ConfigureAwait(false);

                var  len           = stream.Length;
                bool isPossibleSAV = SaveUtil.IsSizeValid((int)len);
                if (!isPossibleSAV)
                {
                    return(null);
                }

                var data = new byte[len];
                stream.Read(data);
                var sav = SaveUtil.GetVariantSAV(data);
                sav?.Metadata.SetExtraInfo(file.FullPath);
                return(sav);
            }
            catch (FileNotFoundException ex)
            {
                await UserDialogs.Instance.AlertAsync($"The file is being passed as a URI instead of a path. Please try moving your saves to a different folder.\n\nStack Trace:\n{ex}").ConfigureAwait(false);

                return(null);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                await UserDialogs.Instance.AlertAsync($"Exception choosing file: {ex}").ConfigureAwait(false);

                return(null);
            }
        }
예제 #9
0
 public static SaveFile TryGetSaveFile(string filePath)
 {
     try
     {
         var  data          = File.ReadAllBytes(filePath);
         var  len           = data.Length;
         bool isPossibleSAV = SaveUtil.IsSizeValid(len);
         if (!isPossibleSAV)
         {
             return(null);
         }
         var sav = SaveUtil.GetVariantSAV(data);
         sav?.Metadata.SetExtraInfo(filePath);
         return(sav);
     }
     catch
     {
         //Ignore errors as this is meant to be a background scanning function
         return(null);
     }
 }
예제 #10
0
    private void CompareSaves()
    {
        var p1 = TB_OldSAV.Text;
        var p2 = TB_NewSAV.Text;

        var f1 = new FileInfo(p1);

        if (!SaveUtil.IsSizeValid((int)f1.Length))
        {
            return;
        }
        var f2 = new FileInfo(p1);

        if (!SaveUtil.IsSizeValid((int)f2.Length))
        {
            return;
        }

        var s1 = SaveUtil.GetVariantSAV(p1);

        if (s1 is not ISCBlockArray w1)
        {
            return;
        }
        var s2 = SaveUtil.GetVariantSAV(p2);

        if (s2 is not ISCBlockArray w2)
        {
            return;
        }

        // Get an external source of names if available.
        var extra   = GetExtraKeyNames(w1);
        var compare = new SCBlockCompare(w1.Accessor, w2.Accessor, extra);

        richTextBox1.Lines = compare.Summary().ToArray();
    }
예제 #11
0
        private void DiffSaves()
        {
            if (!File.Exists(TB_OldSAV.Text))
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (!File.Exists(TB_NewSAV.Text))
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }
            if (new FileInfo(TB_OldSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (new FileInfo(TB_NewSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }

            var s1 = SaveUtil.GetVariantSAV(TB_OldSAV.Text);
            var s2 = SaveUtil.GetVariantSAV(TB_NewSAV.Text);

            if (s1 == null)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return;
            }
            if (s2 == null)
            {
                WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return;
            }

            if (s1.GetType() != s2.GetType())
            {
                WinFormsUtil.Alert(MsgSaveDifferentTypes, $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return;
            }
            if (s1.Version != s2.Version)
            {
                WinFormsUtil.Alert(MsgSaveDifferentVersions, $"S1: {s1.Version}", $"S2: {s2.Version}"); return;
            }

            var tbIsSet = new List <int>();
            var tbUnSet = new List <int>();
            var result  = new List <string>();

            bool[] oldBits  = s1.EventFlags;
            bool[] newBits  = s2.EventFlags;
            var    oldConst = s1.EventConsts;
            var    newConst = s2.EventConsts;

            for (int i = 0; i < oldBits.Length; i++)
            {
                if (oldBits[i] != newBits[i])
                {
                    (newBits[i] ? tbIsSet : tbUnSet).Add(i);
                }
            }
            TB_IsSet.Text = string.Join(", ", tbIsSet.Select(z => $"{z:0000}"));
            TB_UnSet.Text = string.Join(", ", tbUnSet.Select(z => $"{z:0000}"));

            for (int i = 0; i < newConst.Length; i++)
            {
                if (oldConst[i] != newConst[i])
                {
                    result.Add($"{i}: {oldConst[i]}->{newConst[i]}");
                }
            }

            if (result.Count == 0)
            {
                WinFormsUtil.Alert("No Event Constant diff found.");
                return;
            }

            if (DialogResult.Yes == WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Copy Event Constant diff to clipboard?"))
            {
                Clipboard.SetText(string.Join(Environment.NewLine, result));
            }
        }
예제 #12
0
        private void DiffSaves()
        {
            if (!File.Exists(TB_OldSAV.Text))
            {
                WinFormsUtil.Alert("Save 1 path invalid."); return;
            }
            if (!File.Exists(TB_NewSAV.Text))
            {
                WinFormsUtil.Alert("Save 2 path invalid."); return;
            }
            if (new FileInfo(TB_OldSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert("Save 1 file invalid."); return;
            }
            if (new FileInfo(TB_NewSAV.Text).Length > 0x100000)
            {
                WinFormsUtil.Alert("Save 2 file invalid."); return;
            }

            SaveFile s1 = SaveUtil.GetVariantSAV(File.ReadAllBytes(TB_OldSAV.Text));
            SaveFile s2 = SaveUtil.GetVariantSAV(File.ReadAllBytes(TB_NewSAV.Text));

            if (s1 == null)
            {
                WinFormsUtil.Alert("Save 1 file invalid."); return;
            }
            if (s2 == null)
            {
                WinFormsUtil.Alert("Save 2 file invalid."); return;
            }

            if (s1.GetType() != s2.GetType())
            {
                WinFormsUtil.Alert("Save types are different.", $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return;
            }
            if (s1.Version != s2.Version)
            {
                WinFormsUtil.Alert("Save versions are different.", $"S1: {s1.Version}", $"S2: {s2.Version}"); return;
            }

            string tbIsSet = "";
            string tbUnSet = "";

            try
            {
                bool[] oldBits = s1.EventFlags;
                bool[] newBits = s2.EventFlags;
                if (oldBits.Length != newBits.Length)
                {
                    WinFormsUtil.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return;
                }

                for (int i = 0; i < oldBits.Length; i++)
                {
                    if (oldBits[i] == newBits[i])
                    {
                        continue;
                    }
                    if (newBits[i])
                    {
                        tbIsSet += $"{i:0000},";
                    }
                    else
                    {
                        tbUnSet += $"{i:0000},";
                    }
                }
            }
            catch (Exception e)
            {
                WinFormsUtil.Error("An unexpected error has occurred.", e);
                Debug.WriteLine(e);
            }
            TB_IsSet.Text = tbIsSet;
            TB_UnSet.Text = tbUnSet;

            string r = "";

            try
            {
                ushort[] oldConst = s1.EventConsts;
                ushort[] newConst = s2.EventConsts;
                if (oldConst.Length != newConst.Length)
                {
                    WinFormsUtil.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return;
                }

                for (int i = 0; i < newConst.Length; i++)
                {
                    if (oldConst[i] != newConst[i])
                    {
                        r += $"{i}: {oldConst[i]}->{newConst[i]}{Environment.NewLine}";
                    }
                }
            }
            catch (Exception e)
            {
                WinFormsUtil.Error("An unexpected error has occurred.", e);
                Debug.WriteLine(e);
            }

            if (string.IsNullOrEmpty(r))
            {
                WinFormsUtil.Alert("No Event Constant diff found.");
                return;
            }

            if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Copy Event Constant diff to clipboard?"))
            {
                return;
            }
            Clipboard.SetText(r);
        }
예제 #13
0
    public static bool IsFileTooSmall(long length) => length < 0x20; // bigger than PK1

    /// <summary>
    /// Tries to get an <see cref="SaveFile"/> object from the input parameters.
    /// </summary>
    /// <param name="data">Binary data</param>
    /// <param name="sav">Output result</param>
    /// <returns>True if file object reference is valid, false if none found.</returns>
    public static bool TryGetSAV(byte[] data, [NotNullWhen(true)] out SaveFile?sav)
    {
        sav = SaveUtil.GetVariantSAV(data);
        return(sav != null);
    }
예제 #14
0
        public SAV_Database(PKMEditor f1, SAVEditor saveditor)
        {
            SAV       = saveditor.SAV;
            BoxView   = saveditor;
            PKME_Tabs = f1;
            InitializeComponent();

            // Preset Filters to only show PKM available for loaded save
            CB_FormatComparator.SelectedIndex = 3; // <=

            PKXBOXES = new[]
            {
                bpkx1, bpkx2, bpkx3, bpkx4, bpkx5, bpkx6,
                bpkx7, bpkx8, bpkx9, bpkx10, bpkx11, bpkx12,
                bpkx13, bpkx14, bpkx15, bpkx16, bpkx17, bpkx18,
                bpkx19, bpkx20, bpkx21, bpkx22, bpkx23, bpkx24,
                bpkx25, bpkx26, bpkx27, bpkx28, bpkx29, bpkx30,

                bpkx31, bpkx32, bpkx33, bpkx34, bpkx35, bpkx36,
                bpkx37, bpkx38, bpkx39, bpkx40, bpkx41, bpkx42,
                bpkx43, bpkx44, bpkx45, bpkx46, bpkx47, bpkx48,
                bpkx49, bpkx50, bpkx51, bpkx52, bpkx53, bpkx54,
                bpkx55, bpkx56, bpkx57, bpkx58, bpkx59, bpkx60,
                bpkx61, bpkx62, bpkx63, bpkx64, bpkx65, bpkx66,
            };

            // Enable Scrolling when hovered over
            PAN_Box.MouseWheel += (sender, e) =>
            {
                if (ActiveForm == this)
                {
                    SCR_Box.Focus();
                }
            };
            foreach (var slot in PKXBOXES)
            {
                slot.MouseWheel += (sender, e) =>
                {
                    if (ActiveForm == this)
                    {
                        SCR_Box.Focus();
                    }
                };
                // Enable Click
                slot.MouseClick += (sender, e) =>
                {
                    if (ModifierKeys == Keys.Control)
                    {
                        ClickView(sender, e);
                    }
                    else if (ModifierKeys == Keys.Alt)
                    {
                        ClickDelete(sender, e);
                    }
                    else if (ModifierKeys == Keys.Shift)
                    {
                        ClickSet(sender, e);
                    }
                };
            }

            Counter       = L_Count.Text;
            Viewed        = L_Viewed.Text;
            L_Viewed.Text = ""; // invis for now
            var hover = new ToolTip();

            L_Viewed.MouseEnter += (sender, e) => hover.SetToolTip(L_Viewed, L_Viewed.Text);
            PopulateComboBoxes();

            ContextMenuStrip  mnu       = new ContextMenuStrip();
            ToolStripMenuItem mnuView   = new ToolStripMenuItem("View");
            ToolStripMenuItem mnuDelete = new ToolStripMenuItem("Delete");

            // Assign event handlers
            mnuView.Click   += ClickView;
            mnuDelete.Click += ClickDelete;

            // Add to main context menu
            mnu.Items.AddRange(new ToolStripItem[] { mnuView, mnuDelete });

            // Assign to datagridview
            foreach (PictureBox p in PKXBOXES)
            {
                p.ContextMenuStrip = mnu;
            }

            // Load Data
            var dbTemp = new ConcurrentBag <PKM>();
            var files  = Directory.GetFiles(DatabasePath, "*", SearchOption.AllDirectories);

            Parallel.ForEach(files, file =>
            {
                FileInfo fi = new FileInfo(file);
                if (!fi.Extension.Contains(".pk") || !PKX.IsPKM(fi.Length))
                {
                    return;
                }
                var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(file), file, prefer: (fi.Extension.Last() - 0x30) & 7);
                if (pk != null)
                {
                    dbTemp.Add(pk);
                }
            });

#if DEBUG
            if (SaveUtil.GetSavesFromFolder(Main.BackupPath, false, out IEnumerable <string> result))
            {
                Parallel.ForEach(result, file =>
                {
                    var sav  = SaveUtil.GetVariantSAV(File.ReadAllBytes(file));
                    var path = EXTERNAL_SAV + new FileInfo(file).Name;
                    if (sav.HasBox)
                    {
                        foreach (var pk in sav.BoxData)
                        {
                            addPKM(pk);
                        }
                    }

                    void addPKM(PKM pk)
                    {
                        pk.Identifier = Path.Combine(path, pk.Identifier);
                        dbTemp.Add(pk);
                    }
                });
            }
#endif

            // Prepare Database
            RawDB = new List <PKM>(dbTemp.OrderBy(pk => pk.Identifier)
                                   .Concat(SAV.BoxData.Where(pk => pk.Species != 0))      // Fetch from save file
                                   .Where(pk => pk.ChecksumValid && pk.Species != 0 && pk.Sanity == 0)
                                   .Distinct());
            SetResults(RawDB);

            Menu_SearchSettings.DropDown.Closing += (sender, e) =>
            {
                if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
                {
                    e.Cancel = true;
                }
            };
            CenterToParent();
        }