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(); }