Decompiled source of KeepItDown v1.2.1

KeepItDown.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
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("Kesomannen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Volume tuning mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1")]
[assembly: AssemblyProduct("KeepItDown")]
[assembly: AssemblyTitle("KeepItDown")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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 KeepItDown
{
	public class KeepItDownConfig
	{
		private readonly Dictionary<string, VolumeConfig> _volumes = new Dictionary<string, VolumeConfig>();

		private readonly ConfigFile _mainCfg;

		public IReadOnlyDictionary<string, VolumeConfig> Volumes => _volumes;

		internal KeepItDownConfig(ConfigFile mainCfg)
		{
			_mainCfg = mainCfg;
		}

		private static VolumeConfig CreateVolumeConfig(ConfigFile cfg, string key, string section)
		{
			return new VolumeConfig(key, cfg.Bind<float>(section, key + "Volume", 50f, "Volume of " + key));
		}

		public bool AddVolumeConfig(string key, string section, ConfigFile cfg = null)
		{
			if (_volumes.ContainsKey(key))
			{
				KeepItDownPlugin.Instance.Log.LogWarning((object)("Volume config for " + key + " already exists!"));
				return false;
			}
			_volumes[key] = CreateVolumeConfig(cfg ?? _mainCfg, key, section);
			return true;
		}

		public bool AddVolumeConfigs(IEnumerable<string> keys, string section, ConfigFile cfg = null)
		{
			return keys.Select((string key) => AddVolumeConfig(key, section, cfg)).All((bool x) => x);
		}
	}
	public class VolumeConfig : IDisposable
	{
		public delegate void ChangedEventHandler(VolumeConfig config, float rawValue, float normalizedValue);

		public struct Binding
		{
			public GameObject GameObject { get; }

			public float BaseVolume { get; }

			public Action<float> Setter { get; }

			public Binding(GameObject gameObject, float baseVolume, Action<float> setter)
			{
				GameObject = gameObject;
				BaseVolume = baseVolume;
				Setter = setter;
			}
		}

		private readonly ConfigEntry<float> _configEntry;

		private readonly List<Binding> _bindings = new List<Binding>();

		private bool _isDisposed;

		public float NormalizedValue
		{
			get
			{
				return RawValue / 100f * 2f;
			}
			set
			{
				RawValue = value * 100f / 2f;
			}
		}

		public float RawValue
		{
			get
			{
				return _configEntry.Value;
			}
			set
			{
				_configEntry.Value = value;
			}
		}

		public string Key { get; }

		public string Section => ((ConfigEntryBase)_configEntry).Definition.Section;

		public event ChangedEventHandler OnChanged;

		internal VolumeConfig(string key, ConfigEntry<float> configEntry)
		{
			Key = key;
			_configEntry = configEntry;
			_configEntry.SettingChanged += SettingChangedEventHandler;
		}

		~VolumeConfig()
		{
			Dispose();
		}

		public void Dispose()
		{
			if (!_isDisposed)
			{
				_isDisposed = true;
				_configEntry.SettingChanged -= SettingChangedEventHandler;
			}
		}

		private void SettingChangedEventHandler(object sender, EventArgs e)
		{
			for (int i = 0; i < _bindings.Count; i++)
			{
				Binding binding = _bindings[i];
				if ((Object)(object)binding.GameObject == (Object)null)
				{
					_bindings.RemoveAt(i--);
				}
				else
				{
					ActivateBinding(in binding);
				}
			}
			this.OnChanged?.Invoke(this, RawValue, NormalizedValue);
		}

		public void AddBinding(Binding binding)
		{
			_bindings.Add(binding);
			ActivateBinding(in binding);
		}

		public void RemoveBindings(GameObject gameObject)
		{
			for (int i = 0; i < _bindings.Count; i++)
			{
				if ((Object)(object)_bindings[i].GameObject == (Object)(object)gameObject)
				{
					_bindings.RemoveAt(i--);
				}
			}
		}

		private void ActivateBinding(in Binding binding)
		{
			binding.Setter(NormalizedValue * binding.BaseVolume);
		}
	}
	[BepInPlugin("KeepItDown", "KeepItDown", "1.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class KeepItDownPlugin : BaseUnityPlugin
	{
		public static KeepItDownPlugin Instance { get; private set; }

		internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger;

		public KeepItDownConfig Config { get; private set; }

		private void Awake()
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Config = new KeepItDownConfig(((BaseUnityPlugin)this).Config);
			Config.AddVolumeConfigs(new string[24]
			{
				"Airhorn", "Boombox", "CashRegister", "Remote", "Flashlight", "Walkie-talkie", "Scan", "Spraycan", "Dentures", "RobotToy",
				"Hairdryer", "Jetpack", "RadarBoosterPing", "ShipAlarm", "ShipAlarmCord", "ItemCharger", "Shovel", "RubberDucky", "Landmine", "Jester",
				"Thunder", "WhoopieCushion", "ExtensionLadder", "Turret"
			}, "Vanilla");
			Harmony.CreateAndPatchAll(typeof(Patches), "KeepItDown");
			Object.DontDestroyOnLoad((Object)(object)((Component)new GameObject("KeepItDownUI").AddComponent<UI>()).gameObject);
			Log.LogInfo((object)"KeepItDown is loaded!");
		}

		public static bool AddConfig(string key, string section, ConfigFile cfg = null)
		{
			return Instance.Config.AddVolumeConfig(key, section, cfg);
		}

		public static bool TryGetConfig(string key, out VolumeConfig config)
		{
			return Instance.Config.Volumes.TryGetValue(key, out config);
		}

		public static bool Bind(string key, GameObject gameObject, float baseVolume, Action<float> volumeSetter)
		{
			if (!TryGetConfig(key, out var config))
			{
				Instance.Log.LogWarning((object)("Trying to bind volume config for " + key + ", but it doesn't exist"));
				return false;
			}
			config.AddBinding(new VolumeConfig.Binding(gameObject, baseVolume, volumeSetter));
			return true;
		}

		public static bool BindAudioSource(string key, AudioSource audioSource)
		{
			return Bind(key, ((Component)audioSource).gameObject, audioSource.volume, delegate(float v)
			{
				audioSource.volume = v;
			});
		}

		public static bool BindAudioSources(string key, params AudioSource[] audioSources)
		{
			return audioSources.All((AudioSource audioSource) => BindAudioSource(key, audioSource));
		}

		public static bool RemoveBindings(string key, GameObject gameObject)
		{
			if (!TryGetConfig(key, out var config))
			{
				Instance.Log.LogWarning((object)("Trying to remove volume config bindings for " + key + ", but it doesn't exist"));
				return false;
			}
			config.RemoveBindings(gameObject);
			return true;
		}
	}
	internal static class Patches
	{
		private static string GetFormattedName(Object gameObject)
		{
			return gameObject.name.Replace("(Clone)", "").Replace("Item", "");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(NoisemakerProp), "Start")]
		private static void NoiseMakerProp_Start_Postfix(NoisemakerProp __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			string formattedName = GetFormattedName((Object)(object)gameObject);
			KeepItDownPlugin.Bind(formattedName, gameObject, __instance.maxLoudness, delegate(float v)
			{
				__instance.maxLoudness = v;
			});
			KeepItDownPlugin.Bind(formattedName, gameObject, __instance.minLoudness, delegate(float v)
			{
				__instance.minLoudness = v;
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AnimatedItem), "Start")]
		private static void AnimatedItem_Start_Postfix(AnimatedItem __instance)
		{
			KeepItDownPlugin.BindAudioSource(GetFormattedName((Object)(object)((Component)__instance).gameObject), __instance.itemAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RadarBoosterItem), "Start")]
		private static void RadarBoosterItem_Start_Postfix(RadarBoosterItem __instance)
		{
			KeepItDownPlugin.BindAudioSource("RadarBoosterPing", __instance.pingAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ShipAlarmCord), "Start")]
		private static void ShipAlarmCord_Start_Postfix(ShipAlarmCord __instance)
		{
			KeepItDownPlugin.BindAudioSources("ShipAlarm", __instance.hornClose, __instance.hornFar);
			KeepItDownPlugin.BindAudioSource("ShipAlarmCord", __instance.cordAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BoomboxItem), "Start")]
		private static void BoomboxItem_Start_Postfix(BoomboxItem __instance)
		{
			KeepItDownPlugin.BindAudioSource("Boombox", __instance.boomboxAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(WalkieTalkie), "Start")]
		private static void WalkieTalkie_Start_Postfix(WalkieTalkie __instance)
		{
			KeepItDownPlugin.BindAudioSource("Walkie-talkie", __instance.thisAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FlashlightItem), "Start")]
		private static void FlashlightItem_Start_Postfix(FlashlightItem __instance)
		{
			KeepItDownPlugin.BindAudioSource("Flashlight", __instance.flashlightAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SprayPaintItem), "Start")]
		private static void SprayPaintItem_Start_Postfix(SprayPaintItem __instance)
		{
			KeepItDownPlugin.BindAudioSource("Spraycan", __instance.sprayAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Landmine), "Start")]
		private static void Landmine_Start_Postfix(Landmine __instance)
		{
			KeepItDownPlugin.BindAudioSource("Landmine", __instance.mineAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Turret), "Start")]
		private static void Turret_Start_Postfix(Turret __instance)
		{
			KeepItDownPlugin.BindAudioSources("Turret", __instance.mainAudio, __instance.berserkAudio, __instance.farAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(JesterAI), "Start")]
		private static void JesterAI_Start_Postfix(JesterAI __instance)
		{
			KeepItDownPlugin.BindAudioSource("Jester", __instance.farAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StormyWeather), "OnEnable")]
		private static void StormyWeather_OnEnable_Postfix(StormyWeather __instance)
		{
			KeepItDownPlugin.BindAudioSources("Thunder", __instance.randomStrikeAudio, __instance.randomStrikeAudioB, __instance.targetedStrikeAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StormyWeather), "OnDisable")]
		private static void StormyWeather_OnDisable_Postfix(StormyWeather __instance)
		{
			KeepItDownPlugin.RemoveBindings("Thunder", ((Component)__instance).gameObject);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		private static void GrabbableObject_Start_Postfix(GrabbableObject __instance)
		{
			RemoteProp val = (RemoteProp)(object)((__instance is RemoteProp) ? __instance : null);
			if (val == null)
			{
				JetpackItem val2 = (JetpackItem)(object)((__instance is JetpackItem) ? __instance : null);
				if (val2 == null)
				{
					Shovel val3 = (Shovel)(object)((__instance is Shovel) ? __instance : null);
					if (val3 == null)
					{
						WhoopieCushionItem val4 = (WhoopieCushionItem)(object)((__instance is WhoopieCushionItem) ? __instance : null);
						if (val4 == null)
						{
							ExtensionLadderItem val5 = (ExtensionLadderItem)(object)((__instance is ExtensionLadderItem) ? __instance : null);
							if (val5 != null)
							{
								KeepItDownPlugin.BindAudioSource("ExtensionLadder", val5.ladderAudio);
							}
						}
						else
						{
							KeepItDownPlugin.BindAudioSource("WhoopieCushion", val4.whoopieCushionAudio);
						}
					}
					else
					{
						KeepItDownPlugin.BindAudioSource("Shovel", val3.shovelAudio);
					}
				}
				else
				{
					KeepItDownPlugin.BindAudioSource("Jetpack", val2.jetpackAudio);
				}
			}
			else
			{
				KeepItDownPlugin.BindAudioSource("Remote", val.remoteAudio);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(NetworkBehaviour), "OnNetworkSpawn")]
		private static void NetworkBehaviour_OnNetworkSpawn_Postfix(NetworkBehaviour __instance)
		{
			ItemCharger val = (ItemCharger)(object)((__instance is ItemCharger) ? __instance : null);
			if (val != null)
			{
				KeepItDownPlugin.BindAudioSource("ItemCharger", val.zapAudio);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(HUDManager), "OnEnable")]
		private static void HUDManager_OnEnable_Postfix(HUDManager __instance)
		{
			KeepItDownPlugin.BindAudioSource("Scan", __instance.UIAudio);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(HUDManager), "OnDisable")]
		private static void HUDManager_OnDisable_Postfix(HUDManager __instance)
		{
			KeepItDownPlugin.RemoveBindings("Scan", ((Component)__instance.UIAudio).gameObject);
		}
	}
	internal static class ReflectionUtil
	{
		private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		public static T GetPropertyValue<T>(this object obj, string propertyName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
		{
			return (T)(obj.GetType().GetProperty(propertyName, flags)?.GetValue(obj));
		}

		public static T GetFieldValue<T>(this object obj, string fieldName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
		{
			return (T)(obj.GetType().GetField(fieldName, flags)?.GetValue(obj));
		}
	}
	public class UI : MonoBehaviour
	{
		private const string Name = "Keep It Down!";

		private const string Guid = "KeepItDown";

		private const string Version = "1.2.1";

		private const string Description = "Volume control for various sounds in the game.";

		private SliderComponent[] _sliders;

		private readonly Dictionary<SliderComponent, string> _sliderToConfigKey = new Dictionary<SliderComponent, string>();

		public void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0057: Expected O, but got Unknown
			//IL_0057: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			KeepItDownConfig config = KeepItDownPlugin.Instance.Config;
			_sliders = ((IEnumerable<KeyValuePair<string, VolumeConfig>>)config.Volumes).Select((Func<KeyValuePair<string, VolumeConfig>, SliderComponent>)delegate(KeyValuePair<string, VolumeConfig> kvp)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				kvp.Value.OnChanged += OnConfigChangedHandler;
				return new SliderComponent
				{
					MinValue = 0f,
					MaxValue = 100f,
					OnValueChanged = OnSliderValueChanged
				};
			}).ToArray();
			RefreshOrder();
			ButtonComponent item = new ButtonComponent
			{
				Text = "Reset",
				OnClick = ResetSliders
			};
			InputComponent item2 = new InputComponent
			{
				Placeholder = "Search...",
				OnValueChanged = delegate(InputComponent _, string text)
				{
					RefreshOrder(text);
				}
			};
			List<MenuComponent> list = new List<MenuComponent>
			{
				(MenuComponent)(object)item,
				(MenuComponent)(object)item2
			};
			list.AddRange((IEnumerable<MenuComponent>)(object)_sliders);
			ModMenu.RegisterMod(new ModSettingsConfig
			{
				Name = "Keep It Down!",
				Id = "KeepItDown",
				Version = "1.2.1",
				Description = "Volume control for various sounds in the game.",
				MenuComponents = list.ToArray()
			}, true, true);
		}

		private void RefreshOrder(string searchTerm = null)
		{
			KeepItDownConfig config = KeepItDownPlugin.Instance.Config;
			IEnumerable<string> enumerable;
			if (searchTerm == null)
			{
				enumerable = config.Volumes.Keys.OrderBy((string k) => k);
			}
			else
			{
				string lowerSearchTerm = searchTerm.ToLower();
				enumerable = config.Volumes.Keys.OrderBy((string k) => (!k.ToLower().Contains(lowerSearchTerm)) ? 1 : 0);
			}
			_sliderToConfigKey.Clear();
			int num = 0;
			foreach (string item in enumerable)
			{
				SliderComponent val = _sliders[num++];
				VolumeConfig volumeConfig = config.Volumes[item];
				string text = item + " Volume";
				if (volumeConfig.Section != "Vanilla")
				{
					text = text + " (" + volumeConfig.Section + ")";
				}
				val.Text = text;
				val.Value = volumeConfig.RawValue;
				_sliderToConfigKey[val] = item;
			}
		}

		private void OnSliderValueChanged(SliderComponent slider, float value)
		{
			if (_sliderToConfigKey.TryGetValue(slider, out var value2) && KeepItDownPlugin.TryGetConfig(value2, out var config))
			{
				config.RawValue = value;
			}
		}

		private void OnConfigChangedHandler(VolumeConfig config, float rawValue, float normalizedValue)
		{
			SliderComponent val = ((IEnumerable<SliderComponent>)_sliders).FirstOrDefault((Func<SliderComponent, bool>)((SliderComponent s) => _sliderToConfigKey[s] == config.Key));
			if (val != null && !Mathf.Approximately(val.Value, rawValue))
			{
				val.Value = rawValue;
			}
		}

		private void ResetSliders(ButtonComponent instance)
		{
			foreach (VolumeConfig value in KeepItDownPlugin.Instance.Config.Volumes.Values)
			{
				value.NormalizedValue = 1f;
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "KeepItDown";

		public const string PLUGIN_NAME = "KeepItDown";

		public const string PLUGIN_VERSION = "1.2.1";
	}
}