Decompiled source of VoiceCommandsAPI v1.0.0

plugins/DumbassStuff.VoiceCommandsAPI.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Dissonance.Audio.Capture;
using DumbassStuff.VoiceCommandsAPI.NetcodePatcher;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NAudio.Wave;
using Newtonsoft.Json.Linq;
using Unity.Netcode;
using UnityEngine;
using VoiceCommandsAPI.API;
using VoiceCommandsAPI.Audio;
using VoiceCommandsAPI.Networking;
using Vosk;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("DumbassStuff.VoiceCommandsAPI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+de9a0b1b64cbd963af89c54ba8a58bdd4db628ec")]
[assembly: AssemblyProduct("VoiceCommandsAPI")]
[assembly: AssemblyTitle("DumbassStuff.VoiceCommandsAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 VoiceCommandsAPI
{
	[BepInPlugin("DumbassStuff.VoiceCommandsAPI", "VoiceCommandsAPI", "1.0.0")]
	public class VoiceCommandsAPI : BaseUnityPlugin
	{
		private AudioProcessor? _processor;

		public static VoiceCommandsAPI? Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		private static Harmony? Harmony { get; set; }

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		private static extern bool SetDllDirectory(string lpPathName);

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			SetDllDirectory(Paths.PluginPath);
			InitializeAudioProcessor();
			NetcodePatcher();
			Patch();
			Logger.LogInfo((object)"DumbassStuff.VoiceCommandsAPI v1.0.0 has loaded!");
		}

		private void InitializeAudioProcessor()
		{
			string text = Path.Combine(Paths.PluginPath, "vosk-model-small-en-us-0.15");
			if (!Directory.Exists(text))
			{
				Logger.LogError((object)("Vosk model not found at: " + text));
				return;
			}
			_processor = new AudioProcessor(text);
			_processor.OnPartialText += OnPartialRecognition;
			_processor.OnFinalText += OnFinalRecognition;
			CaptureSubscriber.Instance.OnFrame += OnMicFrame;
			Logger.LogInfo((object)"Audio processor initialized successfully.");
		}

		private static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("DumbassStuff.VoiceCommandsAPI");
			}
			Harmony.PatchAll();
		}

		private static void NetcodePatcher()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		private void OnMicFrame(float[] buffer, int count, WaveFormat format)
		{
			_processor?.ProcessFrame(buffer, count, format);
		}

		private void OnPartialRecognition(string text)
		{
			CommandManager.Instance.OnPartialRecognition(text);
		}

		private void OnFinalRecognition(string text)
		{
			CommandManager.Instance.OnFinalRecognition(text);
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)NetworkHandler.Instance))
			{
				CommandManager.Instance.EnsureNetworkSubscription();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "DumbassStuff.VoiceCommandsAPI";

		public const string PLUGIN_NAME = "VoiceCommandsAPI";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace VoiceCommandsAPI.Networking
{
	public class NetworkHandler : NetworkBehaviour
	{
		public static NetworkHandler? Instance { get; private set; }

		public event Action<string, ulong>? OnRemoteCommandReceived;

		public event Action<string, ulong>? OnRemotePartialTextReceived;

		private void Awake()
		{
			Instance = this;
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			VoiceCommandsAPI.Logger.LogInfo((object)"[Network] NetworkHandler spawned");
		}

		public override void OnNetworkDespawn()
		{
			((NetworkBehaviour)this).OnNetworkDespawn();
			VoiceCommandsAPI.Logger.LogInfo((object)"[Network] NetworkHandler despawned");
		}

		public void BroadcastCommand(string command)
		{
			if (((NetworkBehaviour)this).IsSpawned)
			{
				BroadcastCommandServerRpc(command, NetworkManager.Singleton.LocalClientId);
			}
		}

		public void BroadcastPartialText(string text)
		{
			if (((NetworkBehaviour)this).IsSpawned)
			{
				BroadcastPartialTextServerRpc(text, NetworkManager.Singleton.LocalClientId);
			}
		}

		public void SendCommandToClient(string command, ulong targetClientId)
		{
			if (((NetworkBehaviour)this).IsSpawned)
			{
				SendCommandToClientServerRpc(command, NetworkManager.Singleton.LocalClientId, targetClientId);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void BroadcastCommandServerRpc(string command, ulong senderClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2590837682u, val, (RpcDelivery)0);
				bool flag = command != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(command, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2590837682u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				BroadcastCommandClientRpc(command, senderClientId);
			}
		}

		[ClientRpc]
		private void BroadcastCommandClientRpc(string command, ulong senderClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3023733758u, val, (RpcDelivery)0);
				bool flag = command != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(command, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3023733758u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && senderClientId != NetworkManager.Singleton.LocalClientId)
			{
				VoiceCommandsAPI.Logger.LogInfo((object)$"[Network] Received command from client {senderClientId}: '{command}'");
				this.OnRemoteCommandReceived?.Invoke(command, senderClientId);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void BroadcastPartialTextServerRpc(string text, ulong senderClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3825315514u, val, (RpcDelivery)0);
				bool flag = text != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(text, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3825315514u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				BroadcastPartialTextClientRpc(text, senderClientId);
			}
		}

		[ClientRpc]
		private void BroadcastPartialTextClientRpc(string text, ulong senderClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3416087208u, val, (RpcDelivery)0);
				bool flag = text != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(text, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3416087208u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && senderClientId != NetworkManager.Singleton.LocalClientId)
			{
				this.OnRemotePartialTextReceived?.Invoke(text, senderClientId);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void SendCommandToClientServerRpc(string command, ulong senderClientId, ulong targetClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1031174046u, val, (RpcDelivery)0);
				bool flag = command != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(command, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				BytePacker.WriteValueBitPacked(val2, targetClientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1031174046u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				SendCommandToClientClientRpc(command, senderClientId, targetClientId);
			}
		}

		[ClientRpc]
		private void SendCommandToClientClientRpc(string command, ulong senderClientId, ulong targetClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2400043513u, val, (RpcDelivery)0);
				bool flag = command != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(command, false);
				}
				BytePacker.WriteValueBitPacked(val2, senderClientId);
				BytePacker.WriteValueBitPacked(val2, targetClientId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2400043513u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && NetworkManager.Singleton.LocalClientId == targetClientId)
			{
				VoiceCommandsAPI.Logger.LogInfo((object)$"[Network] Received targeted command from client {senderClientId}: '{command}'");
				this.OnRemoteCommandReceived?.Invoke(command, senderClientId);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_NetworkHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2590837682u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_2590837682));
			NetworkManager.__rpc_func_table.Add(3023733758u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_3023733758));
			NetworkManager.__rpc_func_table.Add(3825315514u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_3825315514));
			NetworkManager.__rpc_func_table.Add(3416087208u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_3416087208));
			NetworkManager.__rpc_func_table.Add(1031174046u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_1031174046));
			NetworkManager.__rpc_func_table.Add(2400043513u, (RpcReceiveHandler)new RpcReceiveHandler(__rpc_handler_2400043513));
		}

		private static void __rpc_handler_2590837682(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string command = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref command, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).BroadcastCommandServerRpc(command, senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3023733758(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string command = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref command, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).BroadcastCommandClientRpc(command, senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3825315514(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string text = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).BroadcastPartialTextServerRpc(text, senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3416087208(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string text = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).BroadcastPartialTextClientRpc(text, senderClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1031174046(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string command = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref command, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				ulong targetClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SendCommandToClientServerRpc(command, senderClientId, targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2400043513(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string command = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref command, false);
				}
				ulong senderClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId);
				ulong targetClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).SendCommandToClientClientRpc(command, senderClientId, targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "NetworkHandler";
		}
	}
	[HarmonyPatch]
	public static class NetworkManagerPatch
	{
		private static GameObject? _networkHandlerObject;

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManagerStart(GameNetworkManager __instance)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			VoiceCommandsAPI.Logger.LogInfo((object)"[Network] GameNetworkManager started, registering network prefab");
			if (!((Object)(object)_networkHandlerObject != (Object)null))
			{
				_networkHandlerObject = new GameObject("VoiceCommandsNetworkHandler");
				_networkHandlerObject.AddComponent<NetworkObject>();
				_networkHandlerObject.AddComponent<NetworkHandler>();
				Object.DontDestroyOnLoad((Object)(object)_networkHandlerObject);
				NetworkManager.Singleton.AddNetworkPrefab(_networkHandlerObject);
				VoiceCommandsAPI.Logger.LogInfo((object)"[Network] Network prefab registered");
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void StartOfRoundAwake()
		{
			VoiceCommandsAPI.Logger.LogInfo((object)"[Network] StartOfRound awake, spawning NetworkHandler");
			if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && !((Object)(object)_networkHandlerObject == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(_networkHandlerObject);
				val.GetComponent<NetworkObject>().Spawn(false);
				VoiceCommandsAPI.Logger.LogInfo((object)"[Network] NetworkHandler spawned by host/server");
			}
		}
	}
}
namespace VoiceCommandsAPI.Audio
{
	public class AudioProcessor
	{
		private readonly VoskRecognizer _recognizer;

		public event Action<string> OnPartialText = delegate
		{
		};

		public event Action<string> OnFinalText = delegate
		{
		};

		public AudioProcessor(string modelPath)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			Vosk.SetLogLevel(0);
			Model val = new Model(modelPath);
			_recognizer = new VoskRecognizer(val, 16000f);
			_recognizer.SetWords(true);
		}

		public void ProcessFrame(float[] buffer, int count, WaveFormat format)
		{
			switch (format.SampleRate)
			{
			case 16000:
			{
				byte[] pcmBytes3 = FloatToPcm16Le(buffer, count);
				Dispatch(pcmBytes3);
				break;
			}
			case 48000:
			{
				short[] input2 = Decimate48KTo16K(buffer, count);
				byte[] pcmBytes2 = ShortsToBytesLe(input2);
				Dispatch(pcmBytes2);
				break;
			}
			default:
			{
				float[] array = ResampleTo16K(buffer, count, format.SampleRate);
				short[] input = FloatToShort(array, array.Length);
				byte[] pcmBytes = ShortsToBytesLe(input);
				Dispatch(pcmBytes);
				break;
			}
			}
		}

		private void Dispatch(byte[] pcmBytes)
		{
			if (_recognizer.AcceptWaveform(pcmBytes, pcmBytes.Length))
			{
				string json = _recognizer.Result();
				string text = ParseResult(json);
				if (!string.IsNullOrEmpty(text))
				{
					this.OnFinalText(text);
				}
			}
			else
			{
				string json2 = _recognizer.PartialResult();
				string text2 = ParseResult(json2);
				if (!string.IsNullOrEmpty(text2))
				{
					this.OnPartialText(text2);
				}
			}
		}

		private static string ParseResult(string json)
		{
			JObject val = JObject.Parse(json);
			return ((object)val["text"])?.ToString() ?? ((object)val["partial"])?.ToString() ?? string.Empty;
		}

		private static short[] Decimate48KTo16K(float[] input, int count)
		{
			int num = count / 3;
			short[] array = new short[num];
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				float num3 = input[num2];
				if (num3 > 1f)
				{
					num3 = 1f;
				}
				if (num3 < -1f)
				{
					num3 = -1f;
				}
				array[i] = (short)(num3 * 32767f);
				num2 += 3;
			}
			return array;
		}

		private static float[] ResampleTo16K(float[] input, int count, int inRate)
		{
			float num = (float)inRate / 16000f;
			int num2 = (int)((float)count / num);
			float[] array = new float[num2];
			float num3 = 0f;
			for (int i = 0; i < num2; i++)
			{
				int num4 = (int)num3;
				array[i] = input[num4];
				num3 += num;
			}
			return array;
		}

		private static byte[] FloatToPcm16Le(float[] input, int count)
		{
			byte[] array = new byte[count * 2];
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				float num2 = input[i];
				if (num2 > 1f)
				{
					num2 = 1f;
				}
				if (num2 < -1f)
				{
					num2 = -1f;
				}
				short num3 = (short)(num2 * 32767f);
				array[num++] = (byte)((uint)num3 & 0xFFu);
				array[num++] = (byte)((uint)(num3 >> 8) & 0xFFu);
			}
			return array;
		}

		private static short[] FloatToShort(float[] input, int count)
		{
			short[] array = new short[count];
			for (int i = 0; i < count; i++)
			{
				float num = input[i];
				if (num > 1f)
				{
					num = 1f;
				}
				if (num < -1f)
				{
					num = -1f;
				}
				array[i] = (short)(num * 32767f);
			}
			return array;
		}

		private static byte[] ShortsToBytesLe(short[] input)
		{
			byte[] array = new byte[input.Length * 2];
			Buffer.BlockCopy(input, 0, array, 0, array.Length);
			return array;
		}
	}
	public sealed class CaptureSubscriber : IMicrophoneSubscriber
	{
		public static readonly CaptureSubscriber Instance = new CaptureSubscriber();

		public event Action<float[], int, WaveFormat>? OnFrame;

		private CaptureSubscriber()
		{
		}

		public void ReceiveMicrophoneData(ArraySegment<float> buffer, WaveFormat format)
		{
			if (buffer.Array != null && buffer.Count != 0)
			{
				this.OnFrame?.Invoke(buffer.Array, buffer.Count, format);
			}
		}

		public void Reset()
		{
		}
	}
	[HarmonyPatch]
	public static class LocalMicrophoneCapture
	{
		[HarmonyPatch(typeof(BasicMicrophoneCapture), "StartCapture")]
		[HarmonyPostfix]
		private static void HookLocalMicrophone(BasicMicrophoneCapture __instance)
		{
			__instance.Subscribe((IMicrophoneSubscriber)(object)CaptureSubscriber.Instance);
			VoiceCommandsAPI.Logger.LogInfo((object)"[Capture] Hooked local microphone capture");
		}

		[HarmonyPatch(typeof(BasicMicrophoneCapture), "StopCapture")]
		[HarmonyPostfix]
		private static void UnhookLocalMicrophone(BasicMicrophoneCapture __instance)
		{
			__instance.Unsubscribe((IMicrophoneSubscriber)(object)CaptureSubscriber.Instance);
			CaptureSubscriber.Instance.Reset();
			VoiceCommandsAPI.Logger.LogInfo((object)"[Capture] Unhooked local microphone capture");
		}
	}
}
namespace VoiceCommandsAPI.API
{
	public class CommandManager
	{
		public static readonly CommandManager Instance = new CommandManager();

