using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LC_Bhop")] [assembly: AssemblyDescription("LC_Bhop mod for Lethal Company")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Diman3012")] [assembly: AssemblyProduct("LC_Bhop")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("658b1380-3c08-49da-aaec-43ad07a87f4a")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace lcbhop; public class Config { private readonly ConfigFile config; public ConfigEntry modEnabled; public ConfigEntry autobhop; public ConfigEntry speedometer; public ConfigEntry enablebunnyhopping; public ConfigEntry gravity; public ConfigEntry friction; public ConfigEntry maxspeed; public ConfigEntry movespeed; public ConfigEntry accelerate; public ConfigEntry airaccelerate; public ConfigEntry stopspeed; public ConfigEntry jumpForce; public Config(ConfigFile cfg) { config = cfg; } public void Init() { modEnabled = config.Bind("General", "ModEnabled", false, "Глобальный переключатель мода."); autobhop = config.Bind("General", "Auto Bhop", true, "Авто-прыжок при зажатом пробеле."); speedometer = config.Bind("General", "Speedometer", false, "Спидометр."); enablebunnyhopping = config.Bind("Movement v4", "Enable bunnyhopping", true, "Отключение лимита скорости."); gravity = config.Bind("Movement v4", "Gravity", 800f, "Гравитация."); friction = config.Bind("Movement v4", "Friction", 4f, "Трение."); maxspeed = config.Bind("Movement v4", "Max Speed", 1500f, "Максимальный лимит (1500)."); movespeed = config.Bind("Movement v4", "Move Speed", 250f, "Базовая скорость."); accelerate = config.Bind("Movement v4", "Accelerate", 5f, "Ускорение на земле."); jumpForce = config.Bind("Movement v4", "Jump Force", 295f, "Сила прыжка (стандарт 295)."); airaccelerate = config.Bind("Movement v4", "Air Accelerate", 150f, "Ускорение в воздухе."); stopspeed = config.Bind("Movement v4", "Stop Speed", 75f, "Скорость остановки."); } } internal struct Cmd { public float forwardMove; public float rightMove; public float upMove; } public class CPMPlayer : MonoBehaviour { public PlayerControllerB player; private CharacterController _controller; private Vector3 velocity = Vector3.zero; public bool wishJump; private Cmd _cmd; private GameObject compass; private TextMeshProUGUI speedo; public float gravity => Plugin.cfg.gravity.Value; public float friction => Plugin.cfg.friction.Value; public float maxspeed => Plugin.cfg.maxspeed.Value; public float movespeed => Plugin.cfg.movespeed.Value; public float accelerate => Plugin.cfg.accelerate.Value; public float airaccelerate => Plugin.cfg.airaccelerate.Value; public float stopspeed => Plugin.cfg.stopspeed.Value; public float jumpForce => Plugin.cfg.jumpForce.Value; private void Start() { _controller = player.thisController; } private void Update() { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) if (((ButtonControl)Keyboard.current.f1Key).wasPressedThisFrame) { Plugin.cfg.modEnabled.Value = !Plugin.cfg.modEnabled.Value; HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("LC Bhop", Plugin.cfg.modEnabled.Value ? "Enabled" : "Disabled", false, false, "LC_Tip1"); } if (!Plugin.cfg.modEnabled.Value) { Plugin.patchMove = false; Plugin.patchJump = false; if (Object.op_Implicit((Object)(object)compass)) { compass.SetActive(false); } } } if (!Plugin.cfg.modEnabled.Value) { return; } player.fallValue = 0f; player.fallValueUncapped = 0f; player.sprintMeter = 1f; if (((!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || (((NetworkBehaviour)player).IsServer && !player.isHostPlayerObject)) && !player.isTestingPlayer) || player.quickMenuManager.isMenuOpen || player.inSpecialInteractAnimation || player.isTypingChat) { return; } if (player.isClimbingLadder) { Plugin.patchMove = false; return; } Jump(); if (!wishJump && _controller.isGrounded) { Friction(); } if (_controller.isGrounded) { WalkMove(); } else if (!_controller.isGrounded) { AirMove(); } Plugin.patchMove = false; _controller.Move(velocity / 32f * Time.deltaTime); Plugin.patchMove = true; wishJump = false; if (Plugin.cfg.speedometer.Value) { if (!Object.op_Implicit((Object)(object)compass)) { compass = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/TopLeftCorner/Compass"); GameObject obj = compass; speedo = ((obj != null) ? obj.GetComponentInChildren() : null); } if (Object.op_Implicit((Object)(object)compass)) { compass.SetActive(true); Vector3 val = velocity; val.y = 0f; ((TMP_Text)speedo).text = $"{(int)((Vector3)(ref val)).magnitude} u"; ((TMP_Text)speedo).rectTransform.sizeDelta = ((TMP_Text)speedo).GetPreferredValues(); } } else if (Object.op_Implicit((Object)(object)compass)) { compass.SetActive(false); } } private void SetMovementDir() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) ref Cmd cmd = ref _cmd; MovementActions movement = player.playerActions.Movement; cmd.forwardMove = ((MovementActions)(ref movement)).Move.ReadValue().y * movespeed; ref Cmd cmd2 = ref _cmd; movement = player.playerActions.Movement; cmd2.rightMove = ((MovementActions)(ref movement)).Move.ReadValue().x * movespeed; } private void Jump() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0056: Unknown result type (might be due to invalid IL or missing references) MovementActions movement; if (Plugin.cfg.autobhop.Value) { movement = player.playerActions.Movement; wishJump = ((MovementActions)(ref movement)).Jump.ReadValue() > 0f; } else if (!wishJump) { movement = player.playerActions.Movement; wishJump = ((MovementActions)(ref movement)).SwitchItem.ReadValue() != 0f; } if (!Plugin.cfg.enablebunnyhopping.Value) { PreventMegaBunnyJumping(); } } private void AirMove() { //IL_002e: 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_0034: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) SetMovementDir(); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(_cmd.rightMove, 0f, _cmd.forwardMove); val = ((Component)this).transform.TransformDirection(val); Vector3 wishdir = val; float magnitude = ((Vector3)(ref wishdir)).magnitude; ((Vector3)(ref wishdir)).Normalize(); if (magnitude > maxspeed) { magnitude = maxspeed; } AirAccelerate(wishdir, magnitude, airaccelerate); velocity.y -= gravity * Time.deltaTime; } private void AirAccelerate(Vector3 wishdir, float wishspeed, float accel) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) float num = wishspeed; if (num > 75f) { num = 75f; } float num2 = Vector3.Dot(velocity, wishdir); float num3 = num - num2; if (!(num3 <= 0f)) { float num4 = accel * wishspeed * Time.deltaTime; if (num4 > num3) { num4 = num3; } velocity.x += num4 * wishdir.x; velocity.z += num4 * wishdir.z; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(velocity.x, 0f, velocity.z); if (((Vector3)(ref val)).magnitude > maxspeed) { val = ((Vector3)(ref val)).normalized * maxspeed; velocity.x = val.x; velocity.z = val.z; } } } private void WalkMove() { //IL_002e: 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_0034: 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) //IL_0036: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) SetMovementDir(); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(_cmd.rightMove, 0f, _cmd.forwardMove); val = ((Component)this).transform.TransformDirection(val); Vector3 wishdir = val; float magnitude = ((Vector3)(ref wishdir)).magnitude; ((Vector3)(ref wishdir)).Normalize(); if (magnitude > maxspeed) { val *= maxspeed / magnitude; magnitude = maxspeed; } Accelerate(wishdir, magnitude, accelerate); velocity.y = (0f - gravity) * Time.deltaTime; if (wishJump) { velocity.y = 295f; } if (wishJump) { velocity.y = jumpForce; } } private void Friction() { //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) Vector3 val = velocity; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude < 0.1f)) { float num = 0f; if (_controller.isGrounded) { float num2 = ((magnitude < stopspeed) ? stopspeed : magnitude); num += num2 * friction * Time.deltaTime; } float num3 = magnitude - num; if (num3 < 0f) { num3 = 0f; } num3 /= magnitude; velocity.x *= num3; velocity.z *= num3; } } private void Accelerate(Vector3 wishdir, float wishspeed, float accel) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Dot(velocity, wishdir); float num2 = wishspeed - num; if (!(num2 <= 0f)) { float num3 = accel * Time.deltaTime * wishspeed; if (num3 > num2) { num3 = num2; } velocity.x += num3 * wishdir.x; velocity.z += num3 * wishdir.z; } } private void PreventMegaBunnyJumping() { //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) Vector3 val = velocity; float num = 1.7f * maxspeed; if (!(num <= 0f)) { val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude <= num)) { float num2 = num / magnitude * 0.65f; velocity.x *= num2; velocity.z *= num2; } } } } [HarmonyPatch(typeof(CharacterController), "Move")] internal class Move_Patch { [HarmonyPrefix] internal static bool Prefix(ref Vector3 motion) { if (!Plugin.cfg.modEnabled.Value) { return true; } if ((Object)(object)Plugin.player == (Object)null) { return true; } return !Plugin.patchMove; } } [HarmonyPatch(typeof(PlayerControllerB), "Crouch_performed")] internal class Crouch_performed_Patch { [HarmonyPrefix] internal static bool Prefix(PlayerControllerB __instance, ref CallbackContext context) { if (!Plugin.cfg.modEnabled.Value) { return true; } if (!((CallbackContext)(ref context)).performed) { return false; } if (__instance.quickMenuManager.isMenuOpen) { return false; } if ((!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer) { return false; } if (__instance.inSpecialInteractAnimation || __instance.isTypingChat) { return false; } __instance.Crouch(!__instance.isCrouching); return false; } } [HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")] internal class Jump_performed_Patch { [HarmonyPrefix] internal static bool Prefix(ref CallbackContext context) { if (!Plugin.cfg.modEnabled.Value) { return true; } if ((Object)(object)Plugin.player == (Object)null) { return true; } Plugin.player.wishJump = true; return !Plugin.patchJump; } } [HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")] internal class ScrollMouse_performed_Patch { [HarmonyPrefix] internal static bool Prefix(ref CallbackContext context) { if (!Plugin.cfg.modEnabled.Value) { return true; } return Plugin.cfg.autobhop.Value; } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] internal class SubmitChat_performed_Patch { [HarmonyPrefix] internal static bool Prefix(HUDManager __instance) { string text = __instance.chatTextField.text; if (text.StartsWith("/autobhop")) { Plugin.cfg.autobhop.Value = !Plugin.cfg.autobhop.Value; } else { if (!text.StartsWith("/speedo")) { return true; } Plugin.cfg.speedometer.Value = !Plugin.cfg.speedometer.Value; } __instance.localPlayer.isTypingChat = false; __instance.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); __instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f); ((Behaviour)__instance.typingIndicator).enabled = false; return false; } } public class ComponentAdder : MonoBehaviour { private void Update() { PlayerControllerB[] array = Object.FindObjectsOfType(); foreach (PlayerControllerB val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject.GetComponentInChildren() == (Object)null && ((NetworkBehaviour)val).IsOwner && val.isPlayerControlled) { Plugin.player = ((Component)val).gameObject.AddComponent(); Plugin.player.player = val; } } } } [BepInPlugin("lcbhop", "LC Bhop", "1.0.0")] public class Plugin : BaseUnityPlugin { public static ManualLogSource logger; private readonly Harmony harmony = new Harmony("lcbhop"); public static bool patchMove = true; public static bool patchJump = true; public static CPMPlayer player; public static Config cfg { get; set; } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0048: Expected O, but got Unknown cfg = new Config(((BaseUnityPlugin)this).Config); cfg.Init(); logger = ((BaseUnityPlugin)this).Logger; harmony.PatchAll(); GameObject val = new GameObject("ComponentAdder") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); val.AddComponent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin lcbhop is loaded!"); } } [HarmonyPatch(typeof(NetworkManager))] internal static class NetworkPrefabPatch2 { private static readonly string MOD_GUID = "lcbhop"; [HarmonyPostfix] [HarmonyPatch("SetSingleton")] private static void RegisterPrefab() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0017: 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) GameObject val = new GameObject(MOD_GUID + " Prefab"); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D); Object.DontDestroyOnLoad((Object)(object)val); NetworkObject obj = val.AddComponent(); FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(obj, GetHash(MOD_GUID)); } if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.PrefabHandler != null) { NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val); } } private static uint GetHash(string value) { return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0; } }