Decompiled source of InventoryExpansion v1.1.0

InventoryExpansion.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using InventoryExpansion;
using InventoryExpansion.Config;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Mimic.Actors;
using ReluProtocol;
using ReluProtocol.Enum;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "InventoryExpansion", "1.1.0", "DooDesch", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("InventoryExpansion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+8a961a15c0078692f8e3a84d4442b4ba77ac6e3d")]
[assembly: AssemblyProduct("InventoryExpansion")]
[assembly: AssemblyTitle("InventoryExpansion")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace InventoryExpansion
{
	public sealed class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			InventoryExpansionPreferences.Initialize();
			((MelonBase)this).HarmonyInstance.PatchAll();
			MelonLogger.Msg("InventoryExpansion initialized. Enabled={0}", new object[1] { InventoryExpansionPreferences.Enabled });
		}
	}
}
namespace InventoryExpansion.Patches
{
	[HarmonyPatch(typeof(Hub))]
	internal static class GameConfigPatches
	{
		private static bool _slotsAlreadyExpanded;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Hub_Awake_Postfix(Hub __instance)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled || _slotsAlreadyExpanded)
				{
					return;
				}
				object obj = typeof(Hub).GetField("gameConfig", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
				if (obj == null)
				{
					MelonLogger.Warning("InventoryExpansion: gameConfig is null, cannot adjust inventory slot count.");
					return;
				}
				object obj2 = obj.GetType().GetField("playerActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
				if (obj2 == null)
				{
					MelonLogger.Warning("InventoryExpansion: gameConfig.playerActor is null, cannot adjust inventory slot count.");
					return;
				}
				FieldInfo field = obj2.GetType().GetField("maxGenericInventorySlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					MelonLogger.Warning("InventoryExpansion: PlayerActor.maxGenericInventorySlot field not found.");
					return;
				}
				int num = (int)(field.GetValue(obj2) ?? ((object)4));
				int additionalSlots = InventoryExpansionPreferences.AdditionalSlots;
				if (additionalSlots <= 0)
				{
					MelonLogger.Msg($"InventoryExpansion: keeping base inventory slots = {num}.");
					return;
				}
				int num2 = num + additionalSlots;
				field.SetValue(obj2, num2);
				_slotsAlreadyExpanded = true;
				MelonLogger.Msg($"InventoryExpansion: expanded inventory slots from {num} to {num2}.");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"InventoryExpansion: failed to adjust inventory slot size: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(InventoryController))]
	internal static class InventoryControllerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Initialize")]
		private static void Initialize_Postfix(InventoryController __instance)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					return;
				}
				Hub s = Hub.s;
				object obj = typeof(Hub).GetField("gameConfig", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(s);
				if (obj == null)
				{
					return;
				}
				object obj2 = obj.GetType().GetField("playerActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
				if (obj2 == null)
				{
					return;
				}
				FieldInfo field = obj2.GetType().GetField("maxGenericInventorySlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					return;
				}
				int num = (int)(field.GetValue(obj2) ?? ((object)4));
				if (num <= 4)
				{
					return;
				}
				FieldInfo field2 = typeof(InventoryController).GetField("_inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field2 == null)
				{
					MelonLogger.Warning("InventoryExpansion: failed to find InventoryController._inventorySlots field.");
					return;
				}
				if (!(field2.GetValue(__instance) is IDictionary dictionary))
				{
					MelonLogger.Warning("InventoryExpansion: InventoryController._inventorySlots is not an IDictionary.");
					return;
				}
				for (int i = 5; i <= num; i++)
				{
					if (!dictionary.Contains(i))
					{
						dictionary[i] = null;
					}
				}
				MelonLogger.Msg($"InventoryExpansion: InventoryController extended to {num} slots.");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"InventoryExpansion: failed to extend InventoryController slots: {arg}");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("InvenFull")]
		private static bool InvenFull_Prefix(InventoryController __instance, ref bool __result)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					return true;
				}
				Hub s = Hub.s;
				if ((Object)(object)s == (Object)null)
				{
					return true;
				}
				object obj = typeof(Hub).GetField("gameConfig", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(s);
				object obj2 = (obj?.GetType().GetField("playerActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(obj);
				int num = (int)((obj2?.GetType().GetField("maxGenericInventorySlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(obj2) ?? ((object)4));
				if (!(typeof(InventoryController).GetField("_inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) is IDictionary dictionary))
				{
					return true;
				}
				int num2 = 0;
				foreach (DictionaryEntry item in dictionary)
				{
					if (item.Value != null)
					{
						num2++;
					}
				}
				__result = num2 >= num;
				return false;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"InventoryExpansion: InvenFull prefix failed, falling back to original. {arg}");
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(UIPrefab_Inventory))]
	internal static class InventoryUiPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(UIPrefab_Inventory __instance)
		{
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_069b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					return;
				}
				int val = 4;
				try
				{
					Hub s = Hub.s;
					if ((Object)(object)s != (Object)null)
					{
						object obj = typeof(Hub).GetField("gameConfig", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(s);
						object obj2 = (obj?.GetType().GetField("playerActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(obj);
						FieldInfo fieldInfo = obj2?.GetType().GetField("maxGenericInventorySlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (fieldInfo != null)
						{
							val = (int)(fieldInfo.GetValue(obj2) ?? ((object)4));
						}
					}
				}
				catch
				{
					val = 4;
				}
				int num = Math.Min(val, 4 + InventoryExpansionPreferences.AdditionalSlots);
				FieldInfo field = typeof(UIPrefab_Inventory).GetField("inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field == null || !(field.GetValue(__instance) is IList list))
				{
					return;
				}
				int count = list.Count;
				if (count == 0 || count >= num)
				{
					return;
				}
				Type type = list[0].GetType();
				FieldInfo field2 = type.GetField("frame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field3 = type.GetField("image", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field4 = type.GetField("stackCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field5 = type.GetField("waitEvent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 == null || field3 == null || field4 == null || field5 == null)
				{
					return;
				}
				object? value = field2.GetValue(list[0]);
				Image val2 = (Image)((value is Image) ? value : null);
				object? value2 = field3.GetValue(list[0]);
				Image val3 = (Image)((value2 is Image) ? value2 : null);
				object? value3 = field4.GetValue(list[0]);
				TMP_Text val4 = (TMP_Text)((value3 is TMP_Text) ? value3 : null);
				object? value4 = field5.GetValue(list[0]);
				Transform val5 = (Transform)((value4 is Transform) ? value4 : null);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null)
				{
					return;
				}
				RectTransform rectTransform = ((Graphic)val2).rectTransform;
				_ = ((Graphic)val3).rectTransform;
				_ = val4.rectTransform;
				float num2 = 0f;
				if (count > 1)
				{
					object? value5 = field2.GetValue(list[1]);
					Image val6 = (Image)((value5 is Image) ? value5 : null);
					if ((Object)(object)val6 != (Object)null)
					{
						num2 = ((Graphic)val6).rectTransform.anchoredPosition.x - rectTransform.anchoredPosition.x;
					}
				}
				if (Mathf.Approximately(num2, 0f))
				{
					num2 = rectTransform.sizeDelta.x + 10f;
				}
				float num3 = rectTransform.sizeDelta.y + 10f;
				Transform parent = ((Transform)rectTransform).parent;
				RectTransform val7 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				for (int i = count; i < num; i++)
				{
					int index = count - 1;
					object obj4 = list[index];
					object? value6 = field2.GetValue(obj4);
					Image val8 = (Image)((value6 is Image) ? value6 : null);
					object? value7 = field3.GetValue(obj4);
					Image val9 = (Image)((value7 is Image) ? value7 : null);
					object? value8 = field4.GetValue(obj4);
					TMP_Text val10 = (TMP_Text)((value8 is TMP_Text) ? value8 : null);
					object? value9 = field5.GetValue(obj4);
					Transform val11 = (Transform)((value9 is Transform) ? value9 : null);
					if ((Object)(object)val8 == (Object)null || (Object)(object)val9 == (Object)null || (Object)(object)val10 == (Object)null || (Object)(object)val11 == (Object)null)
					{
						continue;
					}
					int num4 = i - count;
					int num5 = num4 / 8;
					int num6 = num4 % 8;
					GameObject val12 = new GameObject(((Object)((Component)val8).gameObject).name + "_Extra" + i);
					val12.transform.SetParent((Transform)(object)val7, false);
					Image val13 = val12.AddComponent<Image>();
					val13.sprite = val8.sprite;
					val13.type = val8.type;
					((Graphic)val13).material = ((Graphic)val8).material;
					((Graphic)val13).color = ((Graphic)val8).color;
					RectTransform rectTransform2 = ((Graphic)val13).rectTransform;
					rectTransform2.anchorMin = rectTransform.anchorMin;
					rectTransform2.anchorMax = rectTransform.anchorMax;
					rectTransform2.pivot = rectTransform.pivot;
					rectTransform2.sizeDelta = rectTransform.sizeDelta;
					object? value10 = field2.GetValue(list[count - 1]);
					object? obj5 = ((value10 is Image) ? value10 : null);
					float num7 = (((obj5 != null) ? ((Graphic)obj5).rectTransform : null) ?? rectTransform).anchoredPosition.x + num2;
					float y = rectTransform.anchoredPosition.y;
					float num8 = num7 - (float)num6 * num2;
					float num9 = y + (float)num5 * num3;
					rectTransform2.anchoredPosition = new Vector2(num8, num9);
					GameObject val14 = new GameObject(((Object)((Component)val9).gameObject).name + "_Extra" + i);
					val14.transform.SetParent(val12.transform, false);
					Image val15 = val14.AddComponent<Image>();
					val15.sprite = val9.sprite;
					val15.type = val9.type;
					((Graphic)val15).color = ((Graphic)val9).color;
					((Graphic)val15).material = ((Graphic)val9).material;
					RectTransform rectTransform3 = ((Graphic)val15).rectTransform;
					RectTransform rectTransform4 = ((Graphic)val9).rectTransform;
					rectTransform3.anchorMin = rectTransform4.anchorMin;
					rectTransform3.anchorMax = rectTransform4.anchorMax;
					rectTransform3.pivot = rectTransform4.pivot;
					rectTransform3.sizeDelta = rectTransform4.sizeDelta;
					rectTransform3.anchoredPosition = rectTransform4.anchoredPosition;
					GameObject val16 = new GameObject(((Object)((Component)val10).gameObject).name + "_Extra" + i);
					val16.transform.SetParent(val12.transform, false);
					Component obj6 = val16.AddComponent(((object)val10).GetType());
					TMP_Text val17 = (TMP_Text)(object)((obj6 is TMP_Text) ? obj6 : null);
					if ((Object)(object)val17 == (Object)null)
					{
						MelonLogger.Error("[InventoryExpansion][UI] Failed to create TMP_Text for extra slot " + i + "; skipping this slot.");
						Object.Destroy((Object)(object)val12);
						continue;
					}
					val17.text = string.Empty;
					val17.font = val10.font;
					val17.fontSize = val10.fontSize;
					val17.alignment = val10.alignment;
					((Graphic)val17).color = ((Graphic)val10).color;
					RectTransform rectTransform5 = val10.rectTransform;
					RectTransform rectTransform6 = val17.rectTransform;
					rectTransform6.anchorMin = rectTransform5.anchorMin;
					rectTransform6.anchorMax = rectTransform5.anchorMax;
					rectTransform6.pivot = rectTransform5.pivot;
					rectTransform6.sizeDelta = rectTransform5.sizeDelta;
					rectTransform6.anchoredPosition = rectTransform5.anchoredPosition;
					GameObject val18 = new GameObject(((Object)((Component)val11).gameObject).name + "_Extra" + i);
					val18.transform.SetParent(val12.transform, false);
					RectTransform val19 = val18.AddComponent<RectTransform>();
					RectTransform val20 = (RectTransform)(object)((val11 is RectTransform) ? val11 : null);
					if ((Object)(object)val20 != (Object)null)
					{
						val19.anchorMin = val20.anchorMin;
						val19.anchorMax = val20.anchorMax;
						val19.pivot = val20.pivot;
						val19.sizeDelta = val20.sizeDelta;
						val19.anchoredPosition = val20.anchoredPosition;
					}
					object obj7 = Activator.CreateInstance(type);
					field2.SetValue(obj7, val13);
					field3.SetValue(obj7, val15);
					field4.SetValue(obj7, val17);
					field5.SetValue(obj7, ((Component)val19).transform);
					list.Add(obj7);
				}
				MelonLogger.Msg("[InventoryExpansion][UI] Extended inventorySlots from " + count + " to " + list.Count + " visual slots.");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[InventoryExpansion][UI] Awake postfix failed while extending slots: " + ex);
			}
		}
	}
	[HarmonyPatch]
	internal static class InventoryDebugControllerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(InventoryController), "Initialize")]
		private static void InventoryController_Initialize_Postfix(InventoryController __instance)
		{
			try
			{
				if (typeof(InventoryController).GetField("_inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) is IDictionary dictionary)
				{
					string text = string.Join(",", dictionary.Keys.Cast<object>());
					MelonLogger.Msg("[InventoryExpansion][Debug] InventoryController.Initialize: slot dict count = " + dictionary.Count + ", keys = [" + text + "]");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][Debug] InventoryController.Initialize debug failed: {arg}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InventoryController), "GetInventoryInfos")]
		private static void InventoryController_GetInventoryInfos_Postfix(Dictionary<int, ItemInfo> __result)
		{
			try
			{
				if (__result == null)
				{
					MelonLogger.Msg("[InventoryExpansion][Debug] GetInventoryInfos: result is null.");
					return;
				}
				int count = __result.Count;
				int num = ((__result.Count > 0) ? __result.Keys.Max() : 0);
				MelonLogger.Msg($"[InventoryExpansion][Debug] GetInventoryInfos: {count} entries, max key = {num}.");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][Debug] GetInventoryInfos debug failed: {arg}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InventoryController), "HandleAddItem")]
		private static void InventoryController_HandleAddItem_Postfix(InventoryController __instance, MsgErrorCode __result, int addedSlotIndex)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				IDictionary dictionary = typeof(InventoryController).GetField("_inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) as IDictionary;
				int num = dictionary?.Count ?? (-1);
				string text = ((dictionary != null) ? string.Join(",", dictionary.Keys.Cast<object>()) : "null");
				if ((int)__result == 20000012)
				{
					MelonLogger.Msg("[InventoryExpansion][Debug] HandleAddItem: INVENTORY FULL. slotCount=" + num + ", keys=[" + text + "]");
				}
				else if ((int)__result == 0)
				{
					MelonLogger.Msg("[InventoryExpansion][Debug] HandleAddItem: Success, addedSlotIndex=" + addedSlotIndex + ", slotCount=" + num + ".");
				}
				else
				{
					MelonLogger.Msg("[InventoryExpansion][Debug] HandleAddItem: Result=" + ((object)(MsgErrorCode)(ref __result)).ToString() + ", addedSlotIndex=" + addedSlotIndex + ", slotCount=" + num + ".");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][Debug] HandleAddItem debug failed: {arg}");
			}
		}
	}
	[HarmonyPatch]
	internal static class InventoryDebugClientPatches
	{
		private static MethodBase TargetMethod()
		{
			try
			{
				Type nestedType = typeof(ProtoActor).GetNestedType("Inventory", BindingFlags.Public | BindingFlags.NonPublic);
				if (nestedType == null)
				{
					MelonLogger.Error("[InventoryExpansion][Debug] Failed to find nested type ProtoActor.Inventory for ResolveInventoryInfos debug patch.");
					return null;
				}
				MethodInfo? method = nestedType.GetMethod("ResolveInventoryInfos", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					MelonLogger.Error("[InventoryExpansion][Debug] Failed to find ResolveInventoryInfos method on ProtoActor.Inventory.");
				}
				return method;
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[InventoryExpansion][Debug] TargetMethod for ResolveInventoryInfos failed: " + ex);
				return null;
			}
		}

		[HarmonyPostfix]
		private static void Inventory_ResolveInventoryInfos_Postfix(object __instance, Dictionary<int, ItemInfo> serverItemInfos, int? currentServerSlotIndex)
		{
			try
			{
				if (__instance == null)
				{
					return;
				}
				Type type = __instance.GetType();
				int num = (int)(type.GetField("slotSize", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) ?? ((object)0));
				IList list = type.GetField("slotItems", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) as IList;
				int num2 = 0;
				if (list != null)
				{
					foreach (object item in list)
					{
						if (item != null)
						{
							num2++;
						}
					}
				}
				int num3 = serverItemInfos?.Count ?? 0;
				int num4 = ((num3 > 0) ? serverItemInfos.Keys.Max() : 0);
				string text = (currentServerSlotIndex.HasValue ? currentServerSlotIndex.Value.ToString() : "null");
				MelonLogger.Msg("[InventoryExpansion][Debug] ResolveInventoryInfos: slotSize=" + num + ", serverItems=" + num3 + ", serverMaxKey=" + num4 + ", localNonNullItems=" + num2 + ", currentServerSlotIndex=" + text + ".");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[InventoryExpansion][Debug] ResolveInventoryInfos debug failed: " + ex);
			}
		}
	}
	[HarmonyPatch]
	internal static class BackpackPanelPatch
	{
		[CompilerGenerated]
		private sealed class <AnimateBackpackVisibility>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public bool targetVisible;

			private Vector2 <startPos>5__2;

			private Vector2 <targetPos>5__3;

			private float <elapsed>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateBackpackVisibility>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003a: 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)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_01de: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					if ((Object)(object)_backpackPanel == (Object)null)
					{
						return false;
					}
					if (_panelHeight == 0f)
					{
						_panelHeight = _backpackPanel.sizeDelta.y;
					}
					if (_initialPanelY == 0f)
					{
						_initialPanelY = 40f;
					}
					float num = _initialPanelY - _panelHeight * 0.75f;
					float initialPanelY = _initialPanelY;
					<startPos>5__2 = _backpackPanel.anchoredPosition;
					<targetPos>5__3 = (targetVisible ? new Vector2(<startPos>5__2.x, initialPanelY) : new Vector2(<startPos>5__2.x, num));
					if (Mathf.Abs(<startPos>5__2.y - <targetPos>5__3.y) < 1f)
					{
						_backpackFullyVisible = targetVisible;
						UpdateKeyHintVisibility();
						_animationCoroutine = null;
						return false;
					}
					<elapsed>5__4 = 0f;
					((Component)_backpackPanel).gameObject.SetActive(true);
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__4 < 0.3f)
				{
					if ((Object)(object)_backpackPanel == (Object)null || (Object)(object)((Component)_backpackPanel).gameObject == (Object)null)
					{
						return false;
					}
					<elapsed>5__4 += Time.deltaTime;
					float num2 = Mathf.Clamp01(<elapsed>5__4 / 0.3f);
					num2 = 1f - Mathf.Pow(1f - num2, 3f);
					_backpackPanel.anchoredPosition = Vector2.Lerp(<startPos>5__2, <targetPos>5__3, num2);
					UpdateKeyHintVisibility();
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)_backpackPanel != (Object)null && (Object)(object)((Component)_backpackPanel).gameObject != (Object)null)
				{
					_backpackPanel.anchoredPosition = <targetPos>5__3;
					_backpackFullyVisible = targetVisible;
					UpdateKeyHintVisibility();
				}
				_animationCoroutine = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <MoveSlotsToPanelCoroutine>d__26 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UIPrefab_Inventory inventoryUI;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <MoveSlotsToPanelCoroutine>d__26(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0259: Unknown result type (might be due to invalid IL or missing references)
				//IL_0824: Unknown result type (might be due to invalid IL or missing references)
				//IL_0866: Unknown result type (might be due to invalid IL or missing references)
				//IL_0872: Unknown result type (might be due to invalid IL or missing references)
				//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0335: Unknown result type (might be due to invalid IL or missing references)
				//IL_033c: Expected O, but got Unknown
				//IL_036f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0384: Unknown result type (might be due to invalid IL or missing references)
				//IL_0399: Unknown result type (might be due to invalid IL or missing references)
				//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0552: Unknown result type (might be due to invalid IL or missing references)
				//IL_0568: Unknown result type (might be due to invalid IL or missing references)
				//IL_0576: Unknown result type (might be due to invalid IL or missing references)
				//IL_0584: Unknown result type (might be due to invalid IL or missing references)
				//IL_058e: Unknown result type (might be due to invalid IL or missing references)
				//IL_059a: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_0413: Unknown result type (might be due to invalid IL or missing references)
				//IL_0418: Unknown result type (might be due to invalid IL or missing references)
				//IL_044d: Unknown result type (might be due to invalid IL or missing references)
				//IL_045a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0474: Unknown result type (might be due to invalid IL or missing references)
				//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0504: Unknown result type (might be due to invalid IL or missing references)
				//IL_050e: Unknown result type (might be due to invalid IL or missing references)
				//IL_051a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0524: Unknown result type (might be due to invalid IL or missing references)
				//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_07ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_07c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_07de: Unknown result type (might be due to invalid IL or missing references)
				//IL_07e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_069d: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_070d: Unknown result type (might be due to invalid IL or missing references)
				//IL_071b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0729: Unknown result type (might be due to invalid IL or missing references)
				//IL_0737: Unknown result type (might be due to invalid IL or missing references)
				//IL_0741: Unknown result type (might be due to invalid IL or missing references)
				//IL_074f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0759: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					try
					{
						if ((Object)(object)_backpackPanel == (Object)null || _slotsMoved)
						{
							return false;
						}
						FieldInfo field = typeof(UIPrefab_Inventory).GetField("inventorySlots", BindingFlags.Instance | BindingFlags.NonPublic);
						if (field == null)
						{
							MelonLogger.Error("[InventoryExpansion][BackpackPanel] Could not find inventorySlots field!");
							return false;
						}
						if (!(field.GetValue(inventoryUI) is IList list) || list.Count <= 4)
						{
							return false;
						}
						Type type = list[0].GetType();
						FieldInfo field2 = type.GetField("frame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field2 == null)
						{
							MelonLogger.Error("[InventoryExpansion][BackpackPanel] Could not find frame field in slot!");
							return false;
						}
						object obj = list[0];
						object? value = field2.GetValue(obj);
						Image val = (Image)((value is Image) ? value : null);
						if ((Object)(object)val == (Object)null)
						{
							MelonLogger.Error("[InventoryExpansion][BackpackPanel] Could not get first frame!");
							return false;
						}
						RectTransform rectTransform = ((Graphic)val).rectTransform;
						float x = rectTransform.sizeDelta.x;
						float y = rectTransform.sizeDelta.y;
						x *= 0.5f;
						y *= 0.5f;
						Image val2 = null;
						Transform parent = ((Transform)rectTransform).parent;
						if ((Object)(object)parent != (Object)null)
						{
							for (int i = 0; i < parent.childCount; i++)
							{
								Transform child = parent.GetChild(i);
								if (((Object)child).name.Contains("InvenBG") || ((Object)child).name.Contains("BG"))
								{
									val2 = ((Component)child).GetComponent<Image>();
									if ((Object)(object)val2 != (Object)null)
									{
										break;
									}
								}
							}
						}
						float num = 10f;
						int num2 = list.Count - 4;
						int num3 = num2 switch
						{
							4 => 2, 
							9 => 3, 
							16 => 4, 
							_ => Mathf.CeilToInt(Mathf.Sqrt((float)num2)), 
						};
						int num4 = Mathf.CeilToInt((float)num2 / (float)num3);
						float num5 = (float)num3 * x + (float)(num3 + 1) * num;
						float num6 = (float)num4 * y + (float)(num4 + 1) * num;
						(float padding, float paddingTop, float paddingBottom) paddingForSlotCount = GetPaddingForSlotCount(num2);
						float item = paddingForSlotCount.padding;
						float item2 = paddingForSlotCount.paddingTop;
						float item3 = paddingForSlotCount.paddingBottom;
						float num7 = num5 + item * 2f;
						float num8 = num6 + item2 + item3;
						_backpackPanel.sizeDelta = new Vector2(num7, num8);
						FieldInfo field3 = type.GetField("image", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						FieldInfo field4 = type.GetField("stackCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						object? obj2 = field3?.GetValue(obj);
						Image val3 = (Image)((obj2 is Image) ? obj2 : null);
						object? obj3 = field4?.GetValue(obj);
						TMP_Text val4 = (TMP_Text)((obj3 is TMP_Text) ? obj3 : null);
						RectTransform val5 = ((val3 != null) ? ((Graphic)val3).rectTransform : null);
						RectTransform val6 = ((val4 != null) ? val4.rectTransform : null);
						for (int j = 4; j < list.Count; j++)
						{
							object obj4 = list[j];
							object? value2 = field2.GetValue(obj4);
							Image val7 = (Image)((value2 is Image) ? value2 : null);
							if ((Object)(object)val7 == (Object)null)
							{
								continue;
							}
							RectTransform rectTransform2 = ((Graphic)val7).rectTransform;
							if (!((Object)((Component)val7).gameObject).name.Contains("_Extra"))
							{
								continue;
							}
							GameObject val8 = new GameObject("InventoryExpansion_SlotContainer_" + j);
							val8.transform.SetParent((Transform)(object)_backpackPanel, false);
							RectTransform obj5 = val8.AddComponent<RectTransform>();
							int num9 = j - 4;
							int num10 = num9 / num3;
							int num11 = num9 % num3;
							obj5.anchorMin = new Vector2(0f, 1f);
							obj5.anchorMax = new Vector2(0f, 1f);
							obj5.pivot = new Vector2(0f, 1f);
							(float horizontal, float top) slotPaddingForSlotCount = GetSlotPaddingForSlotCount(num2);
							float item4 = slotPaddingForSlotCount.horizontal;
							float item5 = slotPaddingForSlotCount.top;
							float num12 = item4 + num + (float)num11 * (x + num);
							float num13 = 0f - (item5 + num + (float)num10 * (y + num));
							obj5.anchoredPosition = new Vector2(num12, num13);
							obj5.sizeDelta = new Vector2(x, y);
							if ((Object)(object)val2 != (Object)null)
							{
								GameObject val9 = new GameObject("InvenBG_Extra" + j);
								val9.transform.SetParent(val8.transform, false);
								Image obj6 = val9.AddComponent<Image>();
								obj6.sprite = val2.sprite;
								((Graphic)obj6).material = ((Graphic)val2).material;
								((Graphic)obj6).color = ((Graphic)val2).color;
								obj6.type = val2.type;
								obj6.preserveAspect = val2.preserveAspect;
								obj6.fillMethod = val2.fillMethod;
								obj6.fillAmount = val2.fillAmount;
								obj6.fillCenter = val2.fillCenter;
								obj6.fillClockwise = val2.fillClockwise;
								obj6.fillOrigin = val2.fillOrigin;
								((Graphic)obj6).raycastTarget = ((Graphic)val2).raycastTarget;
								((MaskableGraphic)obj6).maskable = ((MaskableGraphic)val2).maskable;
								RectTransform rectTransform3 = ((Graphic)obj6).rectTransform;
								RectTransform rectTransform4 = ((Graphic)val2).rectTransform;
								rectTransform3.anchorMin = rectTransform4.anchorMin;
								rectTransform3.anchorMax = rectTransform4.anchorMax;
								rectTransform3.pivot = rectTransform4.pivot;
								rectTransform3.sizeDelta = rectTransform4.sizeDelta * 0.5f;
								rectTransform3.anchoredPosition = rectTransform4.anchoredPosition * 0.5f;
							}
							((Transform)rectTransform2).SetParent(val8.transform, false);
							RectTransform rectTransform5 = ((Graphic)val).rectTransform;
							rectTransform2.anchorMin = new Vector2(0.5f, 0.5f);
							rectTransform2.anchorMax = new Vector2(0.5f, 0.5f);
							rectTransform2.pivot = rectTransform5.pivot;
							rectTransform2.sizeDelta = rectTransform5.sizeDelta * 0.5f;
							rectTransform2.anchoredPosition = Vector2.zero;
							val7.sprite = val.sprite;
							((Graphic)val7).material = ((Graphic)val).material;
							((Graphic)val7).color = ((Graphic)val).color;
							val7.type = val.type;
							val7.preserveAspect = val.preserveAspect;
							val7.fillMethod = val.fillMethod;
							val7.fillAmount = val.fillAmount;
							val7.fillCenter = val.fillCenter;
							val7.fillClockwise = val.fillClockwise;
							val7.fillOrigin = val.fillOrigin;
							if (field3 != null && (Object)(object)val3 != (Object)null && (Object)(object)val5 != (Object)null)
							{
								object? value3 = field3.GetValue(obj4);
								Image val10 = (Image)((value3 is Image) ? value3 : null);
								if ((Object)(object)val10 != (Object)null)
								{
									RectTransform rectTransform6 = ((Graphic)val10).rectTransform;
									val10.sprite = val3.sprite;
									((Graphic)val10).material = ((Graphic)val3).material;
									((Graphic)val10).color = ((Graphic)val3).color;
									val10.type = val3.type;
									val10.preserveAspect = val3.preserveAspect;
									val10.fillMethod = val3.fillMethod;
									val10.fillAmount = val3.fillAmount;
									val10.fillCenter = val3.fillCenter;
									val10.fillClockwise = val3.fillClockwise;
									val10.fillOrigin = val3.fillOrigin;
									rectTransform6.anchorMin = val5.anchorMin;
									rectTransform6.anchorMax = val5.anchorMax;
									rectTransform6.pivot = val5.pivot;
									rectTransform6.sizeDelta = val5.sizeDelta * 0.5f;
									rectTransform6.anchoredPosition = val5.anchoredPosition * 0.5f;
								}
							}
							if (field4 != null && (Object)(object)val6 != (Object)null)
							{
								object? value4 = field4.GetValue(obj4);
								TMP_Text val11 = (TMP_Text)((value4 is TMP_Text) ? value4 : null);
								if ((Object)(object)val11 != (Object)null)
								{
									RectTransform rectTransform7 = val11.rectTransform;
									rectTransform7.anchorMin = val6.anchorMin;
									rectTransform7.anchorMax = val6.anchorMax;
									rectTransform7.pivot = val6.pivot;
									rectTransform7.sizeDelta = val6.sizeDelta * 0.5f;
									rectTransform7.anchoredPosition = val6.anchoredPosition * 0.5f;
									val11.fontSize = val4.fontSize * 0.5f;
								}
							}
						}
						_slotsMoved = true;
						_panelHeight = _backpackPanel.sizeDelta.y;
						if (_initialPanelY == 0f)
						{
							_initialPanelY = 40f;
						}
						float num14 = _initialPanelY - _panelHeight * 0.75f;
						_backpackPanel.anchoredPosition = new Vector2(_backpackPanel.anchoredPosition.x, num14);
						_backpackFullyVisible = false;
						UpdateKeyHintVisibility();
						MelonLogger.Msg("[InventoryExpansion][BackpackPanel] Moved {0} additional slots to panel. Panel size: {1}", new object[2] { num2, _backpackPanel.sizeDelta });
					}
					catch (Exception ex)
					{
						MelonLogger.Error("[InventoryExpansion][BackpackPanel] Failed to move slots to panel: " + ex);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static GameObject _rootObj;

		private static GameObject _canvasObj;

		private static RectTransform _backpackPanel;

		private static bool _slotsMoved;

		private static bool _backpackFullyVisible;

		private static Sprite _backpackSprite;

		private static object _animationCoroutine;

		private static float _panelHeight;

		private static float _initialPanelY;

		private static TMP_Text _keyHintText;

		internal static bool IsBackpackFullyVisible => _backpackFullyVisible;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIPrefab_Inventory), "Awake")]
		private static void UIPrefab_Inventory_Awake_Postfix(UIPrefab_Inventory __instance)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					return;
				}
				BackpackSceneChangeHandler.Initialize();
				if ((Object)(object)_backpackPanel != (Object)null)
				{
					if (!_slotsMoved)
					{
						MelonCoroutines.Start(MoveSlotsToPanelCoroutine(__instance));
					}
				}
				else
				{
					CreateRoot();
					CreateUI();
					MelonCoroutines.Start(MoveSlotsToPanelCoroutine(__instance));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[InventoryExpansion][BackpackPanel] Failed to create backpack panel: " + ex);
			}
		}

		private static void CreateRoot()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_rootObj != (Object)null))
			{
				_rootObj = new GameObject("InventoryExpansion_Root");
				Object.DontDestroyOnLoad((Object)(object)_rootObj);
			}
		}

