Decompiled source of StoneStickByNano v3.0.2

Mods/StoneStickByNano.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using ButtonLoco;
using HarmonyLib;
using Il2CppRUMBLE.Players.Subsystems;
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.1", "Nano", null)]
[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
{
	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 float _lastDebugLogTime;

		private static bool _movementMethodsLogged;

		private static MethodInfo _sprintPoseMethod;

		private static bool _sprintPosePatched;

		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();
			LogMovementMethodsOnce();
			TryPatchSprintPose();
		}

		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 void TryPatchSprintPose()
		{
			//IL_0036: 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)
			//IL_005e: Expected O, but got Unknown
			if (!_sprintPosePatched)
			{
				_sprintPoseMethod = AccessTools.Method(typeof(PlayerMovement), "OnSprintingPoseInputDone", (Type[])null, (Type[])null);
				if (!(_sprintPoseMethod == null))
				{
					new Harmony("nano.stonestick.buttonloco").Patch((MethodBase)_sprintPoseMethod, (HarmonyMethod)null, new HarmonyMethod(typeof(ButtonLocoMod), "PlayerMovement_OnSprintingPoseInputDone_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_sprintPosePatched = true;
					((MelonBase)this).LoggerInstance.Msg("Stone Stick: patched PlayerMovement.OnSprintingPoseInputDone (log only)");
				}
			}
		}

		private static void PlayerMovement_Move_Prefix(PlayerMovement __instance, ref Vector2 __0)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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;
				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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			//IL_002a: 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();
			}
			val = ApplySprintScaling(movement, val);
			DebugLog(val);
			return val;
		}

		private static void DebugLog(Vector2 finalInput)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && !(((Vector2)(ref finalInput)).sqrMagnitude < 0.0001f) && !(Time.time - _lastDebugLogTime < 2f))
			{
				_lastDebugLogTime = Time.time;
				((MelonBase)Instance).LoggerInstance.Msg($"StoneStick debug | final={finalInput}");
			}
		}

		private static void PlayerMovement_OnSprintingPoseInputDone_Postfix(PlayerMovement __instance)
		{
			if (Instance == null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				object obj = ReadPropertyValue(__instance, "sprintingInputSource");
				object obj2 = ReadPropertyValue(__instance, "currentSprintFactor");
				object obj3 = ReadPropertyValue(__instance, "activeMovementType");
				object obj4 = ReadPropertyValue(__instance, "movementVelocityTarget");
				object obj5 = ReadPropertyValue(__instance, "desiredMovementVelocity");
				object obj6 = ReadPropertyValue(__instance, "maxSprintVectorLength");
				object obj7 = ReadPropertyValue(__instance, "sprintAccelerationRate");
				((MelonBase)Instance).LoggerInstance.Msg(string.Format("StoneStick sprint log | inputSource={0} currentSprintFactor={1} ", obj ?? "n/a", obj2 ?? "n/a") + string.Format("activeMovementType={0} movementVelocityTarget={1} ", obj3 ?? "n/a", obj4 ?? "n/a") + string.Format("desiredMovementVelocity={0} maxSprintVectorLength={1} ", obj5 ?? "n/a", obj6 ?? "n/a") + string.Format("sprintAccelerationRate={0}", obj7 ?? "n/a"));
			}
			catch (Exception ex)
			{
				((MelonBase)Instance).LoggerInstance.Warning("StoneStick sprint log failed: " + ex.Message);
			}
		}

		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 static Vector2 ApplySprintScaling(PlayerMovement movement, Vector2 input)
		{
			//IL_0073: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0068: 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)
			if ((Object)(object)movement == (Object)null || ((Vector2)(ref input)).sqrMagnitude < 0.0001f)
			{
				return input;
			}
			try
			{
				object obj = ReadPropertyValue(movement, "currentSprintFactor");
				if (obj == null)
				{
					return input;
				}
				float num = Convert.ToSingle(obj);
				if (num <= 1.01f)
				{
					return input;
				}
				object obj2 = ReadPropertyValue(movement, "maxSprintVectorLength");
				if (obj2 != null)
				{
					float num2 = Convert.ToSingle(obj2);
					if (num2 > 0f && num > num2)
					{
						num = num2;
					}
				}
				return input * num;
			}
			catch
			{
				return input;
			}
		}

		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 static void LogMovementMethodsOnce()
		{
			if (_movementMethodsLogged || Instance == null)
			{
				return;
			}
			_movementMethodsLogged = true;
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo[] methods = typeof(PlayerMovement).GetMethods(bindingAttr);
				List<string> list = new List<string>();
				MethodInfo[] array = methods;
				for (int i = 0; i < array.Length; i++)
				{
					string name = array[i].Name;
					string text = name.ToLowerInvariant();
					if (text.Contains("run") || text.Contains("sprint") || text.Contains("dash") || text.Contains("jump") || text.Contains("move") || text.Contains("locom"))
					{
						list.Add(name);
					}
				}
				list.Sort(StringComparer.Ordinal);
				if (list.Count > 0)
				{
					((MelonBase)Instance).LoggerInstance.Msg("StoneStick: PlayerMovement methods of interest:");
					{
						foreach (string item in list)
						{
							((MelonBase)Instance).LoggerInstance.Msg(" - " + item);
						}
						return;
					}
				}
				((MelonBase)Instance).LoggerInstance.Msg("StoneStick: no obvious sprint/move methods found in PlayerMovement.");
			}
			catch (Exception ex)
			{
				((MelonBase)Instance).LoggerInstance.Warning("StoneStick: method scan failed: " + ex.Message);
			}
		}
	}
}