From a4f1cc2b2cfe10c999dce89c6e52fbcbbe13b711 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 25 May 2020 00:38:10 +0200 Subject: [PATCH] notofficer fix + audio player volume saved + click notif to open path --- FModel/App.xaml.cs | 7 +- FModel/Creator/Utils.cs | 4 + FModel/Discord/DiscordIntegration.cs | 4 +- FModel/Grabber/Paks/PaksGrabber.cs | 67 +++++++++-------- FModel/PakReader/BinaryHelper.cs | 7 ++ FModel/PakReader/LocResReader.cs | 10 +-- FModel/PakReader/Pak/PakFileReader.cs | 13 ++-- .../Parsers/Objects/FPakCompressedBlock.cs | 3 + FModel/PakReader/Parsers/Objects/FPakEntry.cs | 73 +++++++++++-------- FModel/Properties/Resources.ru-RU.resx | 2 +- FModel/Properties/Settings.Designer.cs | 12 +++ FModel/Properties/Settings.settings | 3 + FModel/Theme/Style.xaml | 5 +- FModel/Utils/Assets.cs | 4 +- FModel/Utils/Keys.cs | 4 +- FModel/Utils/Localizations.cs | 5 +- .../AvalonEdit/AvalonEditViewModel.cs | 2 +- .../ViewModels/ImageBox/ImageBoxViewModel.cs | 2 +- .../MenuItem/BackupMenuItemViewModel.cs | 4 +- .../ViewModels/Notifier/NotifierViewModel.cs | 14 +++- .../SoundPlayer/InputFileViewModel.cs | 3 +- .../CustomNotifier/CustomNotifier.xaml | 6 +- .../CustomNotifier/CustomNotifier.xaml.cs | 15 ++++ .../CustomNotifier/CustomNotifierHelper.cs | 4 +- .../Windows/ImagesMerger/ImagesMerger.xaml.cs | 2 +- .../SoundPlayer/Visualization/OutputSource.cs | 2 + README.md | 1 + 27 files changed, 179 insertions(+), 99 deletions(-) diff --git a/FModel/App.xaml.cs b/FModel/App.xaml.cs index db937cdd..7ae72599 100644 --- a/FModel/App.xaml.cs +++ b/FModel/App.xaml.cs @@ -26,10 +26,11 @@ namespace FModel { StartTimer = Stopwatch.StartNew(); - if (FModel.Properties.Settings.Default.UseEnglish) + DebugHelper.Init(LogsFilePath); // get old settings too + + if (FModel.Properties.Settings.Default.UseEnglish) // use old settings here Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US"); - DebugHelper.Init(LogsFilePath); DebugHelper.WriteLine("{0} {1}", "[FModel]", "––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––"); DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Version]", Assembly.GetExecutingAssembly().GetName().Version.ToString()); DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Build]", Globals.Build); @@ -64,7 +65,7 @@ namespace FModel { string errorMessage = string.Format(FModel.Properties.Resources.UnhandledExceptionOccured, e.Exception.Message); DebugHelper.WriteException(e.Exception, "thrown in App.xaml.cs by OnDispatcherUnhandledException"); - DarkMessageBoxHelper.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error); + DarkMessageBoxHelper.Show(errorMessage, FModel.Properties.Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); e.Handled = true; } diff --git a/FModel/Creator/Utils.cs b/FModel/Creator/Utils.cs index 5b18e873..65acd3ea 100644 --- a/FModel/Creator/Utils.cs +++ b/FModel/Creator/Utils.cs @@ -58,6 +58,10 @@ namespace FModel.Creator public static SKBitmap GetSoftObjectTexture(SoftObjectProperty s) => GetTexture(s.Value.AssetPathName.String); public static SKBitmap GetTexture(string s) { + // FortniteGame/Content/Catalog/DisplayAssets/DA_BattlePassBundle_2020.uasset + if (s.Equals("/Game/UI/Foundation/Textures/BattleRoyale/FeaturedItems/Outfit/T_UI_InspectScreen_annualPass")) + s += "_1024"; + PakPackage p = GetPropertyPakPackage(s); if (p.HasExport() && !p.Equals(default)) { diff --git a/FModel/Discord/DiscordIntegration.cs b/FModel/Discord/DiscordIntegration.cs index d4d4597b..5d428f4f 100644 --- a/FModel/Discord/DiscordIntegration.cs +++ b/FModel/Discord/DiscordIntegration.cs @@ -50,8 +50,8 @@ namespace FModel.Discord { Assets = _assets, Timestamps = _baseTimestamp, - Details = string.IsNullOrEmpty(detail) ? _presence.Details : detail, - State = string.IsNullOrEmpty(state) ? _presence.State : state + Details = string.IsNullOrEmpty(detail) ? _presence?.Details : detail, + State = string.IsNullOrEmpty(state) ? _presence?.State : state }); _client.Invoke(); } diff --git a/FModel/Grabber/Paks/PaksGrabber.cs b/FModel/Grabber/Paks/PaksGrabber.cs index 03736f76..0fb590cd 100644 --- a/FModel/Grabber/Paks/PaksGrabber.cs +++ b/FModel/Grabber/Paks/PaksGrabber.cs @@ -8,6 +8,7 @@ using System; using System.Collections.ObjectModel; using System.IO; using System.Threading.Tasks; +using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; @@ -19,44 +20,48 @@ namespace FModel.Grabber.Paks { PopulateBase(); - if (string.IsNullOrEmpty(Properties.Settings.Default.PakPath)) + await Task.Run(() => { - var launcher = new FLauncher(); - if ((bool)launcher.ShowDialog()) + if (string.IsNullOrEmpty(Properties.Settings.Default.PakPath)) { - Properties.Settings.Default.PakPath = launcher.Path; - Properties.Settings.Default.Save(); - } - } - - // define the current game thank to the pak path - Folders.SetGameName(Properties.Settings.Default.PakPath); - - // Add Pak Files - if (Directory.Exists(Properties.Settings.Default.PakPath)) - { - foreach (string pak in Directory.GetFiles(Properties.Settings.Default.PakPath, "*.pak")) - { - if (!Utils.Paks.IsFileReadLocked(new FileInfo(pak))) + var launcher = new FLauncher(); + if ((bool)launcher.ShowDialog()) { - PakFileReader pakFile = new PakFileReader(pak); - DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Registering]", $"{pakFile.FileName} with GUID {pakFile.Info.EncryptionKeyGuid.Hex}"); + Properties.Settings.Default.PakPath = launcher.Path; + Properties.Settings.Default.Save(); + } + } - MenuItems.pakFiles.Add(new PakMenuItemViewModel + // define the current game thank to the pak path + Folders.SetGameName(Properties.Settings.Default.PakPath); + + // Add Pak Files + if (Directory.Exists(Properties.Settings.Default.PakPath)) + { + foreach (string pak in Directory.GetFiles(Properties.Settings.Default.PakPath, "*.pak")) + { + if (!Utils.Paks.IsFileReadLocked(new FileInfo(pak))) { - PakFile = pakFile, - IsEnabled = false - }); - } - else - { - Globals.gNotifier.ShowCustomMessage(Properties.Resources.PakFiles, string.Format(Properties.Resources.PakFileLocked, Path.GetFileNameWithoutExtension(pak))); - DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Locked]", pak); + PakFileReader pakFile = new PakFileReader(pak); + DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Registering]", $"{pakFile.FileName} with GUID {pakFile.Info.EncryptionKeyGuid.Hex}"); + + Application.Current.Dispatcher.Invoke(delegate + { + MenuItems.pakFiles.Add(new PakMenuItemViewModel + { + PakFile = pakFile, + IsEnabled = false + }); + }); + } + else + { + FConsole.AppendText(string.Format(Properties.Resources.PakFileLocked, Path.GetFileNameWithoutExtension(pak)), FColors.Red, true); + DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Locked]", pak); + } } } - } - - await Task.CompletedTask.ConfigureAwait(false); + }); } private static void PopulateBase() diff --git a/FModel/PakReader/BinaryHelper.cs b/FModel/PakReader/BinaryHelper.cs index e514b292..754f2fce 100644 --- a/FModel/PakReader/BinaryHelper.cs +++ b/FModel/PakReader/BinaryHelper.cs @@ -1,10 +1,17 @@ using System; using System.Linq; +using System.Runtime.CompilerServices; namespace PakReader { static class BinaryHelper { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long Align(long val, long alignment) + { + return val + alignment - 1 & ~(alignment - 1); + } + public static uint Flip(uint value) => (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24; diff --git a/FModel/PakReader/LocResReader.cs b/FModel/PakReader/LocResReader.cs index a5fc54fe..7abe73da 100644 --- a/FModel/PakReader/LocResReader.cs +++ b/FModel/PakReader/LocResReader.cs @@ -105,7 +105,7 @@ namespace PakReader reader.ReadUInt32(); // SourceStringHash - string EntryLocalizedString = string.Empty; + string EntryLocalizedString; if (VersionNumber >= Version.COMPACT) { int LocalizedStringIndex = reader.ReadInt32(); @@ -130,18 +130,16 @@ namespace PakReader } else { - //throw new IOException($"LocRes has an invalid localized string index for namespace '{Namespace}' and key '{Key}'. This entry will have no translation."); + throw new IOException($"LocRes has an invalid localized string index for namespace '{Namespace}' and key '{Key}'. This entry will have no translation."); } } else { EntryLocalizedString = reader.ReadFString(); } - - if (Key != null) Entries.Add(Key, EntryLocalizedString); + Entries.Add(Key, EntryLocalizedString); } - - if (Namespace != null) this.Entries.Add(Namespace, Entries); + this.Entries.Add(Namespace, Entries); } } diff --git a/FModel/PakReader/Pak/PakFileReader.cs b/FModel/PakReader/Pak/PakFileReader.cs index 7d856f72..35eed42d 100644 --- a/FModel/PakReader/Pak/PakFileReader.cs +++ b/FModel/PakReader/Pak/PakFileReader.cs @@ -417,18 +417,17 @@ namespace PakReader.Pak // Get the right pointer to start copying the CompressionBlocks information from. // Alignment of the compressed blocks - var CompressedBlockAlignment = Encrypted ? AESDecryptor.BLOCK_SIZE : 1; + var CompressedBlockAlignment = Encrypted ? 16 : 1; // CompressedBlockOffset is the starting offset. Everything else can be derived from there. long CompressedBlockOffset = BaseOffset + FPakEntry.GetSize(EPakVersion.LATEST, CompressionMethodIndex, CompressionBlocksCount); for (int CompressionBlockIndex = 0; CompressionBlockIndex < CompressionBlocks.Length; ++CompressionBlockIndex) { - CompressionBlocks[CompressionBlockIndex] = new FPakCompressedBlock(CompressedBlockOffset, CompressedBlockOffset + BitConverter.ToUInt32(encodedPakEntries, pakLocation)); - pakLocation += sizeof(uint); - { - var toAlign = CompressionBlocks[CompressionBlockIndex].CompressedEnd - CompressionBlocks[CompressionBlockIndex].CompressedStart; - CompressedBlockOffset += toAlign + CompressedBlockAlignment - (toAlign % CompressedBlockAlignment); - } + FPakCompressedBlock CompressionBlock = new FPakCompressedBlock(CompressedBlockOffset, CompressedBlockOffset + BitConverter.ToUInt32(encodedPakEntries, pakLocation)); + CompressionBlocks[CompressionBlockIndex] = CompressionBlock; + CompressedBlockOffset += BinaryHelper.Align(CompressionBlock.CompressedEnd - CompressionBlock.CompressedStart, CompressedBlockAlignment); + + pakLocation += 4; } } return new FPakEntry(this.FileName, name, Offset, Size, UncompressedSize, new byte[20], CompressionBlocks, CompressionBlockSize, CompressionMethodIndex, (byte)((Encrypted ? 0x01 : 0x00) | (Deleted ? 0x02 : 0x00))); diff --git a/FModel/PakReader/Parsers/Objects/FPakCompressedBlock.cs b/FModel/PakReader/Parsers/Objects/FPakCompressedBlock.cs index d76ec41d..fdbe2c4c 100644 --- a/FModel/PakReader/Parsers/Objects/FPakCompressedBlock.cs +++ b/FModel/PakReader/Parsers/Objects/FPakCompressedBlock.cs @@ -6,17 +6,20 @@ namespace PakReader.Parsers.Objects { public readonly long CompressedStart; public readonly long CompressedEnd; + public readonly long Size; internal FPakCompressedBlock(BinaryReader reader) { CompressedStart = reader.ReadInt64(); CompressedEnd = reader.ReadInt64(); + Size = CompressedEnd - CompressedStart; } internal FPakCompressedBlock(long start, long end) { CompressedStart = start; CompressedEnd = end; + Size = end - start; } } } diff --git a/FModel/PakReader/Parsers/Objects/FPakEntry.cs b/FModel/PakReader/Parsers/Objects/FPakEntry.cs index e19ab17f..7ac1e5cc 100644 --- a/FModel/PakReader/Parsers/Objects/FPakEntry.cs +++ b/FModel/PakReader/Parsers/Objects/FPakEntry.cs @@ -136,52 +136,67 @@ namespace PakReader.Parsers.Objects { lock (stream) { - stream.Position = Offset + StructSize; - if (Encrypted) + if (CompressionMethodIndex == 0U) { - var data = new byte[(Size & 15) == 0 ? Size : ((Size / 16) + 1) * 16]; - stream.Read(data, 0, data.Length); - byte[] decrypted = AESDecryptor.DecryptAES(data, key); - - if (CompressionMethodIndex != 0U) + stream.Position = Offset + StructSize; + if (Encrypted) { - using var m = new MemoryStream(decrypted, 0, decrypted.Length) - { - Position = 0 - }; - Decompress(m, compressionMethods, decrypted); + var data = new byte[(Size & 15) == 0 ? Size : (Size / 16 + 1) * 16]; + stream.Read(data, 0, data.Length); + return new ArraySegment(AESDecryptor.DecryptAES(data, key), 0, (int)UncompressedSize); + } + else + { + var data = new byte[UncompressedSize]; + stream.Read(data, 0, data.Length); + return new ArraySegment(data); } - - return new ArraySegment(decrypted, 0, decrypted.Length <= (int)UncompressedSize ? decrypted.Length : (int)UncompressedSize); } else { var data = new byte[UncompressedSize]; - if (CompressionMethodIndex == 0U) - stream.Read(data, 0, data.Length); - else - Decompress(stream, compressionMethods, data); - + Decompress(stream, key, compressionMethods, data); return new ArraySegment(data); } } throw new NotImplementedException("Decompression not yet implemented"); } - private void Decompress(Stream stream, string[] compressionMethods, byte[] outData) + private void Decompress(Stream stream, byte[] key, string[] compressionMethods, byte[] outData) { if (compressionMethods == null || compressionMethods.Length == 0) - throw new IndexOutOfRangeException("CompressionMethods are null or empty"); + throw new ArgumentOutOfRangeException(nameof(compressionMethods), "CompressionMethods are null or empty"); - var compressionMethod = compressionMethods[CompressionMethodIndex - 1]; // -1 because we dont have 'NAME_None' in the array - Stream compressionStream = compressionMethod.ToLower() switch + string compressionMethod = compressionMethods[CompressionMethodIndex - 1]; // -1 because we dont have 'NAME_None' in the array + int bytesRead = 0; + for (int i = 0; i < CompressionBlocks.Length; i++) { - "zlib" => new ZlibStream(stream, CompressionMode.Decompress, true), - "gzip" => new GZipStream(stream, CompressionMode.Decompress, true), - _ => throw new NotImplementedException($"Decompression not yet implemented ({compressionMethod})") - }; - compressionStream.Read(outData, 0, outData.Length); - compressionStream.Dispose(); + stream.Position = Offset + CompressionBlocks[i].CompressedStart; + int uncompressedSize = (int)Math.Min(CompressionBlockSize, outData.Length - bytesRead); + + byte[] blockBbuffer; + if (Encrypted) + { + blockBbuffer = new byte[BinaryHelper.Align(CompressionBlocks[i].Size, AESDecryptor.BLOCK_SIZE)]; + stream.Read(blockBbuffer, 0, blockBbuffer.Length); + blockBbuffer = AESDecryptor.DecryptAES(blockBbuffer, key); + } + else + { + blockBbuffer = new byte[CompressionBlocks[i].Size]; + stream.Read(blockBbuffer, 0, blockBbuffer.Length); + } + + using var blockMs = new MemoryStream(blockBbuffer, false); + using Stream compressionStream = compressionMethod switch + { + "Zlib" => new ZlibStream(blockMs, CompressionMode.Decompress), + "Gzip" => new GZipStream(blockMs, CompressionMode.Decompress), + _ => throw new NotImplementedException($"Decompression not yet implemented ({compressionMethod})") + }; + + bytesRead += compressionStream.Read(outData, bytesRead, uncompressedSize); + } } public static long GetSize(EPakVersion version, uint CompressionMethodIndex = 0, uint CompressionBlocksCount = 0) diff --git a/FModel/Properties/Resources.ru-RU.resx b/FModel/Properties/Resources.ru-RU.resx index 36592803..b1612cce 100644 --- a/FModel/Properties/Resources.ru-RU.resx +++ b/FModel/Properties/Resources.ru-RU.resx @@ -346,7 +346,7 @@ Немецкий - Здравсвтуйте + Здравствуйте Помощь diff --git a/FModel/Properties/Settings.Designer.cs b/FModel/Properties/Settings.Designer.cs index 3ec55159..103e43dd 100644 --- a/FModel/Properties/Settings.Designer.cs +++ b/FModel/Properties/Settings.Designer.cs @@ -227,6 +227,18 @@ namespace FModel.Properties { } } + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0.5")] + public string AudioPlayerVolume { + get { + return ((string)(this["AudioPlayerVolume"])); + } + set { + this["AudioPlayerVolume"] = value; + } + } + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] diff --git a/FModel/Properties/Settings.settings b/FModel/Properties/Settings.settings index e1871c4f..27ff1761 100644 --- a/FModel/Properties/Settings.settings +++ b/FModel/Properties/Settings.settings @@ -53,6 +53,9 @@ + + 0.5 + False diff --git a/FModel/Theme/Style.xaml b/FModel/Theme/Style.xaml index dfb6e2ce..62ce0ef5 100644 --- a/FModel/Theme/Style.xaml +++ b/FModel/Theme/Style.xaml @@ -1172,12 +1172,12 @@ - + - + @@ -1211,7 +1211,6 @@ -