		private readonly Dictionary<string, Action> _exactCommands = new Dictionary<string, Action>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, Action<ulong>> _networkExactCommands = new Dictionary<string, Action<ulong>>(StringComparer.OrdinalIgnoreCase);

		private readonly List<(Func<string, bool> matcher, Action<string> handler)> _patternCommands = new List<(Func<string, bool>, Action<string>)>();

		private readonly List<(Func<string, bool> matcher, Action<string, ulong> handler)> _networkPatternCommands = new List<(Func<string, bool>, Action<string, ulong>)>();

		private readonly object _lock = new object();

		public event Action<string>? OnPartialText;

		public event Action<string>? OnFinalText;

		public event Action<string>? OnCommandRecognized;

		public event Action<string>? OnCommandNotMatched;

		public event Action<string, ulong>? OnRemotePartialText;

		public event Action<string, ulong>? OnRemoteFinalText;

		public event Action<string, ulong>? OnRemoteCommandRecognized;

		private CommandManager()
		{
			SubscribeToNetworkEvents();
		}

		private void SubscribeToNetworkEvents()
		{
			if ((Object)(object)NetworkHandler.Instance != (Object)null)
			{
				NetworkHandler.Instance.OnRemoteCommandReceived += HandleRemoteCommand;
				NetworkHandler.Instance.OnRemotePartialTextReceived += HandleRemotePartialText;
			}
		}

