Decompiled source of BunnyHopper v1.1.0

BunnyHopper.Il2Cpp.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BunnyHopper;
using BunnyHopper.Models;
using HarmonyLib;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.UI.Settings;
using Il2CppSystem.Collections;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(true)]
[assembly: Guid("78217591-6296-4A47-9657-F90E4322F66F")]
[assembly: MelonInfo(typeof(Main), "Bunny Hopper", "1.1.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.BunnyHopper/releases/latest")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 212, 172, 45)]
[assembly: AssemblyMetadata("NexusModID", "1033")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Roach_")]
[assembly: AssemblyConfiguration("Release_Il2Cpp")]
[assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")]
[assembly: AssemblyDescription("A MelonLoader mod for Schedule I that enables \"true\" auto-jumping/bunny-hopping.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("BunnyHopper.Il2Cpp")]
[assembly: AssemblyTitle("BunnyHopper.Il2Cpp")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace BunnyHopper
{
	public class Main : MelonMod
	{
		[HarmonyPatch(typeof(PlayerMovement), "Move")]
		private static class PlayerMovementMovePatch
		{
			private static Func<PlayerMovement, IEnumerator> _invokeJumpMethod;

			private static Func<PlayerMovement, bool> _getIsJumpingValue;

			static PlayerMovementMovePatch()
			{
				Type typeFromHandle = typeof(PlayerMovement);
				MethodInfo method = typeFromHandle.GetMethod("Jump", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					try
					{
						ParameterExpression parameterExpression = Expression.Parameter(typeFromHandle, "playerMovement");
						_invokeJumpMethod = Expression.Lambda<Func<PlayerMovement, IEnumerator>>(Expression.Call(parameterExpression, method), new ParameterExpression[1] { parameterExpression }).Compile();
					}
					catch (Exception ex)
					{
						Melon<Main>.Logger.Error("Failed to compile delegate for Jump method: " + ex.Message + ". Auto-jumping will not function.");
					}
				}
				else
				{
					Melon<Main>.Logger.Error("Reflection: PlayerMovement.Jump method not found. Auto-jumping will not function.");
				}
				MemberInfo memberInfo = (MemberInfo)(((object)typeof(PlayerMovement).GetField("isJumping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)typeof(PlayerMovement).GetProperty("isJumping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (memberInfo != null)
				{
					try
					{
						ParameterExpression parameterExpression2 = Expression.Parameter(typeFromHandle, "playerMovement");
						_getIsJumpingValue = Expression.Lambda<Func<PlayerMovement, bool>>(Expression.MakeMemberAccess(parameterExpression2, memberInfo), new ParameterExpression[1] { parameterExpression2 }).Compile();
						return;
					}
					catch (Exception ex2)
					{
						Melon<Main>.Logger.Error("Failed to compile delegate for isJumping member: " + ex2.Message + ". Auto-jump condition check might be impaired.");
						return;
					}
				}
				Melon<Main>.Logger.Error("Reflection: PlayerMovement.isJumping member (field/property) not found. Auto-jump condition check might be impaired.");
			}

			public static void Prefix(PlayerMovement __instance)
			{
				if (!ShouldSkipPatch(__instance))
				{
					if (currentPlayerJumpState == null)
					{
						currentPlayerJumpState = new PlayerJumpState();
					}
					currentPlayerJumpState.WasGroundedBeforeMove = __instance.Controller.isGrounded;
				}
			}

			public static void Postfix(PlayerMovement __instance)
			{
				if (ShouldSkipPatch(__instance))
				{
					return;
				}
				if (currentPlayerJumpState == null)
				{
					Melon<Main>.Logger.Error("[PlayerMovement.Move.Postfix] Critical: currentPlayerJumpState is null. Aborting Postfix logic.");
					return;
				}
				bool isGrounded = __instance.Controller.isGrounded;
				if (currentPlayerJumpState.AwaitingLiftoffAfterAutoJump)
				{
					if (!isGrounded)
					{
						currentPlayerJumpState.AwaitingLiftoffAfterAutoJump = false;
						currentPlayerJumpState.ModInitiatedCurrentJump = true;
					}
					return;
				}
				bool wasGroundedBeforeMove = currentPlayerJumpState.WasGroundedBeforeMove;
				bool modInitiatedCurrentJump = currentPlayerJumpState.ModInitiatedCurrentJump;
				if (!wasGroundedBeforeMove && isGrounded)
				{
					if (modInitiatedCurrentJump)
					{
						currentPlayerJumpState.ModInitiatedCurrentJump = false;
					}
					if (ShouldAutoJump(__instance))
					{
						MelonCoroutines.Start(ExecuteAutoJumpCoroutine(__instance, currentPlayerJumpState));
					}
				}
			}

			private static IEnumerator ExecuteAutoJumpCoroutine(PlayerMovement playerMovement, PlayerJumpState jumpState)
			{
				if ((Object)(object)playerMovement == (Object)null || (Object)(object)playerMovement.Controller == (Object)null || jumpState.AwaitingLiftoffAfterAutoJump)
				{
					yield break;
				}
				jumpState.AwaitingLiftoffAfterAutoJump = true;
				jumpState.ModInitiatedCurrentJump = false;
				yield return null;
				if (ShouldAutoJump(playerMovement))
				{
					if (_invokeJumpMethod != null)
					{
						IEnumerator val = _invokeJumpMethod(playerMovement);
						((MonoBehaviour)playerMovement).StartCoroutine(val);
						MelonCoroutines.Start(MonitorLiftoff(playerMovement, jumpState));
					}
					else
					{
						Melon<Main>.Logger.Error("[ExecuteAutoJumpCoro] Jump method delegate is null. Cannot execute jump.");
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
				}
				else
				{
					jumpState.AwaitingLiftoffAfterAutoJump = false;
				}
			}

			private static IEnumerator MonitorLiftoff(PlayerMovement playerMovement, PlayerJumpState jumpState)
			{
				float num = (float)AutoJumpLiftoffTimeoutMilliseconds.Value / 1000f;
				float endTime = Time.time + num;
				while (Time.time < endTime)
				{
					if ((Object)(object)playerMovement == (Object)null || (Object)(object)playerMovement.Controller == (Object)null || !jumpState.AwaitingLiftoffAfterAutoJump)
					{
						yield break;
					}
					yield return null;
				}
				if ((Object)(object)playerMovement != (Object)null && (Object)(object)playerMovement.Controller != (Object)null && jumpState.AwaitingLiftoffAfterAutoJump)
				{
					if (playerMovement.Controller.isGrounded)
					{
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
					else
					{
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
				}
			}

			private static bool ShouldAutoJump(PlayerMovement playerMovement)
			{
				if (!jumpActionReference.action.IsPressed() || (!playerMovement.IsGrounded && !playerMovement.Controller.isGrounded) || !playerMovement.canJump)
				{
					return false;
				}
				try
				{
					return !_getIsJumpingValue(playerMovement);
				}
				catch (Exception ex)
				{
					Melon<Main>.Logger.Error("Error getting PlayerMovement.isJumping via reflection: " + ex.Message);
				}
				return false;
			}

			private static bool ShouldSkipPatch(PlayerMovement playerMovement)
			{
				if (Enabled.Value && _invokeJumpMethod != null && _getIsJumpingValue != null && !((Object)(object)jumpActionReference == (Object)null) && jumpActionReference.action != null && !((Object)(object)playerMovement == (Object)null))
				{
					return (Object)(object)playerMovement.Controller == (Object)null;
				}
				return true;
			}
		}

		private static InputActionReference jumpActionReference;

		private static PlayerJumpState currentPlayerJumpState;

		public static MelonPreferences_Category SettingsCategory { get; private set; }

		public static MelonPreferences_Entry<bool> Enabled { get; private set; }

		public static MelonPreferences_Entry<int> AutoJumpLiftoffTimeoutMilliseconds { get; private set; }

		public override void OnInitializeMelon()
		{
			SettingsCategory = MelonPreferences.CreateCategory("BunnyHopper_Settings", "Bunny Hopper Settings");
			Enabled = SettingsCategory.CreateEntry<bool>("Enabled", true, "Enable or disable the bunny hop feature.", (string)null, false, false, (ValueValidator)null, (string)null);
			AutoJumpLiftoffTimeoutMilliseconds = SettingsCategory.CreateEntry<int>("AutoJumpLiftoffTimeout", 75, "Liftoff timeout (ms) before auto-jump is considered failed.", (string)null, false, false, (ValueValidator)(object)new ValueRange<int>(55, 110), (string)null);
			string value = "IL2CPP";
			Melon<Main>.Logger.Msg($"Bunny Hopper ({value}) initializing with following settings: Enabled={Enabled.Value}, AutoJumpLiftoffTimeoutMilliseconds={AutoJumpLiftoffTimeoutMilliseconds.Value}.");
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
				IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods()
					select p.DeclaringType.FullName + "." + p.Name;
				string text = string.Join(", ", values);
				Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text + ".");
			}
			catch (Exception value2)
			{
				Melon<Main>.Logger.Error($"Error during Harmony's PatchAll execution: {value2}");
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (Enabled.Value && !((Object)(object)jumpActionReference != (Object)null) && !(sceneName != "Menu"))
			{
				Melon<Main>.Logger.Msg("Main menu was loaded, attempting to detect Jump Action reference..");
				DetectJumpAction();
			}
		}

		private static void DetectJumpAction()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("MainMenu");
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Error("Main Menu not found, unable to detect Jump Action!");
				return;
			}
			Transform val2 = val.transform.Find("Settings/Content/Controls/Row/Jump");
			if ((Object)(object)val2 == (Object)null)
			{
				Melon<Main>.Logger.Error("Jump control UI element not found, unable to detect Jump Action!");
				return;
			}
			Keybinder component = ((Component)val2).GetComponent<Keybinder>();
			if ((Object)(object)component == (Object)null)
			{
				Melon<Main>.Logger.Error("Keybinder component not found on Jump control, unable to detect Jump Action!");
				return;
			}
			RebindActionUI rebindActionUI = component.rebindActionUI;
			if ((Object)(object)rebindActionUI == (Object)null)
			{
				Melon<Main>.Logger.Error("Rebind Action UI is null on Keybinder component, unable to detect Jump Action!");
				return;
			}
			InputActionReference actionReference = rebindActionUI.actionReference;
			if ((Object)(object)actionReference == (Object)null)
			{
				Melon<Main>.Logger.Error("Jump Action reference is null on Rebind Action UI!");
				return;
			}
			jumpActionReference = actionReference;
			Melon<Main>.Logger.Msg($"Successfully auto-detected Jump Action: Name={jumpActionReference.action.name}, ID={jumpActionReference.action.id}.");
		}
	}
}
namespace BunnyHopper.Models
{
	public class PlayerJumpState
	{
		public bool WasGroundedBeforeMove { get; set; }

		public bool ModInitiatedCurrentJump { get; set; }

		public bool AwaitingLiftoffAfterAutoJump { get; set; }
	}
}

BunnyHopper.Mono.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BunnyHopper;
using BunnyHopper.Models;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using ScheduleOne.DevUtilities;
using ScheduleOne.PlayerScripts;
using ScheduleOne.UI.Settings;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(true)]
[assembly: Guid("78217591-6296-4A47-9657-F90E4322F66F")]
[assembly: MelonInfo(typeof(Main), "Bunny Hopper", "1.1.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.BunnyHopper/releases/latest")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 212, 172, 45)]
[assembly: AssemblyMetadata("NexusModID", "1033")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Roach_")]
[assembly: AssemblyConfiguration("Release_Mono")]
[assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")]
[assembly: AssemblyDescription("A MelonLoader mod for Schedule I that enables \"true\" auto-jumping/bunny-hopping.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("BunnyHopper.Mono")]
[assembly: AssemblyTitle("BunnyHopper.Mono")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace BunnyHopper
{
	public class Main : MelonMod
	{
		[HarmonyPatch(typeof(PlayerMovement), "Move")]
		private static class PlayerMovementMovePatch
		{
			private static Func<PlayerMovement, IEnumerator> _invokeJumpMethod;

			private static Func<PlayerMovement, bool> _getIsJumpingValue;

			static PlayerMovementMovePatch()
			{
				Type typeFromHandle = typeof(PlayerMovement);
				MethodInfo method = typeFromHandle.GetMethod("Jump", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					try
					{
						ParameterExpression parameterExpression = Expression.Parameter(typeFromHandle, "playerMovement");
						_invokeJumpMethod = Expression.Lambda<Func<PlayerMovement, IEnumerator>>(Expression.Call(parameterExpression, method), new ParameterExpression[1] { parameterExpression }).Compile();
					}
					catch (Exception ex)
					{
						Melon<Main>.Logger.Error("Failed to compile delegate for Jump method: " + ex.Message + ". Auto-jumping will not function.");
					}
				}
				else
				{
					Melon<Main>.Logger.Error("Reflection: PlayerMovement.Jump method not found. Auto-jumping will not function.");
				}
				MemberInfo memberInfo = (MemberInfo)(((object)typeof(PlayerMovement).GetField("isJumping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)typeof(PlayerMovement).GetProperty("isJumping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (memberInfo != null)
				{
					try
					{
						ParameterExpression parameterExpression2 = Expression.Parameter(typeFromHandle, "playerMovement");
						_getIsJumpingValue = Expression.Lambda<Func<PlayerMovement, bool>>(Expression.MakeMemberAccess(parameterExpression2, memberInfo), new ParameterExpression[1] { parameterExpression2 }).Compile();
						return;
					}
					catch (Exception ex2)
					{
						Melon<Main>.Logger.Error("Failed to compile delegate for isJumping member: " + ex2.Message + ". Auto-jump condition check might be impaired.");
						return;
					}
				}
				Melon<Main>.Logger.Error("Reflection: PlayerMovement.isJumping member (field/property) not found. Auto-jump condition check might be impaired.");
			}

			public static void Prefix(PlayerMovement __instance)
			{
				if (!ShouldSkipPatch(__instance))
				{
					if (currentPlayerJumpState == null)
					{
						currentPlayerJumpState = new PlayerJumpState();
					}
					currentPlayerJumpState.WasGroundedBeforeMove = __instance.Controller.isGrounded;
				}
			}

			public static void Postfix(PlayerMovement __instance)
			{
				if (ShouldSkipPatch(__instance))
				{
					return;
				}
				if (currentPlayerJumpState == null)
				{
					Melon<Main>.Logger.Error("[PlayerMovement.Move.Postfix] Critical: currentPlayerJumpState is null. Aborting Postfix logic.");
					return;
				}
				bool isGrounded = __instance.Controller.isGrounded;
				if (currentPlayerJumpState.AwaitingLiftoffAfterAutoJump)
				{
					if (!isGrounded)
					{
						currentPlayerJumpState.AwaitingLiftoffAfterAutoJump = false;
						currentPlayerJumpState.ModInitiatedCurrentJump = true;
					}
					return;
				}
				bool wasGroundedBeforeMove = currentPlayerJumpState.WasGroundedBeforeMove;
				bool modInitiatedCurrentJump = currentPlayerJumpState.ModInitiatedCurrentJump;
				if (!wasGroundedBeforeMove && isGrounded)
				{
					if (modInitiatedCurrentJump)
					{
						currentPlayerJumpState.ModInitiatedCurrentJump = false;
					}
					if (ShouldAutoJump(__instance))
					{
						MelonCoroutines.Start(ExecuteAutoJumpCoroutine(__instance, currentPlayerJumpState));
					}
				}
			}

			private static IEnumerator ExecuteAutoJumpCoroutine(PlayerMovement playerMovement, PlayerJumpState jumpState)
			{
				if ((Object)(object)playerMovement == (Object)null || (Object)(object)playerMovement.Controller == (Object)null || jumpState.AwaitingLiftoffAfterAutoJump)
				{
					yield break;
				}
				jumpState.AwaitingLiftoffAfterAutoJump = true;
				jumpState.ModInitiatedCurrentJump = false;
				yield return null;
				if (ShouldAutoJump(playerMovement))
				{
					if (_invokeJumpMethod != null)
					{
						IEnumerator enumerator = _invokeJumpMethod(playerMovement);
						((MonoBehaviour)playerMovement).StartCoroutine(enumerator);
						MelonCoroutines.Start(MonitorLiftoff(playerMovement, jumpState));
					}
					else
					{
						Melon<Main>.Logger.Error("[ExecuteAutoJumpCoro] Jump method delegate is null. Cannot execute jump.");
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
				}
				else
				{
					jumpState.AwaitingLiftoffAfterAutoJump = false;
				}
			}

			private static IEnumerator MonitorLiftoff(PlayerMovement playerMovement, PlayerJumpState jumpState)
			{
				float num = (float)AutoJumpLiftoffTimeoutMilliseconds.Value / 1000f;
				float endTime = Time.time + num;
				while (Time.time < endTime)
				{
					if ((Object)(object)playerMovement == (Object)null || (Object)(object)playerMovement.Controller == (Object)null || !jumpState.AwaitingLiftoffAfterAutoJump)
					{
						yield break;
					}
					yield return null;
				}
				if ((Object)(object)playerMovement != (Object)null && (Object)(object)playerMovement.Controller != (Object)null && jumpState.AwaitingLiftoffAfterAutoJump)
				{
					if (playerMovement.Controller.isGrounded)
					{
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
					else
					{
						jumpState.AwaitingLiftoffAfterAutoJump = false;
					}
				}
			}

			private static bool ShouldAutoJump(PlayerMovement playerMovement)
			{
				if (!jumpActionReference.action.IsPressed() || (!playerMovement.IsGrounded && !playerMovement.Controller.isGrounded) || !playerMovement.canJump)
				{
					return false;
				}
				try
				{
					return !_getIsJumpingValue(playerMovement);
				}
				catch (Exception ex)
				{
					Melon<Main>.Logger.Error("Error getting PlayerMovement.isJumping via reflection: " + ex.Message);
				}
				return false;
			}

			private static bool ShouldSkipPatch(PlayerMovement playerMovement)
			{
				if (Enabled.Value && _invokeJumpMethod != null && _getIsJumpingValue != null && !((Object)(object)jumpActionReference == (Object)null) && jumpActionReference.action != null && !((Object)(object)playerMovement == (Object)null))
				{
					return (Object)(object)playerMovement.Controller == (Object)null;
				}
				return true;
			}
		}

		private static InputActionReference jumpActionReference;

		private static PlayerJumpState currentPlayerJumpState;

		public static MelonPreferences_Category SettingsCategory { get; private set; }

		public static MelonPreferences_Entry<bool> Enabled { get; private set; }

		public static MelonPreferences_Entry<int> AutoJumpLiftoffTimeoutMilliseconds { get; private set; }

		public override void OnInitializeMelon()
		{
			SettingsCategory = MelonPreferences.CreateCategory("BunnyHopper_Settings", "Bunny Hopper Settings");
			Enabled = SettingsCategory.CreateEntry<bool>("Enabled", true, "Enable or disable the bunny hop feature.", (string)null, false, false, (ValueValidator)null, (string)null);
			AutoJumpLiftoffTimeoutMilliseconds = SettingsCategory.CreateEntry<int>("AutoJumpLiftoffTimeout", 75, "Liftoff timeout (ms) before auto-jump is considered failed.", (string)null, false, false, (ValueValidator)(object)new ValueRange<int>(55, 110), (string)null);
			string arg = "Mono";
			Melon<Main>.Logger.Msg($"Bunny Hopper ({arg}) initializing with following settings: Enabled={Enabled.Value}, AutoJumpLiftoffTimeoutMilliseconds={AutoJumpLiftoffTimeoutMilliseconds.Value}.");
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
				IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods()
					select p.DeclaringType.FullName + "." + p.Name;
				string text = string.Join(", ", values);
				Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text + ".");
			}
			catch (Exception arg2)
			{
				Melon<Main>.Logger.Error($"Error during Harmony's PatchAll execution: {arg2}");
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (Enabled.Value && !((Object)(object)jumpActionReference != (Object)null) && !(sceneName != "Menu"))
			{
				Melon<Main>.Logger.Msg("Main menu was loaded, attempting to detect Jump Action reference..");
				DetectJumpAction();
			}
		}

		private static void DetectJumpAction()
		{
			GameObject val = GameObject.Find("MainMenu");
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Error("Main Menu not found, unable to detect Jump Action!");
				return;
			}
			Transform val2 = val.transform.Find("Settings/Content/Controls/Row/Jump");
			if ((Object)(object)val2 == (Object)null)
			{
				Melon<Main>.Logger.Error("Jump control UI element not found, unable to detect Jump Action!");
				return;
			}
			Keybinder component = ((Component)val2).GetComponent<Keybinder>();
			if ((Object)(object)component == (Object)null)
			{
				Melon<Main>.Logger.Error("Keybinder component not found on Jump control, unable to detect Jump Action!");
				return;
			}
			RebindActionUI rebindActionUI = component.rebindActionUI;
			if ((Object)(object)rebindActionUI == (Object)null)
			{
				Melon<Main>.Logger.Error("Rebind Action UI is null on Keybinder component, unable to detect Jump Action!");
				return;
			}
			InputActionReference actionReference = rebindActionUI.actionReference;
			if ((Object)(object)actionReference == (Object)null)
			{
				Melon<Main>.Logger.Error("Jump Action reference is null on Rebind Action UI!");
				return;
			}
			jumpActionReference = actionReference;
			Melon<Main>.Logger.Msg($"Successfully auto-detected Jump Action: Name={jumpActionReference.action.name}, ID={jumpActionReference.action.id}.");
		}
	}
}
namespace BunnyHopper.Models
{
	public class PlayerJumpState
	{
		public bool WasGroundedBeforeMove { get; set; }

		public bool ModInitiatedCurrentJump { get; set; }

		public bool AwaitingLiftoffAfterAutoJump { get; set; }
	}
}