diff --git a/FModel/PakReader/BnkReader.cs b/FModel/PakReader/WwiseReader.cs similarity index 87% rename from FModel/PakReader/BnkReader.cs rename to FModel/PakReader/WwiseReader.cs index 539bec20..5bc3b85f 100644 --- a/FModel/PakReader/BnkReader.cs +++ b/FModel/PakReader/WwiseReader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace FModel.PakReader { @@ -11,23 +12,28 @@ namespace FModel.PakReader /// STIDSection holds the .wem files name in a dictionary where the key is the .wem file id from DATASection /// i see no use (for FModel) in other sections atm /// - public class BnkReader + public class WwiseReader { + private const uint _AKPK_ID = 0x4B504B41; private const uint _BKHD_ID = 0x44484B42; + private const uint _INIT_ID = 0x54494E49; private const uint _DIDX_ID = 0x58444944; private const uint _DATA_ID = 0x41544144; private const uint _HIRC_ID = 0x43524948; private const uint _STID_ID = 0x44495453; private const uint _STMG_ID = 0x474D5453; + private const uint _ENVS_ID = 0x53564E45; + private const uint _PLAT_ID = 0x54414C50; public Dictionary AudioFiles; - public BnkReader(BinaryReader reader) + public WwiseReader(BinaryReader reader) { DIDXSection didxSection = null; DATASection dataSection = null; HIRCSection hircSection = null; STIDSection stidSection = null; - STMGSection stmgSection = null; + //STMGSection stmgSection = null; + PLATSection platSection = null; AudioFiles = new Dictionary(); while (reader.BaseStream.Position < reader.BaseStream.Length) @@ -37,9 +43,13 @@ namespace FModel.PakReader long Position = reader.BaseStream.Position; switch (SectionIdentifier) { + case _AKPK_ID: + break; case _BKHD_ID: BKHDSection _ = new BKHDSection(reader); break; + case _INIT_ID: + break; case _DIDX_ID: didxSection = new DIDXSection(reader, Position + SectionLength); break; @@ -53,11 +63,22 @@ namespace FModel.PakReader stidSection = new STIDSection(reader); break; case _STMG_ID: - stmgSection = new STMGSection(reader); + //stmgSection = new STMGSection(reader); //broken + break; + case _ENVS_ID: + break; + case _PLAT_ID: + platSection = new PLATSection(reader); break; } - reader.BaseStream.Seek(Position + SectionLength, SeekOrigin.Begin); + if (reader.BaseStream.Position != Position + SectionLength) + { +#if DEBUG + System.Diagnostics.Debug.WriteLine($" Didn't read 0x{SectionIdentifier:X} correctly (at {reader.BaseStream.Position}, should be {Position + SectionLength})"); +#endif + reader.BaseStream.Seek(Position + SectionLength, SeekOrigin.Begin); + } } if (didxSection != null && dataSection != null && didxSection.WemFilesRef.Count == dataSection.WemFiles.Count) @@ -71,6 +92,7 @@ namespace FModel.PakReader AudioFiles[key] = dataSection.WemFiles[i]; } } + // valorant event sound uses the HIRCSection but i don't understand how to get the actual audio atm } public class BKHDSection @@ -219,7 +241,7 @@ namespace FModel.PakReader VolumeThreshold = reader.ReadSingle(); MaxVoiceInstances = reader.ReadUInt16(); StateGroupNumber = reader.ReadUInt32(); - StateGroups = new StateGroupObject[Convert.ToInt32(StateGroups)]; + StateGroups = new StateGroupObject[Convert.ToInt32(StateGroupNumber)]; for (int i = 0; i < StateGroups.Length; i++) { StateGroups[i] = new StateGroupObject(reader); @@ -318,5 +340,16 @@ namespace FModel.PakReader } } } + + public class PLATSection + { + public string Platform; + + public PLATSection(BinaryReader reader) + { + uint length = reader.ReadUInt32(); + Platform = Encoding.UTF8.GetString(reader.ReadBytes(Convert.ToInt32(length)).AsSpan(..^1)); + } + } } } diff --git a/FModel/Properties/Resources.Designer.cs b/FModel/Properties/Resources.Designer.cs index 5f6c5535..afa1b393 100644 --- a/FModel/Properties/Resources.Designer.cs +++ b/FModel/Properties/Resources.Designer.cs @@ -744,7 +744,8 @@ namespace FModel.Properties { /// /// Recherche une chaîne localisée semblable à • Yanteh • Maiky ///• FunGames • HYPEX - ///• Alexander • Netu. + ///• Alexander • Netu + ///• SexyNutella. /// public static string DonatorsFDetails { get { diff --git a/FModel/Properties/Resources.resx b/FModel/Properties/Resources.resx index 333ea28b..ee11ff05 100644 --- a/FModel/Properties/Resources.resx +++ b/FModel/Properties/Resources.resx @@ -351,7 +351,8 @@ It's now the most used free software to leak on Fortnite. • Yanteh • Maiky • FunGames • HYPEX -• Alexander • Netu +• Alexander • Netu +• SexyNutella Do not translate diff --git a/FModel/Utils/Assets.cs b/FModel/Utils/Assets.cs index 76b01098..5b859cc5 100644 --- a/FModel/Utils/Assets.cs +++ b/FModel/Utils/Assets.cs @@ -140,20 +140,20 @@ namespace FModel.Utils break; } case ".ushaderbytecode": - case ".pck": break; case ".bnk": + case ".pck": { using var asset = GetMemoryStream(selected.PakEntry.PakFileName, mount + selected.PakEntry.GetPathWithoutExtension()); asset.Position = 0; - BnkReader bnk = new BnkReader(new BinaryReader(asset)); + WwiseReader bnk = new WwiseReader(new BinaryReader(asset)); Application.Current.Dispatcher.Invoke(delegate { DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Window]", $"Opening Audio Player for {selected.PakEntry.GetNameWithExtension()}"); if (!FWindows.IsWindowOpen(Properties.Resources.AudioPlayer)) - new AudioPlayer().LoadFiles(bnk.AudioFiles, selected.PakEntry.GetPathWithoutFile()); + new AudioPlayer().LoadFiles(bnk.AudioFiles, mount + selected.PakEntry.GetPathWithoutFile()); else - ((AudioPlayer)FWindows.GetOpenedWindow(Properties.Resources.AudioPlayer)).LoadFiles(bnk.AudioFiles, selected.PakEntry.GetPathWithoutFile()); + ((AudioPlayer)FWindows.GetOpenedWindow(Properties.Resources.AudioPlayer)).LoadFiles(bnk.AudioFiles, mount + selected.PakEntry.GetPathWithoutFile()); }); break; } diff --git a/FModel/ViewModels/ListBox/ListBoxViewModel.cs b/FModel/ViewModels/ListBox/ListBoxViewModel.cs index 9cfb3e01..6bbd4bef 100644 --- a/FModel/ViewModels/ListBox/ListBoxViewModel.cs +++ b/FModel/ViewModels/ListBox/ListBoxViewModel.cs @@ -1,14 +1,13 @@ using FModel.Utils; using PakReader.Parsers.Objects; using System; -using System.Collections.ObjectModel; namespace FModel.ViewModels.ListBox { static class ListBoxVm { public static ObservableSortedList gameFiles = new ObservableSortedList(); - public static ObservableCollection soundFiles = new ObservableCollection(); + public static ObservableSortedList soundFiles = new ObservableSortedList(); } public class ListBoxViewModel : PropertyChangedBase, IComparable @@ -37,8 +36,15 @@ namespace FModel.ViewModels.ListBox } } - public class ListBoxViewModel2 : PropertyChangedBase + public class ListBoxViewModel2 : PropertyChangedBase, IComparable { + public int CompareTo(object o) + { + ListBoxViewModel2 a = this; + ListBoxViewModel2 b = o as ListBoxViewModel2; + return string.CompareOrdinal(a.Content, b.Content); + } + private string _content; public string Content { diff --git a/FModel/Windows/SoundPlayer/AudioPlayer.xaml.cs b/FModel/Windows/SoundPlayer/AudioPlayer.xaml.cs index bb70d22b..0058e090 100644 --- a/FModel/Windows/SoundPlayer/AudioPlayer.xaml.cs +++ b/FModel/Windows/SoundPlayer/AudioPlayer.xaml.cs @@ -80,12 +80,8 @@ namespace FModel.Windows.SoundPlayer { Focus(); - if (files.Count > 5) - { - ListBoxVm.soundFiles.Clear(); - if (output.HasMedia) output.Stop(); - } - + ListBoxVm.soundFiles.Clear(); + if (output.HasMedia) output.Stop(); foreach (var (key, value) in files) { ListBoxVm.soundFiles.Add(new ListBoxViewModel2