Decompiled source of ReactorNoiseControl v0.1.0

BepInEx/plugins/ReactorNoiseControl/ReactorNoiseControl.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 ReactorNoiseControl
{
	[BepInPlugin("ReactorNoiseControl", "Reactor Noise Control", "0.1")]
	public class ReactorNoiseControlPlugin : BasePlugin
	{
		internal static ManualLogSource LogSource;

		internal const string ModTag = "[ReactorNoiseControl]";

		internal static ConfigEntry<bool> CfgEnabled;

		internal static ConfigEntry<int> CfgTotalVolume;

		internal static ConfigEntry<bool> CfgInterceptMute;

		internal static ConfigFile ConfigFile;

		public override void Load()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			LogSource = ((BasePlugin)this).Log;
			ConfigFile = ((BasePlugin)this).Config;
			CfgEnabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable reactor audio control.");
			CfgTotalVolume = ((BasePlugin)this).Config.Bind<int>("Volume", "TotalVolume", 100, "Reactor emitter output volume, 0-100. Requires InterceptMute = false.");
			CfgInterceptMute = ((BasePlugin)this).Config.Bind<bool>("Mute", "InterceptMute", true, "Cancel reactor power loop and transitions before Wwise.");
			try
			{
				((BasePlugin)this).Config.Save();
			}
			catch
			{
			}
			try
			{
				new Harmony("ReactorNoiseControl").PatchAll();
				ClassInjector.RegisterTypeInIl2Cpp<ReactorNoiseControlBehaviour>();
				GameObject val = new GameObject("ReactorNoiseControl")
				{
					hideFlags = (HideFlags)61
				};
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<ReactorNoiseControlBehaviour>();
				LogSource.LogInfo((object)"[ReactorNoiseControl] loaded v0.1");
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[ReactorNoiseControl] init failed: " + ex));
			}
		}
	}
	internal static class ReactorNoiseControlState
	{
		internal const uint PowerLoop = 2054029125u;

		internal const uint Transition1To2 = 351743855u;

		internal const uint Transition1To3 = 3643524096u;

		internal const uint Transition2To1 = 2692002185u;

		internal const uint Transition2To3 = 357317039u;

		internal const uint Transition3To2 = 1010911017u;

		internal static readonly List<CellSoundPlayer> Players = new List<CellSoundPlayer>();

		internal static bool VolumeDirty;

		internal static bool IsReactorEvent(uint id)
		{
			if (id != 2054029125 && id != 351743855 && id != 3643524096u && id != 2692002185u && id != 357317039)
			{
				return id == 1010911017;
			}
			return true;
		}

		internal static bool IsPowerLoop(uint id)
		{
			return id == 2054029125;
		}

		internal static bool ShouldIntercept(uint id)
		{
			if (ReactorNoiseControlPlugin.CfgEnabled.Value && ReactorNoiseControlPlugin.CfgInterceptMute.Value)
			{
				return IsReactorEvent(id);
			}
			return false;
		}

		internal static void Track(CellSoundPlayer player, uint eventID)
		{
			if (player == null || !IsPowerLoop(eventID))
			{
				return;
			}
			try
			{
				Players.Add(player);
			}
			catch
			{
			}
		}

		internal static void StopTrackedPlayers()
		{
			for (int num = Players.Count - 1; num >= 0; num--)
			{
				CellSoundPlayer val = Players[num];
				if (val != null)
				{
					try
					{
						val.Stop();
					}
					catch
					{
					}
				}
			}
			Players.Clear();
		}

		internal static void SetTotalVolume(float volume, ulong listenerId)
		{
			if (listenerId == 0L || Players.Count == 0)
			{
				return;
			}
			for (int num = Players.Count - 1; num >= 0; num--)
			{
				CellSoundPlayer val = Players[num];
				if (val == null)
				{
					Players.RemoveAt(num);
				}
				else
				{
					try
					{
						AkSoundEnginePINVOKE.CSharp_SetGameObjectOutputBusVolume(val.ID, listenerId, volume);
					}
					catch
					{
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(CellSound), "Post", new Type[] { typeof(uint) })]
	internal static class CellSoundPostUInt
	{
		[HarmonyPriority(800)]
		[HarmonyPrefix]
		private static bool Prefix(uint eventID)
		{
			return !ReactorNoiseControlState.ShouldIntercept(eventID);
		}
	}
	[HarmonyPatch(typeof(CellSound), "Post", new Type[]
	{
		typeof(uint),
		typeof(Vector3)
	})]
	internal static class CellSoundPostUIntVector
	{
		[HarmonyPriority(800)]
		[HarmonyPrefix]
		private static bool Prefix(uint eventID)
		{
			return !ReactorNoiseControlState.ShouldIntercept(eventID);
		}
	}
	[HarmonyPatch(typeof(CellSoundPlayer), "Post", new Type[]
	{
		typeof(uint),
		typeof(Vector3)
	})]
	internal static class PlayerPostUIntVector
	{
		[HarmonyPriority(800)]
		[HarmonyPrefix]
		private static bool Prefix(uint eventID)
		{
			return !ReactorNoiseControlState.ShouldIntercept(eventID);
		}

		[HarmonyPostfix]
		private static void Postfix(CellSoundPlayer __instance, uint eventID)
		{
			ReactorNoiseControlState.Track(__instance, eventID);
		}
	}
	[HarmonyPatch(typeof(CellSoundPlayer), "Post", new Type[]
	{
		typeof(uint),
		typeof(bool)
	})]
	internal static class PlayerPostUIntBool
	{
		[HarmonyPriority(800)]
		[HarmonyPrefix]
		private static bool Prefix(uint eventID)
		{
			return !ReactorNoiseControlState.ShouldIntercept(eventID);
		}

		[HarmonyPostfix]
		private static void Postfix(CellSoundPlayer __instance, uint eventID)
		{
			ReactorNoiseControlState.Track(__instance, eventID);
		}
	}
	public class ReactorNoiseControlBehaviour : MonoBehaviour
	{
		private static ulong s_listenerId;

		private static CellSoundListener s_listener;

		private int m_lastAppliedPercent = -1;

		private float m_nextApply;

		private float m_nextListener;

		private bool m_lastMute;

		private bool m_warnedIgnoredVolume;

		private DateTime m_lastConfigWrite;

		private float m_nextConfigCheck;

		private void Update()
		{
			try
			{
				if (ReactorNoiseControlPlugin.CfgEnabled == null)
				{
					return;
				}
				if (Time.unscaledTime >= m_nextConfigCheck)
				{
					m_nextConfigCheck = Time.unscaledTime + 1f;
					CheckConfigReload();
				}
				bool value = ReactorNoiseControlPlugin.CfgInterceptMute.Value;
				if (value && !m_lastMute)
				{
					ReactorNoiseControlState.StopTrackedPlayers();
					string text = "intercept mute ON";
					ReactorNoiseControlPlugin.LogSource.LogInfo((object)("[ReactorNoiseControl] " + text));
				}
				if (!value && m_lastMute)
				{
					string text2 = "intercept mute OFF";
					ReactorNoiseControlPlugin.LogSource.LogInfo((object)("[ReactorNoiseControl] " + text2));
				}
				m_lastMute = value;
				if (Time.unscaledTime >= m_nextListener)
				{
					m_nextListener = Time.unscaledTime + 2f;
					RefreshListener();
				}
				if (Time.unscaledTime >= m_nextApply)
				{
					m_nextApply = Time.unscaledTime + 0.2f;
					int num = Mathf.Clamp(ReactorNoiseControlPlugin.CfgTotalVolume.Value, 0, 100);
					if (value && num != 100 && !m_warnedIgnoredVolume)
					{
						m_warnedIgnoredVolume = true;
						ReactorNoiseControlPlugin.LogSource.LogWarning((object)"[ReactorNoiseControl] TotalVolume is ignored while InterceptMute=true; set InterceptMute=false first.");
					}
					if (!value)
					{
						m_warnedIgnoredVolume = false;
					}
					if (num != m_lastAppliedPercent || ReactorNoiseControlState.VolumeDirty)
					{
						ReactorNoiseControlState.SetTotalVolume((float)num / 100f, s_listenerId);
						m_lastAppliedPercent = num;
						ReactorNoiseControlState.VolumeDirty = false;
					}
				}
			}
			catch (Exception ex)
			{
				ReactorNoiseControlPlugin.LogSource.LogError((object)("[ReactorNoiseControl] update failed: " + ex.Message));
			}
		}

		private void CheckConfigReload()
		{
			try
			{
				string text = ((ReactorNoiseControlPlugin.ConfigFile != null) ? ReactorNoiseControlPlugin.ConfigFile.ConfigFilePath : null);
				if (!string.IsNullOrEmpty(text) && File.Exists(text))
				{
					DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(text);
					if (m_lastConfigWrite == default(DateTime))
					{
						m_lastConfigWrite = lastWriteTimeUtc;
					}
					else if (lastWriteTimeUtc != m_lastConfigWrite)
					{
						m_lastConfigWrite = lastWriteTimeUtc;
						ReactorNoiseControlPlugin.ConfigFile.Reload();
						string text2 = "config reloaded";
						ReactorNoiseControlPlugin.LogSource.LogInfo((object)("[ReactorNoiseControl] " + text2));
					}
				}
			}
			catch (Exception ex)
			{
				ReactorNoiseControlPlugin.LogSource.LogWarning((object)("[ReactorNoiseControl] config reload failed: " + ex.Message));
			}
		}

		private void RefreshListener()
		{
			try
			{
				if ((Object)(object)s_listener != (Object)null && (Object)(object)s_listener.m_akListener != (Object)null)
				{
					return;
				}
				CellSoundListener[] array = Il2CppArrayBase<CellSoundListener>.op_Implicit(Object.FindObjectsOfType<CellSoundListener>());
				if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null && (Object)(object)array[0].m_akListener != (Object)null)
				{
					s_listener = array[0];
					ulong akGameObjectID = AkSoundEngine.GetAkGameObjectID(((Component)s_listener.m_akListener).gameObject);
					if (akGameObjectID != s_listenerId)
					{
						s_listenerId = akGameObjectID;
						ReactorNoiseControlState.VolumeDirty = true;
					}
				}
			}
			catch
			{
			}
		}
	}
}