Decompiled source of VoiceRange v1.0.0

VoiceRangeMod.dll

Decompiled 4 months ago
using System;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("VoiceRangeMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("My first plugin")]
[assembly: AssemblyTitle("VoiceRangeMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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]
	[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 VoiceRangeMod
{
	[BepInPlugin("com.Kingo.voicerange", "VoiceRangeMod", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class VoiceRangePlugin : BaseUnityPlugin
	{
		public const string GUID = "com.Kingo.voicerange";

		public const string NAME = "VoiceRangeMod";

		public const string VERSION = "1.0.0";

		internal static ManualLogSource Log;

		private ConfigEntry<KeyboardShortcut> cfgWalkieKey;

		private ConfigEntry<bool> cfgHoldToTalk;

		private ConfigEntry<string> cfgRangeMode;

		private volatile bool walkieActive = false;

		private float lastApplyRangeWhen = 0f;

		private readonly Dictionary<string, float> RangeMultipliers = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Normal", 1f },
			{ "Far", 1.5f },
			{ "VeryFar", 2f }
		};

		private const string DissonanceCommsTypeName = "Dissonance.DissonanceComms";

		private readonly List<Behaviour> cachedBroadcastTriggers = new List<Behaviour>();

		private readonly List<Behaviour> cachedReceiptTriggers = new List<Behaviour>();

		private Behaviour cachedDissonanceComms = null;

		private const float FallbackBaseRange = 15f;

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			cfgWalkieKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "WalkieKey", new KeyboardShortcut((KeyCode)114, (KeyCode[])(object)new KeyCode[0]), "Key to activate Walkie-Talkie (global broadcast). Default: R");
			cfgHoldToTalk = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "HoldToTalk", true, "If true: hold the key to speak globally. If false: press once to toggle global mode.");
			cfgRangeMode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RangeMode", "Normal", "Server preference for proximity voice: Normal, Far, VeryFar");
			if (!RangeMultipliers.ContainsKey(cfgRangeMode.Value))
			{
				Log.LogWarning((object)("[VoiceRangeMod] Invalid RangeMode '" + cfgRangeMode.Value + "' in config. Resetting to 'Normal'."));
				cfgRangeMode.Value = "Normal";
			}
			Log.LogInfo((object)string.Format("[{0}] v{1} loaded. WalkieKey={2}, HoldToTalk={3}, RangeMode={4}", "VoiceRangeMod", "1.0.0", cfgWalkieKey.Value, cfgHoldToTalk.Value, cfgRangeMode.Value));
			if (Chainloader.PluginInfos.ContainsKey("com.Kingo.voicefix"))
			{
				Log.LogInfo((object)"[VoiceRangeMod] VoiceFix (com.Kingo.voicefix) detected — integration enabled.");
			}
			else
			{
				Log.LogInfo((object)"[VoiceRangeMod] VoiceFix not found. Running independent.");
			}
			DiscoverVoiceComponents();
			((MonoBehaviour)this).InvokeRepeating("DiscoverVoiceComponents", 5f, 10f);
		}

		private void OnDestroy()
		{
			try
			{
				((MonoBehaviour)this).CancelInvoke("DiscoverVoiceComponents");
			}
			catch
			{
			}
		}

		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = cfgWalkieKey.Value;
			bool flag = ((KeyboardShortcut)(ref value)).IsDown();
			value = cfgWalkieKey.Value;
			bool flag2 = ((KeyboardShortcut)(ref value)).IsUp();
			value = cfgWalkieKey.Value;
			bool flag3 = ((KeyboardShortcut)(ref value)).IsPressed();
			if (cfgHoldToTalk.Value)
			{
				if (flag3 && !walkieActive)
				{
					walkieActive = true;
					EnableWalkieGlobal();
				}
				else if (!flag3 && walkieActive)
				{
					walkieActive = false;
					DisableWalkieGlobal();
				}
			}
			else if (flag)
			{
				walkieActive = !walkieActive;
				if (walkieActive)
				{
					EnableWalkieGlobal();
				}
				else
				{
					DisableWalkieGlobal();
				}
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!walkieActive && realtimeSinceStartup - lastApplyRangeWhen > 1f)
			{
				ApplyProximityRangeMultiplier();
				lastApplyRangeWhen = realtimeSinceStartup;
			}
			if (walkieActive && realtimeSinceStartup - lastApplyRangeWhen > 0.5f)
			{
				ApplyWalkieGlobalToBroadcasts();
				lastApplyRangeWhen = realtimeSinceStartup;
			}
		}

		private void DiscoverVoiceComponents()
		{
			cachedBroadcastTriggers.Clear();
			cachedReceiptTriggers.Clear();
			cachedDissonanceComms = null;
			try
			{
				Behaviour[] array = Object.FindObjectsOfType<Behaviour>();
				Behaviour[] array2 = array;
				foreach (Behaviour val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						Type type = ((object)val).GetType();
						string text = type.FullName ?? type.Name;
						string text2 = text.ToLowerInvariant();
						if (text2.Contains("voicebroadcast") || text2.Contains("broadcasttrigger"))
						{
							cachedBroadcastTriggers.Add(val);
						}
						if (text2.Contains("voicereceipt") || text2.Contains("receipttrigger"))
						{
							cachedReceiptTriggers.Add(val);
						}
						if (text.Equals("Dissonance.DissonanceComms", StringComparison.Ordinal) || text2.Contains("dissonancecomms"))
						{
							cachedDissonanceComms = val;
						}
					}
				}
				Log.LogDebug((object)string.Format("[{0}] Discovery complete. Broadcasts={1}, Receipts={2}, DissonanceComms={3}", "VoiceRangeMod", cachedBroadcastTriggers.Count, cachedReceiptTriggers.Count, (Object)(object)cachedDissonanceComms != (Object)null));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[VoiceRangeMod] DiscoverVoiceComponents error: " + ex.Message));
			}
		}

		private void EnableWalkieGlobal()
		{
			Log.LogInfo((object)"[VoiceRangeMod] Walkie-Talkie ACTIVATED (global).");
			ApplyWalkieGlobalToBroadcasts();
		}

		private void DisableWalkieGlobal()
		{
			Log.LogInfo((object)"[VoiceRangeMod] Walkie-Talkie DEACTIVATED (back to proximity).");
			ApplyProximityRangeMultiplier();
		}

		private void ApplyWalkieGlobalToBroadcasts()
		{
			Behaviour[] array = cachedBroadcastTriggers.ToArray();
			foreach (Behaviour val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				PropertyInfo property = type.GetProperty("ChannelType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)property != null)
				{
					try
					{
						Type propertyType = property.PropertyType;
						string[] names = Enum.GetNames(propertyType);
						string text = names.FirstOrDefault((string n) => n.Equals("Global", StringComparison.OrdinalIgnoreCase));
						if (text != null)
						{
							object value = Enum.Parse(propertyType, text);
							property.SetValue(val, value, null);
							continue;
						}
					}
					catch (Exception ex)
					{
						Log.LogDebug((object)("[VoiceRangeMod] ChannelType set attempt failed on " + type.FullName + ": " + ex.Message));
					}
				}
				if (!TrySetRangeFieldOrProperty(val, 1.7014117E+38f))
				{
					try
					{
						val.enabled = false;
						val.enabled = true;
					}
					catch
					{
					}
				}
			}
			Behaviour[] array2 = cachedReceiptTriggers.ToArray();
			foreach (Behaviour val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					TrySetRangeFieldOrProperty(val2, 1.7014117E+38f);
				}
			}
		}

		private void ApplyProximityRangeMultiplier()
		{
			float value = 1f;
			if (!RangeMultipliers.TryGetValue(cfgRangeMode.Value, out value))
			{
				value = 1f;
			}
			float valueOrDefault = ReadBaseRangeFromAnyTrigger().GetValueOrDefault(15f);
			float num = valueOrDefault * value;
			Behaviour[] array = cachedBroadcastTriggers.ToArray();
			foreach (Behaviour val in array)
			{
				if ((Object)(object)val == (Object)null || TrySetRangeFieldOrProperty(val, num))
				{
					continue;
				}
				Type type = ((object)val).GetType();
				PropertyInfo property = type.GetProperty("ChannelType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)property == null)
				{
					continue;
				}
				try
				{
					Type propertyType = property.PropertyType;
					string[] names = Enum.GetNames(propertyType);
					string text = names.FirstOrDefault((string n) => n.Equals("Proximity", StringComparison.OrdinalIgnoreCase) || n.Equals("Nearby", StringComparison.OrdinalIgnoreCase));
					if (text != null)
					{
						object value2 = Enum.Parse(propertyType, text);
						property.SetValue(val, value2, null);
					}
				}
				catch
				{
				}
			}
			Behaviour[] array2 = cachedReceiptTriggers.ToArray();
			foreach (Behaviour val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					TrySetRangeFieldOrProperty(val2, num);
				}
			}
			Log.LogInfo((object)string.Format("[{0}] Applied RangeMode={1} multiplier={2} targetRange={3:F1}", "VoiceRangeMod", cfgRangeMode.Value, value, num));
		}

		private bool TrySetRangeFieldOrProperty(Behaviour comp, float value)
		{
			if ((Object)(object)comp == (Object)null)
			{
				return false;
			}
			Type type = ((object)comp).GetType();
			string[] array = new string[8] { "Range", "range", "Radius", "radius", "Distance", "distance", "MaxDistance", "maxDistance" };
			try
			{
				string[] array2 = array;
				foreach (string text in array2)
				{
					PropertyInfo property = type.GetProperty(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if ((object)property != null)
					{
						if ((object)property.PropertyType == typeof(float))
						{
							try
							{
								property.SetValue(comp, value, null);
								return true;
							}
							catch (Exception ex)
							{
								Log.LogDebug((object)("[VoiceRangeMod] prop.SetValue(" + text + ") failed on " + type.FullName + ": " + ex.Message));
							}
						}
						else if ((object)property.PropertyType == typeof(double))
						{
							try
							{
								property.SetValue(comp, (double)value, null);
								return true;
							}
							catch (Exception ex2)
							{
								Log.LogDebug((object)("[VoiceRangeMod] prop.SetValue(" + text + ") failed on " + type.FullName + ": " + ex2.Message));
							}
						}
					}
					FieldInfo field = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if ((object)field == null)
					{
						continue;
					}
					if ((object)field.FieldType == typeof(float))
					{
						try
						{
							field.SetValue(comp, value);
							return true;
						}
						catch (Exception ex3)
						{
							Log.LogDebug((object)("[VoiceRangeMod] fld.SetValue(" + text + ") failed on " + type.FullName + ": " + ex3.Message));
						}
					}
					else if ((object)field.FieldType == typeof(double))
					{
						try
						{
							field.SetValue(comp, (double)value);
							return true;
						}
						catch (Exception ex4)
						{
							Log.LogDebug((object)("[VoiceRangeMod] fld.SetValue(" + text + ") failed on " + type.FullName + ": " + ex4.Message));
						}
					}
				}
			}
			catch (Exception ex5)
			{
				Log.LogDebug((object)("[VoiceRangeMod] TrySetRangeFieldOrProperty outer error: " + ex5.Message));
			}
			return false;
		}

		private float? ReadBaseRangeFromAnyTrigger()
		{
			foreach (Behaviour item in cachedBroadcastTriggers.Concat(cachedReceiptTriggers))
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				Type type = ((object)item).GetType();
				string[] array = new string[8] { "Range", "range", "Radius", "radius", "Distance", "distance", "MaxDistance", "maxDistance" };
				try
				{
					string[] array2 = array;
					foreach (string name in array2)
					{
						PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if ((object)property != null)
						{
							try
							{
								object value = property.GetValue(item, null);
								if (value is float value2)
								{
									return value2;
								}
								if (value is double)
								{
									double num = (double)value;
									if (true)
									{
										return (float)num;
									}
								}
							}
							catch
							{
							}
						}
						FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if ((object)field == null)
						{
							continue;
						}
						try
						{
							object value3 = field.GetValue(item);
							if (value3 is float value4)
							{
								return value4;
							}
							if (value3 is double)
							{
								double num2 = (double)value3;
								if (true)
								{
									return (float)num2;
								}
							}
						}
						catch
						{
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "VoiceRangeMod";

		public const string PLUGIN_NAME = "My first plugin";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}