private void PopulateTreeviewViewModel(EPakLoader mode)
        {
            switch (mode)
            {
            case EPakLoader.Single:
                PopulateProcess(Globals.CachedPakFiles[PakFile.FileName]);
                break;

            case EPakLoader.All:
                foreach (var fileReader in Globals.CachedPakFiles)
                {
                    PopulateProcess(fileReader.Value);
                }
                break;

            case EPakLoader.New:
            case EPakLoader.Modified:
            case EPakLoader.NewModified:
                PopulateProcess(GetOldFiles(mode));
                break;
            }
            DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PakMenuItemViewModel]", "[Loader]", "Treeview populated");
        }
        private Dictionary <string, FPakEntry> GetOldFiles(EPakLoader mode)
        {
            var diff = new Dictionary <string, FPakEntry>();
            var ofd  = new OpenFileDialog()
            {
                Title            = Properties.Resources.SelectFile,
                InitialDirectory = Properties.Settings.Default.OutputPath + "\\Backups\\",
                Filter           = Properties.Resources.FbkpFilter,
                Multiselect      = false
            };

            if ((bool)ofd.ShowDialog())
            {
                string n = Path.GetFileName(ofd.FileName);
                StatusBarVm.statusBarViewModel.Set(string.Format(Properties.Resources.Analyzing, n), Properties.Resources.Processing);
                DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PakMenuItemViewModel]", "[Loader]", $"Backup file is {n}");

                var oldFilesTemp = new Dictionary <string, FPakEntry>();
                using FileStream fileStream = new FileStream(ofd.FileName, FileMode.Open);
                BinaryReader checkReader = new BinaryReader(fileStream);
                bool         isLz4       = checkReader.ReadUInt32() == 0x184D2204u;
                fileStream.Seek(0, SeekOrigin.Begin);
                var target = new MemoryStream();
                if (isLz4)
                {
                    using LZ4DecoderStream compressionStream = LZ4Stream.Decode(fileStream);
                    compressionStream.CopyTo(target);
                }
                else
                {
                    fileStream.CopyTo(target);
                }
                using (target)
                {
                    target.Position           = 0;
                    using BinaryReader reader = new BinaryReader(target);
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        // we must follow this order
                        long   offset                 = reader.ReadInt64();
                        long   size                   = reader.ReadInt64();
                        long   uncompressedSize       = reader.ReadInt64();
                        bool   encrypted              = reader.ReadBoolean();
                        long   structSize             = reader.ReadInt32();
                        string name                   = reader.ReadString();
                        int    compressionMethodIndex = reader.ReadInt32();

                        // we only need name and uncompressedSize to compare
                        FPakEntry entry = new FPakEntry("CatsWillDominateTheWorld.pak", name, offset, size, uncompressedSize, new byte[20], null, 0, (uint)compressionMethodIndex, 0);
                        oldFilesTemp[entry.Name] = entry;
                    }
                }

                var newFiles = new Dictionary <string, FPakEntry>();
                foreach (var fileReader in Globals.CachedPakFiles)
                {
                    foreach (var files in fileReader.Value)
                    {
                        newFiles.Add(files.Key, files.Value);
                    }
                }

                Paks.Merge(oldFilesTemp, out var oldFiles, string.Empty);

                switch (mode)
                {
                case EPakLoader.New:
                    foreach (var kvp in newFiles)
                    {
                        if (!oldFiles.TryGetValue(kvp.Key, out var entry))
                        {
                            diff.Add(kvp.Key, kvp.Value);
                        }
                    }
                    break;

                case EPakLoader.Modified:
                    foreach (var kvp in newFiles)
                    {
                        if (oldFiles.TryGetValue(kvp.Key, out var entry))
                        {
                            if (entry.UncompressedSize != kvp.Value.UncompressedSize)
                            {
                                diff.Add(kvp.Key, kvp.Value);
                            }
                        }
                    }
                    break;

                case EPakLoader.NewModified:
                    foreach (var kvp in newFiles)
                    {
                        if (oldFiles.TryGetValue(kvp.Key, out var entry))
                        {
                            if (entry.UncompressedSize != kvp.Value.UncompressedSize)
                            {
                                diff.Add(kvp.Key, kvp.Value);
                            }
                        }
                        else
                        {
                            diff.Add(kvp.Key, kvp.Value);
                        }
                    }
                    break;
                }

                var deleted = oldFiles.Where(kvp => !newFiles.TryGetValue(kvp.Key, out var _) && kvp.Key.StartsWith("/FortniteGame/Content/Athena/Items/Cosmetics/")).ToDictionary(x => x.Key, x => x.Value);
                if (deleted.Count > 0)
                {
                    FConsole.AppendText(Properties.Resources.RemovedRenamedCosmetics, FColors.Red, true);
                    foreach (var kvp in deleted)
                    {
                        FConsole.AppendText($"    - {kvp.Value.Name.Substring(1)}", FColors.LightGray, true);
                    }
                }
            }
            return(diff);
        }
        private async Task LoadPakFiles(EPakLoader mode)
        {
            ListBoxVm.gameFiles.Clear();
            DataGridVm.dataGridViewModel.Clear();
            ImageBoxVm.imageBoxViewModel.Reset();
            StatusBarVm.statusBarViewModel.Reset();
            AvalonEditVm.avalonEditViewModel.Reset();
            PakPropertiesVm.pakPropertiesViewModel.Reset();
            SortedTreeviewVm.gameFilesPath.Childrens.Clear();
            AssetPropertiesVm.assetPropertiesViewModel.Reset();

            await Task.Run(async() =>
            {
                if (mode == EPakLoader.Single)
                {
                    StatusBarVm.statusBarViewModel.Set($"{Properties.Settings.Default.PakPath}\\{PakFile.FileName}", Properties.Resources.Loading);
                    DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PakMenuItemViewModel]", "[Loader]", $"{PakFile.FileName} was selected ({mode})");
                }
                else
                {
                    StatusBarVm.statusBarViewModel.Set(Properties.Settings.Default.PakPath, Properties.Resources.Loading);
                    DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PakMenuItemViewModel]", "[Loader]", $"All PAK files were selected ({mode})");
                }

                foreach (PakFileReader pakFile in MenuItems.pakFiles.GetPakFileReaders())
                {
                    if (pakFile.AesKey == null)
                    {
                        continue;
                    }

                    if (!Globals.CachedPakFiles.ContainsKey(pakFile.FileName))
                    {
                        pakFile.ReadIndex(pakFile.AesKey);
                        Globals.CachedPakFiles[pakFile.FileName] = pakFile;

                        if (mode != EPakLoader.Single)
                        {
                            StatusBarVm.statusBarViewModel.Set(string.Format(Properties.Resources.MountedPakTo, pakFile.FileName, pakFile.MountPoint), Properties.Resources.Loading);
                        }
                    }
                }

                if (mode == EPakLoader.Single)
                {
                    PakPropertiesVm.pakPropertiesViewModel.Set(PakFile);
                }
                await Localizations.SetLocalization(Properties.Settings.Default.AssetsLanguage, false).ConfigureAwait(false);
                PopulateTreeviewViewModel(mode);
            }).ContinueWith(t =>
            {
                DiscordIntegration.Update(
                    $"{Globals.CachedPakFiles.Count}/{MenuItems.pakFiles.GetPakCount()} {Properties.Resources.PakFiles}",
                    string.Format("{0} - {1}", Globals.Game,
                                  mode == EPakLoader.All ? Properties.Resources.AllFiles :
                                  mode == EPakLoader.New ? Properties.Resources.NewFiles :
                                  mode == EPakLoader.Modified ? Properties.Resources.ModifiedFiles :
                                  mode == EPakLoader.NewModified ? Properties.Resources.NewModifiedFiles :
                                  mode == EPakLoader.Single ? Header.Substring(0, Header.LastIndexOf("-WindowsClient.pak")) :
                                  string.Empty
                                  ));

                if (t.Exception != null)
                {
                    Tasks.TaskCompleted(t.Exception);
                }
                else
                {
                    StatusBarVm.statusBarViewModel.Set(
                        mode == EPakLoader.Single ?
                        $"{Properties.Settings.Default.PakPath}\\{PakFile.FileName}" :
                        Properties.Settings.Default.PakPath,
                        Properties.Resources.Success);
                }
            },
                            TaskScheduler.FromCurrentSynchronizationContext());

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }