Decompiled source of BetterVoiceDetection v1.2.0

BetterVoiceDetection.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MageConfigurationAPI.Data;
using MageConfigurationAPI.Enums;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BetterVoiceDetection")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterVoiceDetection")]
[assembly: AssemblyTitle("BetterVoiceDetection")]
[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.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 BetterVoiceDetection
{
	[BepInProcess("MageArena")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.d1gq.better.voice.detection", "BetterVoiceDetection", "1.2.0")]
	public class BVDPlugin : BaseUnityPlugin
	{
		private const string MyGUID = "com.d1gq.better.voice.detection";

		private const string PluginName = "BetterVoiceDetection";

		private const string VersionString = "1.2.0";

		private static Harmony? Harmony;

		private ManualLogSource? _log;

		internal static BVDPlugin Instance { get; private set; }

		internal static ManualLogSource Log => Instance._log;

		internal static ConfigEntry<float> VoiceSensitivity { get; private set; }

		private void Awake()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Harmony = new Harmony("com.d1gq.better.voice.detection");
			Harmony.PatchAll();
			LoadConfig();
			Log.LogInfo((object)"BetterVoiceDetection v1.2.0 loaded!");
		}

		private void LoadConfig()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			VoiceSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("BetterVoiceDetection", "VoiceSensitivity", 0.7f, new ConfigDescription("Voice recognition sensitivity (0.1-1.0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			new ModConfig((BaseUnityPlugin)(object)this, (ConfigEntryBase)(object)VoiceSensitivity, (SettingsFlag)7);
		}
	}
}
namespace BetterVoiceDetection.Patches.Voice
{
	[HarmonyPatch(typeof(VoiceControlListener))]
	internal class VoiceControlListenerPatch
	{
		private static readonly Dictionary<string, string> _phoneticMap = new Dictionary<string, string>
		{
			{ "fir", "fire" },
			{ "fyur", "fire" },
			{ "far", "fire" },
			{ "fiar", "fire" },
			{ "fayer", "fire" },
			{ "bal", "ball" },
			{ "bol", "ball" },
			{ "bahl", "ball" },
			{ "bawl", "ball" },
			{ "frees", "freeze" },
			{ "ease", "freeze" },
			{ "frieze", "freeze" },
			{ "friz", "freeze" },
			{ "freese", "freeze" },
			{ "froze", "freeze" },
			{ "fleez", "freeze" },
			{ "furizu", "freeze" },
			{ "werm", "worm" },
			{ "vorm", "worm" },
			{ "warm", "worm" },
			{ "wurm", "worm" },
			{ "walrm", "worm" },
			{ "hol", "hole" },
			{ "howl", "hole" },
			{ "hohl", "hole" },
			{ "haul", "hole" },
			{ "hool", "hole" },
			{ "missel", "missle" },
			{ "misle", "missle" },
			{ "majik", "magic" },
			{ "madgic", "magic" },
			{ "mejik", "magic" },
			{ "missail", "missle" },
			{ "misail", "missle" },
			{ "mizile", "missle" },
			{ "blenk", "blink" },
			{ "blank", "blink" },
			{ "bleenk", "blink" },
			{ "brink", "blink" },
			{ "burinku", "blink" },
			{ "dork", "dark" },
			{ "derk", "dark" },
			{ "dak", "dark" },
			{ "dahk", "dark" },
			{ "blost", "blast" },
			{ "blust", "blast" },
			{ "brast", "blast" },
			{ "burasto", "blast" },
			{ "merror", "mirror" },
			{ "mira", "mirror" },
			{ "meeror", "mirror" },
			{ "mirrar", "mirror" },
			{ "mirorr", "mirror" },
			{ "miller", "mirror" },
			{ "miroru", "mirror" },
			{ "devine", "divine" },
			{ "divayn", "divine" },
			{ "diveen", "divine" },
			{ "divyne", "divine" },
			{ "dibin", "divine" },
			{ "divain", "divine" },
			{ "divinu", "divine" },
			{ "wips", "wisp" },
			{ "vesp", "wisp" },
			{ "whisp", "wisp" },
			{ "wesp", "wisp" },
			{ "wipsu", "wisp" },
			{ "vispu", "wisp" },
			{ "wispu", "wisp" },
			{ "thunder", "thunder" },
			{ "thuner", "thunder" },
			{ "tunder", "thunder" },
			{ "sander", "thunder" },
			{ "thunda", "thunder" },
			{ "sandabolt", "thunder" },
			{ "bolt", "bolt" },
			{ "bolto", "bolt" },
			{ "volto", "bolt" },
			{ "bort", "bolt" },
			{ "bold", "bolt" },
			{ "thunderbolto", "thunder" },
			{ "thunderbold", "thunder" },
			{ "rok", "rock" },
			{ "rokk", "rock" },
			{ "raku", "rock" },
			{ "wock", "rock" }
		};

		private static readonly HashSet<string> _highConfidenceSpells = new HashSet<string> { "fire", "ball", "freeze", "worm", "hole", "missle", "magic", "blink", "dark", "blast" };

		[HarmonyPatch("OnStartClient")]
		[HarmonyPrefix]
		private static void OnStartClient_Prefix(VoiceControlListener __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(CoWaitGetPlayer(__instance));
		}

		private static IEnumerator CoWaitGetPlayer(VoiceControlListener __instance)
		{
			PlayerInventory playerInventory = default(PlayerInventory);
			while ((Object)(object)__instance.pi == (Object)null)
			{
				if ((Object)(object)((Component)Camera.main).transform.parent != (Object)null && ((Component)((Component)Camera.main).transform.parent).TryGetComponent<PlayerInventory>(ref playerInventory))
				{
					__instance.pi = playerInventory;
				}
				yield return null;
				playerInventory = null;
			}
			yield return null;
			yield return (object)new WaitForSeconds(0.5f);
			AddToVocabulary(__instance);
		}

		[HarmonyPatch("resetmic")]
		[HarmonyPrefix]
		private static void Resetmic_Prefix(VoiceControlListener __instance)
		{
			if (Time.time - __instance.resetmiccooldown > 10f)
			{
				((MonoBehaviour)__instance).StartCoroutine(CoResetmic(__instance));
			}
		}

		private static IEnumerator CoResetmic(VoiceControlListener __instance)
		{
			yield return (object)new WaitForSeconds(0.5f);
			yield return (object)new WaitForSeconds(0.5f);
			yield return (object)new WaitForSeconds(0.5f);
			AddToVocabulary(__instance);
		}

		private static void AddToVocabulary(VoiceControlListener __instance)
		{
			BVDPlugin.Log.LogInfo((object)"Loading new vocabulary.");
			foreach (string key in _phoneticMap.Keys)
			{
				if (!__instance.sr.Vocabulary.Contains(key))
				{
					__instance.sr.Vocabulary.Add(key);
					BVDPlugin.Log.LogInfo((object)("Add " + key + " to SpeechRecognizer vocabulary."));
				}
			}
		}

		[HarmonyPatch("tryresult")]
		[HarmonyPrefix]
		private static void TryResult_Prefix(ref string res)
		{
			if (string.IsNullOrEmpty(res))
			{
				return;
			}
			float value = BVDPlugin.VoiceSensitivity.Value;
			string text = res.ToLowerInvariant();
			if (res.Length < CalculateMinLength(value))
			{
				return;
			}
			foreach (KeyValuePair<string, string> item in _phoneticMap)
			{
				if (ShouldApplyReplacement(text, item.Key, value))
				{
					BVDPlugin.Log.LogInfo((object)("Corrected spell attempt from (" + res + " to " + item.Value + ")"));
					res = res.Replace(item.Key, item.Value);
					text = text.Replace(item.Key, item.Value);
					if (value > 0.8f && IsConfidentMatch(item.Key))
					{
						break;
					}
				}
			}
		}

		private static int CalculateMinLength(float sensitivity)
		{
			return (sensitivity > 0.7f) ? 3 : 2;
		}

		private static bool ShouldApplyReplacement(string input, string pattern, float sensitivity)
		{
			if (!input.Contains(pattern))
			{
				return false;
			}
			if (sensitivity < 0.4f)
			{
				return input.IndexOf(pattern, StringComparison.Ordinal) >= 0;
			}
			if (sensitivity < 0.7f)
			{
				return input.Contains(" " + pattern + " ") || input.StartsWith(pattern + " ") || input.EndsWith(" " + pattern);
			}
			return Regex.IsMatch(input, "\\b" + pattern + "\\b");
		}

		private static bool IsConfidentMatch(string pattern)
		{
			string value;
			return _phoneticMap.TryGetValue(pattern, out value) && _highConfidenceSpells.Contains(value);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}