using System; using System.Collections.Generic; 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 JetpackPocket.Patches; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalNetworkAPI; using TMPro; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("JetpackPocket")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("JetpackPocket")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("16975d87-0cf9-4922-88fd-a28d56a3ae51")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace JetpackPocket { internal static class ConfigSync { private const string MessageId = "PixelIndieDev_JetpackPocket.CarryMultipleTwoHanded"; internal static bool SyncedCarryMultipleTwoHanded; private static LNetworkMessage networkedMessage; public static void SetNetworkMessage() { SyncedCarryMultipleTwoHanded = JetpackPocketPatchBase.instance.JetpackPocketConfigEntry.Value; networkedMessage = LNetworkMessage.Connect("PixelIndieDev_JetpackPocket.CarryMultipleTwoHanded", (Action)null, (Action)OnReceivedFromHost, (Action)null); } public static void SendToClients(bool value) { SyncedCarryMultipleTwoHanded = value; networkedMessage.SendClients(value); JetpackPocketPatchBase.logSource.LogInfo((object)$"Sent CarryMultipleTwoHanded = {value}, to all clients."); } private static void OnReceivedFromHost(bool value) { SyncedCarryMultipleTwoHanded = value; JetpackPocketPatchBase.logSource.LogInfo((object)$"Received CarryMultipleTwoHanded = {value}, from host."); JetpackHelper.UpdateHUD(); } } internal static class JetpackHelper { public struct JetpackState { public bool HasJetpack; public int HasTwoHandedItem; } private static readonly Dictionary PlayerDictionary = new Dictionary(); public static bool HasJetpack(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } if (PlayerDictionary.TryGetValue(player.playerClientId, out var value)) { return value.HasJetpack; } return false; } public static bool HasTwoHandedAndJetpack(PlayerControllerB player) { if (PlayerDictionary.TryGetValue(player.playerClientId, out var value) && value.HasJetpack) { return value.HasTwoHandedItem > 0; } return false; } public static bool HasTwoHanded(PlayerControllerB player) { if (PlayerDictionary.TryGetValue(player.playerClientId, out var value)) { return value.HasTwoHandedItem > 0; } return false; } private static void SaveState(ulong player, JetpackState value) { PlayerDictionary[player] = value; } public static void Rescan(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } JetpackState value = default(JetpackState); GrabbableObject[] itemSlots = player.ItemSlots; foreach (GrabbableObject item in itemSlots) { if (IsJetpack(item)) { value.HasJetpack = true; } if (IsTwoHanded(item)) { value.HasTwoHandedItem++; } } if (IsJetpack(player.ItemOnlySlot)) { value.HasJetpack = true; } SaveState(player.playerClientId, value); } private static bool IsJetpack(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return false; } return ((object)item).GetType().Name == "JetpackItem"; } private static bool IsTwoHanded(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return false; } return item.itemProperties.twoHanded; } public static void UpdateHUD(PlayerControllerB __instance) { if ((Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).IsOwner) { bool flag = HasTwoHanded(__instance); bool flag2 = HasJetpack(__instance); ((Behaviour)HUDManager.Instance.holdingTwoHandedItem).enabled = (flag && !flag2) || (flag && flag2 && !ConfigSync.SyncedCarryMultipleTwoHanded); } } public static void UpdateHUD() { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController != (Object)null) { UpdateHUD(localPlayerController); } } } [BepInPlugin("PixelIndieDev_JetpackPocket", "Jetpack Pocket", "1.3.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class JetpackPocketPatchBase : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("PixelIndieDev_JetpackPocket"); public static JetpackPocketPatchBase instance; public ConfigEntry JetpackPocketConfigEntry; internal static ManualLogSource logSource; private void Awake() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { instance = this; } logSource = Logger.CreateLogSource("PixelIndieDev_JetpackPocket"); JetpackPocketConfigEntry = ((BaseUnityPlugin)this).Config.Bind("General", "Carry multiple two-handed items", false, "Enables carrying multiple two-handed items at the same time while having a jetpack."); JetpackPocketConfigEntry.SettingChanged += delegate { if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsHost) { ConfigSync.SendToClients(JetpackPocketConfigEntry.Value); } JetpackHelper.UpdateHUD(); }; LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(JetpackPocketConfigEntry, new BoolCheckBoxOptions { RequiresRestart = false })); harmony.PatchAll(typeof(JetpackPocketPatchBase)); harmony.PatchAll(typeof(PlayerControllerBPatch)); harmony.PatchAll(typeof(NetworkPatch)); ConfigSync.SetNetworkMessage(); logSource.LogInfo((object)"Jetpack Pocket (version - 1.3.0.0): patches applied successfully"); } } internal static class ModInfo { internal const string modGUID = "PixelIndieDev_JetpackPocket"; internal const string modName = "Jetpack Pocket"; internal const string modVersion = "1.3.0.0"; } } namespace JetpackPocket.Patches { [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetworkManagerPatch { [HarmonyPostfix] [HarmonyPatch("StartGame")] private static void OnStartGame() { if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsHost) { JetpackPocketPatchBase.logSource.LogInfo((object)"Host started game - sending config to clients."); ConfigSync.SendToClients(JetpackPocketPatchBase.instance.JetpackPocketConfigEntry.Value); } } [HarmonyPostfix] [HarmonyPatch("StartDisconnect")] private static void OnStartDisconnect() { ConfigSync.SyncedCarryMultipleTwoHanded = JetpackPocketPatchBase.instance.JetpackPocketConfigEntry.Value; JetpackPocketPatchBase.logSource.LogInfo((object)"Disconnected — reset synced config to local value."); } } [HarmonyPatch(typeof(NetworkManager))] internal static class NetworkPatch { [HarmonyPostfix] [HarmonyPatch("SetSingleton")] private static void RegisterPrefab() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PixelIndieDev_JetpackPocket Prefab"); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D); Object.DontDestroyOnLoad((Object)(object)val); NetworkObject obj = val.AddComponent(); typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(obj, GetHash("PixelIndieDev_JetpackPocket")); NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val); } private static uint GetHash(string value) { return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0; } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch { private const int objectMask = 1073742656; [HarmonyPatch("GrabObjectClientRpc")] [HarmonyPostfix] [HarmonyPriority(0)] private static void GrabObjectClientRpcPatch(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("ThrowObjectClientRpc")] [HarmonyPostfix] [HarmonyPriority(0)] private static void ThrowObjectClientRpcPatch(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("PlaceObjectClientRpc")] [HarmonyPostfix] [HarmonyPriority(0)] private static void PlaceObjectClientRpcPatch(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("DropAllHeldItems")] [HarmonyPostfix] [HarmonyPriority(0)] private static void DropAllHeldItemsPatch(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("DespawnHeldObjectClientRpc")] [HarmonyPostfix] [HarmonyPriority(0)] private static void DespawnHeldObjectClientRpcPatch(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("ScrollMouse_performed")] [HarmonyPrefix] [HarmonyPriority(0)] private static void ScrollPatch(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && !__instance.inTerminalMenu) { if (__instance.twoHanded && JetpackHelper.HasJetpack(__instance)) { __instance.twoHanded = false; } JetpackHelper.UpdateHUD(__instance); } } [HarmonyPatch("UseUtilitySlot_performed")] [HarmonyPrefix] [HarmonyPriority(0)] private static void tabPatch(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && !__instance.inTerminalMenu) { if (__instance.twoHanded && JetpackHelper.HasJetpack(__instance)) { __instance.twoHanded = false; } JetpackHelper.UpdateHUD(__instance); } } [HarmonyPatch("BeginGrabObject")] [HarmonyPrefix] [HarmonyPriority(0)] private static bool BeginGrabObjectPatch(PlayerControllerB __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (ConfigSync.SyncedCarryMultipleTwoHanded) { return true; } if (__instance.twoHanded) { return true; } if (!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled) { return true; } RaycastHit val = default(RaycastHit); if (!Physics.Raycast(new Ray(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward), ref val, __instance.grabDistance, 1073742656) || ((Component)((RaycastHit)(ref val)).collider).gameObject.layer == 8 || ((Component)((RaycastHit)(ref val)).collider).tag != "PhysicsProp" || __instance.sinkingValue > 0.73f || Physics.Linecast(((Component)__instance.gameplayCamera).transform.position, ((Component)((RaycastHit)(ref val)).collider).transform.position + ((Component)__instance).transform.up * 0.16f, 1073741824, (QueryTriggerInteraction)1)) { return true; } if (JetpackHelper.HasTwoHanded(__instance)) { GrabbableObject component = ((Component)((Component)((RaycastHit)(ref val)).collider).transform).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.itemProperties.twoHanded) { JetpackHelper.UpdateHUD(__instance); return false; } } return true; } [HarmonyPatch("SwitchToItemSlot")] [HarmonyPostfix] [HarmonyPriority(0)] private static void SwitchToItem(PlayerControllerB __instance) { JetpackHelper.Rescan(__instance); JetpackHelper.UpdateHUD(__instance); } [HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")] [HarmonyPostfix] [HarmonyPriority(0)] private static void SetHoverTipPatch(PlayerControllerB __instance) { //IL_002d: 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_0042: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && !ConfigSync.SyncedCarryMultipleTwoHanded && JetpackHelper.HasTwoHanded(__instance) && Physics.Raycast(new Ray(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward), ref val, __instance.grabDistance, 1073742656) && ((Component)((RaycastHit)(ref val)).collider).gameObject.layer != 8 && !(((Component)((RaycastHit)(ref val)).collider).tag != "PhysicsProp")) { GrabbableObject component = ((Component)((Component)((RaycastHit)(ref val)).collider).transform).gameObject.GetComponent(); if (!((Object)(object)component == (Object)null) && component.itemProperties.twoHanded) { ((TMP_Text)__instance.cursorTip).text = "Can't carry more: hands full!"; } } } } }