		public void EnsureNetworkSubscription()
		{
			if ((Object)(object)NetworkHandler.Instance != (Object)null)
			{
				NetworkHandler.Instance.OnRemoteCommandReceived -= HandleRemoteCommand;
				NetworkHandler.Instance.OnRemotePartialTextReceived -= HandleRemotePartialText;
				NetworkHandler.Instance.OnRemoteCommandReceived += HandleRemoteCommand;
				NetworkHandler.Instance.OnRemotePartialTextReceived += HandleRemotePartialText;
			}
		}

		public void RegisterCommand(string phrase, Action callback)
		{
			string key = phrase.Trim();
			lock (_lock)
			{
				_exactCommands[key] = callback;
			}
			VoiceCommandsAPI.Logger.LogInfo((object)("[API] Registered exact command: '" + phrase + "'"));
		}

		public void RegisterNetworkCommand(string phrase, Action<ulong> callback)
		{
			string key = phrase.Trim();
			lock (_lock)
			{
				_networkExactCommands[key] = callback;
			}
			VoiceCommandsAPI.Logger.LogInfo((object)("[API] Registered network command: '" + phrase + "'"));
		}

		public void RegisterPattern(Func<string, bool> matcher, Action<string> handler)
		{
			lock (_lock)
			{
				_patternCommands.Add((matcher, handler));
			}
			VoiceCommandsAPI.Logger.LogInfo((object)"[API] Registered pattern command");
		}

