Decompiled source of BonemenuRefresh v1.0.0

Mods/BonemenuRefresh.dll

Decompiled 5 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using BonemenuRefreshShared;
using BonemenuRefreshStandalone;
using Il2CppSLZ.Marrow;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(BonemenuRefreshMod), "Bonemenu Refresh", "1.0.0", "Codex", null)]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyCompany("BonemenuRefresh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BonemenuRefresh")]
[assembly: AssemblyTitle("BonemenuRefresh")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace BonemenuRefreshStandalone
{
	public sealed class BonemenuRefreshMod : MelonMod
	{
		private static readonly Color MenuColor = Color.cyan;

		private BonemenuRefreshCore _refreshCore;

		public override void OnLateInitializeMelon()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			_refreshCore = new BonemenuRefreshCore(((MelonBase)this).LoggerInstance.Msg, ((MelonBase)this).LoggerInstance.Warning, MenuColor);
			_refreshCore.Initialize();
			if (Page.Root == null)
			{
				Menu.Initialize();
			}
			_refreshCore.CreateMenu(Page.Root);
			((MelonBase)this).LoggerInstance.Msg("Bonemenu Refresh loaded.");
		}

		public override void OnUpdate()
		{
			_refreshCore?.OnUpdate();
		}
	}
}
namespace BonemenuRefreshShared
{
	public sealed class BonemenuRefreshCore
	{
		private enum ComboMode
		{
			Double,
			Single
		}

		private enum ActionMode
		{
			Hold,
			Tap
		}

		private enum RefreshButton
		{
			LeftThumbstick,
			RightThumbstick,
			Y,
			B
		}

		private const string PreferenceCategory = "BonemenuRefresh";

		private const float TapWindowSeconds = 1.25f;

		private const float ResetCooldownSeconds = 1f;

		private readonly Action<string> _log;

		private readonly Action<string> _warn;

		private readonly Color _menuColor;

		private MelonPreferences_Category _preferences;

		private MelonPreferences_Entry<int> _comboModePreference;

		private MelonPreferences_Entry<int> _actionModePreference;

		private MelonPreferences_Entry<float> _holdDurationPreference;

		private MelonPreferences_Entry<int> _tapAmountPreference;

		private MelonPreferences_Entry<int> _firstButtonPreference;

		private MelonPreferences_Entry<int> _secondButtonPreference;

		private FunctionElement _comboModeElement;

		private FunctionElement _actionModeElement;

		private FunctionElement _tapAmountElement;

		private FunctionElement _firstButtonElement;

		private FunctionElement _secondButtonElement;

		private ComboMode _comboMode;

		private ActionMode _actionMode;

		private float _holdDuration = 5f;

		private int _tapAmount = 1;

		private RefreshButton _firstButton;

		private RefreshButton _secondButton = RefreshButton.RightThumbstick;

		private float _holdTimer;

		private int _tapCount;

		private float _tapWindowEnd;

		private float _nextResetTime;

		private bool _createdPreferences;

		public BonemenuRefreshCore(Action<string> log, Action<string> warn, Color? menuColor = null)
		{
			//IL_006f: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			_log = log ?? ((Action<string>)delegate
			{
			});
			_warn = warn ?? _log;
			_menuColor = (Color)(((??)menuColor) ?? Color.cyan);
		}

		public void Initialize()
		{
			CreatePreferences();
		}

