Decompiled source of Dynamic Audio Balancing v1.0.1

Sirdoggy.DynamicAudioBalancing.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMOD.Studio;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Sirdoggy.DynamicAudioBalancing.Common;
using Sirdoggy.DynamicAudioBalancing.Extensions;
using Sirdoggy.DynamicAudioBalancing.Patches;
using Sirdoggy.DynamicAudioBalancing.Patches.Firearms;
using Sirdoggy.DynamicAudioBalancing.Patches.Tags;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Sirdoggy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Makes sustained gunfire less deafening + adds volume controls for different in-game sounds")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Sirdoggy.DynamicAudioBalancing")]
[assembly: AssemblyTitle("Dynamic_Audio_Balancing")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing
{
	[BepInProcess("h3vr.exe")]
	[BepInPlugin("Sirdoggy.DynamicAudioBalancing", "Dynamic_Audio_Balancing", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log = null;

		internal static ExceptionCatcher ExceptionCatcher = null;

		private static float _masterVolumeMultiplier = 1f;

		public const string Id = "Sirdoggy.DynamicAudioBalancing";

		public static string Name => "Dynamic_Audio_Balancing";

		public static string Version => "1.0.1";

		public static void LogVerbose(object data)
		{
			if (PluginConfig.VerboseLogs.Value)
			{
				Log.LogDebug(data);
			}
		}

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			ExceptionCatcher = new ExceptionCatcher(Log);
			PluginConfig.Initialize(((BaseUnityPlugin)this).Config);
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(SoundManagerPatcher), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(FVRPooledAudioSourcePatcher), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
			});
		}

		private IEnumerator Start()
		{
			UpdateMasterVolume();
			PluginConfig.MasterVolume.SettingChanged += delegate
			{
				UpdateMasterVolume();
			};
			yield return (object)new WaitForSecondsRealtime(3f);
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(InitialCreateChamberTagPatchers), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(InitialCreateChamberTagPatchers2), (string)null);
			}, delegate(Exception exception)
			{
				if (exception is TypeLoadException)
				{
					Log.LogDebug((object)exception.Message);
				}
				else
				{
					Log.LogError((object)exception);
				}
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(FVRFireArmChamberPatcher), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(FVRFireArmPatcher), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(AudioSourcePatcher), (string)null);
			});
			ExceptionCatcher.Run(delegate
			{
				Harmony.CreateAndPatchAll(typeof(MusicPatchers), (string)null);
			});
		}

		private static void UpdateMasterVolume()
		{
			_masterVolumeMultiplier = PluginConfig.MasterVolume.PercentToMultiplier();
			Log.LogInfo((object)$"Set master volume multiplier: {_masterVolumeMultiplier}");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FVRPlayerBody), "Update")]
		private static void Update_Postfix_ApplyMasterVolume()
		{
			AudioListener.volume *= _masterVolumeMultiplier;
		}
	}
	internal static class PluginConfig
	{
		public static ConfigEntry<float> MasterVolume;

		public static ConfigEntry<float> Music;

		public static ConfigEntry<float> GunshotsMain;

		public static ConfigEntry<float> GunshotsReverb;

		public static ConfigEntry<float> GunshotsMechanical;

		public static ConfigEntry<float> BulletCasings;

		public static ConfigEntry<float> PhysicsImpacts;

		public static ConfigEntry<float> SosigVoicelines;

		public static ConfigEntry<float> GunshotVolumePercentSemiAuto;

		public static ConfigEntry<float> GunshotVolumePercentSustainedFirst;

		public static ConfigEntry<float> GunshotVolumePercentSustainedSubsequent;

		public static ConfigEntry<float> ReverbVolumePercentSemiAuto;

		public static ConfigEntry<float> ReverbVolumePercentSustainedFirst;

		public static ConfigEntry<float> ReverbVolumePercentSustainedSubsequent;

		public static ConfigEntry<float> HammerHitVolumePercentSemiAuto;

		public static ConfigEntry<float> HammerHitVolumePercentSustainedFirst;

		public static ConfigEntry<float> HammerHitVolumePercentSustainedSubsequent;

		public static ConfigEntry<bool> VerboseLogs;

		public static ConfigEntry<float> DelayBetweenShotsCalculationMargin;

		private const string SectionBaselineVolumes = "Baseline Volumes";

		private const string SectionDynamicGunshotVolumes = "Dynamic Gunshot Volumes";

		private const string SectionDynamicReverbVolumes = "Dynamic Reverb Volumes";

		private const string SectionDynamicHammerHitVolumes = "Dynamic Hammer Hit Volumes";

		private const string SectionTesting = "Testing";

		public const float MaximumDelayMargin = 0.27f;

		public static void Initialize(ConfigFile configFile)
		{
			MasterVolume = configFile.Bind<float>("Baseline Volumes", "Master volume", 100f, "Baseline volume % for all sounds. Set value will be clamped between 0 and 200%.");
			Music = configFile.Bind<float>("Baseline Volumes", "Music", 100f, "Baseline volume % for music in T&H, Meat Fortress, and Return of the Rotwieners. Changes might require scene restart.");
			GunshotsMain = configFile.Bind<float>("Baseline Volumes", "Gunshots main", 100f, "Baseline volume % for all gunshot blasts.");
			GunshotsReverb = configFile.Bind<float>("Baseline Volumes", "Gunshots reverb", 100f, "Baseline volume % for all environment reverb after gunshots.");
			GunshotsMechanical = configFile.Bind<float>("Baseline Volumes", "Gunshots mechanical", 100f, "Baseline volume % for all mechanical sounds that accompany a gunshot. Doesn't affect manual weapon handling sounds.");
			BulletCasings = configFile.Bind<float>("Baseline Volumes", "Bullet casings", 100f, "Volume % for spent bullet casings impact sounds.");
			PhysicsImpacts = configFile.Bind<float>("Baseline Volumes", "Physics impacts", 100f, "Volume % for most physics impact sounds.");
			SosigVoicelines = configFile.Bind<float>("Baseline Volumes", "Sosig voicelines", 100f, "Volume % for most sosig voicelines.");
			GunshotVolumePercentSemiAuto = configFile.Bind<float>("Dynamic Gunshot Volumes", "Semi-auto", 100f, "Volume % for gunshots when in semi-auto mode. Also affects single shot guns. Dynamic volumes are cumulative with baseline volumes.");
			GunshotVolumePercentSustainedFirst = configFile.Bind<float>("Dynamic Gunshot Volumes", "Sustained first", 100f, "Volume % for the first gunshot when beginning full-auto or burst fire.");
			GunshotVolumePercentSustainedSubsequent = configFile.Bind<float>("Dynamic Gunshot Volumes", "Sustained subsequent", 60f, "Volume % for gunshots during sustained full-auto or burst fire.");
			ReverbVolumePercentSemiAuto = configFile.Bind<float>("Dynamic Reverb Volumes", "Semi-auto", 100f, "Volume % for gunshot reverb when in semi-auto mode. Also affects single shot guns.");
			ReverbVolumePercentSustainedFirst = configFile.Bind<float>("Dynamic Reverb Volumes", "Sustained first", 100f, "Volume % for gunshot reverb when beginning full-auto or burst fire.");
			ReverbVolumePercentSustainedSubsequent = configFile.Bind<float>("Dynamic Reverb Volumes", "Sustained subsequent", 70f, "Volume % for gunshot reverb during sustained full-auto or burst fire.");
			HammerHitVolumePercentSemiAuto = configFile.Bind<float>("Dynamic Hammer Hit Volumes", "Semi-auto", 100f, "Volume % for hammer hits when in semi-auto mode. Also affects single shot guns.");
			HammerHitVolumePercentSustainedFirst = configFile.Bind<float>("Dynamic Hammer Hit Volumes", "Sustained first", 125f, "Volume % for the first hammer hit when beginning full-auto or burst fire.");
			HammerHitVolumePercentSustainedSubsequent = configFile.Bind<float>("Dynamic Hammer Hit Volumes", "Sustained subsequent", 40f, "Volume % for hammer hits during sustained full-auto or burst fire.");
			VerboseLogs = configFile.Bind<bool>("Testing", "Enable verbose debug logs", false, "Extra logs that will noticeably spam the console.");
			DelayBetweenShotsCalculationMargin = configFile.Bind<float>("Testing", "Delay between shots calculation margin", 0.03f, "In seconds.");
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing.Patches
{
	[HarmonyPatch(typeof(AudioSource))]
	internal static class AudioSourcePatcher
	{
		private static readonly List<float> QueuedVolumeMultipliers = new List<float>();

		private static float _queuedTimestamp;

		public static void QueueVolumeMultiplier(float multiplier)
		{
			Plugin.LogVerbose(string.Format("[{0}] Queued new multiplier: x{1}", "AudioSourcePatcher", multiplier));
			QueuedVolumeMultipliers.Add(multiplier);
			_queuedTimestamp = Time.time;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Play", new Type[] { typeof(ulong) })]
		private static void Play_Prefix(AudioSource __instance)
		{
			ApplyQueuedMultiplier(__instance);
		}

		private static void ApplyQueuedMultiplier(AudioSource audioSource)
		{
			if (QueuedVolumeMultipliers.Count == 0)
			{
				return;
			}
			if (Time.time - _queuedTimestamp > 0.27f)
			{
				Plugin.LogVerbose("[AudioSourcePatcher] Queued multipliers expired, returning.");
				QueuedVolumeMultipliers.Clear();
				return;
			}
			float num = 1f;
			foreach (float queuedVolumeMultiplier in QueuedVolumeMultipliers)
			{
				num *= queuedVolumeMultiplier;
			}
			int count = QueuedVolumeMultipliers.Count;
			QueuedVolumeMultipliers.Clear();
			if (!((Object)(object)audioSource.clip == (Object)null))
			{
				Plugin.LogVerbose("[AudioSourcePatcher] Consuming queued multipliers. " + $"Multiplying volume of AudioClip '{((Object)audioSource.clip).name}' by x{num} " + $"({count} multipliers total)");
				audioSource.volume *= num;
			}
		}
	}
	[HarmonyPatch(typeof(FVRPooledAudioSource))]
	internal static class FVRPooledAudioSourcePatcher
	{
		[HarmonyPrefix]
		[HarmonyPatch("Play")]
		private static void Play_Prefix(FVRPooledAudioSource __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			AudioSourceTagAudioBalancing component = ((Component)__instance).GetComponent<AudioSourceTagAudioBalancing>();
			float? num = null;
			float? num2;
			if (component != null && component.Type.HasValue)
			{
				FVRPooledAudioType? type = component.Type;
				if (!type.HasValue)
				{
					goto IL_00c8;
				}
				FVRPooledAudioType valueOrDefault = type.GetValueOrDefault();
				if ((int)valueOrDefault <= 2)
				{
					if ((int)valueOrDefault != 1)
					{
						if ((int)valueOrDefault != 2)
						{
							goto IL_00c8;
						}
						num2 = PluginConfig.GunshotsReverb.PercentToMultiplier();
					}
					else
					{
						num2 = PluginConfig.GunshotsMain.PercentToMultiplier();
					}
				}
				else if ((int)valueOrDefault != 33)
				{
					if ((int)valueOrDefault != 40)
					{
						if ((int)valueOrDefault != 41)
						{
							goto IL_00c8;
						}
						num2 = PluginConfig.PhysicsImpacts.PercentToMultiplier();
					}
					else
					{
						num2 = PluginConfig.BulletCasings.PercentToMultiplier();
					}
				}
				else
				{
					num2 = PluginConfig.SosigVoicelines.PercentToMultiplier();
				}
				goto IL_00d4;
			}
			goto IL_00d7;
			IL_00c8:
			num2 = null;
			goto IL_00d4;
			IL_00d4:
			num = num2;
			goto IL_00d7;
			IL_00d7:
			if (!num.HasValue)
			{
				num = ((Object)__instance).name switch
				{
					"PooledSource_Casings" => PluginConfig.BulletCasings.PercentToMultiplier(), 
					"PooledSource_Casings(Clone)" => PluginConfig.BulletCasings.PercentToMultiplier(), 
					"PooledSource_Impacts" => PluginConfig.PhysicsImpacts.PercentToMultiplier(), 
					"PooledSource_Impacts(Clone)" => PluginConfig.PhysicsImpacts.PercentToMultiplier(), 
					"PooledSource_NPCBarks" => PluginConfig.PhysicsImpacts.PercentToMultiplier(), 
					"PooledSource_NPCBarks(Clone)" => PluginConfig.PhysicsImpacts.PercentToMultiplier(), 
					_ => null, 
				};
				if (num.HasValue)
				{
					Plugin.LogVerbose("Using baseline fallback for FVRPooledAudioSource '" + ((Object)__instance).name + "'");
				}
			}
			float num3 = num.GetValueOrDefault(1f);
			if (component != null && component.QueuedMultiplier.HasValue)
			{
				if (Time.time - component.QueuedMultiplierTimestamp > 0.27f)
				{
					Plugin.LogVerbose("[FVRPooledAudioSourcePatcher] Queued multiplier expired.");
				}
				else
				{
					float value = component.QueuedMultiplier.Value;
					Plugin.LogVerbose("[FVRPooledAudioSourcePatcher] Using queued " + $"multiplier (x{value}).");
					num3 *= value;
				}
				component.QueuedMultiplier = null;
			}
			Plugin.LogVerbose("[FVRPooledAudioSourcePatcher] Queuing AudioSource volume multiplier for " + $"FVRPooledAudioSource '{((Object)__instance).name}' (x{num3})");
			AudioSourcePatcher.QueueVolumeMultiplier(num3);
		}
	}
	internal static class MusicPatchers
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(FVRFMODController), "SetMasterVolume")]
		private static void SetMasterVolume_Postfix(float i, FVRFMODController __instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			float num = i * PluginConfig.Music.PercentToMultiplier();
			((Bus)(ref __instance.MasterBus)).setVolume(num);
			Plugin.LogVerbose($"Applied FVRFMODController music volume multiplier: {i} => {num}");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZosigMusicController), "SetMasterVolume")]
		private static void SetMasterVolume_Postfix(float i, ZosigMusicController __instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			float num = i * PluginConfig.Music.PercentToMultiplier();
			((Bus)(ref __instance.MasterBus)).setVolume(num);
			Plugin.LogVerbose($"Applied ZosigMusicController music volume multiplier: {i} => {num}");
		}
	}
	[HarmonyPatch(typeof(SM))]
	internal static class SoundManagerPatcher
	{
		[HarmonyPostfix]
		[HarmonyPatch("CreatePool")]
		private static void CreatePool_Postfix(FVRPooledAudioType type, AudioSourcePool? __result)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (__result?.SourceQueue_Disabled == null)
			{
				return;
			}
			Plugin.Log.LogDebug((object)string.Format("[{0}] New pool created for: {1}", "SoundManagerPatcher", type));
			foreach (FVRPooledAudioSource item in __result.SourceQueue_Disabled)
			{
				if (!((Object)(object)item == (Object)null))
				{
					AudioSourceTagAudioBalancing audioSourceTagAudioBalancing = ((Component)item).GetComponent<AudioSourceTagAudioBalancing>();
					if ((Object)(object)audioSourceTagAudioBalancing == (Object)null)
					{
						audioSourceTagAudioBalancing = ((Component)item).gameObject.AddComponent<AudioSourceTagAudioBalancing>();
						((Object)audioSourceTagAudioBalancing).hideFlags = (HideFlags)61;
					}
					audioSourceTagAudioBalancing.Type = type;
				}
			}
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing.Patches.Tags
{
	internal class AudioSourceTagAudioBalancing : MonoBehaviour
	{
		public FVRPooledAudioType? Type { get; set; }

		public float? QueuedMultiplier { get; set; }

		public float QueuedMultiplierTimestamp { get; set; }
	}
	internal class ChamberTagAudioBalancing : MonoBehaviour
	{
		public FVRFireArm? ParentFirearm { get; set; }

		public AttachableFirearm? ParentAttachableFirearm { get; set; }
	}
	internal enum RecordableEvent
	{
		DynamicGunshot,
		PreviousDynamicGunshot,
		SoundGunshot,
		SoundHammerHit,
		SoundBoltSlideBack,
		SoundBoltSlideForward,
		SoundMagazineEjectRound
	}
	internal static class RecordableEventExtensions
	{
		public static RecordableEvent? ToRecordableEventOrNull(this FirearmAudioEventType audioEventType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			if ((int)audioEventType <= 1)
			{
				if ((int)audioEventType == 0)
				{
					return RecordableEvent.SoundBoltSlideForward;
				}
				if ((int)audioEventType == 1)
				{
					return RecordableEvent.SoundBoltSlideBack;
				}
			}
			else
			{
				if ((int)audioEventType == 6)
				{
					return RecordableEvent.SoundHammerHit;
				}
				if ((int)audioEventType == 29)
				{
					return RecordableEvent.SoundMagazineEjectRound;
				}
				switch (audioEventType - 100)
				{
				case 0:
					return RecordableEvent.SoundGunshot;
				case 1:
					return RecordableEvent.SoundGunshot;
				case 2:
					return RecordableEvent.SoundGunshot;
				}
			}
			return null;
		}
	}
	internal class FirearmTagAudioBalancing : MonoBehaviour
	{
		private readonly Dictionary<RecordableEvent, float> _lastTimestampsInSequence = new Dictionary<RecordableEvent, float>
		{
			{
				RecordableEvent.DynamicGunshot,
				0f
			},
			{
				RecordableEvent.PreviousDynamicGunshot,
				0f
			},
			{
				RecordableEvent.SoundGunshot,
				0f
			},
			{
				RecordableEvent.SoundBoltSlideBack,
				0f
			},
			{
				RecordableEvent.SoundBoltSlideForward,
				0f
			},
			{
				RecordableEvent.SoundMagazineEjectRound,
				0f
			}
		};

		public float LastCalculatedDelayBetweenShots { get; private set; }

		public void RecordTimestampFor(RecordableEvent recordableEvent)
		{
			_lastTimestampsInSequence[recordableEvent] = Time.time;
		}

		public float GetTimeSinceLastTimestampOf(RecordableEvent recordableEvent)
		{
			return Time.time - _lastTimestampsInSequence[recordableEvent];
		}

		public void RecordDynamicGunshotTimestamp()
		{
			LastCalculatedDelayBetweenShots = CalculateDelay();
			_lastTimestampsInSequence[RecordableEvent.PreviousDynamicGunshot] = _lastTimestampsInSequence[RecordableEvent.DynamicGunshot];
			_lastTimestampsInSequence[RecordableEvent.DynamicGunshot] = Time.time;
		}

		public float CalculateDelayBetweenShots()
		{
			float num = CalculateDelay();
			if (PluginConfig.VerboseLogs.Value)
			{
				Plugin.Log.LogInfo((object)$"Calculated delay between shots: {num:N}s");
			}
			return num;
		}

		private float CalculateDelay()
		{
			float num = _lastTimestampsInSequence[RecordableEvent.DynamicGunshot];
			float num2 = _lastTimestampsInSequence[RecordableEvent.PreviousDynamicGunshot];
			if (num2 == 0f)
			{
				return 0.27f;
			}
			float num3 = num - num2 + PluginConfig.DelayBetweenShotsCalculationMargin.Value;
			if (!(num3 > 0.27f))
			{
				return num3;
			}
			return 0.27f;
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing.Patches.Firearms
{
	[HarmonyPriority(100)]
	[HarmonyPatch(typeof(FVRFireArmChamber))]
	internal static class FVRFireArmChamberPatcher
	{
		[HarmonyPostfix]
		[HarmonyPatch("Fire")]
		private static void Fire_Postfix(FVRFireArmChamber __instance, bool __result)
		{
			FVRFireArmChamber __instance2 = __instance;
			Plugin.ExceptionCatcher.Run(delegate
			{
				if (!__result)
				{
					Plugin.Log.LogDebug((object)"[FVRFireArmChamberPatcher] Chamber didn't fire, returning...");
				}
				else
				{
					FVRFireArm firearm = __instance2.Firearm;
					if ((Object)(object)firearm != (Object)null)
					{
						RetrieveFirearmTagAndRecordTimestamp((MonoBehaviour)(object)firearm);
					}
					else
					{
						ChamberTagAudioBalancing component = ((Component)__instance2).GetComponent<ChamberTagAudioBalancing>();
						if ((Object)(object)component == (Object)null)
						{
							throw new Exception("ChamberTag is null, can't save gunshot timestamp.");
						}
						if ((Object)(object)component.ParentFirearm != (Object)null)
						{
							RetrieveFirearmTagAndRecordTimestamp((MonoBehaviour)(object)component.ParentFirearm);
						}
						else
						{
							if (!((Object)(object)component.ParentAttachableFirearm != (Object)null))
							{
								throw new Exception("ChamberTag contains null references, can't save gunshot timestamp.");
							}
							RetrieveFirearmTagAndRecordTimestamp((MonoBehaviour)(object)component.ParentAttachableFirearm);
						}
					}
				}
			});
		}

		private static void RetrieveFirearmTagAndRecordTimestamp(MonoBehaviour firearm)
		{
			FirearmTagAudioBalancing component = ((Component)firearm).GetComponent<FirearmTagAudioBalancing>();
			if ((Object)(object)component == (Object)null)
			{
				throw new Exception("FirearmTag is null, can't save gunshot timestamp.");
			}
			component.RecordDynamicGunshotTimestamp();
		}
	}
	[HarmonyPriority(100)]
	internal static class FVRFireArmPatcher
	{
		private enum FireMode
		{
			SemiAuto,
			SustainedFirst,
			SustainedSubsequent
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FVRFireArm))]
		[HarmonyPatch("Awake")]
		private static void FVRFireArm_Awake_Postfix(FVRFireArm __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<FirearmTagAudioBalancing>() == (Object)null)
			{
				((Object)((Component)__instance).gameObject.AddComponent<FirearmTagAudioBalancing>()).hideFlags = (HideFlags)61;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(FVRFireArm))]
		[HarmonyPatch("PlayAudioEvent")]
		private static void PlayAudioEvent_Prefix(FVRFireArm __instance, FirearmAudioEventType eType, float pitchmod)
		{
			//IL_0007: 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)
			FVRFireArm __instance2 = __instance;
			Plugin.ExceptionCatcher.Run(delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				Plugin.LogVerbose($"Firearm AudioEvent: {eType}");
				if ((int)eType == 7)
				{
					AudioEvent val = __instance2.AudioClipSet?.Prefire;
					if (val != null)
					{
						List<AudioClip> clips = val.Clips;
						if (clips != null && clips.Count > 0)
						{
							AudioSourcePatcher.QueueVolumeMultiplier(PluginConfig.GunshotsMechanical.PercentToMultiplier());
							return;
						}
					}
				}
				RecordableEvent? recordableEvent = eType.ToRecordableEventOrNull();
				if (recordableEvent.HasValue)
				{
					FirearmTagAudioBalancing component = ((Component)__instance2).GetComponent<FirearmTagAudioBalancing>();
					if ((Object)(object)component == (Object)null)
					{
						throw new Exception("Firearm has no FirearmTag component.");
					}
					RecordableEvent value = recordableEvent.Value;
					if (__instance2.AudioClipSet?.TryGetAudioEventBy(eType) == null)
					{
						Plugin.LogVerbose($"Firearm has null clip set for '{value}', returning...");
					}
					else
					{
						FireMode fireMode = FireMode.SemiAuto;
						if (((MonoBehaviour)(object)__instance2).IsInFullAutoMode() || ((MonoBehaviour)(object)__instance2).IsInBurstMode())
						{
							RecordableEvent recordableEvent2 = ((value != RecordableEvent.SoundHammerHit) ? value : RecordableEvent.DynamicGunshot);
							fireMode = ((component.GetTimeSinceLastTimestampOf(recordableEvent2) > component.LastCalculatedDelayBetweenShots) ? FireMode.SustainedFirst : FireMode.SustainedSubsequent);
						}
						if (value == RecordableEvent.SoundHammerHit)
						{
							HandleHammerHit(fireMode);
						}
						else
						{
							HandleGenericRelatedToGunshot(component, __instance2, value, fireMode);
						}
					}
				}
			});
		}

		private static void HandleHammerHit(FireMode fireMode)
		{
			float num = PluginConfig.GunshotsMechanical.PercentToMultiplier();
			float num2 = fireMode switch
			{
				FireMode.SemiAuto => PluginConfig.HammerHitVolumePercentSemiAuto.PercentToMultiplier(), 
				FireMode.SustainedFirst => PluginConfig.HammerHitVolumePercentSustainedFirst.PercentToMultiplier(), 
				FireMode.SustainedSubsequent => PluginConfig.HammerHitVolumePercentSustainedSubsequent.PercentToMultiplier(), 
				_ => throw new NotSupportedException("Invalid enum value."), 
			};
			Plugin.LogVerbose($"Handling '{fireMode}' HammerHit");
			AudioSourcePatcher.QueueVolumeMultiplier(num * num2);
		}

		private static void HandleGenericRelatedToGunshot(FirearmTagAudioBalancing firearmTag, FVRFireArm firearm, RecordableEvent recordableSoundEvent, FireMode fireMode)
		{
			if (firearmTag.GetTimeSinceLastTimestampOf(RecordableEvent.DynamicGunshot) > firearmTag.CalculateDelayBetweenShots())
			{
				Plugin.LogVerbose($"Not handling {recordableSoundEvent}, because too much time passed since " + "last gunshot.");
				return;
			}
			Plugin.LogVerbose($"Handling '{fireMode}' {recordableSoundEvent}");
			ApplyDynamicAudioForGunshot(fireMode, recordableSoundEvent, firearm);
			firearmTag.RecordTimestampFor(recordableSoundEvent);
		}

		private static void ApplyDynamicAudioForGunshot(FireMode mode, RecordableEvent recordableSoundEvent, FVRFireArm firearm)
		{
			float num = mode switch
			{
				FireMode.SemiAuto => PluginConfig.GunshotVolumePercentSemiAuto.PercentToMultiplier(), 
				FireMode.SustainedFirst => PluginConfig.GunshotVolumePercentSustainedFirst.PercentToMultiplier(), 
				FireMode.SustainedSubsequent => PluginConfig.GunshotVolumePercentSustainedSubsequent.PercentToMultiplier(), 
				_ => throw new NotSupportedException("Invalid enum value."), 
			};
			if (recordableSoundEvent != RecordableEvent.SoundGunshot)
			{
				num *= PluginConfig.GunshotsMechanical.PercentToMultiplier();
				AudioSourcePatcher.QueueVolumeMultiplier(num);
				return;
			}
			AudioSourcePatcher.QueueVolumeMultiplier(num);
			float num2 = mode switch
			{
				FireMode.SemiAuto => PluginConfig.ReverbVolumePercentSemiAuto.PercentToMultiplier(), 
				FireMode.SustainedFirst => PluginConfig.ReverbVolumePercentSustainedFirst.PercentToMultiplier(), 
				FireMode.SustainedSubsequent => PluginConfig.ReverbVolumePercentSustainedSubsequent.PercentToMultiplier(), 
				_ => throw new NotSupportedException("Invalid enum value."), 
			};
			AudioSourcePool pool_tail = firearm.m_pool_tail;
			if (pool_tail == null)
			{
				Plugin.Log.LogDebug((object)"(!) m_pool_tail is null.");
				return;
			}
			Queue<FVRPooledAudioSource> sourceQueue_Disabled = pool_tail.SourceQueue_Disabled;
			FVRPooledAudioSource val = (FVRPooledAudioSource)((sourceQueue_Disabled != null && sourceQueue_Disabled.Count > 0) ? ((object)pool_tail.SourceQueue_Disabled.Peek()) : ((object)pool_tail.ActiveSources?.FirstOrDefault()));
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogDebug((object)"(!) Failed to find a free FVRPooledAudioSource in PooledSourcePool.");
				return;
			}
			AudioSourceTagAudioBalancing audioSourceTagAudioBalancing = ((Component)val).GetComponent<AudioSourceTagAudioBalancing>();
			if ((Object)(object)audioSourceTagAudioBalancing == (Object)null)
			{
				audioSourceTagAudioBalancing = ((Component)val).gameObject.AddComponent<AudioSourceTagAudioBalancing>();
				((Object)audioSourceTagAudioBalancing).hideFlags = (HideFlags)61;
			}
			Plugin.LogVerbose($"Saving tail volume multiplier in AudioSourceTag: x{num2}");
			audioSourceTagAudioBalancing.QueuedMultiplier = num2;
			audioSourceTagAudioBalancing.QueuedMultiplierTimestamp = Time.time;
		}
	}
	internal static class InitialCreateChamberTagPatchers
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(BarrageBox))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(BarrageBox __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BoltActionRifle))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(BoltActionRifle __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BreakActionWeapon))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(BreakActionWeapon __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ClosedBoltWeapon))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(ClosedBoltWeapon __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Derringer))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(Derringer __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Flaregun))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(Flaregun __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LeverActionFirearm))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(LeverActionFirearm __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Minigun))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(Minigun __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(OpenBoltReceiver))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(OpenBoltReceiver __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Revolver))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(Revolver __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RevolvingShotgun))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(RevolvingShotgun __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SingleActionRevolver))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(SingleActionRevolver __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(TubeFedShotgun))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(TubeFedShotgun __instance)
		{
			AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AttachableClosedBoltWeapon))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(AttachableClosedBoltWeapon __instance)
		{
			AssignTagToChambers(new List<FVRFireArmChamber>(1) { __instance.Chamber }, null, (AttachableFirearm?)(object)__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AttachableTubeFed))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(AttachableTubeFed __instance)
		{
			AssignTagToChambers(new List<FVRFireArmChamber>(1) { __instance.Chamber }, null, (AttachableFirearm?)(object)__instance);
		}

		internal static void AssignTagToChambers(List<FVRFireArmChamber>? chambers, FVRFireArm? firearm, AttachableFirearm? attachableFirearm)
		{
			List<FVRFireArmChamber> chambers2 = chambers;
			FVRFireArm firearm2 = firearm;
			AttachableFirearm attachableFirearm2 = attachableFirearm;
			Plugin.ExceptionCatcher.Run(delegate
			{
				if (chambers2 == null)
				{
					throw new Exception("Chambers list is null.");
				}
				if (chambers2.Count == 0)
				{
					throw new Exception("Chambers list is empty.");
				}
				if ((Object)(object)firearm2 == (Object)null && (Object)(object)attachableFirearm2 == (Object)null)
				{
					throw new Exception("Both firearm and attachableFirearm are null.");
				}
				ManualLogSource log = Plugin.Log;
				string[] obj = new string[6]
				{
					"[InitialCreateChamberTagPatchers] Creating ChamberTag ",
					$"for {chambers2.Count} chambers",
					"\n- parent firearm: ",
					null,
					null,
					null
				};
				FVRFireArm obj2 = firearm2;
				obj[3] = ((obj2 != null) ? ((Object)obj2).name : null) ?? "null";
				obj[4] = "\n- parent attachableFirearm: ";
				AttachableFirearm obj3 = attachableFirearm2;
				obj[5] = ((obj3 != null) ? ((Object)obj3).name : null) ?? "null";
				log.LogDebug((object)string.Concat(obj));
				foreach (FVRFireArmChamber item in chambers2)
				{
					ChamberTagAudioBalancing chamberTagAudioBalancing = ((Component)item).GetComponent<ChamberTagAudioBalancing>();
					if ((Object)(object)chamberTagAudioBalancing == (Object)null)
					{
						chamberTagAudioBalancing = ((Component)item).gameObject.AddComponent<ChamberTagAudioBalancing>();
						((Object)chamberTagAudioBalancing).hideFlags = (HideFlags)61;
					}
					chamberTagAudioBalancing.ParentFirearm = firearm2;
					chamberTagAudioBalancing.ParentAttachableFirearm = attachableFirearm2;
				}
			});
		}
	}
	internal static class InitialCreateChamberTagPatchers2
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(FBlockPistol))]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(FBlockPistol __instance)
		{
			InitialCreateChamberTagPatchers.AssignTagToChambers(((FVRFireArm)__instance).GetChambers(), (FVRFireArm?)(object)__instance, null);
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing.Extensions
{
	internal static class ArrayExtensions
	{
		public static T? GetElementAtOrNull<T>(this T[] array, int index)
		{
			if (array == null)
			{
				return default(T);
			}
			if (index < 0 || index >= array.Length)
			{
				return default(T);
			}
			return array[index];
		}
	}
	internal static class FVRAudioExtensions
	{
		public static AudioEvent? TryGetAudioEventBy(this FVRFirearmAudioSet clipSet, FirearmAudioEventType audioEventType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected I4, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected I4, but got Unknown
			switch ((int)audioEventType)
			{
			default:
				switch (audioEventType - 100)
				{
				case 0:
					return clipSet.Shots_Main;
				case 1:
					return clipSet.Shots_Suppressed;
				case 2:
					return clipSet.Shots_LowPressure;
				}
				break;
			case 8:
				return clipSet.BoltRelease;
			case 1:
				return clipSet.BoltSlideBack;
			case 3:
				return clipSet.BoltSlideBackHeld;
			case 4:
				return clipSet.BoltSlideBackLocked;
			case 0:
				return clipSet.BoltSlideForward;
			case 2:
				return clipSet.BoltSlideForwardHeld;
			case 17:
				return clipSet.BreachOpen;
			case 18:
				return clipSet.BreachClose;
			case 5:
				return clipSet.CatchOnSear;
			case 42:
				return clipSet.ChamberManual;
			case 15:
				return clipSet.FireSelector;
			case 6:
				return clipSet.HammerHit;
			case 10:
				return clipSet.HandleBack;
			case 41:
				return clipSet.HandleBackEmpty;
			case 11:
				return clipSet.HandleForward;
			case 40:
				return clipSet.HandleForwardEmpty;
			case 12:
				return clipSet.HandleUp;
			case 13:
				return clipSet.HandleDown;
			case 9:
				return clipSet.HandleGrab;
			case 21:
				return clipSet.MagazineOut;
			case 20:
				return clipSet.MagazineIn;
			case 28:
				return clipSet.MagazineInsertRound;
			case 29:
				return clipSet.MagazineEjectRound;
			case 7:
				return clipSet.Prefire;
			case 14:
				return clipSet.Safety;
			case 16:
				return clipSet.TriggerReset;
			case 22:
				return clipSet.TopCoverRelease;
			case 23:
				return clipSet.TopCoverUp;
			case 24:
				return clipSet.TopCoverDown;
			case 30:
				return clipSet.StockOpen;
			case 31:
				return clipSet.StockClosed;
			case 32:
				return clipSet.BipodOpen;
			case 33:
				return clipSet.BipodClosed;
			case 50:
				return clipSet.BeltGrab;
			case 51:
				return clipSet.BeltRelease;
			case 52:
				return clipSet.BeltSeat;
			case 53:
				return clipSet.BeltSettle;
			case 19:
			case 25:
			case 26:
			case 27:
			case 34:
			case 35:
			case 36:
			case 37:
			case 38:
			case 39:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 49:
				break;
			}
			return null;
		}
	}
	internal static class FVRFirearmExtensions
	{
		public static bool IsInFullAutoMode(this MonoBehaviour firearm)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Invalid comparison between Unknown and I4
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Invalid comparison between Unknown and I4
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Invalid comparison between Unknown and I4
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Invalid comparison between Unknown and I4
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Invalid comparison between Unknown and I4
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Invalid comparison between Unknown and I4
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Invalid comparison between Unknown and I4
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Invalid comparison between Unknown and I4
			ClosedBoltWeapon val = (ClosedBoltWeapon)(object)((firearm is ClosedBoltWeapon) ? firearm : null);
			if (val == null)
			{
				OpenBoltReceiver val2 = (OpenBoltReceiver)(object)((firearm is OpenBoltReceiver) ? firearm : null);
				if (val2 == null)
				{
					AttachableClosedBoltWeapon val3 = (AttachableClosedBoltWeapon)(object)((firearm is AttachableClosedBoltWeapon) ? firearm : null);
					if (val3 == null)
					{
						Handgun val4 = (Handgun)(object)((firearm is Handgun) ? firearm : null);
						if (val4 == null)
						{
							RevolvingShotgun val5 = (RevolvingShotgun)(object)((firearm is RevolvingShotgun) ? firearm : null);
							if (val5 == null)
							{
								if (!(firearm is BarrageBox))
								{
									if (!(firearm is FlameThrower))
									{
										if (firearm is Minigun)
										{
											return true;
										}
										return false;
									}
									return true;
								}
								return true;
							}
							FireSelectorMode[] fireSelector_Modes = val5.FireSelector_Modes;
							return fireSelector_Modes != null && (int)(fireSelector_Modes.GetElementAtOrNull(val5.m_fireSelectorMode)?.ModeType).GetValueOrDefault() == 2;
						}
						FireSelectorMode[] fireSelectorModes = val4.FireSelectorModes;
						return fireSelectorModes != null && (int)(fireSelectorModes.GetElementAtOrNull(val4.m_fireSelectorMode)?.ModeType).GetValueOrDefault() == 2;
					}
					FireSelectorModeType? val6 = val3.FireSelector_Modes?.GetElementAtOrNull(val3.m_fireSelectorMode)?.ModeType;
					FireSelectorModeType? val7 = val3.FireSelector_Modes2?.GetElementAtOrNull(val3.m_fireSelectorMode)?.ModeType;
					return (int)val6.GetValueOrDefault() == 3 || (int)val7.GetValueOrDefault() == 3;
				}
				FireSelectorModeType? val8 = val2.FireSelector_Modes?.GetElementAtOrNull(val2.m_fireSelectorMode)?.ModeType;
				FireSelectorModeType? val9 = val2.FireSelector_Modes2?.GetElementAtOrNull(val2.m_fireSelectorMode)?.ModeType;
				return (int)val8.GetValueOrDefault() == 2 || (int)val9.GetValueOrDefault() == 2;
			}
			FireSelectorModeType? val10 = val.FireSelector_Modes?.GetElementAtOrNull(val.m_fireSelectorMode)?.ModeType;
			FireSelectorModeType? val11 = val.FireSelector_Modes2?.GetElementAtOrNull(val.m_fireSelectorMode)?.ModeType;
			return (int)val10.GetValueOrDefault() == 3 || (int)val11.GetValueOrDefault() == 3;
		}

		public static bool IsInBurstMode(this MonoBehaviour firearm)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Invalid comparison between Unknown and I4
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Invalid comparison between Unknown and I4
			//IL_0266: 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)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Invalid comparison between Unknown and I4
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Invalid comparison between Unknown and I4
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Invalid comparison between Unknown and I4
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Invalid comparison between Unknown and I4
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Invalid comparison between Unknown and I4
			ClosedBoltWeapon val = (ClosedBoltWeapon)(object)((firearm is ClosedBoltWeapon) ? firearm : null);
			if (val == null)
			{
				OpenBoltReceiver val2 = (OpenBoltReceiver)(object)((firearm is OpenBoltReceiver) ? firearm : null);
				if (val2 == null)
				{
					AttachableClosedBoltWeapon val3 = (AttachableClosedBoltWeapon)(object)((firearm is AttachableClosedBoltWeapon) ? firearm : null);
					if (val3 == null)
					{
						Handgun val4 = (Handgun)(object)((firearm is Handgun) ? firearm : null);
						if (val4 == null)
						{
							if (firearm is RevolvingShotgun)
							{
								return false;
							}
							return false;
						}
						FireSelectorMode[] fireSelectorModes = val4.FireSelectorModes;
						return fireSelectorModes != null && (int)(fireSelectorModes.GetElementAtOrNull(val4.m_fireSelectorMode)?.ModeType).GetValueOrDefault() == 4;
					}
					FireSelectorModeType? val5 = val3.FireSelector_Modes?.GetElementAtOrNull(val3.m_fireSelectorMode)?.ModeType;
					FireSelectorModeType? val6 = val3.FireSelector_Modes2?.GetElementAtOrNull(val3.m_fireSelectorMode)?.ModeType;
					return (int)val5.GetValueOrDefault() == 2 || (int)val6.GetValueOrDefault() == 2;
				}
				FireSelectorModeType? val7 = val2.FireSelector_Modes?.GetElementAtOrNull(val2.m_fireSelectorMode)?.ModeType;
				FireSelectorModeType? val8 = val2.FireSelector_Modes2?.GetElementAtOrNull(val2.m_fireSelectorMode)?.ModeType;
				return (int)val7.GetValueOrDefault() == 4 || (int)val8.GetValueOrDefault() == 4 || (int)val7.GetValueOrDefault() == 3 || (int)val7.GetValueOrDefault() == 3;
			}
			FireSelectorModeType? val9 = val.FireSelector_Modes?.GetElementAtOrNull(val.m_fireSelectorMode)?.ModeType;
			FireSelectorModeType? val10 = val.FireSelector_Modes2?.GetElementAtOrNull(val.m_fireSelectorMode)?.ModeType;
			return (int)val9.GetValueOrDefault() == 2 || (int)val9.GetValueOrDefault() == 2 || (int)val10.GetValueOrDefault() == 4 || (int)val10.GetValueOrDefault() == 4;
		}
	}
}
namespace Sirdoggy.DynamicAudioBalancing.Common
{
	internal static class ConfigEntryExtensions
	{
		public static float PercentToMultiplier(this ConfigEntry<float> configEntry)
		{
			float num = configEntry.Value / 100f;
			if (!(num > 2f))
			{
				if (num < 0f)
				{
					return 0f;
				}
				return num;
			}
			return 2f;
		}
	}
	internal class ExceptionCatcher
	{
		private readonly ManualLogSource _log;

		public ExceptionCatcher(ManualLogSource log)
		{
			_log = log;
		}

		public void Run(Action action, Action<Exception>? customHandler = null)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				if (customHandler == null)
				{
					_log.LogError((object)ex);
				}
				else
				{
					customHandler(ex);
				}
			}
		}
	}
}