		public void RegisterNetworkPattern(Func<string, bool> matcher, Action<string, ulong> handler)
		{
			lock (_lock)
			{
				_networkPatternCommands.Add((matcher, handler));
			}
			VoiceCommandsAPI.Logger.LogInfo((object)"[API] Registered network pattern command");
		}

		public bool UnregisterCommand(string phrase)
		{
			string key = phrase.Trim();
			lock (_lock)
			{
				bool flag = _exactCommands.Remove(key) || _networkExactCommands.Remove(key);
				if (flag)
				{
					VoiceCommandsAPI.Logger.LogInfo((object)("[API] Unregistered command: '" + phrase + "'"));
				}
				return flag;
			}
		}

		public void UnregisterAll()
		{
			lock (_lock)
			{
				int count = _exactCommands.Count;
				int count2 = _networkExactCommands.Count;
				int count3 = _patternCommands.Count;
				int count4 = _networkPatternCommands.Count;
				_exactCommands.Clear();
				_networkExactCommands.Clear();
				_patternCommands.Clear();
				_networkPatternCommands.Clear();
				VoiceCommandsAPI.Logger.LogInfo((object)$"[API] Unregistered all commands ({count} exact, {count2} network exact, {count3} pattern, {count4} network pattern)");
			}
		}

		public IReadOnlyCollection<string> GetRegisteredCommands()
		{
			lock (_lock)
			{
				return _exactCommands.Keys.Concat(_networkExactCommands.Keys).ToList();
			}
		}

