Decompiled source of EasyBackpack Fix v1.1.9

EasyBackpack.dll

Decompiled 2 weeks 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 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
{
	internal enum WheelTarget
	{
		None,
		Self,
		Carried
	}
	internal static class BackpackShortcut
	{
		private static WheelTarget s_target;

		private static KeyCode s_heldKey;

		private static KeyCode s_cachedMainKey;

		private static KeyCode s_cachedAltKey;

		private static bool s_mainKeyPollable;

		private static bool s_altKeyPollable;

		internal static bool HoldsWheel => s_target != WheelTarget.None;

		internal static bool IsWheelOpen
		{
			get
			{
				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;
			}
		}

		internal static void Reset()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Release();
			s_cachedMainKey = (KeyCode)0;
			s_cachedAltKey = (KeyCode)0;
			s_mainKeyPollable = false;
			s_altKeyPollable = false;
		}

		internal static void Release()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			s_target = WheelTarget.None;
			s_heldKey = (KeyCode)0;
		}

		internal static void AbortWheel()
		{
			Release();
			Character localCharacter = Character.localCharacter;
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance.backpackWheel == (Object)null || (!((Component)instance.backpackWheel).gameObject.activeSelf && !localCharacter.data.usingBackpackWheel))
			{
				return;
			}
			try
			{
				instance.CloseBackpackWheel();
			}
			catch (Exception e)
			{
				Diagnostics.PatchFailed("closing the backpack wheel", e);
			}
		}

		internal static void AbortIfHolding()
		{
			if (HoldsWheel)
			{
				AbortWheel();
			}
			else
			{
				Release();
			}
		}

		internal static void Tick()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			FuelRollback.ExpireStale();
			Character localCharacter = Character.localCharacter;
			if (!Application.isFocused || (Object)(object)localCharacter == (Object)null)
			{
				AbortIfHolding();
				return;
			}
			if (s_target != WheelTarget.None)
			{
				if (!IsWheelOpen)
				{
					Release();
				}
				else if ((int)s_heldKey == 0 || !Input.GetKey(s_heldKey))
				{
					Release();
				}
				else if (!StillValid(localCharacter))
				{
					AbortWheel();
				}
				return;
			}
			CharacterData data = localCharacter.data;
			if (data.passedOut || data.fullyPassedOut || data.dead || data.currentItem is Backpack)
			{
				return;
			}
			KeyCode val = PollPressedKey();
			if ((int)val == 0)
			{
				return;
			}
			try
			{
				Open(localCharacter, val);
			}
			catch (Exception e)
			{
				Diagnostics.WheelOpenFailed(e);
				AbortWheel();
			}
		}

		private static bool StillValid(Character local)
		{
			CharacterData data = local.data;
			if (data.passedOut || data.fullyPassedOut || data.dead)
			{
				return false;
			}
			if (s_target == WheelTarget.Carried)
			{
				return (Object)(object)data.carriedPlayer != (Object)null;
			}
			return !(data.currentItem is Backpack);
		}

		private static KeyCode PollPressedKey()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0013: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = Settings.BackpackKey.Value;
			if (value != s_cachedMainKey)
			{
				s_cachedMainKey = value;
				s_mainKeyPollable = IsPollableKey(value, "Backpack Key");
			}
			KeyCode value2 = Settings.AlternativeBackpackKey.Value;
			if (value2 != s_cachedAltKey)
			{
				s_cachedAltKey = value2;
				s_altKeyPollable = IsPollableKey(value2, "Alternative Backpack Key");
			}
			if (s_mainKeyPollable && Input.GetKeyDown(value))
			{
				return value;
			}
			if (!s_altKeyPollable || !Input.GetKeyDown(value2))
			{
				return (KeyCode)0;
			}
			return value2;
		}

		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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected I4, but got Unknown
			if ((int)key == 0)
			{
				return false;
			}
			if (!Enum.IsDefined(typeof(KeyCode), key))
			{
				Diagnostics.Error($"Config entry \"{configName}\" holds an invalid KeyCode value ({(int)key}); it will be ignored.");
				return false;
			}
			return true;
		}

		private static void Open(Character local, KeyCode key)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Player player = local.player;
			if ((Object)(object)player != (Object)null && player.backpackSlot != null && !((ItemSlot)player.backpackSlot).IsEmpty() && TryOpenWheel(local, player.backpackSlot.backpackType, key, WheelTarget.Self))
			{
				return;
			}
			Character carriedPlayer = local.data.carriedPlayer;
			if (!((Object)(object)carriedPlayer == (Object)null))
			{
				Player player2 = carriedPlayer.player;
				if (!((Object)(object)player2 == (Object)null) && player2.backpackSlot != null && !((ItemSlot)player2.backpackSlot).IsEmpty())
				{
					TryOpenWheel(carriedPlayer, player2.backpackSlot.backpackType, key, WheelTarget.Carried);
				}
			}
		}

		private static bool TryOpenWheel(Character owner, BackpackType backpackType, KeyCode key, WheelTarget target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0050: 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)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((int)backpackType == 4)
			{
				return false;
			}
			if (IsWheelOpen)
			{
				return true;
			}
			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;
				}
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			instance.OpenBackpackWheel(BackpackReference.GetFromEquippedBackpack(owner), num, backpackType);
			if (!IsWheelOpen)
			{
				AbortWheel();
				return false;
			}
			s_target = target;
			s_heldKey = key;
			return true;
		}
	}
	internal static class Diagnostics
	{
		private const float ThrottleSeconds = 5f;

		private static ManualLogSource s_log = Logger.CreateLogSource("EasyBackpack");

		private static float s_lastWheelWarn = float.MinValue;

		private static float s_lastPatchWarn = float.MinValue;

		internal static void Init(ManualLogSource log)
		{
			s_log = log;
		}

		internal static void Reset()
		{
			s_lastWheelWarn = float.MinValue;
			s_lastPatchWarn = float.MinValue;
		}

		internal static void Info(string message)
		{
			s_log.LogInfo((object)message);
		}

		internal static void Error(string message)
		{
			s_log.LogError((object)message);
		}

		internal static void WheelOpenFailed(Exception e)
		{
			if (!(Time.unscaledTime - s_lastWheelWarn < 5f))
			{
				s_lastWheelWarn = Time.unscaledTime;
				s_log.LogWarning((object)$"Could not open the backpack wheel; nothing was opened and no input was taken over. {e}");
			}
		}

		internal static void PatchFailed(string where, Exception e)
		{
			if (!(Time.unscaledTime - s_lastPatchWarn < 5f))
			{
				s_lastPatchWarn = Time.unscaledTime;
				s_log.LogWarning((object)$"Unexpected error in {where}; the game continues with its own behaviour. {e}");
			}
		}
	}
	[BepInPlugin("nickklmao.easybackpack", "EasyBackpack", "1.1.9")]
	internal sealed class Entry : BaseUnityPlugin
	{
		internal const string PluginGuid = "nickklmao.easybackpack";

		internal const string PluginVersion = "1.1.9";

		private readonly Harmony m_harmony = new Harmony("nickklmao.easybackpack");

		private static Entry? s_current;

		private static bool s_quitting;

		private void Awake()
		{
			s_current = this;
			Diagnostics.Init(((BaseUnityPlugin)this).Logger);
			Diagnostics.Reset();
			Settings.Bind(((BaseUnityPlugin)this).Config);
			BackpackShortcut.Reset();
			FuelRollback.Reset();
			s_quitting = false;
			try
			{
				m_harmony.UnpatchSelf();
			}
			catch (Exception e)
			{
				Diagnostics.PatchFailed("clearing patches from a previous load", e);
			}
			PatchSet.Apply(m_harmony);
		}

		private void OnApplicationQuit()
		{
			s_quitting = true;
		}

		private void OnDestroy()
		{
			if (s_current != this)
			{
				return;
			}
			if (s_quitting)
			{
				BackpackShortcut.Release();
				FuelRollback.Reset();
				return;
			}
			BackpackShortcut.AbortIfHolding();
			FuelRollback.Reset();
			try
			{
				m_harmony.UnpatchSelf();
			}
			catch (Exception e)
			{
				Diagnostics.PatchFailed("removing patches on unload", e);
			}
		}

		private void Update()
		{
			if (s_current != this)
			{
				return;
			}
			try
			{
				BackpackShortcut.Tick();
			}
			catch (Exception e)
			{
				BackpackShortcut.AbortIfHolding();
				Diagnostics.PatchFailed("the per-frame update", e);
			}
		}
	}
	internal static class FuelRollback
	{
		private struct PendingRefuel
		{
			public float BaseFuel;

			public float ExpiresAt;
		}

		internal struct SyncState
		{
			public bool Captured;

			public float Fuel;

			public FloatItemData Entry;
		}

		internal const float FuelEpsilon = 0.01f;

		private const float CleanupSeconds = 30f;

		private const int MaxPending = 8;

		private static readonly List<PendingRefuel> s_pending = new List<PendingRefuel>(8);

		private static Player? s_player;

		private static BackpackSlot? s_slot;

		private static Guid s_dataGuid;

		private static bool HasPending => s_pending.Count > 0;

		internal static void Reset()
		{
			s_pending.Clear();
			s_player = null;
			s_slot = null;
			s_dataGuid = Guid.Empty;
		}

		internal static void ExpireStale()
		{
			if (!HasPending)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			for (int num = s_pending.Count - 1; num >= 0; num--)
			{
				if (s_pending[num].ExpiresAt <= unscaledTime)
				{
					s_pending.RemoveAt(num);
				}
			}
			if (!HasPending)
			{
				Reset();
			}
		}

		internal static void Arm(Player player, BackpackSlot slot, Guid dataGuid, float fuelBefore)
		{
			if (HasPending && ((Object)(object)player != (Object)(object)s_player || slot != s_slot || dataGuid != s_dataGuid))
			{
				s_pending.Clear();
			}
			s_player = player;
			s_slot = slot;
			s_dataGuid = dataGuid;
			if (s_pending.Count >= 8)
			{
				s_pending.RemoveAt(0);
			}
			s_pending.Add(new PendingRefuel
			{
				BaseFuel = fuelBefore,
				ExpiresAt = Time.unscaledTime + 30f
			});
		}

		internal static void BeginSync(Player player, bool forceSync, out SyncState state)
		{
			state = default(SyncState);
			if (!HasPending || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)s_player)
			{
				return;
			}
			if (forceSync)
			{
				Reset();
				return;
			}
			BackpackSlot backpackSlot = player.backpackSlot;
			if (backpackSlot == null || backpackSlot != s_slot || ((ItemSlot)backpackSlot).IsEmpty())
			{
				Reset();
				return;
			}
			ItemInstanceData data = ((ItemSlot)backpackSlot).data;
			if (data != null)
			{
				FloatItemData val = default(FloatItemData);
				if (data.guid != s_dataGuid)
				{
					Reset();
				}
				else if (data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val))
				{
					state.Captured = true;
					state.Entry = val;
					state.Fuel = val.Value;
				}
			}
		}

		internal static void EndSync(Player player, SyncState state)
		{
			if (!state.Captured || (Object)(object)player == (Object)null)
			{
				return;
			}
			BackpackSlot backpackSlot = player.backpackSlot;
			if (backpackSlot == null)
			{
				return;
			}
			if (backpackSlot != s_slot || ((ItemSlot)backpackSlot).IsEmpty() || ((ItemSlot)backpackSlot).data == null || ((ItemSlot)backpackSlot).data.guid != s_dataGuid)
			{
				Reset();
			}
			else
			{
				FloatItemData val = default(FloatItemData);
				if (!((ItemSlot)backpackSlot).data.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val) || val == state.Entry)
				{
					return;
				}
				float value = val.Value;
				bool flag = false;
				for (int i = 0; i < s_pending.Count; i++)
				{
					if (Mathf.Abs(value - s_pending[i].BaseFuel) <= 0.01f)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					val.Value = state.Fuel;
					FloatItemData val2 = default(FloatItemData);
					if (((ItemSlot)backpackSlot).data.TryGetDataEntry<FloatItemData>((DataEntryKey)11, ref val2))
					{
						val2.Value = Mathf.Clamp01(state.Fuel / 100f);
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class RefuelAmountPatch
	{
		private static float s_fuelBefore = float.NaN;

		private static Guid s_guidBefore = Guid.Empty;

		internal static MethodBase ResolveTarget()
		{
			return PatchSet.Require(typeof(CharacterBackpackHandler), "AddFuelToJetpack");
		}

		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			return ResolveTarget();
		}

		[HarmonyPrefix]
		private static void Prefix(CharacterBackpackHandler __instance, Character interactor, ref float addedFuel)
		{
			s_fuelBefore = float.NaN;
			s_guidBefore = 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;
				}
				addedFuel = GroundFuelAmount(interactor.data.currentItem);
				if (!PhotonNetwork.IsMasterClient)
				{
					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.TryGetDataEntry<FloatItemData>((DataEntryKey)10, ref val))
					{
						s_fuelBefore = val.Value;
						s_guidBefore = ((ItemSlot)player.backpackSlot).data.guid;
					}
				}
			}
			catch (Exception e)
			{
				s_fuelBefore = float.NaN;
				s_guidBefore = Guid.Empty;
				Diagnostics.PatchFailed("AddFuelToJetpack prefix", e);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(CharacterBackpackHandler __instance, Character interactor, Exception __exception)
		{
			float num = s_fuelBefore;
			Guid guid = s_guidBefore;
			s_fuelBefore = float.NaN;
			s_guidBefore = 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))
					{
						FuelRollback.Arm(player, player.backpackSlot, guid, num);
					}
				}
			}
			catch (Exception e)
			{
				FuelRollback.Reset();
				Diagnostics.PatchFailed("AddFuelToJetpack finalizer", e);
			}
		}

		private static float GroundFuelAmount(Item held)
		{
			int num = 25;
			if ((Object)(object)held != (Object)null)
			{
				RopeSpool val = default(RopeSpool);
				if (((Component)held).TryGetComponent<RopeSpool>(ref val))
				{
					num = Mathf.CeilToInt(val.RopeFuel);
				}
				else if (held.HasData((DataEntryKey)10))
				{
					num = held.overrideJetpackFuelAmount + Mathf.RoundToInt(held.GetData<FloatItemData>((DataEntryKey)10).Value * held.overrideJetpackFuelPerFuelMult);
				}
				else if (held is Backpack)
				{
					num = held.overrideJetpackFuelAmount;
				}
				else if (held.overrideJetpackFuel)
				{
					num = (held.HasData((DataEntryKey)2) ? (held.overrideJetpackFuelAmount + held.GetData<OptionableIntItemData>((DataEntryKey)2).Value * held.overrideJetpackFuelPerUse) : held.overrideJetpackFuelAmount);
				}
			}
			return num;
		}
	}
	[HarmonyPatch]
	internal static class RefuelRollbackPatch
	{
		internal static MethodBase ResolveTarget()
		{
			return PatchSet.Require(typeof(Player), "SyncInventoryRPC");
		}

		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			return ResolveTarget();
		}

		[HarmonyPrefix]
		private static void Prefix(Player __instance, bool forceSync, out FuelRollback.SyncState __state)
		{
			__state = default(FuelRollback.SyncState);
			try
			{
				FuelRollback.BeginSync(__instance, forceSync, out __state);
			}
			catch (Exception e)
			{
				__state = default(FuelRollback.SyncState);
				FuelRollback.Reset();
				Diagnostics.PatchFailed("SyncInventoryRPC prefix", e);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(Player __instance, FuelRollback.SyncState __state, Exception __exception)
		{
			try
			{
				FuelRollback.EndSync(__instance, __state);
			}
			catch (Exception e)
			{
				FuelRollback.Reset();
				Diagnostics.PatchFailed("SyncInventoryRPC finalizer", e);
			}
		}
	}
	internal static class PatchSet
	{
		internal static MethodBase Require(Type type, string name)
		{
			return AccessTools.DeclaredMethod(type, name, (Type[])null, (Type[])null) ?? throw new MissingMethodException(type.FullName + "." + name + " was not found in this game build");
		}

		internal static void Apply(Harmony harmony)
		{
			Apply(harmony, typeof(WheelUpdatePatch), "BackpackWheel.Update", WheelUpdatePatch.ResolveTarget);
			Apply(harmony, typeof(WheelClosedPatch), "GUIManager.CloseBackpackWheel", WheelClosedPatch.ResolveTarget);
			Apply(harmony, typeof(RefuelAmountPatch), "CharacterBackpackHandler.AddFuelToJetpack", RefuelAmountPatch.ResolveTarget);
			Apply(harmony, typeof(RefuelRollbackPatch), "Player.SyncInventoryRPC", RefuelRollbackPatch.ResolveTarget);
		}

		private static void Apply(Harmony harmony, Type patchClass, string target, Func<MethodBase> resolve)
		{
			MethodBase methodBase;
			try
			{
				methodBase = resolve();
			}
			catch (Exception ex)
			{
				Diagnostics.Error("Could not find " + target + " in this game build; that fix is inactive. " + ex.Message);
				return;
			}
			try
			{
				harmony.PatchAll(patchClass);
				Patches patchInfo = Harmony.GetPatchInfo(methodBase);
				if (patchInfo == null || !patchInfo.Owners.Contains(harmony.Id))
				{
					Diagnostics.Error("The patch for " + target + " was not attached; that fix is inactive.");
				}
				else
				{
					Diagnostics.Info("Patched " + target);
				}
			}
			catch (Exception arg)
			{
				Diagnostics.Error($"Could not patch {target}; that fix is inactive for this session. {arg}");
			}
		}
	}
	internal static class Settings
	{
		internal static ConfigEntry<KeyCode> BackpackKey;

		internal static ConfigEntry<KeyCode> AlternativeBackpackKey;

		internal static void Bind(ConfigFile config)
		{
			BackpackKey = config.Bind<KeyCode>("Keybinds", "Backpack Key", (KeyCode)98, "The key you want to use to access the backpack while it's on your back");
			AlternativeBackpackKey = config.Bind<KeyCode>("Keybinds", "Alternative Backpack Key", (KeyCode)0, "An optional alternative key for accessing the backpack while it's on your back");
		}
	}
	[HarmonyPatch]
	internal static class WheelUpdatePatch
	{
		private static bool s_forced;

		private static bool s_savedInteract;

		internal static MethodBase ResolveTarget()
		{
			return PatchSet.Require(typeof(BackpackWheel), "Update");
		}

		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			return ResolveTarget();
		}

		[HarmonyPrefix]
		private static void Prefix()
		{
			s_forced = false;
			try
			{
				if (BackpackShortcut.HoldsWheel)
				{
					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;
				Diagnostics.PatchFailed("BackpackWheel.Update prefix", e);
			}
		}

		[HarmonyFinalizer]
		private static void 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)
			{
				Diagnostics.PatchFailed("BackpackWheel.Update finalizer", e);
			}
		}
	}
	[HarmonyPatch]
	internal static class WheelClosedPatch
	{
		internal static MethodBase ResolveTarget()
		{
			return PatchSet.Require(typeof(GUIManager), "CloseBackpackWheel");
		}

		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			return ResolveTarget();
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			BackpackShortcut.Release();
		}
	}
}