Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of R2API Sound v1.0.3
plugins/R2API.Sound/R2API.Sound.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AK.Wwise; using BepInEx; using BepInEx.Logging; using HG; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.RoR2; using R2API.AutoVersionGen; using R2API.ContentManagement; using R2API.Utils; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("R2API.Sound")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3+4ab123e8fb22d95bcc11c94c9804307ec130fa2c")] [assembly: AssemblyProduct("R2API.Sound")] [assembly: AssemblyTitle("R2API.Sound")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace R2API { [AutoVersion] public static class SoundAPI { public static class SoundBanks { internal class Bank { private static uint _bankIteration; internal IntPtr? BankDataPtr; internal byte[] BankData; internal GCHandle? Memory; internal uint Size; internal uint PublicID; internal uint BankID; internal Bank(byte[] bankData) { BankData = bankData; Size = (uint)bankData.Length; PublicID = _bankIteration++; } internal Bank(nint bankPtr, uint size) { BankDataPtr = bankPtr; Size = size; PublicID = _bankIteration++; } internal bool Load() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 IntPtr valueOrDefault = BankDataPtr.GetValueOrDefault(); if (!BankDataPtr.HasValue) { GCHandle? gCHandle = (Memory = GCHandle.Alloc(BankData, GCHandleType.Pinned)); valueOrDefault = gCHandle.Value.AddrOfPinnedObject(); BankDataPtr = valueOrDefault; } AKRESULT val = AkSoundEngine.LoadBankMemoryView(BankDataPtr.Value, Size, ref BankID); if ((int)val != 1) { Debug.LogError((object)("WwiseUnity: AkMemBankLoader: bank loading failed with result " + ((object)(AKRESULT)(ref val)).ToString())); return false; } BankData = null; return true; } internal AKRESULT UnLoad() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) AKRESULT val = AkSoundEngine.UnloadBank(BankID, BankDataPtr.Value); if ((int)val != 1) { Debug.LogError((object)("Failed to unload bank " + PublicID + ": " + ((object)(AKRESULT)(ref val)).ToString())); return val; } Memory?.Free(); Memory = null; soundBanks.Remove(this); return val; } } internal static bool Loaded = false; internal static List<Bank> soundBanks = new List<Bank>(); public static uint Add(byte[]? bank) { SetHooks(); Bank bank2 = new Bank(bank); if (Loaded) { if (bank2.Load()) { soundBanks.Add(bank2); } } else { soundBanks.Add(bank2); } return bank2.PublicID; } public static uint Add(string? path) { SetHooks(); return Add(File.ReadAllBytes(path)); } public static uint Add(string resourceName, Assembly owningAssembly) { SetHooks(); nint num; int num2; (num, num2) = EmbeddedResources.GetEmbeddedResource(resourceName, owningAssembly); if (num == 0 || num2 == 0) { throw new ArgumentException(resourceName + " did not return a valid resource", "resourceName"); } Bank bank = new Bank(num, (uint)num2); if (Loaded) { if (bank.Load()) { soundBanks.Add(bank); } } else { soundBanks.Add(bank); } return bank.PublicID; } public static AKRESULT Remove(uint ID) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) SetHooks(); return soundBanks.Find((Bank bank) => bank.PublicID == ID).UnLoad(); } } public static class Music { public class CustomMusicData { public BepInPlugin BepInPlugin; public string PlayMusicSystemEventName; public string BanksFolderPath; public string InitBankName; public string SoundBankName; public Dictionary<SceneDef, IEnumerable<MainAndBossTracks>> SceneDefToTracks; internal uint _loadedInitBankId; internal uint _loadedSoundBankId; public uint LoadedInitBankId { get { return _loadedInitBankId; } private set { _loadedInitBankId = value; } } public uint LoadedSoundBankId { get { return _loadedSoundBankId; } private set { _loadedSoundBankId = value; } } } public struct MainAndBossTracks { public MusicTrackDef MainTrack; public MusicTrackDef BossTrack; public MainAndBossTracks(MusicTrackDef mainTrack, MusicTrackDef bossTrack) { SetHooks(); MainTrack = mainTrack; BossTrack = bossTrack; } } public class CustomMusicTrackDef : MusicTrackDef { public struct CustomState { public uint GroupId; public uint StateId; } public List<CustomState> CustomStates; public string SoundBankName; public override void Preload() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) SetHooks(); if (!string.IsNullOrWhiteSpace(SoundBankName)) { uint num = default(uint); AkSoundEngine.LoadBank(SoundBankName, ref num); } } public override void Play() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) SetHooks(); ((MusicTrackDef)this).Preload(); foreach (CustomState customState in CustomStates) { AkSoundEngine.SetState(customState.GroupId, customState.StateId); } } public override void Stop() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) SetHooks(); foreach (CustomState customState in CustomStates) { AkSoundEngine.SetState(customState.GroupId, 0u); } } } [CompilerGenerated] private static class <>O { public static hook_StartIntroMusic <0>__EnableCustomMusicSystems; public static Action<SceneDef> <1>__OnSceneChangeReplaceMusic; public static hook_UpdateState <2>__IsGameMusicBankInUse; public static Manipulator <3>__PauseMusicIfGameMusicBankNotInUse; public static Func<bool, bool> <4>__PauseMusicIfGameMusicBankNotInUse; } private const string GameMusicBankName = "Music"; private const string GameInitBankName = "Init"; private const string GameEventNamePlayMusicSystem = "Play_Music_System"; private static readonly List<CustomMusicData> CustomMusicDatas = new List<CustomMusicData>(); private static readonly Dictionary<string, BepInPlugin> EventNameToBepinPlugin = new Dictionary<string, BepInPlugin>(); private static readonly HashSet<string> PlayMusicSystemEventNames = new HashSet<string>(); private static readonly Dictionary<SceneDef, MainAndBossTracks> SceneDefToOriginalTracks = new Dictionary<SceneDef, MainAndBossTracks>(); private static readonly Dictionary<SceneDef, List<MainAndBossTracks>> SceneDefToTracks = new Dictionary<SceneDef, List<MainAndBossTracks>>(); private static bool GameMusicBankInUse; private static Hook AddCustomMusicDatasHook; private static bool _hooksEnabled = false; private static bool IsVanillaMusicTrack(MusicTrackDef self) { if (Object.op_Implicit((Object)(object)self) && self.soundBank != null) { return ((BaseType)self.soundBank).Name == "Music"; } return false; } internal static void SetHooks() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown if (!_hooksEnabled) { AddCustomMusicDatasHook = new Hook((MethodBase)Reflection.GetMethodCached(typeof(AkSoundEngineInitialization), "InitializeSoundEngine"), Reflection.GetMethodCached(typeof(Music), "AddCustomMusicDatas")); object obj = <>O.<0>__EnableCustomMusicSystems; if (obj == null) { hook_StartIntroMusic val = EnableCustomMusicSystems; <>O.<0>__EnableCustomMusicSystems = val; obj = (object)val; } MusicController.StartIntroMusic += (hook_StartIntroMusic)obj; SceneCatalog.onMostRecentSceneDefChanged += OnSceneChangeReplaceMusic; object obj2 = <>O.<2>__IsGameMusicBankInUse; if (obj2 == null) { hook_UpdateState val2 = IsGameMusicBankInUse; <>O.<2>__IsGameMusicBankInUse = val2; obj2 = (object)val2; } MusicController.UpdateState += (hook_UpdateState)obj2; object obj3 = <>O.<3>__PauseMusicIfGameMusicBankNotInUse; if (obj3 == null) { Manipulator val3 = PauseMusicIfGameMusicBankNotInUse; <>O.<3>__PauseMusicIfGameMusicBankNotInUse = val3; obj3 = (object)val3; } MusicController.LateUpdate += (Manipulator)obj3; _hooksEnabled = true; } } internal static void UnsetHooks() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown AddCustomMusicDatasHook.Dispose(); object obj = <>O.<0>__EnableCustomMusicSystems; if (obj == null) { hook_StartIntroMusic val = EnableCustomMusicSystems; <>O.<0>__EnableCustomMusicSystems = val; obj = (object)val; } MusicController.StartIntroMusic -= (hook_StartIntroMusic)obj; SceneCatalog.onMostRecentSceneDefChanged -= OnSceneChangeReplaceMusic; object obj2 = <>O.<2>__IsGameMusicBankInUse; if (obj2 == null) { hook_UpdateState val2 = IsGameMusicBankInUse; <>O.<2>__IsGameMusicBankInUse = val2; obj2 = (object)val2; } MusicController.UpdateState -= (hook_UpdateState)obj2; object obj3 = <>O.<3>__PauseMusicIfGameMusicBankNotInUse; if (obj3 == null) { Manipulator val3 = PauseMusicIfGameMusicBankNotInUse; <>O.<3>__PauseMusicIfGameMusicBankNotInUse = val3; obj3 = (object)val3; } MusicController.LateUpdate -= (Manipulator)obj3; _hooksEnabled = false; } private static void IsGameMusicBankInUse(orig_UpdateState orig, MusicController self) { orig.Invoke(self); if (Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.currentTrack)) { GameMusicBankInUse = IsVanillaMusicTrack(self.currentTrack); } } private static bool AddCustomMusicDatas(Func<AkSoundEngineInitialization, bool> orig, AkSoundEngineInitialization self) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) bool result = orig(self); foreach (CustomMusicData customMusicData in CustomMusicDatas) { AKRESULT val = AkSoundEngine.AddBasePath(customMusicData.BanksFolderPath); if ((int)val != 1) { SoundPlugin.Logger.LogError((object)("Error adding base path : " + customMusicData.BanksFolderPath + ". " + $"Error code : {val}")); continue; } val = AkSoundEngine.LoadBank(customMusicData.InitBankName, ref customMusicData._loadedInitBankId); if ((int)val != 1) { SoundPlugin.Logger.LogError((object)("Error loading init bank : " + customMusicData.InitBankName + ". " + $"Error code : {val}")); continue; } val = AkSoundEngine.LoadBank(customMusicData.SoundBankName, ref customMusicData._loadedSoundBankId); if ((int)val != 1) { SoundPlugin.Logger.LogError((object)("Error loading sound bank : " + customMusicData.SoundBankName + ". " + $"Error code : {val}")); } else { AddCustomTracksToDictionary(customMusicData); } } return result; } private static void AddCustomTracksToDictionary(CustomMusicData data) { if (data.SceneDefToTracks == null) { return; } foreach (var (key, collection) in data.SceneDefToTracks) { if (SceneDefToTracks.TryGetValue(key, out List<MainAndBossTracks> value)) { value.AddRange(collection); continue; } List<MainAndBossTracks> list = new List<MainAndBossTracks>(); list.AddRange(collection); SceneDefToTracks.Add(key, list); } } private static void EnableCustomMusicSystems(orig_StartIntroMusic orig, MusicController self) { orig.Invoke(self); foreach (string playMusicSystemEventName in PlayMusicSystemEventNames) { AkSoundEngine.PostEvent(playMusicSystemEventName, ((Component)self).gameObject); } } private static void OnSceneChangeReplaceMusic(SceneDef sceneDef) { if (Object.op_Implicit((Object)(object)sceneDef)) { ReplaceSceneMusicWithCustomTracks(sceneDef); } } private static void ReplaceSceneMusicWithCustomTracks(SceneDef sceneDef) { if (!SceneDefToTracks.TryGetValue(sceneDef, out List<MainAndBossTracks> value)) { return; } if (!SceneDefToOriginalTracks.ContainsKey(sceneDef)) { MainAndBossTracks value2 = new MainAndBossTracks(sceneDef.mainTrack, sceneDef.bossTrack); SceneDefToOriginalTracks.Add(sceneDef, value2); } if (value.Count > 0) { MainAndBossTracks mainAndBossTracks = value[RoR2Application.rng.RangeInt(0, value.Count)]; if (Object.op_Implicit((Object)(object)mainAndBossTracks.MainTrack)) { sceneDef.mainTrack = mainAndBossTracks.MainTrack; } if (Object.op_Implicit((Object)(object)mainAndBossTracks.BossTrack)) { sceneDef.bossTrack = mainAndBossTracks.BossTrack; } } } private static void PauseMusicIfGameMusicBankNotInUse(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = default(int); val.GotoNext(new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref num) }); val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)PauseMusicIfGameMusicBankNotInUse); static bool PauseMusicIfGameMusicBankNotInUse(bool shouldPauseMusic) { if (shouldPauseMusic) { return shouldPauseMusic; } return !GameMusicBankInUse; } } public static bool Add(CustomMusicData data) { SetHooks(); if (data.BepInPlugin == null) { throw new ArgumentNullException("CustomMusicData.BepInPlugin"); } if (data.InitBankName == "Init") { SoundPlugin.Logger.LogError((object)"Error loading custom init bank. Called the same as the game Init Bank. The name must be different."); return false; } if (string.IsNullOrWhiteSpace(data.InitBankName)) { SoundPlugin.Logger.LogError((object)"Error loading custom init bank. Should not be empty."); return false; } if (data.PlayMusicSystemEventName == "Play_Music_System") { SoundPlugin.Logger.LogError((object)"Error adding the play music system event name. Called the same as the game play music system event name. The name must be different."); return false; } if (string.IsNullOrWhiteSpace(data.PlayMusicSystemEventName)) { SoundPlugin.Logger.LogError((object)"Error adding the play music system event name. Should not be empty."); return false; } if (!PlayMusicSystemEventNames.Add(data.PlayMusicSystemEventName)) { SoundPlugin.Logger.LogError((object)("Error adding playMusicSystemEventName : " + data.PlayMusicSystemEventName + ". Already in use by " + EventNameToBepinPlugin[data.PlayMusicSystemEventName].GUID + ".")); return false; } EventNameToBepinPlugin.Add(data.PlayMusicSystemEventName, data.BepInPlugin); CustomMusicDatas.Add(data); return true; } public static bool Remove(CustomMusicData data) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) SetHooks(); AKRESULT val = AkSoundEngine.UnloadBank(data.LoadedSoundBankId, IntPtr.Zero); if ((int)val != 1) { SoundPlugin.Logger.LogError((object)("Error unloading sound bank : " + data.SoundBankName + ". " + $"Error code : {val}")); return false; } val = AkSoundEngine.UnloadBank(data.LoadedInitBankId, IntPtr.Zero); if ((int)val != 1) { SoundPlugin.Logger.LogError((object)("Error unloading init bank : " + data.InitBankName + ". " + $"Error code : {val}")); return false; } PlayMusicSystemEventNames.Remove(data.PlayMusicSystemEventName); EventNameToBepinPlugin.Remove(data.PlayMusicSystemEventName); RemoveTracksFromThatBankFromTheScenes(data); return CustomMusicDatas.Remove(data); } private static void RemoveTracksFromThatBankFromTheScenes(CustomMusicData data) { if (data.SceneDefToTracks == null) { return; } foreach (KeyValuePair<SceneDef, IEnumerable<MainAndBossTracks>> sceneDefToTrack in data.SceneDefToTracks) { sceneDefToTrack.Deconstruct(out var key, out var value); SceneDef key2 = key; IEnumerable<MainAndBossTracks> enumerable = value; List<MainAndBossTracks> list = SceneDefToTracks[key2]; foreach (MainAndBossTracks item in enumerable) { list.Remove(item); RestoreOriginalTracksIfNeeded(item); } } } private static void RestoreOriginalTracksIfNeeded(MainAndBossTracks customTracks) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) Enumerator<SceneDef> enumerator = SceneCatalog.allSceneDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { SceneDef current = enumerator.Current; if ((Object)(object)current.mainTrack == (Object)(object)customTracks.MainTrack) { current.mainTrack = SceneDefToOriginalTracks[current].MainTrack; } if ((Object)(object)current.bossTrack == (Object)(object)customTracks.BossTrack) { current.bossTrack = SceneDefToOriginalTracks[current].BossTrack; } } } finally { ((IDisposable)enumerator).Dispose(); } } } public const string PluginGUID = "com.bepis.r2api.sound"; public const string PluginName = "R2API.Sound"; private static Hook AddBanksAfterEngineInitHook; private static readonly List<NetworkSoundEventDef> NetworkSoundEventDefs = new List<NetworkSoundEventDef>(); private static bool _hooksEnabled = false; public const string PluginVersion = "1.0.3"; [Obsolete("All submodules are automatically loaded and this property is now unused")] public static bool Loaded => true; internal static void SetHooks() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (!_hooksEnabled && !Application.isBatchMode) { _hooksEnabled = true; string[] files = Directory.GetFiles(Paths.PluginPath, "*.sound", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { SoundBanks.Add(files[i]); } _hooksEnabled = false; AddBanksAfterEngineInitHook = new Hook((MethodBase)Reflection.GetMethodCached(typeof(AkSoundEngineInitialization), "InitializeSoundEngine"), Reflection.GetMethodCached(typeof(SoundAPI), "AddBanksAfterEngineInit")); Music.SetHooks(); _hooksEnabled = true; } } internal static void UnsetHooks() { AddBanksAfterEngineInitHook.Dispose(); Music.UnsetHooks(); _hooksEnabled = false; } private static bool AddBanksAfterEngineInit(Func<AkSoundEngineInitialization, bool> orig, AkSoundEngineInitialization self) { bool result = orig(self); LoadBanks(); return result; } private static void LoadBanks() { List<SoundBanks.Bank> list = new List<SoundBanks.Bank>(); bool flag = false; foreach (SoundBanks.Bank soundBank in SoundBanks.soundBanks) { if (!soundBank.Load()) { list.Add(soundBank); } else { flag = true; } } foreach (SoundBanks.Bank item in list) { SoundBanks.soundBanks.Remove(item); } SoundBanks.Loaded = true; if (flag) { SoundPlugin.Logger.LogInfo((object)"Custom sound banks loaded."); } } [Obsolete("AddNetworkedSoundEvent is obsolete, please add your NetworkSoundEventDefs via R2API.ContentManagement.ContentAdditionHelpers.AddNetworkSoundEventDef()")] public static bool AddNetworkedSoundEvent(NetworkSoundEventDef? networkSoundEventDef) { NetworkSoundEventDef networkSoundEventDef2 = networkSoundEventDef; SetHooks(); if (!CatalogBlockers.GetAvailability<NetworkSoundEventDef>()) { SoundPlugin.Logger.LogError((object)("Too late ! Tried to add network sound event: " + networkSoundEventDef2.eventName + " after the NetworkSoundEventCatalog has initalized!")); return false; } if (NetworkSoundEventDefs.Contains(networkSoundEventDef2) || NetworkSoundEventDefs.Any((NetworkSoundEventDef n) => n.eventName == networkSoundEventDef2.eventName)) { SoundPlugin.Logger.LogError((object)("NetworkSoundEventDef or NetworkSoundEventDef with EventName: " + networkSoundEventDef2.eventName + " already exists in the catalog! Consider changing your event name to avoid the collision. Aborting!")); return false; } NetworkSoundEventDefs.Add(networkSoundEventDef2); R2APIContentManager.HandleContentAddition(Assembly.GetCallingAssembly(), (Object)(object)networkSoundEventDef2); return true; } [Obsolete("AddNetworkedSoundEvent is obsolete, please add your NetworkSoundEventDefs via R2API.ContentManagement.ContentAdditionHelpers.AddNetworkSoundEventDef()")] public static bool AddNetworkedSoundEvent(string eventName) { string eventName2 = eventName; SetHooks(); if (!CatalogBlockers.GetAvailability<NetworkSoundEventDef>()) { SoundPlugin.Logger.LogError((object)("Too late! Tried to add network sound event: " + eventName2 + " after the NetworkSoundEventCatalog has initalized!")); return false; } NetworkSoundEventDef val = ScriptableObject.CreateInstance<NetworkSoundEventDef>(); val.eventName = eventName2; if (NetworkSoundEventDefs.Any((NetworkSoundEventDef n) => n.eventName == eventName2)) { SoundPlugin.Logger.LogError((object)("NetworkSoundEventDef with Event Name: " + eventName2 + " already exists in the catalog! Consider changing your event name to avoid the collision. Aborting!")); return false; } NetworkSoundEventDefs.Add(val); R2APIContentManager.HandleContentAddition(Assembly.GetCallingAssembly(), (Object)(object)val); return true; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.bepis.r2api.sound", "R2API.Sound", "1.0.3")] public sealed class SoundPlugin : BaseUnityPlugin { internal static ManualLogSource Logger { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; } private void OnEnable() { SoundAPI.SetHooks(); } private void OnDisable() { SoundAPI.UnsetHooks(); } } } namespace R2API.AutoVersionGen { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] internal class AutoVersionAttribute : Attribute { } }