Decompiled source of Item Slots Doubled v1.0.0

plugins/PeakItemSlotsDoubled.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.iJamesss.becomeGod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("com.github.iJamesss.becomeGod")]
[assembly: AssemblyTitle("BecomeGod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 Peak.ExpandAndDirectEquip
{
	[BepInPlugin("com.github.iJamesss.ItemSlotsDoubled", "PEAK: Item Slots Doubled", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		private static class Player_Awake_Patch
		{
			internal static MethodInfo? TargetMethod()
			{
				return FindType("Player")?.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}

			private static void Prefix(object __instance)
			{
				EnsureSlots(__instance);
			}
		}

		[HarmonyPatch]
		private static class Player_OnEnable_Patch
		{
			internal static MethodInfo? TargetMethod()
			{
				return FindType("Player")?.GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}

			private static void Prefix(object __instance)
			{
				EnsureSlots(__instance);
			}
		}

		[HarmonyPatch]
		private static class Player_AddItem_Prefix
		{
			internal static MethodInfo? TargetMethod()
			{
				return Player_AddItem_Postfix.TargetMethod();
			}

			private static void Prefix()
			{
				_suspendEnforceFrames = Math.Max(_suspendEnforceFrames, 4);
			}
		}

		[HarmonyPatch]
		private static class Player_AddItem_Postfix
		{
			internal static MethodInfo? TargetMethod()
			{
				Type type = FindType("Player");
				if (type == null)
				{
					return null;
				}
				return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
				{
					if (m.Name != "AddItem" || m.ReturnType != typeof(bool))
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					return parameters.Length == 3 && parameters[0].ParameterType == typeof(ushort) && parameters[1].ParameterType.Name == "ItemInstanceData" && parameters[2].IsOut;
				});
			}

			private static void Postfix(object __instance, bool __result, ref object? __2, ushort itemID)
			{
				if (!__result || __2 == null)
				{
					return;
				}
				try
				{
					object itemPrefabFromID = GetItemPrefabFromID(itemID);
					if (itemPrefabFromID != null && IsBackpack(itemPrefabFromID))
					{
						return;
					}
					object obj = __2;
					Type type = obj.GetType();
					if (type.Name == "BackpackSlot")
					{
						return;
					}
					FieldInfo field = type.GetField("itemSlotID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field2 = type.GetField("prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field3 = type.GetField("data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					MethodInfo method = type.GetMethod("EmptyOut", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					int num = (byte)(field?.GetValue(obj) ?? ((object)byte.MaxValue));
					object obj2 = field2?.GetValue(obj);
					if (num != 3 || IsBackpack(obj2))
					{
						return;
					}
					var (obj3, num2) = NextFreeNonReserved(__instance);
					if (obj3 == null || num2 < 0)
					{
						try
						{
							Type type2 = __instance.GetType();
							object obj4 = type2.GetField("tempFullSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance);
							if (obj4 != null)
							{
								MethodInfo method2 = obj4.GetType().GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
								object obj5 = field3?.GetValue(obj);
								if (method2 != null)
								{
									method2.Invoke(obj4, new object[2] { obj2, obj5 });
									try
									{
										method?.Invoke(obj, null);
									}
									catch
									{
									}
									__2 = obj4;
									ManualLogSource? log = Log;
									if (log != null)
									{
										log.LogInfo((object)"[ ] Moved non-backpack from index 3 to tempFullSlot (250) due to full bar.");
									}
								}
							}
							return;
						}
						catch (Exception ex)
						{
							ManualLogSource? log2 = Log;
							if (log2 != null)
							{
								log2.LogWarning((object)("[ ] Failed moving from 3 to tempFullSlot: " + ex.Message));
							}
							return;
						}
					}
					MethodInfo method3 = obj3.GetType().GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					object obj7 = field3?.GetValue(obj);
					if (method3 != null)
					{
						method3.Invoke(obj3, new object[2] { obj2, obj7 });
						try
						{
							method?.Invoke(obj, null);
						}
						catch
						{
						}
						__2 = obj3;
						ManualLogSource? log3 = Log;
						if (log3 != null)
						{
							log3.LogInfo((object)$"[ ] Moved non-backpack from index 3 to {num2}.");
						}
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource? log4 = Log;
					if (log4 != null)
					{
						log4.LogWarning((object)("[ ] AddItem post-move failed: " + ex2.Message));
					}
				}
			}
		}

		[HarmonyPatch]
		private static class Player_SyncInventoryRPC_Postfix
		{
			internal static MethodInfo? TargetMethod()
			{
				Type type = FindType("Player");
				if (type == null)
				{
					return null;
				}
				return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
				{
					if (m.Name != "SyncInventoryRPC")
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					return parameters.Length == 2 && parameters[0].ParameterType == typeof(byte[]) && parameters[1].ParameterType == typeof(bool);
				});
			}

			private static void Postfix(object __instance)
			{
				try
				{
					_suspendEnforceFrames = Math.Max(_suspendEnforceFrames, 3);
					_enforcePendingPlayer = __instance;
					_enforcePendingFrames = 1;
				}
				catch
				{
				}
			}
		}

		private sealed class RefEq : IEqualityComparer<object>
		{
			public static readonly RefEq Instance = new RefEq();

			public new bool Equals(object x, object y)
			{
				return x == y;
			}

			public int GetHashCode(object obj)
			{
				return RuntimeHelpers.GetHashCode(obj);
			}
		}

		public sealed class InputPoller : MonoBehaviour
		{
			private object? _player;

			private object? _owner;

			private MethodInfo? _equip;

			private Type? _optByte;

			private MethodInfo? _optSome;

			private ConstructorInfo? _optCtor;

			private float _nextScan;

			private float _fastUntil;

			private void OnEnable()
			{
				SceneManager.sceneLoaded += OnSceneLoaded;
				Prime();
			}

			private void OnDisable()
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
			}

			private void OnSceneLoaded(Scene s, LoadSceneMode m)
			{
				Prime();
			}

			private void Prime()
			{
				_player = null;
				_owner = null;
				_equip = null;
				_optByte = null;
				_optSome = null;
				_optCtor = null;
				_nextScan = 0f;
				_fastUntil = Time.unscaledTime + 10f;
			}

			private void Update()
			{
				if (_suspendEnforceFrames > 0)
				{
					_suspendEnforceFrames--;
				}
				if (_enforcePendingFrames > 0)
				{
					_enforcePendingFrames--;
					if (_enforcePendingFrames == 0 && _enforcePendingPlayer != null)
					{
						TryEnforce(_enforcePendingPlayer);
						_enforcePendingPlayer = null;
					}
				}
				float num = ((Time.unscaledTime < _fastUntil) ? 0.25f : 2f);
				if (Time.unscaledTime >= _nextScan)
				{
					_nextScan = Time.unscaledTime + num;
					if (_player == null)
					{
						_player = FindLocalPlayerInstance();
					}
					if (_player != null && _equip == null)
					{
						WireEquip();
					}
				}
				if (_player == null || _owner == null || _equip == null)
				{
					return;
				}
				for (int i = 1; i <= 9; i++)
				{
					if (WasPressed(i))
					{
						byte index = (byte)(i - 1);
						TryEquip(index);
						break;
					}
				}
				if (ENABLE_NUMPAD4 && Input.GetKeyDown((KeyCode)260))
				{
					TryEquip(3);
				}
			}

			private static object? FindLocalPlayerInstance()
			{
				Type type = FindType("Player");
				MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
				foreach (MonoBehaviour val in array)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Type type2 = ((object)val).GetType();
					if (!(type2 == type) && (!(type != null) || !type2.IsSubclassOf(type)))
					{
						continue;
					}
					try
					{
						Component component = ((Component)val).GetComponent("PhotonView");
						if ((Object)(object)component != (Object)null && (bool?)((object)component).GetType().GetProperty("IsMine")?.GetValue(component) == true)
						{
							return val;
						}
					}
					catch
					{
					}
					if (((Behaviour)val).isActiveAndEnabled)
					{
						return val;
					}
				}
				return null;
			}

			private bool WasPressed(int oneBased)
			{
				if (USE_INPUT_ACTIONS)
				{
					try
					{
						InputActionAsset actions = InputSystem.actions;
						InputAction val = ((actions != null) ? actions.FindAction($"Hotbar{oneBased}", false) : null);
						if (val != null && val.enabled && val.WasPressedThisFrame())
						{
							return true;
						}
					}
					catch
					{
					}
				}
				return Input.GetKeyDown((KeyCode)(48 + oneBased));
			}

			private void WireEquip()
			{
				_owner = ResolveOwnerFromPath(_player, "", "CharacterItems");
				if (_owner == null)
				{
					_owner = FindOwnerDeep(_player, "CharacterItems");
				}
				if (_owner == null)
				{
					if (FORCE_EXACT_OWNER)
					{
						ManualLogSource? log = Log;
						if (log != null)
						{
							log.LogWarning((object)"[] Owner 'CharacterItems' not found; number keys disabled.");
						}
						return;
					}
					_owner = _player;
				}
				(_optByte, _optSome, _optCtor) = ResolveOptionableByte();
				if (_optByte == null)
				{
					ManualLogSource? log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[] Could not resolve Optionable<byte>. Number keys disabled.");
					}
					return;
				}
				Type type = _owner.GetType();
				_equip = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
				{
					if (m.Name != "EquipSlot")
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					return parameters.Length == 1 && parameters[0].ParameterType == _optByte;
				});
				if (_equip == null)
				{
					ManualLogSource? log3 = Log;
					if (log3 != null)
					{
						log3.LogWarning((object)("[] Method not found on owner '" + type.Name + "': EquipSlot(" + (_optByte?.Name ?? "?") + ")."));
					}
				}
			}

			private object? MakeOptionableByte(byte index)
			{
				try
				{
					if (_optByte == null)
					{
						return null;
					}
					if (_optSome != null)
					{
						return _optSome.Invoke(null, new object[1] { index });
					}
					if (_optCtor != null)
					{
						ParameterInfo[] parameters = _optCtor.GetParameters();
						if (parameters.Length == 2)
						{
							return _optCtor.Invoke(new object[2] { index, true });
						}
						if (parameters.Length == 1)
						{
							return _optCtor.Invoke(new object[1] { index });
						}
					}
				}
				catch
				{
				}
				return null;
			}

			private void TryEquip(byte index)
			{
				if (_equip == null || _owner == null)
				{
					return;
				}
				object obj = MakeOptionableByte(index);
				if (obj == null)
				{
					return;
				}
				try
				{
					_equip.Invoke(_owner, new object[1] { obj });
				}
				catch (Exception ex)
				{
					ManualLogSource? log = Log;
					if (log != null)
					{
						log.LogWarning((object)$"[ ] Equip failed idx {index}: {ex.Message}");
					}
				}
			}
		}

		internal static ManualLogSource? Log;

		private Harmony? _h;

		private const int TARGET_SLOTS = 7;

		private static readonly bool USE_INPUT_ACTIONS = true;

		private static readonly bool ENABLE_NUMPAD4 = true;

		private const string OWNER_TYPE_NAME = "CharacterItems";

		private const string EQUIP_METHOD_NAME = "EquipSlot";

		private static readonly bool FORCE_EXACT_OWNER = true;

		private static readonly bool PARTIAL_TYPE_MATCH = true;

		private const string OWNER_MEMBER_PATH = "";

		private static bool _enforcing;

		private static int _suspendEnforceFrames;

		private static object? _enforcePendingPlayer;

		private static int _enforcePendingFrames;

		internal static Assembly? GameAsm => AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Assembly-CSharp");

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_h = new Harmony("com.yourname.peak.expand_and_directequip");
			_h.PatchAll();
			GameObject val = new GameObject("PEAK_ExpandAndDirectEquip_Input");
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<InputPoller>();
			Log.LogInfo((object)$"[ ] Loaded. TargetSlots={7}, UseActions={USE_INPUT_ACTIONS}, Keypad4={ENABLE_NUMPAD4}");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony? h = _h;
				if (h != null)
				{
					h.UnpatchSelf();
				}
			}
			catch
			{
			}
		}

		internal static Type? FindType(string name)
		{
			string name2 = name;
			return GameAsm?.GetTypes().FirstOrDefault((Type t) => t?.Name == name2);
		}

		private static bool TypeMatches(Type t, string nameHint)
		{
			if (string.IsNullOrWhiteSpace(nameHint))
			{
				return false;
			}
			if (string.Equals(t.Name, nameHint, StringComparison.Ordinal))
			{
				return true;
			}
			if (PARTIAL_TYPE_MATCH)
			{
				string text = t.FullName ?? t.Name;
				if (text.EndsWith("." + nameHint, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		private static object? GetMemberValue(object obj, string memberName)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
			if (property != null && property.GetIndexParameters().Length == 0)
			{
				try
				{
					return property.GetValue(obj);
				}
				catch
				{
				}
			}
			FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
			if (field != null)
			{
				try
				{
					return field.GetValue(obj);
				}
				catch
				{
				}
			}
			return null;
		}

		private static object? ResolveOwnerFromPath(object player, string path, string ownerTypeName)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return null;
			}
			object obj = player;
			string[] array = path.Split(new char[1] { '.' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string memberName in array)
			{
				object memberValue = GetMemberValue(obj, memberName);
				if (memberValue == null)
				{
					return null;
				}
				obj = memberValue;
			}
			return TypeMatches(obj.GetType(), ownerTypeName) ? obj : null;
		}

		private static bool IsBackpack(object? prefab)
		{
			if (prefab == null)
			{
				return false;
			}
			try
			{
				Type type = prefab.GetType();
				if (type.Name.IndexOf("Backpack", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				Type type2 = FindType("Backpack");
				if (type2 != null && (type == type2 || type.IsSubclassOf(type2)))
				{
					return true;
				}
				object? obj = type.GetProperty("gameObject")?.GetValue(prefab);
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent("Backpack") != (Object)null)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static object? GetItemPrefabFromID(ushort itemID)
		{
			try
			{
				Type type = FindType("ItemDatabase");
				if (type == null)
				{
					return null;
				}
				MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo mi)
				{
					if (mi.Name != "TryGetItem")
					{
						return false;
					}
					ParameterInfo[] parameters = mi.GetParameters();
					return parameters.Length == 2 && parameters[0].ParameterType == typeof(ushort) && parameters[1].IsOut;
				});
				if (methodInfo == null)
				{
					return null;
				}
				object[] array = new object[2] { itemID, null };
				return ((bool)methodInfo.Invoke(null, array)) ? array[1] : null;
			}
			catch
			{
			}
			return null;
		}

		private static void EnsureSlots(object player)
		{
			try
			{
				int num = Mathf.Clamp(7, 4, 16);
				Type type = player.GetType();
				FieldInfo field = type.GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				Type type2 = FindType("ItemSlot");
				if (field == null || type2 == null)
				{
					return;
				}
				Array array = field.GetValue(player) as Array;
				if (array != null && array.Length >= num && array.GetType().GetElementType() == type2)
				{
					return;
				}
				int num2 = array?.Length ?? 0;
				Array array2 = Array.CreateInstance(type2, num);
				if (array != null)
				{
					Array.Copy(array, array2, Math.Min(num2, num));
				}
				ConstructorInfo constructor = type2.GetConstructor(new Type[1] { typeof(byte) });
				for (int i = 0; i < num; i++)
				{
					if (array2.GetValue(i) == null)
					{
						object value = ((constructor != null) ? constructor.Invoke(new object[1] { (byte)i }) : Activator.CreateInstance(type2));
						array2.SetValue(value, i);
					}
				}
				field.SetValue(player, array2);
				ManualLogSource? log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"[ ] itemSlots resized {num2} -> {num}");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource? log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[ ] EnsureSlots failed: " + ex.Message));
				}
			}
		}

		private static bool SlotIsEmpty(object slot)
		{
			if (slot == null)
			{
				return false;
			}
			try
			{
				MethodInfo method = slot.GetType().GetMethod("IsEmpty", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					return (bool)method.Invoke(slot, null);
				}
				FieldInfo field = slot.GetType().GetField("prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				return field == null || field.GetValue(slot) == null;
			}
			catch
			{
				return false;
			}
		}

		private static (object? freeSlot, int idx) NextFreeNonReserved(object player)
		{
			Type type = player.GetType();
			if (type.GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Array array)
			{
				for (int i = 0; i < array.Length; i++)
				{
					if (i != 3)
					{
						object value = array.GetValue(i);
						if (value != null && SlotIsEmpty(value))
						{
							return (value, i);
						}
					}
				}
			}
			return (null, -1);
		}

		private static void TryEnforce(object player)
		{
			if (_suspendEnforceFrames <= 0)
			{
				EnforceBackpackReservation(player);
			}
		}

		private static void EnforceBackpackReservation(object player)
		{
			if (_enforcing)
			{
				return;
			}
			_enforcing = true;
			try
			{
				Type type = player.GetType();
				if (!(type.GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Array array) || array.Length < 4)
				{
					return;
				}
				object value = array.GetValue(3);
				if (value == null)
				{
					return;
				}
				Type type2 = value.GetType();
				if (type2.Name == "BackpackSlot")
				{
					return;
				}
				FieldInfo field = type2.GetField("prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field2 = type2.GetField("data", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo method = type2.GetMethod("EmptyOut", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null || field2 == null)
				{
					return;
				}
				object value2 = field.GetValue(value);
				if (value2 == null || IsBackpack(value2))
				{
					return;
				}
				var (obj, num) = NextFreeNonReserved(player);
				if (obj == null)
				{
					try
					{
						Type type3 = player.GetType();
						object obj2 = type3.GetField("tempFullSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player);
						if (obj2 != null)
						{
							MethodInfo method2 = obj2.GetType().GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							object value3 = field2.GetValue(value);
							if (method2 != null)
							{
								method2.Invoke(obj2, new object[2] { value2, value3 });
								try
								{
									method?.Invoke(value, null);
								}
								catch
								{
								}
								ManualLogSource? log = Log;
								if (log != null)
								{
									log.LogInfo((object)"[ ] Enforced reservation: moved non-backpack from index 3 to tempFullSlot (250).");
								}
							}
						}
						return;
					}
					catch (Exception ex)
					{
						ManualLogSource? log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)("[ ] tempFullSlot move failed: " + ex.Message));
						}
						return;
					}
				}
				MethodInfo method3 = obj.GetType().GetMethod("SetItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method3 != null)
				{
					object value4 = field2.GetValue(value);
					method3.Invoke(obj, new object[2] { value2, value4 });
					try
					{
						method?.Invoke(value, null);
					}
					catch
					{
					}
					ManualLogSource? log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)$"[ ] Enforced reservation: moved non-backpack from index 3 to {num}.");
					}
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource? log4 = Log;
				if (log4 != null)
				{
					log4.LogWarning((object)("[ ] EnforceBackpackReservation failed: " + ex2.Message));
				}
			}
			finally
			{
				_enforcing = false;
			}
		}

		private static object? FindOwnerDeep(object player, string ownerTypeName, int maxDepth = 3)
		{
			if (TypeMatches(player.GetType(), ownerTypeName))
			{
				return player;
			}
			HashSet<object> visited = new HashSet<object>(RefEq.Instance);
			Queue<(object obj, int depth)> q = new Queue<(object, int)>();
			Enq(player, 0);
			try
			{
				object? obj = player.GetType().GetProperty("gameObject")?.GetValue(player);
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
					foreach (MonoBehaviour o2 in components)
					{
						Enq(o2, 0);
					}
					MonoBehaviour[] componentsInParent = val.GetComponentsInParent<MonoBehaviour>(true);
					foreach (MonoBehaviour o3 in componentsInParent)
					{
						Enq(o3, 0);
					}
					MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
					foreach (MonoBehaviour o4 in componentsInChildren)
					{
						Enq(o4, 0);
					}
				}
			}
			catch
			{
			}
			while (q.Count > 0)
			{
				var (obj3, num) = q.Dequeue();
				if (TypeMatches(obj3.GetType(), ownerTypeName))
				{
					return obj3;
				}
				if (num >= maxDepth)
				{
					continue;
				}
				FieldInfo[] array;
				try
				{
					array = obj3.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
				}
				catch
				{
					array = Array.Empty<FieldInfo>();
				}
				FieldInfo[] array2 = array;
				foreach (FieldInfo fieldInfo in array2)
				{
					object value;
					try
					{
						value = fieldInfo.GetValue(obj3);
					}
					catch
					{
						continue;
					}
					if (value != null)
					{
						Type type = value.GetType();
						if (!type.IsPrimitive && type != typeof(string))
						{
							Enq(value, num + 1);
						}
					}
				}
				PropertyInfo[] array3;
				try
				{
					array3 = obj3.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
				}
				catch
				{
					array3 = Array.Empty<PropertyInfo>();
				}
				PropertyInfo[] array4 = array3;
				foreach (PropertyInfo propertyInfo in array4)
				{
					if (propertyInfo.GetIndexParameters().Length != 0)
					{
						continue;
					}
					object value2;
					try
					{
						value2 = propertyInfo.GetValue(obj3);
					}
					catch
					{
						continue;
					}
					if (value2 != null)
					{
						Type type2 = value2.GetType();
						if (!type2.IsPrimitive && type2 != typeof(string))
						{
							Enq(value2, num + 1);
						}
					}
				}
				try
				{
					object? obj8 = obj3.GetType().GetProperty("gameObject")?.GetValue(obj3);
					GameObject val2 = (GameObject)((obj8 is GameObject) ? obj8 : null);
					if ((Object)(object)val2 != (Object)null)
					{
						MonoBehaviour[] components2 = val2.GetComponents<MonoBehaviour>();
						foreach (MonoBehaviour o5 in components2)
						{
							Enq(o5, num + 1);
						}
					}
				}
				catch
				{
				}
			}
			return null;
			void Enq(object? o, int d)
			{
				if (o != null && !visited.Contains(o))
				{
					visited.Add(o);
					q.Enqueue((o, d));
				}
			}
		}

		private static (Type? optType, MethodInfo? some, ConstructorInfo? ctor) ResolveOptionableByte()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (!type.IsGenericTypeDefinition || !type.Name.StartsWith("Optionable`"))
					{
						continue;
					}
					try
					{
						Type closed = type.MakeGenericType(typeof(byte));
						MethodInfo item = closed.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Some" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(byte) && m.ReturnType == closed);
						ConstructorInfo item2 = closed.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(ConstructorInfo ci)
						{
							ParameterInfo[] parameters = ci.GetParameters();
							return (parameters.Length == 2 && parameters[0].ParameterType == typeof(byte) && parameters[1].ParameterType == typeof(bool)) || (parameters.Length == 1 && parameters[0].ParameterType == typeof(byte));
						});
						return (closed, item, item2);
					}
					catch
					{
					}
				}
			}
			return (null, null, null);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}