		public void CreateMenu(Page parent)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			CreatePreferences();
			if (parent == null)
			{
				EnsureMenuInitialized();
				parent = Page.Root;
			}
			if (parent == null)
			{
				_warn.Invoke("Bonemenu refresh: BoneMenu root was not ready; settings page was not created.");
				return;
			}
			Page val = parent.CreatePage("Bonemenu refresh", _menuColor, 0, true);
			val.CreateFunction("Reset now", _menuColor, new Action(ForceReset));
			_comboModeElement = val.CreateFunction(GetComboModeLabel(), _menuColor, new Action(CycleComboMode));
			_actionModeElement = val.CreateFunction(GetActionModeLabel(), _menuColor, new Action(CycleActionMode));
			val.CreateFloat("Hold duration", _menuColor, _holdDuration, 0.5f, 1f, 15f, (Action<float>)([CompilerGenerated] (float value) =>
			{
				_holdDuration = Mathf.Clamp(value, 1f, 15f);
				_holdDurationPreference.Value = _holdDuration;
				SavePreferences();
			}));
			_tapAmountElement = val.CreateFunction(GetTapAmountLabel(), _menuColor, new Action(CycleTapAmount));
			_firstButtonElement = val.CreateFunction(GetFirstButtonLabel(), _menuColor, new Action(CycleFirstButton));
			_secondButtonElement = val.CreateFunction(GetSecondButtonLabel(), _menuColor, new Action(CycleSecondButton));
		}

		public void OnUpdate()
		{
			if (Input.GetKeyDown((KeyCode)286))
			{
				ForceReset();
				return;
			}
			BaseController leftController = Player.LeftController;
			BaseController rightController = Player.RightController;
			if ((Object)(object)leftController == (Object)null || (Object)(object)rightController == (Object)null)
			{
				ResetInputState();
			}
			else if (_actionMode == ActionMode.Hold)
			{
				UpdateHoldInput(leftController, rightController);
			}
			else
			{
				UpdateTapInput(leftController, rightController);
			}
		}

		public void ForceReset()
		{
			if (Time.time < _nextResetTime)
			{
				return;
			}
			_nextResetTime = Time.time + 1f;
			ResetInputState();
			try
			{
				EnsureMenuInitialized();
				Page root = Page.Root;
				if (root == null)
				{
					_warn.Invoke("Bonemenu refresh: reset skipped because BoneMenu root is not ready.");
					return;
				}
				TrySetCurrentPage(root);
				TryInvokeStaticMenuMethod("OpenPage", root);
				Menu.OpenPage(root);
				TrySetCurrentPage(root);
				_log.Invoke("Bonemenu refresh: reset to root.");
			}
			catch (global::System.Exception ex)
			{
				_warn.Invoke("Bonemenu refresh: reset failed safely: " + ex.Message);
			}
		}

		private void CreatePreferences()
		{
			if (!_createdPreferences)
			{
				_preferences = MelonPreferences.CreateCategory("BonemenuRefresh", "Bonemenu Refresh");
				_comboModePreference = _preferences.CreateEntry<int>("ComboMode", (int)_comboMode, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_actionModePreference = _preferences.CreateEntry<int>("ActionMode", (int)_actionMode, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_holdDurationPreference = _preferences.CreateEntry<float>("HoldDuration", _holdDuration, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_tapAmountPreference = _preferences.CreateEntry<int>("TapAmount", _tapAmount, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_firstButtonPreference = _preferences.CreateEntry<int>("FirstButton", (int)_firstButton, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_secondButtonPreference = _preferences.CreateEntry<int>("SecondButton", (int)_secondButton, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
				_comboMode = ClampComboMode(_comboModePreference.Value);
				_actionMode = ClampActionMode(_actionModePreference.Value);
				_holdDuration = Mathf.Clamp(_holdDurationPreference.Value, 1f, 15f);
				_tapAmount = Mathf.Clamp(_tapAmountPreference.Value, 1, 5);
				_firstButton = ClampRefreshButton(_firstButtonPreference.Value);
				_secondButton = ClampRefreshButton(_secondButtonPreference.Value);
				_createdPreferences = true;
			}
		}

		private void UpdateHoldInput(BaseController left, BaseController right)
		{
			if (!IsComboHeld(left, right))
			{
				_holdTimer = 0f;
				return;
			}
			_holdTimer += Time.deltaTime;
			if (_holdTimer >= _holdDuration)
			{
				ForceReset();
			}
		}

		private void UpdateTapInput(BaseController left, BaseController right)
		{
			if (!IsComboPressedThisFrame(left, right))
			{
				if (Time.time > _tapWindowEnd)
				{
					_tapCount = 0;
				}
				return;
			}
			if (Time.time > _tapWindowEnd)
			{
				_tapCount = 0;
				_tapWindowEnd = Time.time + 1.25f;
			}
			_tapCount++;
			if (_tapCount >= _tapAmount)
			{
				ForceReset();
			}
		}

		private bool IsComboHeld(BaseController left, BaseController right)
		{
			if (!IsButtonHeld(_firstButton, left, right))
			{
				return false;
			}
			if (_comboMode != ComboMode.Single)
			{
				return IsButtonHeld(_secondButton, left, right);
			}
			return true;
		}

		private bool IsComboPressedThisFrame(BaseController left, BaseController right)
		{
			if (_comboMode == ComboMode.Single)
			{
				return IsButtonDown(_firstButton, left, right);
			}
			bool num = IsButtonHeld(_firstButton, left, right);
			bool flag = IsButtonHeld(_secondButton, left, right);
			if (!num || !flag)
			{
				return false;
			}
			if (!IsButtonDown(_firstButton, left, right))
			{
				return IsButtonDown(_secondButton, left, right);
			}
			return true;
		}

		private static bool IsButtonDown(RefreshButton button, BaseController left, BaseController right)
		{
			return button switch
			{
				RefreshButton.RightThumbstick => InvokeBool(right, "GetThumbStickDown", "GetThumbstickDown", "GetThumbStickButtonDown"), 
				RefreshButton.Y => InvokeBool(left, "GetBButtonDown", "GetYButtonDown"), 
				RefreshButton.B => InvokeBool(right, "GetBButtonDown"), 
				_ => InvokeBool(left, "GetThumbStickDown", "GetThumbstickDown", "GetThumbStickButtonDown"), 
			};
		}

		private static bool IsButtonHeld(RefreshButton button, BaseController left, BaseController right)
		{
			return button switch
			{
				RefreshButton.RightThumbstick => InvokeBool(right, "GetThumbStick", "GetThumbstick", "GetThumbStickButton"), 
				RefreshButton.Y => InvokeBool(left, "GetBButton", "GetYButton"), 
				RefreshButton.B => InvokeBool(right, "GetBButton"), 
				_ => InvokeBool(left, "GetThumbStick", "GetThumbstick", "GetThumbStickButton"), 
			};
		}

		private static bool InvokeBool(object target, params string[] methodNames)
		{
			if (target == null)
			{
				return false;
			}
			global::System.Type type = target.GetType();
			foreach (string text in methodNames)
			{
				MethodInfo method = type.GetMethod(text, (BindingFlags)52);
				if (!(method == (MethodInfo)null) && ((MethodBase)method).GetParameters().Length == 0)
				{
					object obj = ((MethodBase)method).Invoke(target, (object[])null);
					if (obj is bool)
					{
						return (bool)obj;
					}
				}
			}
			return false;
		}

		private static void EnsureMenuInitialized()
		{
			if (Page.Root == null)
			{
				Menu.Initialize();
			}
		}

		private static void TrySetCurrentPage(Page root)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			global::System.Type pageType = typeof(Page);
			Try((Action)delegate
			{
				PropertyInfo property = pageType.GetProperty("CurrentPage", (BindingFlags)56);
				if (property != null)
				{
					property.SetValue((object)null, (object)root);
				}
			});
			Try((Action)delegate
			{
				FieldInfo field = pageType.GetField("_currentPage", (BindingFlags)56);
				if (field != null)
				{
					field.SetValue((object)null, (object)root);
				}
			});
		}

		private static void TryInvokeStaticMenuMethod(string methodName, Page root)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			Try((Action)delegate
			{
				MethodInfo method = typeof(Menu).GetMethod(methodName, (BindingFlags)56, (Binder)null, new global::System.Type[1] { typeof(Page) }, (ParameterModifier[])null);
				if (method != null)
				{
					((MethodBase)method).Invoke((object)null, new object[1] { root });
				}
			});
		}

		private void CycleComboMode()
		{
			_comboMode = ((_comboMode == ComboMode.Double) ? ComboMode.Single : ComboMode.Double);
			_comboModePreference.Value = (int)_comboMode;
			SavePreferences();
			ResetInputState();
			UpdateLabels();
		}

		private void CycleActionMode()
		{
			_actionMode = ((_actionMode == ActionMode.Hold) ? ActionMode.Tap : ActionMode.Hold);
			_actionModePreference.Value = (int)_actionMode;
			SavePreferences();
			ResetInputState();
			UpdateLabels();
		}

		private void CycleTapAmount()
		{
			_tapAmount++;
			if (_tapAmount > 5)
			{
				_tapAmount = 1;
			}
			_tapAmountPreference.Value = _tapAmount;
			SavePreferences();
			ResetInputState();
			UpdateLabels();
		}

		private void CycleFirstButton()
		{
			_firstButton = NextButton(_firstButton);
			_firstButtonPreference.Value = (int)_firstButton;
			SavePreferences();
			ResetInputState();
			UpdateLabels();
		}

		private void CycleSecondButton()
		{
			_secondButton = NextButton(_secondButton);
			_secondButtonPreference.Value = (int)_secondButton;
			SavePreferences();
			ResetInputState();
			UpdateLabels();
		}

		private void UpdateLabels()
		{
			SetElementName(_comboModeElement, GetComboModeLabel());
			SetElementName(_actionModeElement, GetActionModeLabel());
			SetElementName(_tapAmountElement, GetTapAmountLabel());
			SetElementName(_firstButtonElement, GetFirstButtonLabel());
			SetElementName(_secondButtonElement, GetSecondButtonLabel());
		}

		private string GetComboModeLabel()
		{
			return "Keybind mode: " + ((_comboMode == ComboMode.Double) ? "Double" : "Single");
		}

		private string GetActionModeLabel()
		{
			return "Action mode: " + ((_actionMode == ActionMode.Hold) ? "Hold" : "Tap");
		}

		private string GetTapAmountLabel()
		{
			return $"Tap amount: {_tapAmount}";
		}

		private string GetFirstButtonLabel()
		{
			return "First keybind: " + GetButtonName(_firstButton);
		}

		private string GetSecondButtonLabel()
		{
			return "Second keybind: " + GetButtonName(_secondButton);
		}

		private static string GetButtonName(RefreshButton button)
		{
			return button switch
			{
				RefreshButton.RightThumbstick => "right thumbstick press", 
				RefreshButton.Y => "Y", 
				RefreshButton.B => "B", 
				_ => "left thumbstick press", 
			};
		}

		private static RefreshButton NextButton(RefreshButton button)
		{
			return button switch
			{
				RefreshButton.LeftThumbstick => RefreshButton.RightThumbstick, 
				RefreshButton.RightThumbstick => RefreshButton.Y, 
				RefreshButton.Y => RefreshButton.B, 
				_ => RefreshButton.LeftThumbstick, 
			};
		}

		private static ComboMode ClampComboMode(int value)
		{
			if (value != 1)
			{
				return ComboMode.Double;
			}
			return ComboMode.Single;
		}

		private static ActionMode ClampActionMode(int value)
		{
			if (value != 1)
			{
				return ActionMode.Hold;
			}
			return ActionMode.Tap;
		}

		private static RefreshButton ClampRefreshButton(int value)
		{
			if (value < 0 || value > 3)
			{
				return RefreshButton.LeftThumbstick;
			}
			return (RefreshButton)value;
		}

		private static void SavePreferences()
		{
			MelonPreferences.Save();
		}

		private void ResetInputState()
		{
			_holdTimer = 0f;
			_tapCount = 0;
			_tapWindowEnd = 0f;
		}

		private static void SetElementName(FunctionElement element, string name)
		{
			if (element != null)
			{
				((Element)element).ElementName = name;
			}
		}

		private static void Try(Action action)
		{
			try
			{
				action.Invoke();
			}
			catch
			{
			}
		}
	}
}