Decompiled source of StoneStick v3.0.4

Mods/StoneStickByNano.dll

Decompiled 2 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using ButtonLoco;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.Players.Subsystems;
using Il2CppRUMBLE.Serialization;
using Il2CppRUMBLE.Utilities;
using Il2CppSystem;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(ButtonLocoMod), "Stone Stick By Nano", "3.0.4", "Nano", null)]
[assembly: MelonColor(127, 52, 235, 131)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 ButtonLoco
{
	internal static class BocoLoggor
	{
		private static bool DiagnosticsEnabled = false;

		private const float InputLogCooldownSeconds = 3f;

		private const float StateLogCooldownSeconds = 20f;

		private const float SprintLogCooldownSeconds = 8f;

		private static bool _initialized;

		private static Vector2 _lastInput = Vector2.zero;

		private static bool _hasInputSample;

		private static float _lastInputLogTime;

		private static float _lastStateLogTime;

		private static float _lastSprintLogTime;

		private static string _lastActiveMovementType = string.Empty;

		private static string _lastSuppressedType = string.Empty;

		private static bool _suppressionLogged;

		public static void Initialize(object logger)
		{
			if (!_initialized)
			{
				_initialized = true;
				if (DiagnosticsEnabled)
				{
					Log("StoneStick diagnostics ready (rate-limited).");
				}
			}
		}

		public static void OnActiveMovementTypeObserved(object activeType)
		{
			if (DiagnosticsEnabled && _initialized)
			{
				string text = activeType?.ToString() ?? "n/a";
				if (!string.Equals(text, _lastActiveMovementType, StringComparison.Ordinal))
				{
					_lastActiveMovementType = text;
					_suppressionLogged = false;
					_lastSuppressedType = string.Empty;
					Log("StoneStick state | activeMovementType=" + text);
				}
			}
		}

		public static void OnMovementSuppressed(string activeType)
		{
			if (DiagnosticsEnabled && _initialized)
			{
				string text = (string.IsNullOrWhiteSpace(activeType) ? "n/a" : activeType);
				if (!_suppressionLogged || !string.Equals(text, _lastSuppressedType, StringComparison.Ordinal))
				{
					_suppressionLogged = true;
					_lastSuppressedType = text;
					Log("StoneStick state | movement override paused (activeMovementType=" + text + ")");
				}
			}
		}

		public static void OnMovementApplied(PlayerMovement movement, Vector2 finalInput)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (DiagnosticsEnabled && _initialized)
			{
				_suppressionLogged = false;
				_lastSuppressedType = string.Empty;
				TryLogInput(finalInput);
				TryLogStateSnapshot(movement, finalInput);
			}
		}

		public static void OnSprintScaled(Vector2 baseInput, float sprintFactor, float scale, Vector2 result)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (DiagnosticsEnabled && _initialized && !(((Vector2)(ref result)).sqrMagnitude < 0.0001f) && !(scale <= 1.01f) && !(Time.time - _lastSprintLogTime < 8f))
			{
				_lastSprintLogTime = Time.time;
				Log($"StoneStick sprint scale | base={baseInput} factor={sprintFactor:0.00} scale={scale:0.00} result={result}");
			}
		}

		private static void TryLogInput(Vector2 finalInput)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.time - _lastInputLogTime < 3f))
			{
				bool num = !_hasInputSample || Mathf.Abs(finalInput.x - _lastInput.x) > 0.1f || Mathf.Abs(finalInput.y - _lastInput.y) > 0.1f;
				bool flag = (_hasInputSample && ((Vector2)(ref _lastInput)).sqrMagnitude < 0.001f && ((Vector2)(ref finalInput)).sqrMagnitude >= 0.001f) || (_hasInputSample && ((Vector2)(ref _lastInput)).sqrMagnitude >= 0.001f && ((Vector2)(ref finalInput)).sqrMagnitude < 0.001f);
				if (num || flag)
				{
					_hasInputSample = true;
					_lastInput = finalInput;
					_lastInputLogTime = Time.time;
					Log($"StoneStick input | final={finalInput}");
				}
			}
		}

		private static void TryLogStateSnapshot(PlayerMovement movement, Vector2 finalInput)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)movement == (Object)null) && !(((Vector2)(ref finalInput)).sqrMagnitude < 0.001f) && !(Time.time - _lastStateLogTime < 20f))
			{
				_lastStateLogTime = Time.time;
				object obj = ReadPropertyValue(movement, "activeMovementType");
				object obj2 = ReadPropertyValue(movement, "currentSprintFactor");
				object obj3 = ReadPropertyValue(movement, "desiredMovementVelocity");
				object obj4 = ReadPropertyValue(movement, "maxSprintVectorLength");
				object obj5 = TryCallMethod(movement, "IsGrounded");
				object obj6 = TryCallMethod(movement, "GetSurfaceSpeedMultiplier");
				Log(string.Format("StoneStick state | input={0} active={1} grounded={2} ", finalInput, obj ?? "n/a", obj5 ?? "n/a") + string.Format("surface={0} sprintFactor={1} desiredVel={2} ", obj6 ?? "n/a", obj2 ?? "n/a", obj3 ?? "n/a") + string.Format("maxSprint={0}", obj4 ?? "n/a"));
			}
		}

		private static void Log(string message)
		{
			ButtonLocoMod instance = ButtonLocoMod.Instance;
			if (instance != null)
			{
				Instance loggerInstance = ((MelonBase)instance).LoggerInstance;
				if (loggerInstance != null)
				{
					loggerInstance.Msg(message);
				}
			}
		}

		public static void PttLog(string message)
		{
			ButtonLocoMod instance = ButtonLocoMod.Instance;
			if (instance != null)
			{
				Instance loggerInstance = ((MelonBase)instance).LoggerInstance;
				if (loggerInstance != null)
				{
					loggerInstance.Msg(message);
				}
			}
		}

		public static void PttWarn(string message)
		{
			ButtonLocoMod instance = ButtonLocoMod.Instance;
			if (instance != null)
			{
				Instance loggerInstance = ((MelonBase)instance).LoggerInstance;
				if (loggerInstance != null)
				{
					loggerInstance.Warning(message);
				}
			}
		}

		private static object ReadPropertyValue(PlayerMovement movement, string propName)
		{
			if ((Object)(object)movement == (Object)null)
			{
				return null;
			}
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				return ((object)movement).GetType().GetProperty(propName, bindingAttr)?.GetValue(movement);
			}
			catch
			{
				return null;
			}
		}

		private static object TryCallMethod(PlayerMovement movement, string methodName)
		{
			if ((Object)(object)movement == (Object)null)
			{
				return null;
			}
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo method = ((object)movement).GetType().GetMethod(methodName, bindingAttr);
				if (method == null || method.GetParameters().Length != 0)
				{
					return null;
				}
				return method.Invoke(movement, null);
			}
			catch
			{
				return null;
			}
		}
	}
	public sealed class ButtonLocoMod : MelonMod
	{
		internal static ButtonLocoMod Instance;

		private const string HarmonyId = "nano.stonestick.buttonloco";

		private static bool _patched;

		private static bool _inputFaulted;

		private static float _lastInputFaultLogTime;

		private static Camera _cachedCamera;

		private const bool EnableSprintMultiplier = true;

		private const float SprintMultiplier = 1f;

		private const bool ForceInstantSprint = false;

		private static bool _inputSystemReady;

		private static InputAction _moveAction;

		public override void OnInitializeMelon()
		{
			Instance = this;
			TryPatch();
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (!_patched)
			{
				TryPatch();
			}
		}

		public override void OnLateInitializeMelon()
		{
			TrySetupInputSystem();
			PTTREVOLT.Initialize(((MelonBase)this).LoggerInstance);
			BocoLoggor.Initialize(((MelonBase)this).LoggerInstance);
		}

		public override void OnUpdate()
		{
			PTTREVOLT.OnUpdate();
		}

		public override void OnLateUpdate()
		{
			PTTREVOLT.OnLateUpdate();
		}

		private void TryPatch()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerMovement), "Move", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				((MelonBase)this).LoggerInstance.Error("PlayerMovement.Move not found.");
				return;
			}
			new Harmony("nano.stonestick.buttonloco").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ButtonLocoMod), "PlayerMovement_Move_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_patched = true;
			((MelonBase)this).LoggerInstance.Msg("Stone Stick: patched PlayerMovement.Move");
		}

		private static void PlayerMovement_Move_Prefix(PlayerMovement __instance, ref Vector2 __0)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (Instance == null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (_inputFaulted)
			{
				__0 = Vector2.zero;
			}
			else
			{
				if (!Instance.ShouldOverrideMovement(__instance))
				{
					return;
				}
				try
				{
					__0 = Instance.GetButtonMovementVector(__instance);
				}
				catch (Exception arg)
				{
					_inputFaulted = true;
					if (Time.time - _lastInputFaultLogTime > 5f)
					{
						_lastInputFaultLogTime = Time.time;
						((MelonBase)Instance).LoggerInstance.Error($"Stone Stick input disabled due to exception: {arg}");
					}
					__0 = Vector2.zero;
				}
			}
		}

		private Vector2 GetButtonMovementVector(PlayerMovement movement)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Vector2 val = ReadMoveInput();
			if (((Vector2)(ref val)).sqrMagnitude > 1f)
			{
				((Vector2)(ref val)).Normalize();
			}
			Vector2 input = val;
			val = ApplySprintMultiplier(movement, input);
			TrySetLatestSprintingHeadingVector(movement, input);
			BocoLoggor.OnMovementApplied(movement, val);
			return val;
		}

		private bool ShouldOverrideMovement(PlayerMovement movement)
		{
			object obj = ReadPropertyValue(movement, "activeMovementType");
			BocoLoggor.OnActiveMovementTypeObserved(obj);
			if (obj == null)
			{
				return true;
			}
			string text = obj.ToString();
			if (!string.Equals(text, "Normal", StringComparison.OrdinalIgnoreCase))
			{
				BocoLoggor.OnMovementSuppressed(text);
				return false;
			}
			return true;
		}

		private static object ReadPropertyValue(PlayerMovement movement, string propName)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			PropertyInfo property = ((object)movement).GetType().GetProperty(propName, bindingAttr);
			if (property == null)
			{
				return null;
			}
			try
			{
				return property.GetValue(movement);
			}
			catch
			{
				return null;
			}
		}

		private Vector2 ReadMoveInput()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (!_inputSystemReady)
			{
				TrySetupInputSystem();
			}
			if (_inputSystemReady && _moveAction != null)
			{
				try
				{
					return _moveAction.ReadValue<Vector2>();
				}
				catch
				{
					_inputSystemReady = false;
				}
			}
			return Vector2.zero;
		}

		private void TrySetupInputSystem()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (_inputSystemReady)
			{
				return;
			}
			try
			{
				_moveAction = new InputAction("StoneStickMove", (InputActionType)0, (string)null, (string)null, (string)null, "Vector2");
				InputActionSetupExtensions.AddCompositeBinding(_moveAction, "2DVector", (string)null, (string)null).With("Up", "<XRController>{LeftHand}/primaryButton", (string)null, (string)null).With("Left", "<XRController>{LeftHand}/secondaryButton", (string)null, (string)null)
					.With("Down", "<XRController>{RightHand}/primaryButton", (string)null, (string)null)
					.With("Right", "<XRController>{RightHand}/secondaryButton", (string)null, (string)null);
				_moveAction.Enable();
				_inputSystemReady = true;
			}
			catch (Exception ex)
			{
				_inputSystemReady = false;
				((MelonBase)this).LoggerInstance.Warning("Stone Stick input system init failed: " + ex.Message);
			}
		}

		private Vector2 ApplySprintMultiplier(PlayerMovement movement, Vector2 input)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)movement == (Object)null || ((Vector2)(ref input)).sqrMagnitude < 0.0001f)
			{
				return input;
			}
			object obj = ReadPropertyValue(movement, "currentSprintFactor");
			if (obj == null)
			{
				return input;
			}
			if (ReadPropertyValue(movement, "sprintingPoseSet") == null)
			{
				return input;
			}
			float num;
			try
			{
				num = Convert.ToSingle(obj);
			}
			catch
			{
				return input;
			}
			if (num <= 1f)
			{
				return input;
			}
			float num2 = 1f;
			object obj3 = ReadPropertyValue(movement, "maxSprintVectorLength");
			if (obj3 != null)
			{
				try
				{
					num2 = Mathf.Max(1f, Convert.ToSingle(obj3));
				}
				catch
				{
					num2 = 1f;
				}
			}
			float num3 = Mathf.Min(num, num2);
			num3 *= 1f;
			Vector2 result = input * num3;
			BocoLoggor.OnSprintScaled(input, num, num3, result);
			return result;
		}

		private static void TrySetLatestSprintingHeadingVector(PlayerMovement movement, Vector2 input)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)movement == (Object)null || ((Vector2)(ref input)).sqrMagnitude < 0.0001f)
			{
				return;
			}
			float num;
			try
			{
				object obj = ReadPropertyValue(movement, "currentSprintFactor");
				if (obj == null)
				{
					return;
				}
				num = Convert.ToSingle(obj);
			}
			catch
			{
				return;
			}
			if (num <= 0f || !TryGetHeadingRotation(movement, out var headingRotation))
			{
				return;
			}
			Vector3 val = headingRotation * new Vector3(input.x, 0f, input.y);
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			PropertyInfo property = ((object)movement).GetType().GetProperty("latestSprintingHeadingVector", bindingAttr);
			if (property == null || !property.CanWrite)
			{
				return;
			}
			try
			{
				if (property.PropertyType == typeof(Vector3))
				{
					property.SetValue(movement, val);
				}
				else if (property.PropertyType == typeof(Vector2))
				{
					property.SetValue(movement, (object)new Vector2(val.x, val.z));
				}
			}
			catch
			{
			}
		}

		private static bool TryGetHeadingRotation(PlayerMovement movement, out Quaternion headingRotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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)
			headingRotation = Quaternion.identity;
			Camera camera = GetCamera();
			if ((Object)(object)camera != (Object)null)
			{
				Quaternion rotation = ((Component)camera).transform.rotation;
				headingRotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
				return true;
			}
			if ((Object)(object)movement != (Object)null && (Object)(object)((Component)movement).transform != (Object)null)
			{
				Quaternion rotation2 = ((Component)movement).transform.rotation;
				headingRotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation2)).eulerAngles.y, 0f);
				return true;
			}
			return false;
		}

		private static Camera GetCamera()
		{
			if ((Object)(object)_cachedCamera != (Object)null && ((Behaviour)_cachedCamera).enabled && ((Component)_cachedCamera).gameObject.activeInHierarchy)
			{
				return _cachedCamera;
			}
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && ((Behaviour)main).enabled && ((Component)main).gameObject.activeInHierarchy)
			{
				_cachedCamera = main;
				return _cachedCamera;
			}
			int allCamerasCount = Camera.allCamerasCount;
			if (allCamerasCount <= 0)
			{
				return null;
			}
			Camera[] array = (Camera[])(object)new Camera[allCamerasCount];
			int allCameras = Camera.GetAllCameras(Il2CppReferenceArray<Camera>.op_Implicit(array));
			for (int i = 0; i < allCameras; i++)
			{
				Camera val = array[i];
				if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy && val.stereoEnabled)
				{
					_cachedCamera = val;
					return _cachedCamera;
				}
			}
			_cachedCamera = array[0];
			return _cachedCamera;
		}
	}
	internal static class PTTREVOLT
	{
		private const float MicThresholdOn = 0.0353f;

		private const float MicThresholdOff = 10f;

		private static bool EnableRecorderTransmitForce;

		private static bool _initialized;

		private static bool _loggedInputReady;

		private static bool _loggedMicModeSkip;

		private static InputAction _rightTriggerAction;

		private static bool _inputReady;

		private static bool _appliedAnyValue;

		private static bool _stableTriggerPressed;

		private static bool? _lastAppliedTriggerState;

		private static float _lastTriggerChangeTime;

		private const float TriggerToggleDebounceSeconds = 0.12f;

		private static PlayerVoiceSystem _voiceSystem;

		private static float _lastVoiceFindTime;

		private static PropertyInfo _recorderProperty;

		private static PropertyInfo _transmitEnabledProperty;

		private static object _cachedRecorder;

		public static void Initialize(Instance logger)
		{
			if (!_initialized)
			{
				_initialized = true;
				TrySetupInput();
			}
		}

		public static void OnUpdate()
		{
			Tick(enforceLate: false);
		}

		public static void OnLateUpdate()
		{
			Tick(enforceLate: true);
		}

		private static void Tick(bool enforceLate)
		{
			if (!_initialized)
			{
				return;
			}
			if (!IsPushToTalkEnabled())
			{
				_appliedAnyValue = false;
				_stableTriggerPressed = false;
				_lastAppliedTriggerState = null;
				if (!_loggedMicModeSkip)
				{
					_loggedMicModeSkip = true;
					Log("PTTREVOLT: mic override paused (voice mode is not push-to-talk).");
				}
				return;
			}
			if (_loggedMicModeSkip)
			{
				_loggedMicModeSkip = false;
				Log("PTTREVOLT: push-to-talk detected, trigger mic override active.");
			}
			bool stableTriggerPressed = GetStableTriggerPressed();
			if (!_appliedAnyValue || !_lastAppliedTriggerState.HasValue || stableTriggerPressed != _lastAppliedTriggerState.Value)
			{
				float num = (stableTriggerPressed ? 0.0353f : 10f);
				if (TryApplyOpenMicThreshold(num))
				{
					_appliedAnyValue = true;
					_lastAppliedTriggerState = stableTriggerPressed;
					Log($"PTTREVOLT threshold | trigger={stableTriggerPressed} threshold={num:0.0000}");
				}
			}
			if (EnableRecorderTransmitForce)
			{
				TryForceRecorderTransmit(stableTriggerPressed);
			}
		}

		private static bool IsRightTriggerPressed()
		{
			if (!_inputReady)
			{
				TrySetupInput();
			}
			if (!_inputReady || _rightTriggerAction == null)
			{
				return false;
			}
			try
			{
				return _rightTriggerAction.IsPressed();
			}
			catch
			{
				_inputReady = false;
				return false;
			}
		}

		private static bool GetStableTriggerPressed()
		{
			bool flag = IsRightTriggerPressed();
			if (flag == _stableTriggerPressed)
			{
				return _stableTriggerPressed;
			}
			if (Time.time - _lastTriggerChangeTime < 0.12f)
			{
				return _stableTriggerPressed;
			}
			_lastTriggerChangeTime = Time.time;
			_stableTriggerPressed = flag;
			return _stableTriggerPressed;
		}

		private static void TrySetupInput()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (_inputReady)
			{
				return;
			}
			try
			{
				_rightTriggerAction = new InputAction("StoneStickRightTriggerButton", (InputActionType)1, (string)null, (string)null, (string)null, "Button");
				InputActionSetupExtensions.AddBinding(_rightTriggerAction, "<XRController>{RightHand}/triggerPressed", (string)null, (string)null, (string)null);
				_rightTriggerAction.Enable();
				_inputReady = true;
				if (!_loggedInputReady)
				{
					_loggedInputReady = true;
					Log("PTTREVOLT: right trigger button input ready.");
				}
			}
			catch (Exception ex)
			{
				_inputReady = false;
				Warn("PTTREVOLT: failed to init trigger input: " + ex.Message);
			}
		}

		private static bool TryApplyOpenMicThreshold(float value)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			try
			{
				AudioManager instance = Singleton<AudioManager>.instance;
				if ((Object)(object)instance == (Object)null || ((Object)instance).Equals((Object)null))
				{
					return false;
				}
				VoiceConfiguration val = new VoiceConfiguration(instance.voiceConfig);
				val.OpenMicrophoneTreshold = value;
				instance.ApplyVoiceConfiguration(val);
				return true;
			}
			catch (Exception ex)
			{
				Warn("PTTREVOLT: failed applying mic threshold: " + ex.Message);
				return false;
			}
		}

		private static bool IsPushToTalkEnabled()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				AudioManager instance = Singleton<AudioManager>.instance;
				if ((Object)(object)instance == (Object)null || ((Object)instance).Equals((Object)null))
				{
					return false;
				}
				MicrophoneMode micMode = instance.voiceConfig.MicMode;
				string text = ((object)(MicrophoneMode)(ref micMode)).ToString();
				if (string.IsNullOrWhiteSpace(text))
				{
					return false;
				}
				string text2 = text.ToLowerInvariant();
				return text2.Contains("push") || text2.Contains("ptt") || (text2.Contains("hold") && text2.Contains("talk"));
			}
			catch
			{
				return false;
			}
		}

		private static void TryForceRecorderTransmit(bool triggerPressed)
		{
			object recorderObject = GetRecorderObject();
			if (recorderObject == null || _transmitEnabledProperty == null)
			{
				return;
			}
			try
			{
				object value = _transmitEnabledProperty.GetValue(recorderObject);
				bool flag = default(bool);
				int num;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != (triggerPressed ? 1u : 0u))
				{
					_transmitEnabledProperty.SetValue(recorderObject, triggerPressed);
				}
			}
			catch
			{
			}
		}

		private static object GetRecorderObject()
		{
			if ((Object)(object)_voiceSystem == (Object)null || ((Object)_voiceSystem).Equals((Object)null))
			{
				if (Time.time - _lastVoiceFindTime < 1f)
				{
					return null;
				}
				_lastVoiceFindTime = Time.time;
				_voiceSystem = Object.FindObjectOfType<PlayerVoiceSystem>();
				_recorderProperty = null;
				_transmitEnabledProperty = null;
				_cachedRecorder = null;
				if ((Object)(object)_voiceSystem == (Object)null || ((Object)_voiceSystem).Equals((Object)null))
				{
					return null;
				}
				Log("PTTREVOLT: PlayerVoiceSystem found.");
			}
			if (_recorderProperty == null)
			{
				try
				{
					BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
					_recorderProperty = ((object)_voiceSystem).GetType().GetProperty("recorder", bindingAttr);
				}
				catch
				{
					_recorderProperty = null;
				}
			}
			if (_recorderProperty == null || !_recorderProperty.CanRead)
			{
				return null;
			}
			object value;
			try
			{
				value = _recorderProperty.GetValue(_voiceSystem);
			}
			catch
			{
				return null;
			}
			if (value == null)
			{
				return null;
			}
			if (_cachedRecorder != value)
			{
				_cachedRecorder = value;
				_transmitEnabledProperty = FindWritableBoolProperty(value.GetType(), "TransmitEnabled");
				if (_transmitEnabledProperty != null)
				{
					Log("PTTREVOLT: recorder TransmitEnabled hook ready.");
				}
			}
			return value;
		}

		private static PropertyInfo FindWritableBoolProperty(Type type, string name)
		{
			if (type == null)
			{
				return null;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			PropertyInfo property = type.GetProperty(name, bindingAttr);
			if (property == null || !property.CanWrite)
			{
				return null;
			}
			if (property.PropertyType != typeof(bool) && !string.Equals(property.PropertyType?.FullName ?? string.Empty, "System.Boolean", StringComparison.Ordinal))
			{
				return null;
			}
			return property;
		}

		private static void Log(string message)
		{
			BocoLoggor.PttLog(message);
		}

		private static void Warn(string message)
		{
			BocoLoggor.PttWarn(message);
		}
	}
}