using System;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Windows.Speech;
[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("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SpeechControl")]
[assembly: AssemblyTitle("SpeechControl")]
[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 Empress.VoiceCommands
{
[BepInPlugin("gg.empress.repo.voicecommands", "Empress Voice Commands", "1.0.1")]
public class VoiceCommandActionsPlugin : BaseUnityPlugin
{
[HarmonyPatch]
private static class InputManager_KeyPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(InputManager), "KeyHold")]
private static void KeyHold_Postfix(InputKey key, ref bool __result)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Invalid comparison between Unknown and I4
if (Chainloader.PluginInfos.ContainsKey("gg.empress.repo.voicecommands") && (int)key == 10 && VoiceGrabHold)
{
__result = true;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(InputManager), "KeyDown")]
private static void KeyDown_Postfix(InputKey key, ref bool __result)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Invalid comparison between Unknown and I4
if (Chainloader.PluginInfos.ContainsKey("gg.empress.repo.voicecommands") && !__result)
{
if ((int)key == 2 && InteractPulseFrames > 0)
{
__result = true;
}
else if ((int)key == 9 && ConfirmPulseFrames > 0)
{
__result = true;
}
}
}
}
public const string PluginGuid = "gg.empress.repo.voicecommands";
public const string PluginName = "Empress Voice Commands";
public const string PluginVersion = "1.0.1";
private Harmony _harmony;
private ConfigEntry<bool> _enabled;
private ConfigEntry<string> _keywordsCsv;
private ConfigEntry<float> _shootToggleHoldSeconds;
private ConfigEntry<int> _pressFrames;
private ConfigEntry<bool> _logDebug;
internal static bool VoiceGrabHold;
internal static int InteractPulseFrames;
internal static int ConfirmPulseFrames;
internal static float ShootToggleHoldTimer;
internal static bool ShootToggleArmed;
private KeywordRecognizer _recognizer;
private Dictionary<string, Action> _handlers;
private void Awake()
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Expected O, but got Unknown
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master enable for the plugin.");
_keywordsCsv = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Keywords", "grab,drop,shoot,tranq,use,press", "Comma-separated keywords to listen for. Supported actions: grab, drop, shoot, tranq, use, press.");
_shootToggleHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "ShootToggleHoldSeconds", 0.06f, "How long to keep ItemToggle set when faking a shot (seconds). Useful for weapons that read a toggle edge.");
_pressFrames = ((BaseUnityPlugin)this).Config.Bind<int>("Timing", "KeyPressFrames", 2, "How many frames a voice-triggered key press should be reported as down (Interact/Confirm).");
_logDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogDebug", false, "Verbose logging.");
_harmony = new Harmony("gg.empress.repo.voicecommands");
_harmony.PatchAll(typeof(InputManager_KeyPatches));
TryInitSpeech();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Empress Voice Commands 1.0.1 loaded.");
}
private void OnDestroy()
{
try
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch
{
}
try
{
KeywordRecognizer recognizer = _recognizer;
if (recognizer != null)
{
((PhraseRecognizer)recognizer).Stop();
}
KeywordRecognizer recognizer2 = _recognizer;
if (recognizer2 != null)
{
((PhraseRecognizer)recognizer2).Dispose();
}
}
catch
{
}
}
private void Update()
{
if (!_enabled.Value)
{
return;
}
if (InteractPulseFrames > 0)
{
InteractPulseFrames--;
}
if (ConfirmPulseFrames > 0)
{
ConfirmPulseFrames--;
}
if (ShootToggleArmed)
{
ShootToggleHoldTimer -= Time.unscaledDeltaTime;
if (ShootToggleHoldTimer <= 0f)
{
ShootToggleArmed = false;
ToggleCurrentItem(state: false);
}
}
}
private void TryInitSpeech()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Expected O, but got Unknown
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Expected O, but got Unknown
if (!_enabled.Value)
{
return;
}
if ((int)Application.platform != 2 && (int)Application.platform != 7)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Windows speech only supported on Windows. Voice commands disabled.");
return;
}
List<string> list = ParseKeywords(_keywordsCsv.Value);
if (list.Count == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"No keywords configured; voice commands disabled.");
return;
}
_handlers = new Dictionary<string, Action>(StringComparer.InvariantCultureIgnoreCase)
{
{ "grab", OnGrab },
{ "drop", OnDrop },
{ "use", OnUse },
{ "press", OnPress },
{ "shoot", OnShoot },
{ "tranq", OnShoot }
};
List<string> list2 = new List<string>();
foreach (string item in list)
{
if (_handlers.ContainsKey(item))
{
list2.Add(item);
}
}
if (list2.Count == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Configured keywords had no supported actions. Nothing to listen for.");
return;
}
try
{
_recognizer = new KeywordRecognizer(list2.ToArray(), (ConfidenceLevel)2);
((PhraseRecognizer)_recognizer).OnPhraseRecognized += (PhraseRecognizedDelegate)delegate(PhraseRecognizedEventArgs evt)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
string text = evt.text;
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Heard '{text}' (conf {evt.confidence}).");
}
if (_handlers.TryGetValue(text, out Action value))
{
try
{
value?.Invoke();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
};
((PhraseRecognizer)_recognizer).Start();
((BaseUnityPlugin)this).Logger.LogInfo((object)("Voice listening started for: " + string.Join(", ", list2)));
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to start KeywordRecognizer: {arg}");
}
}
private static List<string> ParseKeywords(string csv)
{
List<string> list = new List<string>();
if (string.IsNullOrWhiteSpace(csv))
{
return list;
}
string[] array = csv.Split(',');
foreach (string text in array)
{
string text2 = text.Trim();
if (!string.IsNullOrEmpty(text2))
{
list.Add(text2.ToLowerInvariant());
}
}
return list;
}
private void OnGrab()
{
VoiceGrabHold = true;
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] GRAB -> hold enabled");
}
}
private void OnDrop()
{
VoiceGrabHold = false;
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] DROP -> hold disabled");
}
}
private void OnUse()
{
InteractPulseFrames = Mathf.Max(1, _pressFrames.Value);
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VC] USE -> Interact pulse {InteractPulseFrames} frames");
}
}
private void OnPress()
{
ConfirmPulseFrames = Mathf.Max(1, _pressFrames.Value);
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VC] PRESS -> Confirm pulse {ConfirmPulseFrames} frames");
}
}
private void OnShoot()
{
PhysGrabber instance = PhysGrabber.instance;
if ((Object)(object)instance == (Object)null)
{
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] SHOOT -> no PhysGrabber instance");
}
return;
}
PhysGrabObject grabbedPhysGrabObject = instance.grabbedPhysGrabObject;
if ((Object)(object)grabbedPhysGrabObject == (Object)null || !grabbedPhysGrabObject.grabbedLocal)
{
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] SHOOT -> nothing grabbed locally");
}
return;
}
ItemGun component = ((Component)grabbedPhysGrabObject).GetComponent<ItemGun>();
if ((Object)(object)component != (Object)null)
{
try
{
component.Shoot();
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] SHOOT -> ItemGun.Shoot()");
}
return;
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"[VC] SHOOT -> ItemGun.Shoot() failed: {arg}");
return;
}
}
if (ToggleCurrentItem(state: true))
{
ShootToggleHoldTimer = Mathf.Max(0.01f, _shootToggleHoldSeconds.Value);
ShootToggleArmed = true;
if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] SHOOT -> ItemToggle pulse");
}
}
else if (_logDebug.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[VC] SHOOT -> no supported shooter on held object");
}
}
private static bool ToggleCurrentItem(bool state)
{
PhysGrabber instance = PhysGrabber.instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
PhysGrabObject grabbedPhysGrabObject = instance.grabbedPhysGrabObject;
if ((Object)(object)grabbedPhysGrabObject == (Object)null)
{
return false;
}
ItemToggle component = ((Component)grabbedPhysGrabObject).GetComponent<ItemToggle>();
if ((Object)(object)component == (Object)null)
{
return false;
}
try
{
component.ToggleItem(state, -1);
}
catch
{
return false;
}
return true;
}
}
}
namespace SpeechControl
{
[BepInPlugin("Omniscye.SpeechControl", "SpeechControl", "1.0")]
public class SpeechControl : BaseUnityPlugin
{
internal static SpeechControl Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Patch();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
internal void Patch()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0026: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
}
}
}