using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EasyBackpack")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EasyBackpack")]
[assembly: AssemblyTitle("EasyBackpack")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 EasyBackpack
{
[BepInPlugin("nickklmao.easybackpack", "EasyBackpack", "1.1.8")]
internal sealed class Entry : BaseUnityPlugin
{
[HarmonyPatch(typeof(GUIManager), "CloseBackpackWheel")]
private static class WheelClosedPatch
{
[HarmonyPostfix]
private static void Postfix()
{
ReleaseWheel();
}
}
[HarmonyPatch(typeof(BackpackWheel), "Update")]
private static class BackpackWheelUpdatePatch
{
private static bool s_forced;
private static bool s_savedInteract;
[HarmonyPrefix]
private static void Prefix()
{
s_forced = false;
try
{
if (isAccessingBackpack)
{
Character localCharacter = Character.localCharacter;
if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.input == (Object)null))
{
s_savedInteract = localCharacter.input.interactIsPressed;
localCharacter.input.interactIsPressed = true;
s_forced = true;
}
}
}
catch (Exception e)
{
s_forced = false;
LogPatchError("BackpackWheel.Update prefix", e);
}
}
[HarmonyFinalizer]
private static Exception Finalizer(Exception __exception)
{
try
{
if (s_forced)
{
s_forced = false;
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.input != (Object)null)
{
localCharacter.input.interactIsPressed = s_savedInteract;
}
}
}
catch (Exception e)
{
LogPatchError("BackpackWheel.Update finalizer", e);
}
return __exception;
}
}
[HarmonyPatch(typeof(CharacterBackpackHandler), "AddFuelToJetpack")]
private static class SelfRefuelRollbackFix
{
private static float s_beforeFuel = float.NaN;
private static Guid s_beforeGuid = Guid.Empty;
[HarmonyPrefix]
private static void Prefix(CharacterBackpackHandler __instance, Character interactor, ref float addedFuel)
{
s_beforeFuel = float.NaN;
s_beforeGuid = Guid.Empty;
try
{
if ((Object)(object)interactor == (Object)null || (Object)(object)__instance == (Object)null || interactor.refs == null || (Object)(object)interactor.refs.backpackHandler != (Object)(object)__instance)
{
return;
}
int num = 25;
Item currentItem = interactor.data.currentItem;
if ((Object)(object)currentItem != (Object)null)
{
RopeSpool val = default(RopeSpool);
if (((Component)currentItem).TryGetComponent<RopeSpool>(ref val))
{
num = Mathf.CeilToInt(val.RopeFuel);
}
else if (currentItem.HasData((DataEntryKey)10))
{
num = currentItem.overrideJetpackFuelAmount + Mathf.RoundToInt(currentItem.GetData<FloatItemData>((DataEntryKey)10).Value * currentItem.overrideJetpackFuelPerFuelMult);
}
else if (currentItem is Backpack)
{
num = currentItem.overrideJetpackFuelAmount;
}
else if (currentItem.overrideJetpackFuel)
{
num = (currentItem.HasData((DataEntryKey)2) ? (currentItem.overrideJetpackFuelAmount + currentItem.GetData<OptionableIntItemData>((DataEntryKey)2).Value * currentItem.overrideJetpackFuelPerUse) : currentItem.overrideJetpackFuelAmount);
}
}
addedFuel = num;
if (!PhotonNetwork.IsMasterClient)
{
Player player = interactor.player;
FloatItemData val2 = default(FloatItemData);
if (!((Object)(object)player == (Object)null) && player.backpackSlot != null && ((ItemSlot)player.backpackSlot).data != null && ((ItemSlot)player.backpackSlot).data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val2))
{
s_beforeFuel = val2.Value;
s_beforeGuid = ((ItemSlot)player.backpackSlot).data.guid;
}
}
}
catch (Exception e)
{
s_beforeFuel = float.NaN;
s_beforeGuid = Guid.Empty;
LogPatchError("AddFuelToJetpack prefix", e);
}
}
[HarmonyPostfix]
private static void Postfix(CharacterBackpackHandler __instance, Character interactor)
{
float num = s_beforeFuel;
Guid guid = s_beforeGuid;
s_beforeFuel = float.NaN;
s_beforeGuid = Guid.Empty;
try
{
if (!float.IsNaN(num) && !((Object)(object)interactor == (Object)null) && !((Object)(object)__instance == (Object)null) && interactor.refs != null && !((Object)(object)interactor.refs.backpackHandler != (Object)(object)__instance))
{
Player player = interactor.player;
FloatItemData val = default(FloatItemData);
if (!((Object)(object)player == (Object)null) && player.backpackSlot != null && ((ItemSlot)player.backpackSlot).data != null && !(((ItemSlot)player.backpackSlot).data.guid != guid) && ((ItemSlot)player.backpackSlot).data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val) && !(val.Value <= num + 0.01f))
{
s_pendingArmed = true;
s_pendingBaseFuel = num;
s_pendingPlayer = player;
s_pendingDataGuid = guid;
s_pendingLastRefuelTime = Time.unscaledTime;
}
}
}
catch (Exception e)
{
ClearPendingRefuel();
LogPatchError("AddFuelToJetpack postfix", e);
}
}
}
[HarmonyPatch(typeof(Player), "SyncInventoryRPC")]
private static class SyncInventoryRefuelFix
{
[HarmonyPrefix]
private static void Prefix(Player __instance)
{
s_pendingPreSyncFuel = float.NaN;
try
{
if ((Object)(object)__instance == (Object)null || !s_pendingArmed || PhotonNetwork.IsMasterClient || (Object)(object)__instance != (Object)(object)s_pendingPlayer)
{
return;
}
BackpackSlot backpackSlot = __instance.backpackSlot;
if (backpackSlot != null && !((ItemSlot)backpackSlot).IsEmpty())
{
ItemInstanceData data = ((ItemSlot)backpackSlot).data;
FloatItemData val = default(FloatItemData);
if (data != null && !(data.guid != s_pendingDataGuid) && data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val))
{
s_pendingPreSyncFuel = val.Value;
}
}
}
catch (Exception e)
{
s_pendingPreSyncFuel = float.NaN;
LogPatchError("SyncInventoryRPC prefix", e);
}
}
[HarmonyPostfix]
private static void Postfix(Player __instance)
{
float s_pendingPreSyncFuel = Entry.s_pendingPreSyncFuel;
Entry.s_pendingPreSyncFuel = float.NaN;
try
{
if (float.IsNaN(s_pendingPreSyncFuel) || (Object)(object)__instance == (Object)null)
{
return;
}
BackpackSlot backpackSlot = __instance.backpackSlot;
if (backpackSlot == null)
{
return;
}
if (((ItemSlot)backpackSlot).IsEmpty())
{
ClearPendingRefuel();
return;
}
ItemInstanceData data = ((ItemSlot)backpackSlot).data;
if (data == null)
{
return;
}
if (data.guid != s_pendingDataGuid)
{
ClearPendingRefuel();
}
else
{
FloatItemData val = default(FloatItemData);
if (!data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val))
{
return;
}
if (val.Value > s_pendingBaseFuel + 0.01f)
{
ClearPendingRefuel();
return;
}
val.Value = s_pendingPreSyncFuel;
FloatItemData val2 = default(FloatItemData);
if (data.TryGetDataEntry<FloatItemData>((DataEntryKey)11, ref val2))
{
val2.Value = Mathf.Clamp01(s_pendingPreSyncFuel / 100f);
}
}
}
catch (Exception e)
{
ClearPendingRefuel();
LogPatchError("SyncInventoryRPC postfix", e);
}
}
}
private static readonly ManualLogSource logger = Logger.CreateLogSource("EasyBackpack");
private static ConfigEntry<KeyCode> backpackKey;
private static ConfigEntry<KeyCode> alternativeBackpackKey;
private static bool isAccessingBackpack;
private static bool isAccessingCarriedPlayersBackpack;
private static KeyCode s_activeKey = (KeyCode)0;
private static float s_lastOpenWarn = float.MinValue;
private static float s_lastPatchWarn = float.MinValue;
private static KeyCode s_cachedMainKey = (KeyCode)0;
private static KeyCode s_cachedAltKey = (KeyCode)0;
private static bool s_mainKeyPollable;
private static bool s_altKeyPollable;
private static bool s_quitting;
private static bool s_pendingArmed;
private static float s_pendingBaseFuel;
private static float s_pendingPreSyncFuel;
private static Player s_pendingPlayer;
private static Guid s_pendingDataGuid;
private static float s_pendingLastRefuelTime;
private const float s_pendingCleanupSeconds = 30f;
private readonly Harmony m_harmony = new Harmony("nickklmao.easybackpack");
private void Awake()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
logger.LogInfo((object)"Creating config entries");
backpackKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keybinds", "Backpack Key", (KeyCode)98, new ConfigDescription("The key you want to use to access the backpack while it's on your back", (AcceptableValueBase)null, Array.Empty<object>()));
alternativeBackpackKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keybinds", "Alternative Backpack Key", (KeyCode)0, new ConfigDescription("An optional alternative key for accessing the backpack while it's on your back", (AcceptableValueBase)null, Array.Empty<object>()));
ReleaseWheel();
ClearPendingRefuel();
s_quitting = false;
s_cachedAltKey = (KeyCode)0;
s_cachedMainKey = (KeyCode)0;
s_mainKeyPollable = (s_altKeyPollable = false);
logger.LogInfo((object)"Hooking BackpackWheel.Update");
ApplyPatch(typeof(BackpackWheelUpdatePatch), "BackpackWheel.Update");
ApplyPatch(typeof(WheelClosedPatch), "GUIManager.CloseBackpackWheel");
ApplyPatch(typeof(SelfRefuelRollbackFix), "CharacterBackpackHandler.AddFuelToJetpack");
ApplyPatch(typeof(SyncInventoryRefuelFix), "Player.SyncInventoryRPC");
}
private void ApplyPatch(Type patchClass, string target)
{
try
{
m_harmony.PatchAll(patchClass);
}
catch (Exception arg)
{
logger.LogError((object)$"Failed to patch {target}: {arg}");
}
}
private void OnApplicationQuit()
{
s_quitting = true;
}
private void OnDestroy()
{
ReleaseWheel();
ClearPendingRefuel();
if (s_quitting)
{
return;
}
try
{
m_harmony.UnpatchSelf();
}
catch (Exception arg)
{
logger.LogWarning((object)$"Failed to remove patches on unload: {arg}");
}
}
private void Update()
{
try
{
UpdateInternal();
}
catch (Exception e)
{
ReleaseWheel();
LogPatchError("Update", e);
}
}
private void UpdateInternal()
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: 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_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
if (s_pendingArmed && Time.unscaledTime - s_pendingLastRefuelTime > 30f)
{
ClearPendingRefuel();
}
Character localCharacter = Character.localCharacter;
if (!Application.isFocused || (Object)(object)localCharacter == (Object)null)
{
ReleaseWheel();
return;
}
if (isAccessingBackpack && !IsBackpackWheelActive())
{
ReleaseWheel();
}
if (isAccessingBackpack && ((int)s_activeKey == 0 || !Input.GetKey(s_activeKey)))
{
ReleaseWheel();
return;
}
if (isAccessingCarriedPlayersBackpack)
{
if ((Object)(object)localCharacter.data.carriedPlayer == (Object)null)
{
ReleaseWheel();
return;
}
}
else if (localCharacter.data.passedOut || localCharacter.data.fullyPassedOut || localCharacter.data.dead || localCharacter.data.currentItem is Backpack)
{
ReleaseWheel();
return;
}
KeyCode value = backpackKey.Value;
KeyCode value2 = alternativeBackpackKey.Value;
if (value != s_cachedMainKey)
{
s_cachedMainKey = value;
s_mainKeyPollable = IsPollableKey(value, "Backpack Key");
}
if (value2 != s_cachedAltKey)
{
s_cachedAltKey = value2;
s_altKeyPollable = IsPollableKey(value2, "Alternative Backpack Key");
}
KeyCode val = (KeyCode)0;
if (s_mainKeyPollable && Input.GetKeyDown(value))
{
val = value;
}
else if (s_altKeyPollable && Input.GetKeyDown(value2))
{
val = value2;
}
if ((int)val == 0)
{
return;
}
try
{
Player player = localCharacter.player;
if ((Object)(object)player != (Object)null)
{
BackpackSlot backpackSlot = player.backpackSlot;
if (backpackSlot != null && !((ItemSlot)backpackSlot).IsEmpty())
{
TryOpenWheel(localCharacter, backpackSlot.backpackType, val, carried: false);
return;
}
}
Character carriedPlayer = localCharacter.data.carriedPlayer;
if ((Object)(object)carriedPlayer == (Object)null)
{
return;
}
Player player2 = carriedPlayer.player;
if (!((Object)(object)player2 == (Object)null))
{
BackpackSlot backpackSlot2 = player2.backpackSlot;
if (backpackSlot2 != null && !((ItemSlot)backpackSlot2).IsEmpty())
{
TryOpenWheel(carriedPlayer, backpackSlot2.backpackType, val, carried: true);
}
}
}
catch (Exception e)
{
LogOpenFailure(e);
}
}
private static void ReleaseWheel()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
isAccessingCarriedPlayersBackpack = (isAccessingBackpack = false);
s_activeKey = (KeyCode)0;
}
private static bool IsPollableKey(KeyCode key, string configName)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected I4, but got Unknown
if ((int)key == 0)
{
return false;
}
if (!Enum.IsDefined(typeof(KeyCode), key))
{
logger.LogWarning((object)$"Config entry \"{configName}\" holds an invalid KeyCode value ({(int)key}); this key is ignored.");
return false;
}
return true;
}
private static void TryOpenWheel(Character owner, BackpackType backpackType, KeyCode openedWith, bool carried)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
if ((int)backpackType == 4 || IsBackpackWheelActive())
{
return;
}
int num = 4;
CharacterBackpackHandler backpackHandler = owner.refs.backpackHandler;
if ((Object)(object)backpackHandler != (Object)null)
{
BackpackOnBackVisuals activeBackpackVisuals = backpackHandler.activeBackpackVisuals;
if ((Object)(object)activeBackpackVisuals != (Object)null)
{
num = activeBackpackVisuals.slotCount;
}
}
BackpackReference fromEquippedBackpack = BackpackReference.GetFromEquippedBackpack(owner);
GUIManager.instance.OpenBackpackWheel(fromEquippedBackpack, num, backpackType);
if (IsBackpackWheelActive())
{
isAccessingBackpack = true;
s_activeKey = openedWith;
if (carried)
{
isAccessingCarriedPlayersBackpack = true;
}
}
}
private static bool IsBackpackWheelActive()
{
GUIManager instance = GUIManager.instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
BackpackWheel backpackWheel = instance.backpackWheel;
if ((Object)(object)backpackWheel != (Object)null)
{
return ((Component)backpackWheel).gameObject.activeSelf;
}
return false;
}
private static void LogOpenFailure(Exception e)
{
if (Time.unscaledTime - s_lastOpenWarn > 5f)
{
s_lastOpenWarn = Time.unscaledTime;
logger.LogWarning((object)$"Failed to open the backpack wheel (player, backpack visuals or ragdoll not ready); the wheel was not opened. {e}");
}
}
private static void LogPatchError(string where, Exception e)
{
if (Time.unscaledTime - s_lastPatchWarn > 5f)
{
s_lastPatchWarn = Time.unscaledTime;
logger.LogWarning((object)$"Unexpected error in {where}: {e}");
}
}
private static void ClearPendingRefuel()
{
s_pendingArmed = false;
s_pendingPlayer = null;
s_pendingDataGuid = Guid.Empty;
s_pendingPreSyncFuel = float.NaN;
}
}
}