Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of R2API Sound v1.0.3
plugins/R2API.Sound/R2API.Sound.dll
Decompiled a year 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 { } }