		public void BroadcastCommand(string command)
		{
			NetworkHandler.Instance?.BroadcastCommand(command);
		}

		public void BroadcastPartialText(string text)
		{
			NetworkHandler.Instance?.BroadcastPartialText(text);
		}

		public void SendCommandToClient(string command, ulong targetClientId)
		{
			NetworkHandler.Instance?.SendCommandToClient(command, targetClientId);
		}

		internal void OnPartialRecognition(string text)
		{
			this.OnPartialText?.Invoke(text);
		}

		internal void OnFinalRecognition(string text)
		{
			this.OnFinalText?.Invoke(text);
			string text2 = text.ToLowerInvariant().Trim();
			lock (_lock)
			{
				if (_exactCommands.TryGetValue(text2, out Action value))
				{
					VoiceCommandsAPI.Logger.LogInfo((object)("[API] Executing exact command: '" + text + "'"));
					this.OnCommandRecognized?.Invoke(text);
					value?.Invoke();
					return;
				}
				foreach (var (func, action) in _patternCommands)
				{
					if (!func(text2))
					{
						continue;
					}
					VoiceCommandsAPI.Logger.LogInfo((object)("[API] Executing pattern command: '" + text + "'"));
					this.OnCommandRecognized?.Invoke(text);
					action(text);
					return;
				}
			}
			VoiceCommandsAPI.Logger.LogDebug((object)("[API] No command matched: '" + text + "'"));
			this.OnCommandNotMatched?.Invoke(text);
		}

		private void HandleRemoteCommand(string command, ulong senderClientId)
		{
			this.OnRemoteFinalText?.Invoke(command, senderClientId);
			string text = command.ToLowerInvariant().Trim();
			lock (_lock)
			{
				if (_networkExactCommands.TryGetValue(text, out Action<ulong> value))
				{
					VoiceCommandsAPI.Logger.LogInfo((object)$"[API] Executing network command from client {senderClientId}: '{command}'");
					this.OnRemoteCommandRecognized?.Invoke(command, senderClientId);
					value?.Invoke(senderClientId);
					return;
				}
				foreach (var (func, action) in _networkPatternCommands)
				{
					if (!func(text))
					{
						continue;
					}
					VoiceCommandsAPI.Logger.LogInfo((object)$"[API] Executing network pattern command from client {senderClientId}: '{command}'");
					this.OnRemoteCommandRecognized?.Invoke(command, senderClientId);
					action(command, senderClientId);
					break;
				}
			}
		}

