Decompiled source of R2API Sound v1.0.3

plugins/R2API.Sound/R2API.Sound.dll

Decompiled 4 months ago
using 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
	{
	}
}