Decompiled source of BunnyHop v1.0.0

HowToFishBunnyHop.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[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: AssemblyCompany("HowToFishBunnyHop")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HowToFishBunnyHop")]
[assembly: AssemblyTitle("HowToFishBunnyHop")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BunnyHopMod
{
	public class BhopHud : MonoBehaviour
	{
		private const float Margin = 20f;

		private GameObject canvasObject;

		private Text speedText;

		private Text unitText;

		private Text statusText;

		private PlayerMovement localMovement;

		private float nextPlayerSearchTime;

		private void Awake()
		{
			BuildUI();
		}

		private void Update()
		{
			if ((Object)(object)canvasObject != (Object)null)
			{
				canvasObject.SetActive(Plugin.HudEnabled.Value);
			}
			if (Plugin.HudEnabled.Value)
			{
				EnsureLocalPlayer();
				RefreshTexts();
			}
		}

		private void EnsureLocalPlayer()
		{
			if ((Object)(object)localMovement != (Object)null || Time.time < nextPlayerSearchTime)
			{
				return;
			}
			nextPlayerSearchTime = Time.time + 0.5f;
			PlayerMovement[] array = Object.FindObjectsByType<PlayerMovement>((FindObjectsInactive)0);
			PlayerMovement[] array2 = array;
			foreach (PlayerMovement val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					if (((NetworkBehaviour)val).IsOwner)
					{
						localMovement = val;
						break;
					}
				}
				catch
				{
				}
			}
		}

		private void RefreshTexts()
		{
			//IL_0018: 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_0032: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localMovement != (Object)null)
			{
				Vector2 val = new Vector2(localMovement.Velocity.x, localMovement.Velocity.z);
				float magnitude = ((Vector2)(ref val)).magnitude;
				float num = magnitude * 3.6f;
				if ((Object)(object)speedText != (Object)null)
				{
					speedText.text = Mathf.RoundToInt(num).ToString();
				}
			}
			else if ((Object)(object)speedText != (Object)null)
			{
				speedText.text = "--";
			}
			if ((Object)(object)statusText != (Object)null)
			{
				bool value = Plugin.Enabled.Value;
				statusText.text = (value ? "BHOP: ON" : "BHOP: OFF");
				((Graphic)statusText).color = (Color)(value ? Color.white : new Color(1f, 1f, 1f, 0.45f));
			}
		}

		private void BuildUI()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			canvasObject = new GameObject("BunnyHopHudCanvas");
			canvasObject.transform.SetParent((Transform)null, false);
			Object.DontDestroyOnLoad((Object)(object)canvasObject);
			Canvas val = canvasObject.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 4000;
			CanvasScaler val2 = canvasObject.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)1;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			GameObject val3 = new GameObject("HudRoot");
			val3.transform.SetParent(canvasObject.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(1f, 1f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(1f, 1f);
			val4.anchoredPosition = new Vector2(-20f, -20f);
			val4.sizeDelta = new Vector2(220f, 90f);
			speedText = CreateText(val3.transform, "0", 46, (TextAnchor)2, (FontStyle)1);
			RectTransform component = ((Component)speedText).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(1f, 1f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(220f, 52f);
			unitText = CreateText(val3.transform, "KM/H", 15, (TextAnchor)2, (FontStyle)0);
			((Graphic)unitText).color = new Color(1f, 1f, 1f, 0.7f);
			RectTransform component2 = ((Component)unitText).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 1f);
			component2.anchoredPosition = new Vector2(0f, -50f);
			component2.sizeDelta = new Vector2(220f, 20f);
			statusText = CreateText(val3.transform, "BHOP: ON", 15, (TextAnchor)2, (FontStyle)1);
			RectTransform component3 = ((Component)statusText).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(1f, 1f);
			component3.anchoredPosition = new Vector2(0f, -74f);
			component3.sizeDelta = new Vector2(220f, 20f);
		}

		private Text CreateText(Transform parent, string value, int size, TextAnchor alignment, FontStyle style)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text");
			val.transform.SetParent(parent, false);
			val.AddComponent<RectTransform>();
			Text val2 = val.AddComponent<Text>();
			val2.text = value;
			val2.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			val2.fontSize = size;
			val2.fontStyle = style;
			val2.alignment = alignment;
			((Graphic)val2).color = Color.white;
			val2.horizontalOverflow = (HorizontalWrapMode)1;
			val2.verticalOverflow = (VerticalWrapMode)0;
			Shadow val3 = val.AddComponent<Shadow>();
			val3.effectColor = new Color(0f, 0f, 0f, 0.6f);
			val3.effectDistance = new Vector2(1.5f, -1.5f);
			return val2;
		}
	}
	[HarmonyPatch]
	internal static class MovementPatches
	{
		private static readonly FieldRef<PlayerMovement, float> CurMoveSpeedRef = AccessTools.FieldRefAccess<PlayerMovement, float>("_curMoveSpeed");

		private static readonly Dictionary<PlayerMovement, bool> WasGrounded = new Dictionary<PlayerMovement, bool>();

		private static readonly Dictionary<PlayerMovement, float> LastLandTime = new Dictionary<PlayerMovement, float>();

		[HarmonyPatch(typeof(PlayerMovement), "GroundCheck")]
		[HarmonyPostfix]
		private static void GroundCheck_Postfix(PlayerMovement __instance)
		{
			if (Plugin.Enabled.Value && IsLocalOwner(__instance))
			{
				bool grounded = __instance.Grounded;
				bool value;
				bool flag = WasGrounded.TryGetValue(__instance, out value) && value;
				if (grounded && !flag)
				{
					LastLandTime[__instance] = Time.time;
				}
				WasGrounded[__instance] = grounded;
				if (Plugin.AutoBhop.Value && grounded && IsJumpHeld())
				{
					__instance.Jump();
				}
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "UpdateMoveSpeed")]
		[HarmonyPostfix]
		private static void UpdateMoveSpeed_Postfix(PlayerMovement __instance)
		{
			if (!Plugin.Enabled.Value || !IsLocalOwner(__instance))
			{
				return;
			}
			bool grounded = __instance.Grounded;
			float value;
			bool flag = LastLandTime.TryGetValue(__instance, out value) && Time.time - value <= Plugin.BhopGraceWindow.Value;
			if (!grounded || flag)
			{
				float value2 = Plugin.AirSpeedCap.Value;
				if (CurMoveSpeedRef.Invoke(__instance) < value2)
				{
					CurMoveSpeedRef.Invoke(__instance) = value2;
				}
			}
		}

		private static bool IsLocalOwner(PlayerMovement pm)
		{
			try
			{
				return ((NetworkBehaviour)pm).IsOwner;
			}
			catch
			{
				return false;
			}
		}

		private static bool IsJumpHeld()
		{
			try
			{
				PlayerInput input = GameInfo.Input;
				if ((Object)(object)input == (Object)null)
				{
					return false;
				}
				return input.actions["PlayerJump"].IsPressed();
			}
			catch
			{
				return false;
			}
		}
	}
	[BepInPlugin("neko.howtofish.bunnyhop", "How To Fish Bunny Hop", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "neko.howtofish.bunnyhop";

		public const string PluginName = "How To Fish Bunny Hop";

		public const string PluginVersion = "1.0.0";

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<bool> AutoBhop;

		public static ConfigEntry<float> AirSpeedCap;

		public static ConfigEntry<float> BhopGraceWindow;

		public static ConfigEntry<KeyCode> ToggleKey;

		public static ConfigEntry<bool> HudEnabled;

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0019: 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_002f: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			new Harmony("neko.howtofish.bunnyhop").PatchAll();
			GameObject val = new GameObject("BunnyHopHud");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<BhopHud>();
			Log.LogInfo((object)string.Format("{0} {1} loaded. Toggle key: {2}", "How To Fish Bunny Hop", "1.0.0", ToggleKey.Value));
		}

		private void BindConfig()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Включает/выключает мод целиком. | Master on/off switch for the mod.");
			AutoBhop = ((BaseUnityPlugin)this).Config.Bind<bool>("Bhop", "AutoBhop", true, "Автоматически прыгать, пока зажата клавиша прыжка. | Automatically jump while the jump key is held.");
			AirSpeedCap = ((BaseUnityPlugin)this).Config.Bind<float>("Bhop", "AirSpeedCap", 14f, new ConfigDescription("Потолок горизонтальной скорости в воздухе / во время бхоп-цепочки. | Horizontal speed cap while airborne / mid bhop-chain.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			BhopGraceWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Bhop", "BhopGraceWindow", 0.12f, new ConfigDescription("Окно в секундах после приземления, где потолок ещё повышен. | Grace window in seconds after landing during which the cap stays raised.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)288, "Клавиша быстрого вкл/выкл мода в игре. | Hotkey to toggle the mod on/off in-game.");
			HudEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hud", "HudEnabled", true, "Показывать HUD со скоростью и статусом бхопа в правом верхнем углу. | Show the speed/status HUD in the top-right corner.");
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(ToggleKey.Value))
			{
				Enabled.Value = !Enabled.Value;
				Log.LogInfo((object)("BunnyHop " + (Enabled.Value ? "enabled" : "disabled")));
			}
		}
	}
}