		private void HandleRemotePartialText(string text, ulong senderClientId)
		{
			this.OnRemotePartialText?.Invoke(text, senderClientId);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace DumbassStuff.VoiceCommandsAPI.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/Vosk.dll

Decompiled 2 months ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Vosk;

public class Model : IDisposable
{
	private HandleRef handle;

	internal Model(IntPtr cPtr)
	{
		handle = new HandleRef(this, cPtr);
	}

	public Model(string model_path)
		: this(VoskPINVOKE.new_Model(model_path))
	{
	}

	internal static HandleRef getCPtr(Model obj)
	{
		return obj?.handle ?? new HandleRef(null, IntPtr.Zero);
	}

	~Model()
	{
		Dispose(disposing: false);
	}

	public void Dispose()
	{
		Dispose(disposing: true);
		GC.SuppressFinalize(this);
	}

	protected virtual void Dispose(bool disposing)
	{
		lock (this)
		{
			if (handle.Handle != IntPtr.Zero)
			{
				VoskPINVOKE.delete_Model(handle);
				handle = new HandleRef(null, IntPtr.Zero);
			}
		}
	}

	public int FindWord(string word)
	{
		return VoskPINVOKE.Model_vosk_model_find_word(handle, word);
	}
}
public class SpkModel : IDisposable
{
	private HandleRef handle;

	internal SpkModel(IntPtr cPtr)
	{
		handle = new HandleRef(this, cPtr);
	}

	public SpkModel(string model_path)
		: this(VoskPINVOKE.new_SpkModel(model_path))
	{
	}

	internal static HandleRef getCPtr(SpkModel obj)
	{
		return obj?.handle ?? new HandleRef(null, IntPtr.Zero);
	}

	~SpkModel()
	{
		Dispose(disposing: false);
	}

	public void Dispose()
	{
		Dispose(disposing: true);
		GC.SuppressFinalize(this);
	}

	protected virtual void Dispose(bool disposing)
	{
		lock (this)
		{
			if (handle.Handle != IntPtr.Zero)
			{
				VoskPINVOKE.delete_SpkModel(handle);
				handle = new HandleRef(null, IntPtr.Zero);
			}
		}
	}
}
public class Vosk
{
	public static void SetLogLevel(int level)
	{
		VoskPINVOKE.SetLogLevel(level);
	}

	public static void GpuInit()
	{
		VoskPINVOKE.GpuInit();
	}

	public static void GpuThreadInit()
	{
		VoskPINVOKE.GpuThreadInit();
	}
}
internal class VoskPINVOKE
{
	static VoskPINVOKE()
	{
	}

	[DllImport("libvosk", EntryPoint = "vosk_model_new")]
	public static extern IntPtr new_Model(string jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_model_free")]
	public static extern void delete_Model(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_model_find_word")]
	public static extern int Model_vosk_model_find_word(HandleRef jarg1, string jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_spk_model_new")]
	public static extern IntPtr new_SpkModel(string jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_spk_model_free")]
	public static extern void delete_SpkModel(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_new")]
	public static extern IntPtr new_VoskRecognizer(HandleRef jarg1, float jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_new_spk")]
	public static extern IntPtr new_VoskRecognizerSpk(HandleRef jarg1, float jarg2, HandleRef jarg3);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_new_grm")]
	public static extern IntPtr new_VoskRecognizerGrm(HandleRef jarg1, float jarg2, string jarg3);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_free")]
	public static extern void delete_VoskRecognizer(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_set_max_alternatives")]
	public static extern void VoskRecognizer_SetMaxAlternatives(HandleRef jarg1, int jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_set_words")]
	public static extern void VoskRecognizer_SetWords(HandleRef jarg1, int jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_set_partial_words")]
	public static extern void VoskRecognizer_SetPartialWords(HandleRef jarg1, int jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_set_spk_model")]
	public static extern void VoskRecognizer_SetSpkModel(HandleRef jarg1, HandleRef jarg2);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform")]
	public static extern bool VoskRecognizer_AcceptWaveform(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] byte[] jarg2, int jarg3);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform_s")]
	public static extern bool VoskRecognizer_AcceptWaveformShort(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] short[] jarg2, int jarg3);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_accept_waveform_f")]
	public static extern bool VoskRecognizer_AcceptWaveformFloat(HandleRef jarg1, [In][MarshalAs(UnmanagedType.LPArray)] float[] jarg2, int jarg3);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_result")]
	public static extern IntPtr VoskRecognizer_Result(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_partial_result")]
	public static extern IntPtr VoskRecognizer_PartialResult(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_final_result")]
	public static extern IntPtr VoskRecognizer_FinalResult(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_recognizer_reset")]
	public static extern void VoskRecognizer_Reset(HandleRef jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_set_log_level")]
	public static extern void SetLogLevel(int jarg1);

	[DllImport("libvosk", EntryPoint = "vosk_gpu_init")]
	public static extern void GpuInit();

	[DllImport("libvosk", EntryPoint = "vosk_gpu_thread_init")]
	public static extern void GpuThreadInit();
}
public class VoskRecognizer : IDisposable
{
	private HandleRef handle;

	internal VoskRecognizer(IntPtr cPtr)
	{
		handle = new HandleRef(this, cPtr);
	}

	public VoskRecognizer(Model model, float sample_rate)
		: this(VoskPINVOKE.new_VoskRecognizer(Model.getCPtr(model), sample_rate))
	{
	}

	public VoskRecognizer(Model model, float sample_rate, SpkModel spk_model)
		: this(VoskPINVOKE.new_VoskRecognizerSpk(Model.getCPtr(model), sample_rate, SpkModel.getCPtr(spk_model)))
	{
	}

	public VoskRecognizer(Model model, float sample_rate, string grammar)
		: this(VoskPINVOKE.new_VoskRecognizerGrm(Model.getCPtr(model), sample_rate, grammar))
	{
	}

	internal static HandleRef getCPtr(VoskRecognizer obj)
	{
		return obj?.handle ?? new HandleRef(null, IntPtr.Zero);
	}

	~VoskRecognizer()
	{
		Dispose(disposing: false);
	}

	public void Dispose()
	{
		Dispose(disposing: true);
		GC.SuppressFinalize(this);
	}

	protected virtual void Dispose(bool disposing)
	{
		lock (this)
		{
			if (handle.Handle != IntPtr.Zero)
			{
				VoskPINVOKE.delete_VoskRecognizer(handle);
				handle = new HandleRef(null, IntPtr.Zero);
			}
		}
	}

	public void SetMaxAlternatives(int max_alternatives)
	{
		VoskPINVOKE.VoskRecognizer_SetMaxAlternatives(handle, max_alternatives);
	}

	public void SetWords(bool words)
	{
		VoskPINVOKE.VoskRecognizer_SetWords(handle, words ? 1 : 0);
	}

	public void SetPartialWords(bool partial_words)
	{
		VoskPINVOKE.VoskRecognizer_SetPartialWords(handle, partial_words ? 1 : 0);
	}

	public void SetSpkModel(SpkModel spk_model)
	{
		VoskPINVOKE.VoskRecognizer_SetSpkModel(handle, SpkModel.getCPtr(spk_model));
	}

	public bool AcceptWaveform(byte[] data, int len)
	{
		return VoskPINVOKE.VoskRecognizer_AcceptWaveform(handle, data, len);
	}

	public bool AcceptWaveform(short[] sdata, int len)
	{
		return VoskPINVOKE.VoskRecognizer_AcceptWaveformShort(handle, sdata, len);
	}

	public bool AcceptWaveform(float[] fdata, int len)
	{
		return VoskPINVOKE.VoskRecognizer_AcceptWaveformFloat(handle, fdata, len);
	}

	private static string PtrToStringUTF8(IntPtr ptr)
	{
		int i;
		for (i = 0; Marshal.ReadByte(ptr, i) != 0; i++)
		{
		}
		byte[] array = new byte[i];
		Marshal.Copy(ptr, array, 0, i);
		return Encoding.UTF8.GetString(array);
	}

	public string Result()
	{
		return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_Result(handle));
	}

	public string PartialResult()
	{
		return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_PartialResult(handle));
	}

	public string FinalResult()
	{
		return PtrToStringUTF8(VoskPINVOKE.VoskRecognizer_FinalResult(handle));
	}

	public void Reset()
	{
		VoskPINVOKE.VoskRecognizer_Reset(handle);
	}
}