		private static void CreateUI()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvasObj != (Object)null)
			{
				return;
			}
			if ((Object)(object)_rootObj == (Object)null)
			{
				CreateRoot();
			}
			_canvasObj = new GameObject("InventoryExpansion_Canvas");
			_canvasObj.transform.SetParent(_rootObj.transform, false);
			Canvas val = _canvasObj.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			CanvasScaler obj = _canvasObj.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)0;
			obj.scaleFactor = 1f;
			Canvas val2 = null;
			Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0);
			foreach (Canvas val3 in array)
			{
				if ((int)val3.renderMode == 0 && ((Object)val3).name.Contains("Canvas") && !((Object)val3).name.Contains("InventoryExpansion"))
				{
					val2 = val3;
					break;
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val.sortingOrder = val2.sortingOrder + 1;
			}
			_canvasObj.AddComponent<GraphicRaycaster>();
			GameObject val4 = new GameObject("InventoryExpansion_BackpackPanel");
			val4.transform.SetParent(_canvasObj.transform, false);
			Image val5 = val4.AddComponent<Image>();
			LoadBackpackSprite();
			if ((Object)(object)_backpackSprite != (Object)null)
			{
				val5.sprite = _backpackSprite;
				val5.type = (Type)0;
				val5.preserveAspect = false;
			}
			else
			{
				((Graphic)val5).color = new Color(0f, 0f, 0f, 0.8f);
			}
			((Graphic)val5).raycastTarget = false;
			_backpackPanel = val4.GetComponent<RectTransform>();
			_backpackPanel.anchorMin = new Vector2(1f, 0f);
			_backpackPanel.anchorMax = new Vector2(1f, 0f);
			_backpackPanel.pivot = new Vector2(1f, 0f);
			_backpackPanel.sizeDelta = new Vector2(450f, 200f);
			_backpackPanel.anchoredPosition = new Vector2(-40f, 40f);
			_initialPanelY = 40f;
			try
			{
				CreateKeyHintText(val4);
			}
			catch (Exception arg)
			{
				MelonLogger.Warning($"[InventoryExpansion][BackpackPanel] Failed to create key hint text during UI creation: {arg}");
			}
			_backpackFullyVisible = false;
			((Component)_backpackPanel).gameObject.SetActive(true);
		}

		private static void LoadBackpackSprite()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(typeof(BackpackPanelPatch).Assembly.Location), "Assets", "Backpack.png");
				if (!File.Exists(text))
				{
					MelonLogger.Warning("[InventoryExpansion][BackpackPanel] Backpack asset not found at: " + text);
					return;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2);
				bool flag = false;
				try
				{
					flag = ImageConversion.LoadImage(val, array);
				}
				catch
				{
					try
					{
						flag = ImageConversion.LoadImage(val, array);
					}
					catch
					{
					}
				}
				if (!flag)
				{
					MelonLogger.Error("[InventoryExpansion][BackpackPanel] Failed to load Backpack.png as texture");
					Object.Destroy((Object)(object)val);
				}
				else
				{
					_backpackSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
					MelonLogger.Msg($"[InventoryExpansion][BackpackPanel] Loaded Backpack sprite: {((Texture)val).width}x{((Texture)val).height}");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][BackpackPanel] Failed to load Backpack sprite: {arg}");
			}
		}

		internal static void ToggleBackpack()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_backpackPanel == (Object)null) && !IsInLoadingScreen() && !IsGamePaused())
			{
				bool targetVisible = !_backpackFullyVisible;
				if (_animationCoroutine != null)
				{
					MelonCoroutines.Stop(_animationCoroutine);
					_animationCoroutine = null;
				}
				((Component)_backpackPanel).gameObject.SetActive(true);
				if (_panelHeight == 0f)
				{
					_panelHeight = _backpackPanel.sizeDelta.y;
				}
				if (_initialPanelY == 0f)
				{
					_initialPanelY = 40f;
				}
				_animationCoroutine = MelonCoroutines.Start(AnimateBackpackVisibility(targetVisible));
			}
		}

		internal static bool IsGamePaused()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Time.timeScale <= 0.01f)
				{
					return true;
				}
				if ((int)Cursor.lockState == 0 && Cursor.visible && IsInGame())
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsInGame()
		{
			try
			{
				Hub s = Hub.s;
				if ((Object)(object)s == (Object)null)
				{
					return false;
				}
				FieldInfo field = typeof(Hub).GetField("protoActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				ProtoActor val = null;
				if (field == null)
				{
					FieldInfo[] fields = typeof(Hub).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.FieldType == typeof(ProtoActor) || fieldInfo.FieldType.IsSubclassOf(typeof(ProtoActor)))
						{
							object? value = fieldInfo.GetValue(s);
							val = (ProtoActor)((value is ProtoActor) ? value : null);
							if ((Object)(object)val != (Object)null && val.AmIAvatar())
							{
								return true;
							}
						}
					}
					return false;
				}
				object? value2 = field.GetValue(s);
				val = (ProtoActor)((value2 is ProtoActor) ? value2 : null);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				return val.AmIAvatar();
			}
			catch (Exception arg)
			{
				MelonLogger.Warning($"[InventoryExpansion][BackpackPanel] IsInGame check failed: {arg}");
				return false;
			}
		}

		private static bool IsInLoadingScreen()
		{
			try
			{
				Hub s = Hub.s;
				if ((Object)(object)s == (Object)null)
				{
					return true;
				}
				FieldInfo field = typeof(Hub).GetField("protoActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					return false;
				}
				object? value = field.GetValue(s);
				ProtoActor val = (ProtoActor)((value is ProtoActor) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				return !val.AmIAvatar();
			}
			catch
			{
				return false;
			}
		}

		internal static void HideBackpackCompletely()
		{
			if ((Object)(object)_backpackPanel != (Object)null && (Object)(object)((Component)_backpackPanel).gameObject != (Object)null)
			{
				((Component)_backpackPanel).gameObject.SetActive(false);
			}
		}

		[IteratorStateMachine(typeof(<AnimateBackpackVisibility>d__21))]
		private static IEnumerator AnimateBackpackVisibility(bool targetVisible)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateBackpackVisibility>d__21(0)
			{
				targetVisible = targetVisible
			};
		}

		private static void CreateKeyHintText(GameObject parent)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)parent == (Object)null)
				{
					MelonLogger.Warning("[InventoryExpansion][BackpackPanel] Cannot create key hint text: parent is null");
					return;
				}
				Type type = null;
				TMP_FontAsset val = null;
				try
				{
					TMP_Text[] array = Object.FindObjectsByType<TMP_Text>((FindObjectsSortMode)0);
					if (array != null && array.Length != 0)
					{
						TMP_Text[] array2 = array;
						foreach (TMP_Text val2 in array2)
						{
							if ((Object)(object)val2 != (Object)null && !((object)val2).Equals((object?)null) && (Object)(object)val2.font != (Object)null)
							{
								type = ((object)val2).GetType();
								val = val2.font;
								break;
							}
						}
					}
				}
				catch (Exception arg)
				{
					MelonLogger.Warning($"[InventoryExpansion][BackpackPanel] Error finding TMP_Text type: {arg}");
				}
				if (type == null)
				{
					type = typeof(TMP_Text);
				}
				GameObject val3 = new GameObject("InventoryExpansion_KeyHint");
				if ((Object)(object)val3 == (Object)null)
				{
					MelonLogger.Warning("[InventoryExpansion][BackpackPanel] Failed to create key hint GameObject");
					return;
				}
				val3.transform.SetParent(parent.transform, false);
				val3.transform.SetAsLastSibling();
				Component obj = val3.AddComponent(type);
				_keyHintText = (TMP_Text)(object)((obj is TMP_Text) ? obj : null);
				if ((Object)(object)_keyHintText == (Object)null)
				{
					MelonLogger.Warning("[InventoryExpansion][BackpackPanel] Failed to add TMP_Text component");
					Object.Destroy((Object)(object)val3);
					return;
				}
				if ((Object)(object)val != (Object)null)
				{
					_keyHintText.font = val;
				}
				else
				{
					TMP_FontAsset defaultFontAsset = TMP_Settings.defaultFontAsset;
					if ((Object)(object)defaultFontAsset != (Object)null)
					{
						_keyHintText.font = defaultFontAsset;
					}
				}
				TMP_Text keyHintText = _keyHintText;
				KeyCode backpackKey = InventoryExpansionPreferences.BackpackKey;
				keyHintText.text = ((object)(KeyCode)(ref backpackKey)).ToString();
				_keyHintText.fontSize = 24f;
				_keyHintText.alignment = (TextAlignmentOptions)514;
				((Graphic)_keyHintText).color = new Color(1f, 1f, 1f, 1f);
				_keyHintText.fontStyle = (FontStyles)1;
				Outline val4 = val3.AddComponent<Outline>();
				if ((Object)(object)val4 != (Object)null)
				{
					((Shadow)val4).effectColor = new Color(0f, 0f, 0f, 1f);
					((Shadow)val4).effectDistance = new Vector2(2f, 2f);
				}
				if ((Object)(object)_keyHintText.rectTransform == (Object)null)
				{
					MelonLogger.Warning("[InventoryExpansion][BackpackPanel] Key hint text has no RectTransform");
					return;
				}
				RectTransform rectTransform = _keyHintText.rectTransform;
				rectTransform.anchorMin = new Vector2(0.5f, 1f);
				rectTransform.anchorMax = new Vector2(0.5f, 1f);
				rectTransform.pivot = new Vector2(0.5f, 0.5f);
				rectTransform.sizeDelta = new Vector2(60f, 35f);
				rectTransform.anchoredPosition = new Vector2(0f, -95f);
				((Graphic)_keyHintText).raycastTarget = false;
				((Component)_keyHintText).gameObject.SetActive(true);
				MelonLogger.Msg("[InventoryExpansion][BackpackPanel] Key hint text created successfully");
			}
			catch (Exception arg2)
			{
				MelonLogger.Error($"[InventoryExpansion][BackpackPanel] Failed to create key hint text: {arg2}");
				_keyHintText = null;
			}
		}

		private static void UpdateKeyHintVisibility()
		{
			if ((Object)(object)_keyHintText == (Object)null || (Object)(object)((Component)_keyHintText).gameObject == (Object)null)
			{
				return;
			}
			try
			{
				((Component)_keyHintText).gameObject.SetActive(true);
			}
			catch
			{
			}
		}

		private static (float padding, float paddingTop, float paddingBottom) GetPaddingForSlotCount(int additionalSlots)
		{
			return additionalSlots switch
			{
				4 => (90f, 130f, 90f), 
				9 => (160f, 200f, 140f), 
				_ => (200f, 240f, 180f), 
			};
		}

		private static (float horizontal, float top) GetSlotPaddingForSlotCount(int additionalSlots)
		{
			return additionalSlots switch
			{
				4 => (90f, 170f), 
				9 => (160f, 260f), 
				_ => (200f, 320f), 
			};
		}

		[IteratorStateMachine(typeof(<MoveSlotsToPanelCoroutine>d__26))]
		private static IEnumerator MoveSlotsToPanelCoroutine(UIPrefab_Inventory inventoryUI)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MoveSlotsToPanelCoroutine>d__26(0)
			{
				inventoryUI = inventoryUI
			};
		}
	}
	[HarmonyPatch(typeof(ProtoActor), "Update")]
	internal static class BackpackInputUpdatePatch
	{
		private static bool wasKeyPressedLastFrame;

		[HarmonyPostfix]
		private static void Update_Postfix(ProtoActor __instance)
		{
			//IL_0084: 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)
			//IL_0057: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!InventoryExpansionPreferences.Enabled || !__instance.AmIAvatar())
				{
					return;
				}
				if (BackpackPanelPatch.IsGamePaused())
				{
					if (BackpackPanelPatch.IsBackpackFullyVisible)
					{
						BackpackPanelPatch.ToggleBackpack();
					}
					else
					{
						BackpackPanelPatch.HideBackpackCompletely();
					}
					wasKeyPressedLastFrame = false;
					return;
				}
				Keyboard current = Keyboard.current;
				if (current == null)
				{
					wasKeyPressedLastFrame = false;
					return;
				}
				KeyCode backpackKey = InventoryExpansionPreferences.BackpackKey;
				Key val = (Key)0;
				try
				{
					val = (Key)Enum.Parse(typeof(Key), ((object)(KeyCode)(ref backpackKey)).ToString());
				}
				catch
				{
					MelonLogger.Warning($"[InventoryExpansion][BackpackPanel] Could not convert KeyCode {backpackKey} to Input System Key");
					return;
				}
				bool isPressed = ((ButtonControl)current[val]).isPressed;
				bool num = isPressed && !wasKeyPressedLastFrame;
				wasKeyPressedLastFrame = isPressed;
				if (num)
				{
					BackpackPanelPatch.ToggleBackpack();
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][BackpackPanel] Update postfix failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(ProtoActor))]
	internal static class BackpackMovementSpeedPatch
	{
		private static FieldInfo _netSyncActorDataField;

		private static bool _fieldInitialized;

		private static long _originalMoveSpeedWalk;

		private static long _originalMoveSpeedRun;

		private static bool _speedReduced;

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void Update_Postfix(ProtoActor __instance)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					RestoreMoveSpeed(__instance);
				}
				else
				{
					if (!__instance.AmIAvatar())
					{
						return;
					}
					if (!_fieldInitialized)
					{
						_netSyncActorDataField = typeof(ProtoActor).GetField("netSyncActorData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						_fieldInitialized = true;
					}
					if (_netSyncActorDataField == null)
					{
						return;
					}
					object value = _netSyncActorDataField.GetValue(__instance);
					if (value == null)
					{
						return;
					}
					FieldInfo field = value.GetType().GetField("MoveSpeedWalk", BindingFlags.Instance | BindingFlags.Public);
					FieldInfo field2 = value.GetType().GetField("MoveSpeedRun", BindingFlags.Instance | BindingFlags.Public);
					if (field == null || field2 == null)
					{
						return;
					}
					if (BackpackPanelPatch.IsBackpackFullyVisible && InventoryExpansionPreferences.ReduceMovementSpeed)
					{
						if (!_speedReduced)
						{
							_originalMoveSpeedWalk = (long)(field.GetValue(value) ?? ((object)350L));
							_originalMoveSpeedRun = (long)(field2.GetValue(value) ?? ((object)700L));
							_speedReduced = true;
						}
						field.SetValue(value, (long)((float)_originalMoveSpeedWalk * 0.5f));
						field2.SetValue(value, (long)((float)_originalMoveSpeedRun * 0.5f));
					}
					else
					{
						RestoreMoveSpeed(value, field, field2);
					}
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][Movement] Movement speed patch failed: {arg}");
			}
		}

		private static void RestoreMoveSpeed(ProtoActor instance)
		{
			if (!_speedReduced || _netSyncActorDataField == null)
			{
				return;
			}
			object value = _netSyncActorDataField.GetValue(instance);
			if (value != null)
			{
				FieldInfo field = value.GetType().GetField("MoveSpeedWalk", BindingFlags.Instance | BindingFlags.Public);
				FieldInfo field2 = value.GetType().GetField("MoveSpeedRun", BindingFlags.Instance | BindingFlags.Public);
				if (field != null && field2 != null)
				{
					RestoreMoveSpeed(value, field, field2);
				}
			}
		}

		private static void RestoreMoveSpeed(object netSyncActorData, FieldInfo moveSpeedWalkField, FieldInfo moveSpeedRunField)
		{
			if (_speedReduced && _originalMoveSpeedWalk > 0 && _originalMoveSpeedRun > 0)
			{
				moveSpeedWalkField.SetValue(netSyncActorData, _originalMoveSpeedWalk);
				moveSpeedRunField.SetValue(netSyncActorData, _originalMoveSpeedRun);
				_speedReduced = false;
			}
		}
	}
	[HarmonyPatch(typeof(ProtoActor), "OnDestroy")]
	internal static class BackpackProtoActorDestroyPatch
	{
		[HarmonyPostfix]
		private static void OnDestroy_Postfix(ProtoActor __instance)
		{
			try
			{
				if (InventoryExpansionPreferences.Enabled && __instance.AmIAvatar())
				{
					BackpackSceneChangeHandler.HideBackpack();
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][BackpackPanel] ProtoActor OnDestroy patch failed: {arg}");
			}
		}
	}
	internal static class BackpackSceneChangeHandler
	{
		private static bool _initialized;

		internal static void Initialize()
		{
			if (!_initialized)
			{
				SceneManager.activeSceneChanged += OnActiveSceneChanged;
				_initialized = true;
			}
		}

		private static void OnActiveSceneChanged(Scene previousScene, Scene newScene)
		{
			try
			{
				if (InventoryExpansionPreferences.Enabled && !IsInGame())
				{
					HideBackpack();
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][BackpackPanel] Scene change handler failed: {arg}");
			}
		}

		private static bool IsInGame()
		{
			try
			{
				Hub s = Hub.s;
				if ((Object)(object)s == (Object)null)
				{
					return false;
				}
				FieldInfo field = typeof(Hub).GetField("protoActor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				ProtoActor val = null;
				if (field == null)
				{
					FieldInfo[] fields = typeof(Hub).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.FieldType == typeof(ProtoActor) || fieldInfo.FieldType.IsSubclassOf(typeof(ProtoActor)))
						{
							object? value = fieldInfo.GetValue(s);
							val = (ProtoActor)((value is ProtoActor) ? value : null);
							if ((Object)(object)val != (Object)null && val.AmIAvatar())
							{
								return true;
							}
						}
					}
					return false;
				}
				object? value2 = field.GetValue(s);
				val = (ProtoActor)((value2 is ProtoActor) ? value2 : null);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				return val.AmIAvatar();
			}
			catch
			{
				return false;
			}
		}

		internal static void HideBackpack()
		{
			if (BackpackPanelPatch.IsBackpackFullyVisible)
			{
				BackpackPanelPatch.ToggleBackpack();
			}
			else
			{
				BackpackPanelPatch.HideBackpackCompletely();
			}
		}
	}
	internal static class InventorySelectionHelper
	{
		internal static Type GetInventoryType()
		{
			return typeof(ProtoActor).GetNestedType("Inventory", BindingFlags.Public | BindingFlags.NonPublic);
		}

		internal static FieldInfo GetSelectedSlotIndexField(Type inventoryType)
		{
			return inventoryType?.GetField("selectedSlotIndex", BindingFlags.Instance | BindingFlags.NonPublic);
		}

		internal static FieldInfo GetSlotSizeField(Type inventoryType)
		{
			return inventoryType?.GetField("slotSize", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}
	[HarmonyPatch]
	internal static class InventorySelectionNextPatches
	{
		private static MethodBase TargetMethod()
		{
			return InventorySelectionHelper.GetInventoryType()?.GetMethod("SelectNextSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		[HarmonyPrefix]
		private static bool SelectNextSlot_Prefix(object __instance)
		{
			return InventorySelectionCommon.HandleSlotSelection(__instance, forward: true);
		}
	}
	[HarmonyPatch]
	internal static class InventorySelectionPreviousPatches
	{
		private static MethodBase TargetMethod()
		{
			return InventorySelectionHelper.GetInventoryType()?.GetMethod("SelectPreviousSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		[HarmonyPrefix]
		private static bool SelectPreviousSlot_Prefix(object __instance)
		{
			return InventorySelectionCommon.HandleSlotSelection(__instance, forward: false);
		}
	}
	internal static class InventorySelectionCommon
	{
		internal static bool HandleSlotSelection(object __instance, bool forward)
		{
			try
			{
				if (!InventoryExpansionPreferences.Enabled)
				{
					return true;
				}
				if (__instance == null)
				{
					return true;
				}
				Type type = __instance.GetType();
				FieldInfo selectedSlotIndexField = InventorySelectionHelper.GetSelectedSlotIndexField(type);
				FieldInfo slotSizeField = InventorySelectionHelper.GetSlotSizeField(type);
				if (selectedSlotIndexField == null || slotSizeField == null)
				{
					return true;
				}
				int num = (int)(selectedSlotIndexField.GetValue(__instance) ?? ((object)0));
				int num2 = (int)(slotSizeField.GetValue(__instance) ?? ((object)4));
				int num3;
				int num4;
				if (BackpackPanelPatch.IsBackpackFullyVisible)
				{
					num3 = 4;
					num4 = num2 - 1;
				}
				else
				{
					num3 = 0;
					num4 = 3;
				}
				if (num3 > num4 || num < num3 || num > num4)
				{
					MethodInfo method = type.GetMethod("SelectSlot", BindingFlags.Instance | BindingFlags.NonPublic);
					if (method != null)
					{
						method.Invoke(__instance, new object[1] { num3 });
						return false;
					}
					return true;
				}
				int num5;
				if (forward)
				{
					num5 = num + 1;
					if (num5 > num4)
					{
						num5 = num3;
					}
				}
				else
				{
					num5 = num - 1;
					if (num5 < num3)
					{
						num5 = num4;
					}
				}
				MethodInfo method2 = type.GetMethod("SelectSlot", BindingFlags.Instance | BindingFlags.NonPublic);
				if (method2 != null)
				{
					method2.Invoke(__instance, new object[1] { num5 });
					return false;
				}
				return true;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"[InventoryExpansion][Selection] Slot selection prefix failed: {arg}");
				return true;
			}
		}
	}
}
namespace InventoryExpansion.Config
{
	internal static class InventoryExpansionPreferences
	{
		private const string CategoryId = "InventoryExpansion";

		private static MelonPreferences_Category _category;

		private static MelonPreferences_Entry<bool> _enabled;

		private static MelonPreferences_Entry<int> _additionalSlots;

		private static MelonPreferences_Entry<string> _backpackKey;

		private static MelonPreferences_Entry<bool> _reduceMovementSpeed;

		internal static bool Enabled => _enabled.Value;

		internal static int AdditionalSlots
		{
			get
			{
				if (_additionalSlots == null)
				{
					return 4;
				}
				int value = _additionalSlots.Value;
				int num = ClampToValidBackpackSize(value);
				if (num != value)
				{
					_additionalSlots.Value = num;
				}
				return num;
			}
		}

		internal static KeyCode BackpackKey
		{
			get
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (_backpackKey == null)
				{
					return (KeyCode)99;
				}
				string value = _backpackKey.Value;
				if (string.IsNullOrEmpty(value))
				{
					return (KeyCode)99;
				}
				if (Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result))
				{
					return result;
				}
				return (KeyCode)99;
			}
		}

		internal static bool ReduceMovementSpeed => _reduceMovementSpeed?.Value ?? true;

		internal static void Initialize()
		{
			if (_category == null)
			{
				_category = MelonPreferences.CreateCategory("InventoryExpansion", "InventoryExpansion");
				_enabled = CreateEntry("Enabled", defaultValue: true, "Enabled", "Enable InventoryExpansion functionality. When disabled, the mod will not modify game behavior.");
				_additionalSlots = CreateEntry("AdditionalSlots", 4, "Additional Inventory Slots", "Number of extra inventory slots to add on top of the game's default inventory size. Valid values: 4, 9, or 16 (for square grids: 2x2, 3x3, or 4x4). Other values will be rounded to the nearest valid option.");
				_backpackKey = CreateEntry("BackpackKey", "C", "Backpack Toggle Key", "Key to toggle backpack visibility. Press to switch between standard inventory and backpack.");
				_reduceMovementSpeed = CreateEntry("ReduceMovementSpeed", defaultValue: true, "Reduce Movement Speed", "When enabled, player movement speed is reduced to 50% while the backpack is fully open.");
			}
		}

		private static MelonPreferences_Entry<T> CreateEntry<T>(string identifier, T defaultValue, string displayName, string description = null)
		{
			if (_category == null)
			{
				throw new InvalidOperationException("Preference category not initialized.");
			}
			return _category.CreateEntry<T>(identifier, defaultValue, displayName, description, false, false, (ValueValidator)null, (string)null);
		}

		private static int ClampToValidBackpackSize(int value)
		{
			if (value <= 0)
			{
				return 4;
			}
			if (value <= 6)
			{
				return 4;
			}
			if (value <= 12)
			{
				return 9;
			}
			return 16;
		}
	}
}