Decompiled source of AudioOverlapFix v1.2.0

plugins/AudioOverlapFix/AudioOverlapFix.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("AudioOverlapFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AudioOverlapFix")]
[assembly: AssemblyTitle("AudioOverlapFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 AudioOverlapFix
{
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("AudioOverlapFix");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "AudioOverlapFix".Length + 1);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Gorakh.AudioOverlapFix", "AudioOverlapFix", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.AudioOverlapFix";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "AudioOverlapFix";

		public const string PluginVersion = "1.2.0";

		internal static ConfigEntry<float> DuplicateSoundCooldown;

		internal static ConfigEntry<bool> ExcludeMithrixPizzaSound;

		private static readonly HashSet<TimeStampedSoundEvent> _trackedSoundEvents = new HashSet<TimeStampedSoundEvent>(TimeStampedSoundEvent.EventIDComparer);

		internal static Main Instance { get; private set; }

		private void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = this;
			DuplicateSoundCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Sound Cooldown", 0f, new ConfigDescription("How many seconds to keep track of sounds and prevent it from playing again. Set to 0 to only prevent duplicate sounds within the same frame", (AcceptableValueBase)null, Array.Empty<object>()));
			ExcludeMithrixPizzaSound = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Exclude Mithrix Pizza Attack", true, new ConfigDescription("Excludes Mithrix's pizza attack sound from the mod. The sound was seemingly designed with overlap in mind and will be very low volume if this is turned off.", (AcceptableValueBase)null, Array.Empty<object>()));
			if (RiskOfOptionsCompat.Active)
			{
				RiskOfOptionsCompat.Init();
			}
			SoundEnginePatcher.OverridePostEvent += SoundEnginePatcher_OverridePostEvent;
			SoundEventLibrary.Init();
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
		}

		private void LateUpdate()
		{
			if (DuplicateSoundCooldown != null)
			{
				float soundCooldown = DuplicateSoundCooldown.Value;
				_trackedSoundEvents.RemoveWhere((TimeStampedSoundEvent evnt) => evnt.TimeSince > soundCooldown);
			}
		}

		private void OnDestroy()
		{
			SoundEnginePatcher.OverridePostEvent -= SoundEnginePatcher_OverridePostEvent;
			_trackedSoundEvents.Clear();
		}

		private static bool excludeSound(uint eventID)
		{
			if (SoundEventLibrary.IsInitialized && ExcludeMithrixPizzaSound.Value && eventID == SoundEventLibrary.Play_moonBrother_blueWall_explode)
			{
				return true;
			}
			return false;
		}

		private static bool tryPlaySound(uint eventID)
		{
			if (!excludeSound(eventID))
			{
				return _trackedSoundEvents.Add(new TimeStampedSoundEvent(eventID, Time.unscaledTime));
			}
			return true;
		}

		private static void SoundEnginePatcher_OverridePostEvent(uint eventID, ref bool post)
		{
			if (post && !tryPlaySound(eventID))
			{
				post = false;
			}
		}
	}
	internal static class RiskOfOptionsCompat
	{
		public static bool Active => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		public static void Init()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			ModSettingsManager.SetModDescription("Mod options for Audio Overlap Fix", "Gorakh.AudioOverlapFix", "Audio Overlap Fix");
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(Main.DuplicateSoundCooldown, new StepSliderConfig
			{
				formatString = "{0:F2}s",
				min = 0f,
				max = 2f,
				increment = 0.01f
			}), "Gorakh.AudioOverlapFix", "Audio Overlap Fix");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Main.ExcludeMithrixPizzaSound, new CheckBoxConfig()), "Gorakh.AudioOverlapFix", "Audio Overlap Fix");
			FileInfo fileInfo = findPluginIconFile();
			if (fileInfo == null || !fileInfo.Exists)
			{
				return;
			}
			using FileStream fileStream = fileInfo.OpenRead();
			byte[] array = new byte[fileStream.Length];
			try
			{
				fileStream.Read(array, 0, array.Length);
			}
			catch (Exception arg)
			{
				Log.Error($"Exception reading icon file {fileInfo.FullName}: {arg}", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\RiskOfOptionsCompat.cs", "Init", 46);
				return;
			}
			Texture2D val = new Texture2D(1, 1);
			if (ImageConversion.LoadImage(val, array))
			{
				ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), Vector2.zero), "Gorakh.AudioOverlapFix", "Audio Overlap Fix");
			}
		}

		private static FileInfo findPluginIconFile()
		{
			try
			{
				return findPluginFileRecursive(new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)Main.Instance).Info.Location)));
			}
			catch (SecurityException arg)
			{
				Log.Error($"Unable to find icon file. Encountered Exception: {arg}", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\RiskOfOptionsCompat.cs", "findPluginIconFile", 74);
				return null;
			}
			static FileInfo findPluginFileRecursive(DirectoryInfo directory)
			{
				if (directory == null || !directory.Exists)
				{
					return null;
				}
				return directory.EnumerateFiles("icon.png", SearchOption.TopDirectoryOnly).FirstOrDefault() ?? findPluginFileRecursive(directory.Parent);
			}
		}
	}
	public static class SoundEnginePatcher
	{
		public delegate void OverridePostEventDelegate(uint eventID, ref bool post);

		private static bool _hasAppliedPatches;

		private static event OverridePostEventDelegate _overridePostEvent;

		public static event OverridePostEventDelegate OverridePostEvent
		{
			add
			{
				_overridePostEvent += value;
				tryApplyPatches();
			}
			remove
			{
				_overridePostEvent -= value;
			}
		}

		private static bool shouldPostEvent(uint eventID)
		{
			bool post = true;
			SoundEnginePatcher._overridePostEvent?.Invoke(eventID, ref post);
			return post;
		}

		private static bool shouldPostEvent(string eventName)
		{
			return shouldPostEvent(AkSoundEngine.GetIDFromString(eventName));
		}

		private static uint tryPostEvent(bool shouldPost, uint playingID)
		{
			if (!shouldPost && playingID != 0)
			{
				AkSoundEngine.StopPlayingID(playingID);
			}
			return playingID;
		}

		private static void tryApplyPatches()
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_065b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
			if (_hasAppliedPatches)
			{
				return;
			}
			MethodInfo methodInfo = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent(0u, (GameObject)null, 0u, (EventCallback)null, (object)null, 0u, (AkExternalSourceInfoArray)null, 0u)));
			if ((object)methodInfo != null)
			{
				new Hook((MethodBase)methodInfo, (Delegate)(Func<Func<uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint>, uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint>)((Func<uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint> orig, uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources, uint in_PlayingID) => tryPostEvent(shouldPostEvent(in_eventID), orig(in_eventID, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie, in_cExternals, in_pExternalSources, in_PlayingID))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources, uint in_PlayingID)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 72);
			}
			MethodInfo methodInfo2 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent(0u, (GameObject)null, 0u, (EventCallback)null, (object)null, 0u, (AkExternalSourceInfoArray)null)));
			if ((object)methodInfo2 != null)
			{
				new Hook((MethodBase)methodInfo2, (Delegate)(Func<Func<uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint>, uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint>)((Func<uint, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint> orig, uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources) => tryPostEvent(shouldPostEvent(in_eventID), orig(in_eventID, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie, in_cExternals, in_pExternalSources))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 89);
			}
			MethodInfo methodInfo3 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent(0u, (GameObject)null, 0u, (EventCallback)null, (object)null)));
			if ((object)methodInfo3 != null)
			{
				new Hook((MethodBase)methodInfo3, (Delegate)(Func<Func<uint, GameObject, uint, EventCallback, object, uint>, uint, GameObject, uint, EventCallback, object, uint>)((Func<uint, GameObject, uint, EventCallback, object, uint> orig, uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie) => tryPostEvent(shouldPostEvent(in_eventID), orig(in_eventID, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(uint in_eventID, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 106);
			}
			MethodInfo methodInfo4 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent(0u, (GameObject)null)));
			if ((object)methodInfo4 != null)
			{
				new Hook((MethodBase)methodInfo4, (Delegate)(Func<Func<uint, GameObject, uint>, uint, GameObject, uint>)((Func<uint, GameObject, uint> orig, uint in_eventID, GameObject in_gameObjectID) => tryPostEvent(shouldPostEvent(in_eventID), orig(in_eventID, in_gameObjectID))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(uint in_eventID, GameObject in_gameObjectID)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 123);
			}
			MethodInfo methodInfo5 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent((string)null, (GameObject)null, 0u, (EventCallback)null, (object)null, 0u, (AkExternalSourceInfoArray)null, 0u)));
			if ((object)methodInfo5 != null)
			{
				new Hook((MethodBase)methodInfo5, (Delegate)(Func<Func<string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint>, string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint>)((Func<string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint, uint> orig, string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources, uint in_PlayingID) => tryPostEvent(shouldPostEvent(in_pszEventName), orig(in_pszEventName, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie, in_cExternals, in_pExternalSources, in_PlayingID))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources, uint in_PlayingID)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 140);
			}
			MethodInfo methodInfo6 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent((string)null, (GameObject)null, 0u, (EventCallback)null, (object)null, 0u, (AkExternalSourceInfoArray)null)));
			if ((object)methodInfo6 != null)
			{
				new Hook((MethodBase)methodInfo6, (Delegate)(Func<Func<string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint>, string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint>)((Func<string, GameObject, uint, EventCallback, object, uint, AkExternalSourceInfoArray, uint> orig, string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources) => tryPostEvent(shouldPostEvent(in_pszEventName), orig(in_pszEventName, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie, in_cExternals, in_pExternalSources))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie, uint in_cExternals, AkExternalSourceInfoArray in_pExternalSources, uint in_PlayingID)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 157);
			}
			MethodInfo methodInfo7 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent((string)null, (GameObject)null, 0u, (EventCallback)null, (object)null)));
			if ((object)methodInfo7 != null)
			{
				new Hook((MethodBase)methodInfo7, (Delegate)(Func<Func<string, GameObject, uint, EventCallback, object, uint>, string, GameObject, uint, EventCallback, object, uint>)((Func<string, GameObject, uint, EventCallback, object, uint> orig, string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie) => tryPostEvent(shouldPostEvent(in_pszEventName), orig(in_pszEventName, in_gameObjectID, in_uFlags, in_pfnCallback, in_pCookie))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(string in_pszEventName, GameObject in_gameObjectID, uint in_uFlags, AkCallbackManager.EventCallback in_pfnCallback, object in_pCookie)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 174);
			}
			MethodInfo methodInfo8 = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostEvent((string)null, (GameObject)null)));
			if ((object)methodInfo8 != null)
			{
				new Hook((MethodBase)methodInfo8, (Delegate)(Func<Func<string, GameObject, uint>, string, GameObject, uint>)((Func<string, GameObject, uint> orig, string in_pszEventName, GameObject in_gameObjectID) => tryPostEvent(shouldPostEvent(in_pszEventName), orig(in_pszEventName, in_gameObjectID))));
			}
			else
			{
				Log.Warning("Unable to find AkSoundEngine method: static uint PostEvent(string in_pszEventName, GameObject in_gameObjectID)", "X:\\Git\\RoR2\\AudioOverlapFix\\AudioOverlapFix\\SoundEnginePatcher.cs", "tryApplyPatches", 191);
			}
			_hasAppliedPatches = true;
		}
	}
	public static class SoundEventLibrary
	{
		public static bool IsInitialized { get; private set; }

		public static uint Play_moonBrother_blueWall_explode { get; private set; }

		public static void Init()
		{
			if (AkSoundEngine.IsInitialized())
			{
				setupEventIDs();
			}
			else
			{
				RoR2Application.onUpdate += update;
			}
			static void update()
			{
				if (AkSoundEngine.IsInitialized())
				{
					setupEventIDs();
					RoR2Application.onUpdate -= update;
				}
			}
		}

		private static void setupEventIDs()
		{
			IsInitialized = true;
			Play_moonBrother_blueWall_explode = AkSoundEngine.GetIDFromString("Play_moonBrother_blueWall_explode");
		}
	}
	public readonly struct TimeStampedSoundEvent
	{
		private sealed class _EventIDComparer : IEqualityComparer<TimeStampedSoundEvent>
		{
			public bool Equals(TimeStampedSoundEvent x, TimeStampedSoundEvent y)
			{
				return x.EventID == y.EventID;
			}

			public int GetHashCode(TimeStampedSoundEvent obj)
			{
				uint eventID = obj.EventID;
				return eventID.GetHashCode();
			}
		}

		public readonly uint EventID;

		public readonly float TimeStamp;

		public static readonly IEqualityComparer<TimeStampedSoundEvent> EventIDComparer = new _EventIDComparer();

		public float TimeSince => Time.unscaledTime - TimeStamp;

		public TimeStampedSoundEvent(uint EventID, float TimeStamp)
		{
			this.EventID = EventID;
			this.TimeStamp = TimeStamp;
		}
	}
}