Decompiled source of Advanced Backpacks v1.0.2

AdvancedBackpacks.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdvancedBackpacks
{
	internal static class Assets
	{
		internal static GameObject Storage;

		internal static readonly List<GameObject> ItemPrefabs = new List<GameObject>();

		internal static readonly List<Object> Owned = new List<Object>();

		internal static void CreateStorage(ZNetScene scene)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			Release();
			Storage = new GameObject("Advanced Backpacks storage");
			Storage.SetActive(false);
			Storage.transform.SetParent(((Component)scene).transform, false);
		}

		internal static void Release()
		{
			if (ItemPrefabs.Count > 0 && (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null)
			{
				ObjectDB.instance.m_items.RemoveAll((GameObject i) => (Object)(object)i == (Object)null || ItemPrefabs.Contains(i));
			}
			ItemPrefabs.Clear();
			foreach (Object item in Owned)
			{
				if (item != (Object)null)
				{
					Object.Destroy(item);
				}
			}
			Owned.Clear();
			if ((Object)(object)Storage != (Object)null)
			{
				Object.Destroy((Object)(object)Storage);
			}
			Storage = null;
		}

		internal static void RegisterScene(ZNetScene scene, GameObject prefab)
		{
			Dictionary<int, GameObject> obj = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene);
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
			if (obj.ContainsKey(stableHashCode))
			{
				throw new InvalidOperationException("Prefab name collision: " + ((Object)prefab).name);
			}
			obj.Add(stableHashCode, prefab);
			scene.m_prefabs.Add(prefab);
		}

		internal static GameObject Need(ZNetScene scene, string name)
		{
			return scene.GetPrefab(name) ?? throw new InvalidOperationException("Prefab missing: " + name);
		}

		internal static void RegisterItems(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_items == null || ItemPrefabs.Count == 0)
			{
				return;
			}
			bool flag = false;
			foreach (GameObject itemPrefab in ItemPrefabs)
			{
				if ((Object)(object)itemPrefab != (Object)null && !db.m_items.Contains(itemPrefab))
				{
					db.m_items.Add(itemPrefab);
					flag = true;
				}
			}
			if (!flag)
			{
				return;
			}
			try
			{
				AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(db, null);
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogError((object)("ObjectDB.UpdateRegisters failed: " + ex));
			}
		}

		internal static Stream Resource(string name)
		{
			return Assembly.GetExecutingAssembly().GetManifestResourceStream("advancedbackpacks." + name) ?? throw new FileNotFoundException("Embedded resource missing: " + name);
		}

		private static byte[] Bytes(string resource)
		{
			using Stream stream = Resource(resource);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		internal static Texture2D LoadTexture(string resource)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
			if (!ImageConversion.LoadImage(val, Bytes(resource)))
			{
				throw new InvalidDataException(resource);
			}
			((Object)val).name = "AB " + resource;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Owned.Add((Object)(object)val);
			return val;
		}

		internal static Sprite LoadIcon(string resource)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, Bytes(resource)))
			{
				throw new InvalidDataException(resource);
			}
			((Object)val).name = "AB " + resource;
			Owned.Add((Object)(object)val);
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			Owned.Add((Object)(object)val2);
			return val2;
		}

		internal static void ReadMeshes(string resource, out Mesh visual, out Mesh collision)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			BinaryReader reader = new BinaryReader(Resource(resource));
			try
			{
				if (Encoding.ASCII.GetString(reader.ReadBytes(8)) != "COAHS100")
				{
					throw new InvalidDataException(resource + ": bad header");
				}
				int num = reader.ReadInt32();
				int arg = reader.ReadInt32();
				int arg2 = reader.ReadInt32();
				int arg3 = reader.ReadInt32();
				Func<int, Vector3[]> func = delegate(int count)
				{
					//IL_002e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: Unknown result type (might be due to invalid IL or missing references)
					Vector3[] array2 = (Vector3[])(object)new Vector3[count];
					for (int i = 0; i < count; i++)
					{
						array2[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
					}
					return array2;
				};
				Func<int, int[]> func2 = delegate(int count)
				{
					int[] array2 = new int[count];
					for (int i = 0; i < count; i++)
					{
						array2[i] = reader.ReadInt32();
					}
					return array2;
				};
				Vector3[] vertices = func(num);
				Vector3[] normals = func(num);
				Vector2[] array = (Vector2[])(object)new Vector2[num];
				for (int num2 = 0; num2 < num; num2++)
				{
					array[num2] = new Vector2(reader.ReadSingle(), reader.ReadSingle());
				}
				visual = new Mesh
				{
					name = "AB " + resource
				};
				if (num > 65000)
				{
					visual.indexFormat = (IndexFormat)1;
				}
				visual.vertices = vertices;
				visual.normals = normals;
				visual.uv = array;
				visual.triangles = func2(arg);
				visual.RecalculateBounds();
				visual.RecalculateTangents();
				collision = new Mesh
				{
					name = "AB " + resource + " collider",
					vertices = func(arg2),
					triangles = func2(arg3)
				};
				collision.RecalculateBounds();
				collision.RecalculateNormals();
				Owned.Add((Object)(object)visual);
				Owned.Add((Object)(object)collision);
			}
			finally
			{
				if (reader != null)
				{
					((IDisposable)reader).Dispose();
				}
			}
		}

		private static void SetTexture(Material m, string name, Texture t)
		{
			if (m.HasProperty(name))
			{
				m.SetTexture(name, t);
			}
		}

		private static void SetFloat(Material m, string name, float v)
		{
			if (m.HasProperty(name))
			{
				m.SetFloat(name, v);
			}
		}

		internal static Material Surface(string colour, string normal, string glow, float glowStrength)
		{
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject prefab = instance.GetPrefab("StoneGolem");
			GameObject val = Need(instance, "JotunWarrior");
			Material val2 = (from r in val.GetComponentsInChildren<SkinnedMeshRenderer>(true)
				where ((Object)r).name == "bodymale"
				select ((Renderer)r).sharedMaterial).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null)) ?? (from r in val.GetComponentsInChildren<SkinnedMeshRenderer>(true)
				select ((Renderer)r).sharedMaterial).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null));
			if ((Object)(object)val2 == (Object)null && (Object)(object)prefab != (Object)null)
			{
				val2 = (from r in prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true)
					select ((Renderer)r).sharedMaterial).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null));
			}
			Material val3 = (((Object)(object)val2 != (Object)null) ? new Material(val2) : new Material(Shader.Find("Standard") ?? Shader.Find("Diffuse")));
			((Object)val3).name = "AB " + colour;
			Owned.Add((Object)(object)val3);
			Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, true);
			if (!ImageConversion.LoadImage(val4, Bytes(colour)))
			{
				throw new InvalidDataException(colour);
			}
			((Object)val4).name = "AB " + colour;
			((Texture)val4).wrapMode = (TextureWrapMode)1;
			((Texture)val4).filterMode = (FilterMode)1;
			((Texture)val4).anisoLevel = 4;
			try
			{
				val4.Compress(false);
				val4.Apply(false, true);
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Texture compression skipped for " + colour + ": " + ex.Message));
			}
			Owned.Add((Object)(object)val4);
			Texture2D val5 = new Texture2D(2, 2, (TextureFormat)4, true, true);
			if (!ImageConversion.LoadImage(val5, Bytes(normal)))
			{
				throw new InvalidDataException(normal);
			}
			((Object)val5).name = "AB " + normal;
			((Texture)val5).wrapMode = (TextureWrapMode)1;
			((Texture)val5).anisoLevel = 4;
			Owned.Add((Object)(object)val5);
			val3.mainTexture = (Texture)(object)val4;
			val3.color = Color.white;
			if (val3.HasProperty("_BumpMap"))
			{
				val3.SetTexture("_BumpMap", (Texture)(object)val5);
				SetFloat(val3, "_BumpScale", 1f);
				val3.EnableKeyword("_NORMALMAP");
			}
			SetTexture(val3, "_MetallicGlossMap", null);
			SetTexture(val3, "_EmissionMap", null);
			val3.DisableKeyword("_METALLICGLOSSMAP");
			val3.DisableKeyword("_EMISSION");
			SetFloat(val3, "_Metallic", 0f);
			SetFloat(val3, "_MetalGloss", 0f);
			SetFloat(val3, "_Glossiness", 0.06f);
			SetFloat(val3, "_GlossMapScale", 0.06f);
			SetFloat(val3, "_UseGlossmap", 0f);
			SetFloat(val3, "_Hue", 0f);
			SetFloat(val3, "_Saturation", 0f);
			SetFloat(val3, "_Value", 0f);
			if (val3.HasProperty("_EmissionColor"))
			{
				val3.SetColor("_EmissionColor", Color.black);
			}
			if (glow != null && val3.HasProperty("_EmissionMap") && val3.HasProperty("_EmissionColor"))
			{
				val3.SetTexture("_EmissionMap", (Texture)(object)LoadTexture(glow));
				val3.SetColor("_EmissionColor", new Color(glowStrength, glowStrength, glowStrength, 1f));
				val3.EnableKeyword("_EMISSION");
			}
			return val3;
		}
	}
	internal static class Backpacks
	{
		internal enum Kind
		{
			Portal,
			Boat,
			Dead
		}

		internal sealed class Slot
		{
			public Kind Kind;

			public string[] Items = new string[0];

			public int[] Caps = new int[0];

			public float Factor = 1f;

			public int CapOf(string prefab)
			{
				for (int i = 0; i < Items.Length; i++)
				{
					if (Items[i] == prefab)
					{
						return Caps[i];
					}
				}
				return 0;
			}
		}

		internal sealed class State
		{
			public ItemData Item;

			public int Level;
		}

		private sealed class Pair
		{
			public int Level;

			public Inventory Rows;

			public Inventory Extras;
		}

		[HarmonyPatch(typeof(Player), "Update")]
		internal static class UpdatePatch
		{
			private static void Postfix(Player __instance)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || Time.unscaledTime < nextCheck)
				{
					return;
				}
				nextCheck = Time.unscaledTime + 0.25f;
				try
				{
					RestoreWorn(__instance);
				}
				catch (Exception ex)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: " + ex));
				}
				try
				{
					Reconcile(__instance);
				}
				catch (Exception ex2)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: " + ex2));
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Save", new Type[] { typeof(ZPackage) })]
		internal static class SavePatch
		{
			private static void Prefix(Player __instance, out ItemData __state)
			{
				__state = null;
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					MarkWorn(__instance);
				}
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && wornItem != null && !busy)
				{
					__state = wornItem;
					Collapse();
				}
			}

			private static void Postfix(Player __instance, ItemData __state)
			{
				if (__state != null)
				{
					Reconcile(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "CreateTombStone")]
		internal static class TombPatch
		{
			[HarmonyPriority(800)]
			private static void Prefix(Player __instance)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && wornItem != null && !busy)
				{
					Collapse();
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetInventorySize")]
		internal static class SizePatch
		{
			[HarmonyPriority(900)]
			private static void Prefix(Player __instance, ref int rows)
			{
				if (!busy && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && wornItem != null)
				{
					rows = Mathf.Max(0, rows - addedRows);
					Collapse();
				}
			}

			private static void Postfix(Player __instance)
			{
				Reconcile(__instance);
			}
		}

		[HarmonyPatch(typeof(Inventory), "UpdateTotalWeight")]
		internal static class RowWeightPatch
		{
			private static void Postfix(Inventory __instance)
			{
				if (wornItem == null || __instance != wornInventory || TotalWeight == null)
				{
					return;
				}
				float num = RowFactor(LevelOf(wornItem));
				if (num >= 1f)
				{
					return;
				}
				float num2 = 0f;
				foreach (ItemData item in (List<ItemData>)InvList.GetValue(__instance))
				{
					if (InLightRow(item) && item != wornItem)
					{
						num2 += item.GetWeight(-1) * (1f - num);
					}
				}
				TotalWeight.SetValue(__instance, Mathf.Max(0f, (float)TotalWeight.GetValue(__instance) - num2));
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		internal static class AddAtPatch
		{
			private static bool Prefix(Inventory __instance, ItemData item, ref int amount, int x, int y, ref bool __result)
			{
				if (InOwnRows(__instance, item, y))
				{
					__result = false;
					return false;
				}
				if (!Mine(__instance, out var state))
				{
					return true;
				}
				int num = Allowed(__instance, state, item, Mathf.Min(amount, item.m_stack), x, y);
				if (num <= 0)
				{
					__result = false;
					return false;
				}
				amount = num;
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(Vector2i)
		})]
		internal static class AddPosPatch
		{
			private static bool Prefix(Inventory __instance, ItemData item, Vector2i pos, ref bool __result)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if (InOwnRows(__instance, item, pos.y))
				{
					__result = false;
					return false;
				}
				if (!Mine(__instance, out var state))
				{
					return true;
				}
				if (Allowed(__instance, state, item, item.m_stack, pos.x, pos.y) < item.m_stack)
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		internal static class AddAnywherePatch
		{
			private static bool Prefix(Inventory __instance, ItemData item, ref bool __result)
			{
				if (!Mine(__instance, out var _))
				{
					return true;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int)
		})]
		internal static class CanAddPatch
		{
			private static void Postfix(Inventory __instance, ref bool __result)
			{
				if (Mine(__instance, out var _))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "FindEmptySlot")]
		internal static class EmptySlotPatch
		{
			private static bool Prefix(Inventory __instance, ref Vector2i __result)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if (!Mine(__instance, out var _))
				{
					return true;
				}
				__result = new Vector2i(-1, -1);
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "FindFreeStackItem")]
		internal static class FreeStackItemPatch
		{
			private static bool Prefix(Inventory __instance, ref ItemData __result)
			{
				if (!Mine(__instance, out var _))
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "FindFreeStackSpace")]
		internal static class FreeStackSpacePatch
		{
			private static bool Prefix(Inventory __instance, ref int __result)
			{
				if (!Mine(__instance, out var _))
				{
					return true;
				}
				__result = 0;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "HaveEmptySlot")]
		internal static class HaveEmptyPatch
		{
			private static bool Prefix(Inventory __instance, ref bool __result)
			{
				if (!Mine(__instance, out var _))
				{
					return true;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetWeight")]
		internal static class WeightPatch
		{
			private static void Postfix(ItemData __instance, ref float __result)
			{
				if (Prefabs.Count != 0 && !((Object)(object)__instance.m_dropPrefab == (Object)null) && LevelOf(__instance) >= 0)
				{
					__result += ContentWeight(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		internal static class EquipPatch
		{
			private static bool Prefix(Humanoid __instance, ItemData item, ref bool __result)
			{
				if (!IsBackpack(item))
				{
					return true;
				}
				Inventory inventory = __instance.GetInventory();
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && wornItem != null && (object)wornPlayer == __instance && item != wornItem && InWindow(item) && inventory.ContainsItem(item))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Take it out of the backpack's rows first", 0, (Sprite)null, false);
					__result = false;
					return false;
				}
				foreach (ItemData item2 in (from i in inventory.GetEquippedItems()
					where i != item && IsBackpack(i)
					select i).ToList())
				{
					__instance.UnequipItem(item2, false);
					if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
					{
						((Character)Player.m_localPlayer).Message((MessageType)1, "One backpack at a time: " + item2.m_shared.m_name + " taken off", 0, (Sprite)null, false);
					}
				}
				return true;
			}

			private static void Postfix(Humanoid __instance, ItemData item)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsBackpack(item) || !item.m_equipped)
				{
					return;
				}
				Reconcile(Player.m_localPlayer);
				if (InventoryGui.IsVisible() && ExtrasOf(item) != null)
				{
					InventoryGui instance = InventoryGui.instance;
					if ((Object)(object)instance != (Object)null && CurrentContainer.GetValue(instance) == null)
					{
						instance.Show(Proxy(Player.m_localPlayer, item), 1);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		internal static class UnequipPatch
		{
			private static void Postfix(Humanoid __instance, ItemData item)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsBackpack(item))
				{
					return;
				}
				Reconcile(Player.m_localPlayer);
				if (InventoryGui.IsVisible())
				{
					InventoryGui instance = InventoryGui.instance;
					if ((Object)(object)instance != (Object)null && IsProxy((Container)/*isinst with value type is only supported in some contexts*/) && Equipped(Player.m_localPlayer) == null && CloseContainer != null)
					{
						CloseContainer.Invoke(instance, null);
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		internal static class CarryPatch
		{
			private static void Prefix(InventoryGui __instance, Player player)
			{
				carried = null;
				Recipe val = (Recipe)((CraftRecipe != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val == (Object)null || (Object)(object)val.m_item == (Object)null || !IsPackPrefab(((Component)val.m_item).gameObject))
				{
					return;
				}
				Requirement[] resources = val.m_resources;
				foreach (Requirement val2 in resources)
				{
					if ((Object)(object)val2.m_resItem == (Object)null || !IsPackPrefab(((Component)val2.m_resItem).gameObject))
					{
						continue;
					}
					foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
					{
						if (!(allItem.m_shared.m_name != val2.m_resItem.m_itemData.m_shared.m_name))
						{
							carried = new Dictionary<string, string>();
							if (allItem.m_customData != null && allItem.m_customData.TryGetValue("adv_bp", out var value))
							{
								carried["adv_bp"] = value;
							}
							if (allItem.m_customData != null && allItem.m_customData.TryGetValue("adv_bpx", out value))
							{
								carried["adv_bpx"] = value;
							}
							return;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		internal static class CarryDonePatch
		{
			private static void Postfix()
			{
				carried = null;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(long),
			typeof(string),
			typeof(Vector2i),
			typeof(bool),
			typeof(bool),
			typeof(bool)
		})]
		internal static class CarryAddPatch
		{
			private static void Postfix(ItemData __result)
			{
				if (carried == null || __result == null || !IsBackpack(__result))
				{
					return;
				}
				if (__result.m_customData == null)
				{
					__result.m_customData = new Dictionary<string, string>();
				}
				foreach (KeyValuePair<string, string> item in carried)
				{
					__result.m_customData[item.Key] = item.Value;
				}
				carried = null;
				pairs.Remove(__result);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show", new Type[]
		{
			typeof(Container),
			typeof(int)
		})]
		internal static class ShowPatch
		{
			private static void Prefix(ref Container container)
			{
				if ((Object)(object)container != (Object)null)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				ItemData val = Equipped(localPlayer);
				if (val == null || ExtrasOf(val) == null)
				{
					return;
				}
				try
				{
					container = Proxy(localPlayer, val);
				}
				catch (Exception ex)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the dock could not be opened (" + ex.Message + ")"));
				}
			}
		}

		[HarmonyPatch(typeof(Container), "IsOwner")]
		internal static class OwnerPatch
		{
			private static bool Prefix(Container __instance, ref bool __result)
			{
				if (!IsProxy(__instance))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "SetInUse")]
		internal static class InUsePatch
		{
			private static bool Prefix(Container __instance)
			{
				return !IsProxy(__instance);
			}
		}

		[HarmonyPatch(typeof(Container), "StackAll")]
		internal static class StackAllPatch
		{
			private static bool Prefix(Container __instance)
			{
				return !IsProxy(__instance);
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		internal static class SwapPatch
		{
			private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, ref bool __result)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = __instance.GetInventory();
				ItemData val = ((inventory != null) ? inventory.GetItemAt(pos.x, pos.y) : null);
				if (val == null || item == null || fromInventory == null || val == item || item.m_stack != amount)
				{
					return true;
				}
				if (!(val.m_shared.m_name != item.m_shared.m_name) && (item.m_shared.m_maxQuality <= 1 || val.m_quality == item.m_quality) && val.m_shared.m_maxStackSize != 1)
				{
					return true;
				}
				if (SwapFits(inventory, item, pos.x, pos.y) && SwapFits(fromInventory, val, item.m_gridPos.x, item.m_gridPos.y))
				{
					return true;
				}
				__result = false;
				return false;
			}

			private static bool SwapFits(Inventory inv, ItemData item, int x, int y)
			{
				if (InOwnRows(inv, item, y))
				{
					return false;
				}
				if (!Mine(inv, out var state))
				{
					return true;
				}
				if (IsBackpack(item))
				{
					return false;
				}
				Slot slot = SlotAt(state.Level, x, y);
				if (slot.Kind != Kind.Dead)
				{
					return slot.CapOf(PrefabOf(item)) >= item.m_stack;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		internal static class CtrlDropPatch
		{
			private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				if ((int)mod != 2 || item == null || (Object)(object)grid != (Object)(object)__instance.m_playerGrid)
				{
					return true;
				}
				object? value = CurrentContainer.GetValue(__instance);
				if (!IsProxy((Container)((value is Container) ? value : null)))
				{
					return true;
				}
				if (DragGo != null && DragGo.GetValue(__instance) != null)
				{
					return true;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || item.m_shared.m_questItem)
				{
					return false;
				}
				if (((Humanoid)localPlayer).DropItem(grid.GetInventory(), item, item.m_stack))
				{
					__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		internal static class DockPatch
		{
			private static void Prefix(InventoryGui __instance)
			{
				Refresh(__instance);
			}

			private static void Postfix(InventoryGui __instance)
			{
				if (!archeryLooked)
				{
					archeryLooked = true;
					Type type = AccessTools.TypeByName("BetterArchery.BetterArchery");
					if (type != null)
					{
						archeryContainerOpen = AccessTools.Field(type, "IsContainerOpen");
					}
					if (archeryContainerOpen != null)
					{
						AdvancedBackpacksPlugin.Log.LogInfo((object)"Advanced Backpacks: Better Archery found - the backpack's row goes above its quiver rows, and the dock keeps its quiver in place.");
					}
				}
				if (archeryContainerOpen == null || !IsProxy((Container)/*isinst with value type is only supported in some contexts*/))
				{
					return;
				}
				try
				{
					archeryContainerOpen.SetValue(null, false);
				}
				catch (Exception ex)
				{
					archeryContainerOpen = null;
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: Better Archery's quiver could not be kept in place (" + ex.Message + ")"));
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Update")]
		internal static class DockOffPatch
		{
			private static void Postfix(InventoryGui __instance)
			{
				Refresh(__instance);
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		internal static class GridPatch
		{
			private static void Postfix(InventoryGrid __instance)
			{
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = __instance.GetInventory();
				if (inventory != null && (Object)(object)InventoryGui.instance != (Object)null && __instance == InventoryGui.instance.m_playerGrid)
				{
					LightMarks(__instance, inventory);
				}
				else
				{
					if (inventory == null || !Mine(inventory, out var state) || !(Elements.GetValue(__instance) is List<InventoryElement> list))
					{
						return;
					}
					int width = inventory.GetWidth();
					for (int i = 0; i < list.Count; i++)
					{
						InventoryElement val = list[i];
						int num = i % width;
						int num2 = i / width;
						Slot slot = SlotAt(state.Level, num, num2);
						bool flag = slot.Kind == Kind.Dead;
						if (((Component)val).gameObject.activeSelf == flag)
						{
							((Component)val).gameObject.SetActive(!flag);
						}
						if (!flag && inventory.GetItemAt(num, num2) == null)
						{
							Sprite val2 = IconOf(slot.Items[(slot.Items.Length != 1) ? ((int)(Time.unscaledTime / 1.4f) % slot.Items.Length) : 0]);
							if (!((Object)(object)val2 == (Object)null))
							{
								((Behaviour)val.m_icon).enabled = true;
								val.m_icon.sprite = val2;
								((Graphic)val.m_icon).color = Burnt;
							}
						}
					}
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<ItemData, bool> <>9__76_0;

			public static Func<ItemData, Vector2i> <>9__76_1;

			public static Func<ItemData, bool> <>9__80_0;

			public static Func<ItemData, bool> <>9__80_1;

			public static Func<Image, bool> <>9__140_2;

			public static Func<Image, float> <>9__140_4;

			public static UnityAction <>9__140_0;

			internal bool <Mirror>b__76_0(ItemData i)
			{
				if (InWindow(i))
				{
					return i != wornItem;
				}
				return false;
			}

			internal Vector2i <Mirror>b__76_1(ItemData i)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return i.m_gridPos;
			}

			internal bool <RestoreWorn>b__80_0(ItemData i)
			{
				if (IsBackpack(i) && i.m_customData != null)
				{
					return i.m_customData.ContainsKey("adv_bpw");
				}
				return false;
			}

			internal bool <RestoreWorn>b__80_1(ItemData i)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				if (i.m_shared.m_itemType == SlotType)
				{
					return !IsBackpack(i);
				}
				return false;
			}

			internal bool <BuildDock>b__140_2(Image i)
			{
				string text = (((Object)i).name + " " + ((Object)i.sprite).name).ToLowerInvariant();
				string[] array = new string[13]
				{
					"darken", "blob", "shadow", "glow", "select", "icon", "scroll", "handle", "bar", "highlight",
					"button", "tab", "weight"
				};
				foreach (string value in array)
				{
					if (text.Contains(value))
					{
						return true;
					}
				}
				return false;
			}

			internal float <BuildDock>b__140_4(Image i)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				Rect rect = ((Graphic)i).rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				rect = ((Graphic)i).rectTransform.rect;
				return width * ((Rect)(ref rect)).height;
			}

			internal void <BuildDock>b__140_0()
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				Hidden = !Hidden;
				GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("sfx_gui_button") : null);
				if ((Object)(object)val != (Object)null && (Object)(object)Utils.GetMainCamera() != (Object)null)
				{
					Object.Instantiate<GameObject>(val, ((Component)Utils.GetMainCamera()).transform.position, Quaternion.identity);
				}
			}
		}

		internal const string RowsKey = "adv_bp";

		internal const string ExtrasKey = "adv_bpx";

		internal const string WornKey = "adv_bpw";

		internal const string ProxyName = "AB_BackpackProxy";

		internal static readonly List<GameObject> Prefabs = new List<GameObject>();

		private static ConfigEntry<float> rowFactor1;

		private static ConfigEntry<float> rowFactor2;

		private static ConfigEntry<float> rowFactor3;

		private static ConfigEntry<float> rowFactor4;

		private static ConfigEntry<float> portalFactor;

		private static ConfigEntry<float> boatFactor;

		private static readonly Slot Dead = new Slot
		{
			Kind = Kind.Dead
		};

		private static readonly string[] PortalItems = new string[3] { "GreydwarfEye", "FineWood", "SurtlingCore" };

		private static readonly string[][] BoatItems = new string[4][]
		{
			new string[2] { "Wood", "FineWood" },
			new string[3] { "LeatherScraps", "DeerHide", "YggdrasilWood" },
			new string[3] { "Resin", "ElderBark", "CeramicPlate" },
			new string[2] { "IronNails", "BronzeNails" }
		};

		private static readonly int[][] BoatCaps = new int[4][]
		{
			new int[2] { 20, 50 },
			new int[3] { 6, 10, 25 },
			new int[3] { 20, 40, 30 },
			new int[2] { 100, 80 }
		};

		private static readonly ConditionalWeakTable<Inventory, State> states = new ConditionalWeakTable<Inventory, State>();

		private static readonly ConditionalWeakTable<ItemData, Pair> pairs = new ConditionalWeakTable<ItemData, Pair>();

		private static readonly ConditionalWeakTable<Inventory, object> hooked = new ConditionalWeakTable<Inventory, object>();

		private static readonly FieldInfo Elements = AccessTools.Field(typeof(InventoryGrid), "m_elements");

		private static readonly FieldInfo ContainerInventory = AccessTools.Field(typeof(Container), "m_inventory");

		private static readonly FieldInfo CurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

		private static readonly FieldInfo InvList = AccessTools.Field(typeof(Inventory), "m_inventory");

		private static readonly FieldInfo TotalWeight = AccessTools.Field(typeof(Inventory), "m_totalWeight");

		private static readonly MethodInfo CloseContainer = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null);

		private static readonly MethodInfo UpdateWeight = AccessTools.Method(typeof(Inventory), "UpdateTotalWeight", (Type[])null, (Type[])null);

		private static readonly MethodInfo InvChanged = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null);

		private static ItemData wornItem;

		private static Player wornPlayer;

		private static Inventory wornInventory;

		private static int startRow;

		private static int addedRows;

		private static int nativeRows;

		private static bool busy;

		private static int tailShift;

		private static float nextCheck;

		private static PropertyInfo extraSlotsHeight;

		private static bool extraSlotsLooked;

		private static float nextWarn;

		private static Player restoreFor;

		private static float restoreUntil;

		private static Dictionary<string, string> carried;

		private static readonly FieldInfo CraftRecipe = AccessTools.Field(typeof(InventoryGui), "m_craftRecipe");

		private static Container proxy;

		private const float Pad = 8f;

		private const float ButtonSize = 50f;

		private const float Gap = 6f;

		private const float DockGap = 22f;

		private static GameObject dock;

		private static GameObject frame;

		private static RectTransform dockRt;

		private static RectTransform frameRt;

		private static RectTransform chestPanel;

		private static Image toggleIcon;

		private static Sprite portalSprite;

		private static CanvasGroup dockGroup;

		private static float dockFade = 1f;

		private static bool parked;

		private static bool logged;

		private static Transform homeParent;

		private static int homeIndex;

		private static Vector2 homeAMin;

		private static Vector2 homeAMax;

		private static Vector2 homePivot;

		private static Vector2 homeSize;

		private static Vector2 homePos;

		private static Vector3 homeScale;

		private static Vector3 chestScale;

		private static readonly FieldInfo DragGo = AccessTools.Field(typeof(InventoryGui), "m_dragGo");

		private static bool archeryLooked;

		private static FieldInfo archeryContainerOpen;

		private static readonly Color Burnt = new Color(0.09f, 0.05f, 0.02f, 0.58f);

		private static readonly Dictionary<string, Sprite> icons = new Dictionary<string, Sprite>();

		private static Sprite lightSprite;

		private static readonly Color LightTint = new Color(0.09f, 0.05f, 0.02f, 0.26f);

		internal static ItemType SlotType => (ItemType)18;

		private static int LightFrom => Math.Max(0, startRow - 1);

		private static int LightTo => startRow + addedRows - 1;

		private static bool Hidden
		{
			get
			{
				try
				{
					return PlayerPrefs.GetInt("AB_BackpackDockHidden", 0) == 1;
				}
				catch
				{
					return false;
				}
			}
			set
			{
				try
				{
					PlayerPrefs.SetInt("AB_BackpackDockHidden", value ? 1 : 0);
					PlayerPrefs.Save();
				}
				catch
				{
				}
			}
		}

		internal static void Init(ConfigFile config)
		{
			rowFactor1 = config.Bind<float>("Backpack", "LastRowWeight1", 0.8f, "Weight of what lies in the lighter rows of the inventory (the last row; the Superior and Masterwork Backpack also lighten the row they add) while the Basic Backpack is worn (1 = full weight, 0.8 = 20% lighter).");
			rowFactor2 = config.Bind<float>("Backpack", "LastRowWeight2", 0.8f, "The same for the Enhanced Backpack.");
			rowFactor3 = config.Bind<float>("Backpack", "LastRowWeight3", 0.8f, "The same for the Superior Backpack.");
			rowFactor4 = config.Bind<float>("Backpack", "LastRowWeight4", 0.75f, "The same for the Masterwork Backpack (25% lighter).");
			portalFactor = config.Bind<float>("Backpack", "PortalSlotWeight", 0.6f, "Weight of what lies in the portal slots (0.6 = 40% lighter).");
			boatFactor = config.Bind<float>("Backpack", "ShipSlotWeight", 0.5f, "Weight of what lies in the ship slots (0.5 = 50% lighter).");
		}

		internal static int Rows(int level)
		{
			return (level >= 2) ? 1 : 0;
		}

		internal static int PortalSets(int level)
		{
			return level switch
			{
				3 => 2, 
				0 => 0, 
				_ => 1, 
			};
		}

		internal static bool HasBoat(int level)
		{
			return level == 3;
		}

		internal static int ExtrasHeight(int level)
		{
			return ((PortalSets(level) > 0) ? 1 : 0) + (HasBoat(level) ? 1 : 0);
		}

		internal static int ExtrasWidth(int level)
		{
			if (!HasBoat(level))
			{
				return 3;
			}
			return 4;
		}

		private static float RowFactor(int level)
		{
			return level switch
			{
				2 => rowFactor3.Value, 
				1 => rowFactor2.Value, 
				0 => rowFactor1.Value, 
				_ => rowFactor4.Value, 
			};
		}

		internal static Slot SlotAt(int level, int x, int y)
		{
			int num = ((PortalSets(level) <= 0) ? (-1) : 0);
			int num2 = (HasBoat(level) ? ((num >= 0) ? 1 : 0) : (-1));
			if (y == num)
			{
				if (x > 2)
				{
					return Dead;
				}
				int num3 = PortalSets(level);
				int[] array = new int[3]
				{
					10 * num3,
					20 * num3,
					2 * num3
				};
				Slot slot = new Slot();
				slot.Kind = Kind.Portal;
				slot.Items = new string[1] { PortalItems[x] };
				slot.Caps = new int[1] { array[x] };
				slot.Factor = portalFactor.Value;
				return slot;
			}
			if (y == num2)
			{
				if (x <= 3)
				{
					return new Slot
					{
						Kind = Kind.Boat,
						Items = BoatItems[x],
						Caps = BoatCaps[x],
						Factor = boatFactor.Value
					};
				}
				return Dead;
			}
			return Dead;
		}

		internal static int LevelOf(ItemData item)
		{
			if (item == null || (Object)(object)item.m_dropPrefab == (Object)null)
			{
				return -1;
			}
			for (int i = 0; i < Prefabs.Count; i++)
			{
				if (Prefabs[i] == item.m_dropPrefab || ((Object)(object)Prefabs[i] != (Object)null && ((Object)Prefabs[i]).name == ((Object)item.m_dropPrefab).name))
				{
					return i;
				}
			}
			return -1;
		}

		internal static bool IsBackpack(ItemData item)
		{
			return LevelOf(item) >= 0;
		}

		private static Inventory MakeRows(ItemData item, int level)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			Inventory val = new Inventory("Backpack", (Sprite)null, 8, Math.Max(1, Rows(level)));
			if (item.m_customData != null && item.m_customData.TryGetValue("adv_bp", out var value) && !string.IsNullOrEmpty(value))
			{
				try
				{
					val.Load(new ZPackage(value));
				}
				catch (Exception ex)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: its rows could not be read (" + ex.Message + ")"));
				}
			}
			return val;
		}

		private static Inventory MakeExtras(ItemData item, int level)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			Inventory inv = new Inventory("Portal and ship", (Sprite)null, ExtrasWidth(level), ExtrasHeight(level));
			states.Add(inv, new State
			{
				Item = item,
				Level = level
			});
			if (item.m_customData != null && item.m_customData.TryGetValue("adv_bpx", out var value) && !string.IsNullOrEmpty(value))
			{
				try
				{
					inv.Load(new ZPackage(value));
				}
				catch (Exception ex)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: its portal and ship slots could not be read (" + ex.Message + ")"));
				}
			}
			inv.m_onChanged = (Action)Delegate.Combine(inv.m_onChanged, (Action)delegate
			{
				ExtrasChanged(item, inv);
			});
			return inv;
		}

		private static Pair PairOf(ItemData item)
		{
			int num = LevelOf(item);
			if (num < 0)
			{
				return null;
			}
			if (pairs.TryGetValue(item, out var value))
			{
				return value;
			}
			value = new Pair
			{
				Level = num
			};
			pairs.Add(item, value);
			value.Rows = MakeRows(item, num);
			value.Extras = ((ExtrasHeight(num) > 0) ? MakeExtras(item, num) : null);
			return value;
		}

		internal static Inventory ExtrasOf(ItemData item)
		{
			return PairOf(item)?.Extras;
		}

		private static void ExtrasChanged(ItemData item, Inventory inv)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			try
			{
				ZPackage val = new ZPackage();
				inv.Save(val);
				if (item.m_customData == null)
				{
					item.m_customData = new Dictionary<string, string>();
				}
				item.m_customData["adv_bpx"] = val.GetBase64();
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && UpdateWeight != null)
				{
					UpdateWeight.Invoke(((Humanoid)localPlayer).GetInventory(), null);
				}
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: contents not saved (" + ex.Message + ")"));
			}
		}

		internal static float ContentWeight(ItemData item)
		{
			Pair pair = PairOf(item);
			if (pair == null)
			{
				return 0f;
			}
			float num = 0f;
			float num2 = RowFactor(pair.Level);
			foreach (ItemData allItem in pair.Rows.GetAllItems())
			{
				num += allItem.GetWeight(-1) * num2;
			}
			if (pair.Extras != null)
			{
				foreach (ItemData allItem2 in pair.Extras.GetAllItems())
				{
					num += allItem2.GetWeight(-1) * SlotAt(pair.Level, allItem2.m_gridPos.x, allItem2.m_gridPos.y).Factor;
				}
			}
			return num;
		}

		internal static ItemData Equipped(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems())
			{
				if (IsBackpack(equippedItem))
				{
					return equippedItem;
				}
			}
			return null;
		}

		private static bool Mine(Inventory inv, out State state)
		{
			return states.TryGetValue(inv, out state);
		}

		private static int NativeRows(Player player)
		{
			string s = default(string);
			if (!player.TryGetUniqueKeyValue("invrows", ref s) || !int.TryParse(s, out var result))
			{
				return 4;
			}
			return Mathf.Clamp(result, 0, 9);
		}

		private static int PlayerRows(Player player)
		{
			if (!extraSlotsLooked)
			{
				extraSlotsLooked = true;
				Type type = AccessTools.TypeByName("ExtraSlots.Slots");
				if (type != null)
				{
					extraSlotsHeight = AccessTools.Property(type, "InventoryHeightPlayer");
				}
			}
			if (extraSlotsHeight != null)
			{
				try
				{
					return (int)extraSlotsHeight.GetValue(null, null);
				}
				catch (Exception ex)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the height of the Extra Slots inventory could not be read (" + ex.Message + ")"));
				}
			}
			return ((Humanoid)player).GetInventory().GetHeight();
		}

		private static bool InWindow(ItemData item)
		{
			if (item.m_gridPos.y >= startRow)
			{
				return item.m_gridPos.y < startRow + addedRows;
			}
			return false;
		}

		private static bool IsLightRow(int y)
		{
			if (wornItem != null && y >= LightFrom)
			{
				return y <= LightTo;
			}
			return false;
		}

		private static bool InLightRow(ItemData item)
		{
			return IsLightRow(item.m_gridPos.y);
		}

		private static void Notify(Inventory inv)
		{
			try
			{
				if (InvChanged != null)
				{
					InvChanged.Invoke(inv, new object[2] { false, false });
				}
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the inventory could not be refreshed (" + ex.Message + ")"));
			}
		}

		private static void Forget()
		{
			wornItem = null;
			wornPlayer = null;
			wornInventory = null;
		}

		private static void Expand(Player player, ItemData item)
		{
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			Pair pair = PairOf(item);
			if (pair == null || (Object)(object)player == (Object)null || (Object)(object)InventoryGui.instance == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			int num = Rows(pair.Level);
			int num2 = 0;
			int num3 = NativeRows(player);
			if (num3 + num > 9)
			{
				if (Time.unscaledTime > nextWarn)
				{
					nextWarn = Time.unscaledTime + 60f;
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the inventory already has " + num3 + " rows, the backpack's rows do not fit under the limit of 9."));
				}
				return;
			}
			busy = true;
			try
			{
				int num4 = PlayerRows(player);
				List<ItemData> list = (List<ItemData>)InvList.GetValue(inventory);
				startRow = ((extraSlotsHeight != null) ? num4 : Mathf.Min(num3, inventory.GetHeight()));
				addedRows = num;
				nativeRows = num3;
				tailShift = ((extraSlotsHeight == null) ? num : 0);
				if (tailShift > 0)
				{
					int num5 = 0;
					foreach (ItemData item2 in list)
					{
						if (item2.m_gridPos.y >= startRow)
						{
							item2.m_gridPos = new Vector2i(item2.m_gridPos.x, item2.m_gridPos.y + tailShift);
							num5++;
						}
					}
					if (inventory.GetHeight() > num3)
					{
						AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks: " + (inventory.GetHeight() - num3) + " row(s) of another mod under the inventory (Better Archery's quiver?) moved down by " + tailShift + " (" + num5 + " stack(s))."));
					}
				}
				player.SetInventorySize(num3 + num);
				List<ItemData> list2 = (List<ItemData>)InvList.GetValue(pair.Rows);
				foreach (ItemData item3 in list2.ToList())
				{
					item3.m_equipped = false;
					if (num == 0)
					{
						if (!inventory.AddItem(item3))
						{
							ItemDrop.DropItem(item3, item3.m_stack, ((Component)player).transform.position + ((Component)player).transform.forward + Vector3.up, ((Component)player).transform.rotation);
						}
						num2++;
					}
					else
					{
						item3.m_gridPos = new Vector2i(item3.m_gridPos.x, Mathf.Clamp(item3.m_gridPos.y, 0, num - 1) + startRow);
						list.Add(item3);
						num2++;
					}
				}
				list2.Clear();
				wornItem = item;
				wornPlayer = player;
				wornInventory = inventory;
				if (!hooked.TryGetValue(inventory, out var _))
				{
					hooked.Add(inventory, null);
					inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(Mirror));
				}
			}
			finally
			{
				busy = false;
			}
			Notify(inventory);
			InventoryGrid val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerGrid : null);
			if ((Object)(object)val != (Object)null)
			{
				LightMarks(val, inventory);
			}
			AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks: " + num + " row(s) added to the inventory (" + num3 + " -> " + (num3 + num) + "), the lighter rows are " + LightFrom + "-" + LightTo + ", " + num2 + " stack(s) put back."));
		}

		private static void Collapse(bool release = false)
		{
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			ItemData item = wornItem;
			if (item == null)
			{
				return;
			}
			Player val = wornPlayer;
			Inventory val2 = wornInventory;
			Pair pair = PairOf(item);
			int num = 0;
			int num2 = 0;
			List<ItemData> list = new List<ItemData>();
			busy = true;
			try
			{
				if (val2 != null && pair != null)
				{
					List<ItemData> list2 = (List<ItemData>)InvList.GetValue(val2);
					List<ItemData> list3 = (List<ItemData>)InvList.GetValue(pair.Rows);
					foreach (ItemData item2 in list2.Where((ItemData i) => InWindow(i) && i != item).ToList())
					{
						if (item2.m_equipped && (Object)(object)val != (Object)null)
						{
							((Humanoid)val).UnequipItem(item2, false);
						}
						item2.m_equipped = false;
						list2.Remove(item2);
						if (release)
						{
							list.Add(item2);
							num++;
						}
						else
						{
							item2.m_gridPos = new Vector2i(item2.m_gridPos.x, item2.m_gridPos.y - startRow);
							list3.Add(item2);
							num++;
						}
					}
					if (InWindow(item))
					{
						for (int num3 = 0; num3 < startRow; num3++)
						{
							for (int num4 = 0; num4 < val2.GetWidth(); num4++)
							{
								if (val2.GetItemAt(num4, num3) == null)
								{
									item.m_gridPos = new Vector2i(num4, num3);
									num3 = startRow;
									break;
								}
							}
						}
					}
					ZPackage val3 = new ZPackage();
					pair.Rows.Save(val3);
					if (item.m_customData == null)
					{
						item.m_customData = new Dictionary<string, string>();
					}
					item.m_customData["adv_bp"] = val3.GetBase64();
				}
				if (val2 != null && tailShift > 0)
				{
					foreach (ItemData item3 in (List<ItemData>)InvList.GetValue(val2))
					{
						if (item3.m_gridPos.y >= startRow + addedRows)
						{
							item3.m_gridPos = new Vector2i(item3.m_gridPos.x, item3.m_gridPos.y - tailShift);
						}
					}
				}
				tailShift = 0;
				if ((Object)(object)val != (Object)null && (Object)(object)InventoryGui.instance != (Object)null)
				{
					val.SetInventorySize(nativeRows);
				}
				foreach (ItemData item4 in list)
				{
					if ((val2 == null || !val2.AddItem(item4)) && (Object)(object)val != (Object)null && item4.m_stack > 0)
					{
						ItemDrop.DropItem(item4, item4.m_stack, ((Component)val).transform.position + ((Component)val).transform.forward + Vector3.up, ((Component)val).transform.rotation);
						num2++;
					}
				}
			}
			finally
			{
				busy = false;
				Forget();
			}
			if (val2 != null)
			{
				Notify(val2);
			}
			AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks: rows " + (release ? ("emptied into the inventory (" + (num - num2) + " stack(s) put in, " + num2 + " dropped)") : ("taken back into the backpack, " + num + " stack(s)")) + "; the inventory has " + nativeRows + " rows again."));
		}

		internal static void Reconcile(Player player)
		{
			if (busy || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (wornItem != null && ((Object)(object)wornPlayer == (Object)null || (Object)(object)wornPlayer != (Object)(object)player))
			{
				Forget();
			}
			ItemData val = Equipped(player);
			if (val == null || val != wornItem)
			{
				if (wornItem != null)
				{
					Collapse(release: true);
				}
				if (val != null)
				{
					Expand(player, val);
				}
			}
		}

		private static void Mirror()
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00fc: Expected O, but got Unknown
			if (busy || wornItem == null || wornInventory == null)
			{
				return;
			}
			try
			{
				List<ItemData> list = ((List<ItemData>)InvList.GetValue(wornInventory)).Where((ItemData i) => InWindow(i) && i != wornItem).ToList();
				List<Vector2i> list2 = list.Select((ItemData i) => i.m_gridPos).ToList();
				Inventory val = new Inventory("copy", (Sprite)null, 8, 9);
				List<ItemData> list3 = (List<ItemData>)InvList.GetValue(val);
				for (int num = 0; num < list.Count; num++)
				{
					list[num].m_gridPos = new Vector2i(list2[num].x, list2[num].y - startRow);
					list3.Add(list[num]);
				}
				ZPackage val2 = new ZPackage();
				try
				{
					val.Save(val2);
				}
				finally
				{
					for (int num2 = 0; num2 < list.Count; num2++)
					{
						list[num2].m_gridPos = list2[num2];
					}
				}
				if (wornItem.m_customData == null)
				{
					wornItem.m_customData = new Dictionary<string, string>();
				}
				wornItem.m_customData["adv_bp"] = val2.GetBase64();
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the rows were not copied (" + ex.Message + ")"));
			}
		}

		private static void MarkWorn(Player player)
		{
			try
			{
				ItemData val = Equipped(player);
				foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
				{
					if (!IsBackpack(allItem))
					{
						continue;
					}
					if (allItem == val)
					{
						if (allItem.m_customData == null)
						{
							allItem.m_customData = new Dictionary<string, string>();
						}
						allItem.m_customData["adv_bpw"] = "1";
					}
					else if (allItem.m_customData != null)
					{
						allItem.m_customData.Remove("adv_bpw");
					}
				}
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the worn backpack was not marked (" + ex.Message + ")"));
			}
		}

		private static void RestoreWorn(Player player)
		{
			if (restoreFor != player)
			{
				restoreFor = player;
				restoreUntil = Time.unscaledTime + 15f;
			}
			if (Time.unscaledTime > restoreUntil)
			{
				return;
			}
			if (Equipped(player) != null)
			{
				restoreUntil = 0f;
			}
			else if (!((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Object)(object)InventoryGui.instance == (Object)null))
			{
				Inventory inventory = ((Humanoid)player).GetInventory();
				ItemData val = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => IsBackpack(i) && i.m_customData != null && i.m_customData.ContainsKey("adv_bpw")));
				if (val == null)
				{
					restoreUntil = 0f;
				}
				else if (inventory.GetEquippedItems().Any((ItemData i) => i.m_shared.m_itemType == SlotType && !IsBackpack(i)))
				{
					restoreUntil = 0f;
				}
				else if (((Humanoid)player).EquipItem(val, false))
				{
					restoreUntil = 0f;
					AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks: " + val.m_shared.m_name + " was worn at the last save and is put back on."));
				}
			}
		}

		private static string PrefabOf(ItemData item)
		{
			if (!((Object)(object)item.m_dropPrefab != (Object)null))
			{
				return "";
			}
			return ((Object)item.m_dropPrefab).name;
		}

		private static int Allowed(Inventory inv, State state, ItemData item, int amount, int x, int y)
		{
			if (IsBackpack(item))
			{
				return 0;
			}
			Slot slot = SlotAt(state.Level, x, y);
			if (slot.Kind == Kind.Dead)
			{
				return 0;
			}
			int num = slot.CapOf(PrefabOf(item));
			if (num <= 0)
			{
				return 0;
			}
			ItemData itemAt = inv.GetItemAt(x, y);
			if (itemAt != null && PrefabOf(itemAt) != PrefabOf(item))
			{
				return 0;
			}
			int num2 = itemAt?.m_stack ?? 0;
			return Mathf.Max(0, Mathf.Min(amount, num - num2));
		}

		private static bool InOwnRows(Inventory inv, ItemData item, int y)
		{
			if (wornItem != null && item == wornItem && inv == wornInventory && y >= startRow)
			{
				return y < startRow + addedRows;
			}
			return false;
		}

		private static bool IsPackPrefab(GameObject prefab)
		{
			if ((Object)(object)prefab != (Object)null)
			{
				return ((Object)prefab).name.StartsWith("AdvancedBackpack", StringComparison.Ordinal);
			}
			return false;
		}

		private static Container Proxy(Player player, ItemData item)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)proxy == (Object)null)
			{
				GameObject val = new GameObject("AB_BackpackProxy");
				val.SetActive(false);
				val.transform.SetParent(((Component)player).transform, false);
				proxy = val.AddComponent<Container>();
			}
			if ((Object)(object)((Component)proxy).transform.parent != (Object)(object)((Component)player).transform)
			{
				((Component)proxy).transform.SetParent(((Component)player).transform, false);
			}
			Inventory val2 = ExtrasOf(item);
			if (val2 != null)
			{
				ContainerInventory.SetValue(proxy, val2);
				proxy.m_name = val2.GetName();
				proxy.m_width = val2.GetWidth();
				proxy.m_height = val2.GetHeight();
			}
			return proxy;
		}

		internal static bool IsProxy(Container container)
		{
			if ((Object)(object)container != (Object)null)
			{
				return ((Object)((Component)container).gameObject).name == "AB_BackpackProxy";
			}
			return false;
		}

		private static void BuildDock(InventoryGui gui)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: 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_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Expected O, but got Unknown
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)gui.m_player).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int layer = ((Component)gui.m_player).gameObject.layer;
			dock = new GameObject("AB_BackpackDock", new Type[1] { typeof(RectTransform) });
			dock.layer = layer;
			dockRt = dock.GetComponent<RectTransform>();
			((Transform)dockRt).SetParent((Transform)(object)val, false);
			RectTransform obj = dockRt;
			RectTransform obj2 = dockRt;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val2;
			obj.anchorMin = val2;
			dockRt.pivot = new Vector2(0f, 1f);
			dockRt.sizeDelta = new Vector2(50f, 50f);
			dock.AddComponent<DockFollower>();
			dockGroup = dock.AddComponent<CanvasGroup>();
			((Transform)dockRt).SetAsLastSibling();
			frame = new GameObject("frame", new Type[1] { typeof(RectTransform) });
			frame.layer = layer;
			frameRt = frame.GetComponent<RectTransform>();
			((Transform)frameRt).SetParent((Transform)(object)dockRt, false);
			RectTransform obj3 = frameRt;
			RectTransform obj4 = frameRt;
			((Vector2)(ref val2))..ctor(0f, 1f);
			obj4.anchorMax = val2;
			obj3.anchorMin = val2;
			frameRt.pivot = new Vector2(0f, 1f);
			frameRt.anchoredPosition = new Vector2(56f, 0f);
			Image val3 = frame.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.1f, 0.07f, 0.04f, 0.92f);
			try
			{
				InventoryGrid grid = gui.ContainerGrid;
				List<Image> source = (from i in ((Component)gui.m_container).GetComponentsInChildren<Image>(true)
					where (Object)(object)i.sprite != (Object)null && ((Object)(object)grid == (Object)null || !((Component)i).transform.IsChildOf(((Component)grid).transform))
					select i).ToList();
				Func<Image, bool> bad = delegate(Image i)
				{
					string text = (((Object)i).name + " " + ((Object)i.sprite).name).ToLowerInvariant();
					string[] array = new string[13]
					{
						"darken", "blob", "shadow", "glow", "select", "icon", "scroll", "handle", "bar", "highlight",
						"button", "tab", "weight"
					};
					foreach (string value in array)
					{
						if (text.Contains(value))
						{
							return true;
						}
					}
					return false;
				};
				Image val4 = source.Where((Image i) => !bad(i) && ((Graphic)i).color.a > 0.3f).OrderByDescending(delegate(Image i)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0019: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					Rect rect = ((Graphic)i).rectTransform.rect;
					float width = ((Rect)(ref rect)).width;
					rect = ((Graphic)i).rectTransform.rect;
					return width * ((Rect)(ref rect)).height;
				}).FirstOrDefault();
				if ((Object)(object)val4 != (Object)null)
				{
					val3.sprite = val4.sprite;
					val3.type = val4.type;
					((Graphic)val3).color = ((Graphic)val4).color;
					val3.pixelsPerUnitMultiplier = val4.pixelsPerUnitMultiplier;
					if ((Object)(object)((Graphic)val4).material != (Object)null)
					{
						((Graphic)val3).material = ((Graphic)val4).material;
					}
				}
				else
				{
					AdvancedBackpacksPlugin.Log.LogInfo((object)"Advanced Backpacks: no panel skin found in the container panel, plain colours for the dock.");
				}
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks: the dock skin was not found (" + ex.Message + ")"));
			}
			if ((Object)(object)portalSprite == (Object)null)
			{
				portalSprite = Assets.LoadIcon("dock_icon.png");
			}
			GameObject val5 = new GameObject("toggle", new Type[1] { typeof(RectTransform) })
			{
				layer = layer
			};
			RectTransform component = val5.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)dockRt, false);
			((Vector2)(ref val2))..ctor(0f, 1f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(50f, 50f);
			toggleIcon = val5.AddComponent<Image>();
			toggleIcon.sprite = portalSprite;
			toggleIcon.preserveAspect = true;
			Button obj5 = val5.AddComponent<Button>();
			((Selectable)obj5).targetGraphic = (Graphic)(object)toggleIcon;
			ColorBlock colors = ((Selectable)obj5).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1.25f, 1.2f, 1.1f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.7f, 0.7f, 0.7f, 1f);
			((Selectable)obj5).colors = colors;
			ButtonClickedEvent onClick = obj5.onClick;
			object obj6 = <>c.<>9__140_0;
			if (obj6 == null)
			{
				UnityAction val6 = delegate
				{
					//IL_004e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0053: Unknown result type (might be due to invalid IL or missing references)
					Hidden = !Hidden;
					GameObject val7 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("sfx_gui_button") : null);
					if ((Object)(object)val7 != (Object)null && (Object)(object)Utils.GetMainCamera() != (Object)null)
					{
						Object.Instantiate<GameObject>(val7, ((Component)Utils.GetMainCamera()).transform.position, Quaternion.identity);
					}
				};
				<>c.<>9__140_0 = val6;
				obj6 = (object)val6;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj6);
			dock.SetActive(false);
		}

		private static void Park(InventoryGui gui, Inventory inv)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			InventoryGrid containerGrid = gui.ContainerGrid;
			if ((Object)(object)containerGrid == (Object)null)
			{
				return;
			}
			RectTransform val = (RectTransform)((Component)containerGrid).transform;
			if (!parked)
			{
				homeParent = ((Transform)val).parent;
				homeIndex = ((Transform)val).GetSiblingIndex();
				homeAMin = val.anchorMin;
				homeAMax = val.anchorMax;
				homePivot = val.pivot;
				homeSize = val.sizeDelta;
				homePos = val.anchoredPosition;
				homeScale = ((Transform)val).localScale;
				chestPanel = gui.m_container;
				chestScale = ((Transform)chestPanel).localScale;
				parked = true;
				if (!logged)
				{
					logged = true;
					AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks dock: inventory panel " + Describe(gui.m_player) + ", its grid " + Describe((RectTransform)((Component)gui.m_playerGrid).transform) + ", the chest panel " + Describe(gui.m_container) + ", the chest grid " + Describe(val) + " (element space " + containerGrid.m_elementSpace + ")."));
				}
			}
			if ((Object)(object)((Transform)val).parent != (Object)(object)frameRt)
			{
				((Transform)val).SetParent((Transform)(object)frameRt, false);
			}
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0f, 1f);
			((Transform)val).localScale = Vector3.one;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor((float)inv.GetWidth() * containerGrid.m_elementSpace, (float)inv.GetHeight() * containerGrid.m_elementSpace);
			val.sizeDelta = val3;
			val.anchoredPosition = new Vector2(8f, -8f);
			frameRt.sizeDelta = val3 + new Vector2(16f, 16f);
			dockRt.sizeDelta = new Vector2(56f + frameRt.sizeDelta.x, Mathf.Max(50f, frameRt.sizeDelta.y));
			((Transform)chestPanel).localScale = Vector3.zero;
		}

		private static void Unpark(InventoryGui gui)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (parked)
			{
				parked = false;
				InventoryGrid containerGrid = gui.ContainerGrid;
				if ((Object)(object)containerGrid != (Object)null && (Object)(object)homeParent != (Object)null)
				{
					RectTransform val = (RectTransform)((Component)containerGrid).transform;
					((Transform)val).SetParent(homeParent, false);
					((Transform)val).SetSiblingIndex(homeIndex);
					val.anchorMin = homeAMin;
					val.anchorMax = homeAMax;
					val.pivot = homePivot;
					val.sizeDelta = homeSize;
					val.anchoredPosition = homePos;
					((Transform)val).localScale = homeScale;
				}
				if ((Object)(object)chestPanel != (Object)null)
				{
					((Transform)chestPanel).localScale = chestScale;
				}
			}
		}

		private static string Describe(RectTransform rt)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			string[] obj = new string[11]
			{
				((Object)rt).name,
				" [anchors ",
				((object)rt.anchorMin/*cast due to .constrained prefix*/).ToString(),
				((object)rt.anchorMax/*cast due to .constrained prefix*/).ToString(),
				" pivot ",
				((object)rt.pivot/*cast due to .constrained prefix*/).ToString(),
				" size ",
				null,
				null,
				null,
				null
			};
			Rect rect = rt.rect;
			obj[7] = ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString();
			obj[8] = " pos ";
			obj[9] = ((object)rt.anchoredPosition/*cast due to .constrained prefix*/).ToString();
			obj[10] = "]";
			return string.Concat(obj);
		}

		internal static void PlaceDock()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)dockRt == (Object)null) && dock.activeSelf)
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				Vector3[] array3 = (Vector3[])(object)new Vector3[4];
				instance.m_player.GetWorldCorners(array);
				((RectTransform)((Component)instance.m_playerGrid).transform).GetWorldCorners(array2);
				float num = array[0].y;
				if ((Object)(object)instance.m_playerGrid.m_gridRoot != (Object)null)
				{
					instance.m_playerGrid.m_gridRoot.GetWorldCorners(array3);
					num = Mathf.Min(num, array3[0].y);
				}
				((Transform)dockRt).position = new Vector3(array2[0].x, num, array[0].z);
				RectTransform obj = dockRt;
				obj.anchoredPosition += new Vector2(0f, -22f);
			}
		}

		private static void Refresh(InventoryGui gui)
		{
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? value = CurrentContainer.GetValue(gui);
				Container val = (Container)((value is Container) ? value : null);
				ItemData val2 = (IsProxy(val) ? Equipped(Player.m_localPlayer) : null);
				Inventory val3 = ((val2 != null) ? ExtrasOf(val2) : null);
				if (val3 == null)
				{
					if ((Object)(object)val != (Object)null && !IsProxy(val))
					{
						Unpark(gui);
						if ((Object)(object)dock != (Object)null && dock.activeSelf)
						{
							dock.SetActive(false);
						}
					}
					else if ((Object)(object)dock != (Object)null && dock.activeSelf)
					{
						dockFade = Mathf.MoveTowards(dockFade, 0f, Time.unscaledDeltaTime / 0.25f);
						dockGroup.alpha = dockFade;
						dockGroup.blocksRaycasts = false;
						if (dockFade <= 0f)
						{
							dock.SetActive(false);
						}
					}
					return;
				}
				if ((Object)(object)dock == (Object)null)
				{
					BuildDock(gui);
				}
				if (!((Object)(object)dock == (Object)null))
				{
					dockFade = 1f;
					dockGroup.alpha = 1f;
					dockGroup.blocksRaycasts = true;
					if (!dock.activeSelf)
					{
						dock.SetActive(true);
					}
					Park(gui, val3);
					bool hidden = Hidden;
					if (frame.activeSelf == hidden)
					{
						frame.SetActive(!hidden);
					}
					((Graphic)toggleIcon).color = (Color)(hidden ? new Color(1f, 1f, 1f, 0.45f) : Color.white);
				}
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks dock: " + ex.Message));
			}
		}

		private static Sprite IconOf(string prefab)
		{
			if (icons.TryGetValue(prefab, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			value = (((Object)(object)val2 != (Object)null && val2.m_itemData.m_shared.m_icons.Length != 0) ? val2.m_itemData.m_shared.m_icons[0] : null);
			icons[prefab] = value;
			return value;
		}

		private static Sprite LightSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)lightSprite != (Object)null)
			{
				return lightSprite;
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
			float[] array = new float[4] { -17f, 17f, 10f, -10f };
			float[] array2 = new float[4] { -16f, -16f, 5f, 5f };
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = ((float)j - 63.5f) / 1.7f;
					float num2 = ((float)i - 63.5f) / 1.7f + 0.75f;
					float num3 = -1E+09f;
					for (int k = 0; k < 4; k++)
					{
						int num4 = (k + 1) % 4;
						float num5 = array[num4] - array[k];
						float num6 = array2[num4] - array2[k];
						float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
						num3 = Mathf.Max(num3, (0f - (num5 * (num2 - array2[k]) - num6 * (num - array[k]))) / num7);
					}
					float num8 = Mathf.Clamp01(0.5f - num3 * 1.7f);
					float num9 = Mathf.Clamp01(0.5f - (Mathf.Abs(Mathf.Sqrt(num * num + (num2 - 9f) * (num2 - 9f)) - 6.75f) - 1.75f) * 1.7f);
					float num10 = Mathf.Abs(num);
					float num11 = Mathf.Clamp01(0.5f - Mathf.Max(num10 - 2.2f, Mathf.Abs(num2 + 2.25f) - 3.75f) * 1.7f);
					float num12 = Mathf.Clamp01(0.5f - Mathf.Max((num10 - 6f * (num2 + 13f) / 7f) * 0.759f, num2 + 6f) * 1.7f);
					val.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Max(num8 * (1f - Mathf.Max(num11, num12)), num9)));
				}
			}
			val.Apply();
			lightSprite = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
			((Object)lightSprite).hideFlags = (HideFlags)61;
			return lightSprite;
		}

		private static void LightMarks(InventoryGrid grid, Inventory inv)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!(Elements.GetValue(grid) is List<InventoryElement> list) || wornItem == null || inv != wornInventory)
			{
				return;
			}
			int width = inv.GetWidth();
			Sprite sprite = LightSprite();
			for (int i = 0; i < list.Count; i++)
			{
				int num = i % width;
				int num2 = i / width;
				if (IsLightRow(num2) && inv.GetItemAt(num, num2) == null)
				{
					Image icon = list[i].m_icon;
					((Behaviour)icon).enabled = true;
					icon.sprite = sprite;
					((Graphic)icon).color = LightTint;
				}
			}
		}
	}
	internal sealed class DockFollower : MonoBehaviour
	{
		private void LateUpdate()
		{
			Backpacks.PlaceDock();
		}
	}
	internal static class Items
	{
		internal const float GroundScale = 2f;

		internal const string PackPrefix = "AdvancedBackpack";

		internal static void Register(ZNetScene scene)
		{
			GameObject storage = Assets.Storage ?? throw new InvalidOperationException("Advanced Backpacks storage missing.");
			string[] array = new string[4] { "Basic Backpack", "Enhanced Backpack", "Superior Backpack", "Masterwork Backpack" };
			string[] array2 = new string[4] { "A leather flap over a sack of dark stone-cloth, a wooden frame and a small stone heart on a strap. Worn like a charm, it makes the last row of your inventory 20% lighter.", "Wider straps, two side pockets and the heart on a leather cross. The last row of your inventory 20% lighter, and a small dock of three slots made for the materials of a portal.", "A bedroll on top, runed stones and a plate on the front; the heart has begun to glow. One added row; it and the row above it are 20% lighter. And the portal slots.", "Iron fittings, thorned branches around a heart with cracks of embers. One added row; it and the row above it are 25% lighter. And slots for the materials of two portals and of a ship." };
			Backpacks.Prefabs.Clear();
			for (int i = 0; i < 4; i++)
			{
				Add(scene, storage, "AdvancedBackpack" + (i + 1), "pack_" + i + ".bin", "pack_" + i + ".jpg", "pack_n.jpg", "item_pack" + i + "_icon.png", array[i], array2[i], (i >= 2) ? ("pack_" + i + "_e.jpg") : null);
			}
			Assets.RegisterItems(ObjectDB.instance);
			Recipes.Build(scene);
			Recipes.Register(ObjectDB.instance);
		}

		private static void Add(ZNetScene scene, GameObject storage, string prefabName, string meshRes, string colour, string normal, string iconRes, string name, string description, string glow)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = Assets.Need(scene, "Ruby");
				GameObject val2 = Object.Instantiate<GameObject>(val, storage.transform, false);
				((Object)val2).name = prefabName;
				for (int num = val2.transform.childCount - 1; num >= 0; num--)
				{
					Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject);
				}
				Renderer[] components = val2.GetComponents<Renderer>();
				for (int i = 0; i < components.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)components[i]);
				}
				MeshFilter[] components2 = val2.GetComponents<MeshFilter>();
				for (int i = 0; i < components2.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)components2[i]);
				}
				Collider[] components3 = val2.GetComponents<Collider>();
				for (int i = 0; i < components3.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)components3[i]);
				}
				LODGroup[] components4 = val2.GetComponents<LODGroup>();
				for (int i = 0; i < components4.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)components4[i]);
				}
				Assets.ReadMeshes(meshRes, out var visual, out var _);
				GameObject val3 = new GameObject("attach");
				val3.transform.SetParent(val2.transform, false);
				val3.AddComponent<MeshFilter>().sharedMesh = visual;
				Material val4 = Assets.Surface(colour, normal, glow, (glow != null) ? 1.5f : 0f);
				string[] array = new string[2] { "_Glossiness", "_MetalGloss" };
				foreach (string text in array)
				{
					if (val4.HasProperty(text))
					{
						val4.SetFloat(text, 0.15f);
					}
				}
				if (val4.HasProperty("_Metallic"))
				{
					val4.SetFloat("_Metallic", 0f);
				}
				((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterial = val4;
				val3.transform.localScale = Vector3.one * 2f;
				BoxCollider obj = val2.AddComponent<BoxCollider>();
				Bounds bounds = visual.bounds;
				obj.center = ((Bounds)(ref bounds)).center * 2f;
				bounds = visual.bounds;
				obj.size = Vector3.Max(((Bounds)(ref bounds)).size * 2f, new Vector3(0.06f, 0.04f, 0.06f));
				ItemDrop component = val2.GetComponent<ItemDrop>();
				ItemDrop component2 = val.GetComponent<ItemDrop>();
				component.m_itemData = component2.m_itemData.Clone();
				SharedData val5 = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(component2.m_itemData.m_shared, null);
				val5.m_name = name;
				val5.m_description = description;
				val5.m_icons = (Sprite[])(object)new Sprite[1] { Assets.LoadIcon(iconRes) };
				val5.m_weight = 1f;
				val5.m_maxStackSize = 1;
				val5.m_value = 0;
				val5.m_itemType = Backpacks.SlotType;
				val5.m_maxQuality = 1;
				val5.m_armor = 0f;
				val5.m_equipDuration = 1f;
				val5.m_teleportable = true;
				component.m_itemData.m_shared = val5;
				component.m_itemData.m_dropPrefab = val2;
				Assets.ItemPrefabs.Add(val2);
				Assets.RegisterScene(scene, val2);
				Backpacks.Prefabs.Add(val2);
			}
			catch (Exception ex)
			{
				AdvancedBackpacksPlugin.Log.LogError((object)("Advanced Backpacks item " + prefabName + " failed: " + ex));
			}
		}
	}
	[BepInPlugin("p0kahontazz.advancedbackpacks", "Advanced Backpacks", "1.0.1")]
	public sealed class AdvancedBackpacksPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class RegisterPatch
		{
			private static void Postfix(ZNetScene __instance)
			{
				try
				{
					Assets.CreateStorage(__instance);
					Items.Register(__instance);
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Advanced Backpacks registration failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
		private static class UnregisterPatch
		{
			private static void Prefix()
			{
				Recipes.Forget();
				Assets.Release();
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDbAwakePatch
		{
			private static void Postfix(ObjectDB __instance)
			{
				Assets.RegisterItems(__instance);
				Recipes.Register(__instance);
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		private static class ObjectDbCopyPatch
		{
			private static void Postfix(ObjectDB __instance)
			{
				Assets.RegisterItems(__instance);
				Recipes.Register(__instance);
			}
		}

		public const string Id = "p0kahontazz.advancedbackpacks";

		public const string Version = "1.0.1";

		internal static ManualLogSource Log;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("p0kahontazz.advancedbackpacks");
			Backpacks.Init(((BaseUnityPlugin)this).Config);
			List<Type> list = (from t in typeof(Backpacks).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)
				where t.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0
				select t).ToList();
			list.AddRange(new Type[6]
			{
				typeof(Recipes.UnlockPatch),
				typeof(Recipes.ListPatch),
				typeof(RegisterPatch),
				typeof(UnregisterPatch),
				typeof(ObjectDbAwakePatch),
				typeof(ObjectDbCopyPatch)
			});
			foreach (Type item in list)
			{
				try
				{
					harmony.CreateClassProcessor(item).Patch();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Patch " + item.Name + " failed: " + ex));
				}
			}
			Log.LogInfo((object)("Advanced Backpacks 1.0.1 loaded (" + list.Count + " patches)."));
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	internal static class Recipes
	{
		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Recipe),
			typeof(bool),
			typeof(int),
			typeof(int)
		})]
		internal static class UnlockPatch
		{
			private static void Postfix(Player __instance, Recipe recipe, bool discover, ref bool __result)
			{
				if (discover && !((Object)(object)recipe == (Object)null) && ours.Contains(recipe))
				{
					__result = TierKnown(__instance, recipe);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "GetAvailableRecipes")]
		internal static class ListPatch
		{
			private static void Postfix(Player __instance, ref List<Recipe> available)
			{
				if (available != null && ours.Count != 0)
				{
					available.RemoveAll((Recipe r) => ours.Contains(r) && !TierKnown(__instance, r));
				}
			}
		}

		private const int Scraps = 20;

		private const int Hide = 10;

		private static readonly List<Recipe> all = new List<Recipe>();

		private static readonly HashSet<Recipe> ours = new HashSet<Recipe>();

		private static readonly MethodInfo KnowLevel = AccessTools.Method(typeof(Player), "KnowStationLevel", (Type[])null, (Type[])null);

		private static Tuple<string, int> Need(string prefab, int amount)
		{
			return Tuple.Create(prefab, amount);
		}

		private static void Make(ZNetScene scene, CraftingStation station, string result, int level, params Tuple<string, int>[] needs)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			GameObject prefab = scene.GetPrefab(result);
			ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val == (Object)null)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks recipe: " + result + " does not exist, its recipe is left out."));
				return;
			}
			List<Requirement> list = new List<Requirement>();
			foreach (Tuple<string, int> tuple in needs)
			{
				GameObject prefab2 = scene.GetPrefab(tuple.Item1);
				ItemDrop val2 = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					AdvancedBackpacksPlugin.Log.LogWarning((object)("Advanced Backpacks recipe " + result + ": " + tuple.Item1 + " does not exist, the recipe is left out."));
					return;
				}
				list.Add(new Requirement
				{
					m_resItem = val2,
					m_amount = tuple.Item2,
					m_recover = false
				});
			}
			Recipe val3 = ScriptableObject.CreateInstance<Recipe>();
			((Object)val3).name = "Recipe_" + result;
			val3.m_item = val;
			val3.m_amount = 1;
			val3.m_enabled = true;
			val3.m_craftingStation = station;
			val3.m_minStationLevel = level;
			val3.m_resources = list.ToArray();
			Assets.Owned.Add((Object)(object)val3);
			all.Add(val3);
			ours.Add(val3);
		}

		internal static void Build(ZNetScene scene)
		{
			all.Clear();
			ours.Clear();
			GameObject prefab = scene.GetPrefab("piece_workbench");
			CraftingStation val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null);
			if ((Object)(object)val == (Object)null)
			{
				AdvancedBackpacksPlugin.Log.LogWarning((object)"Advanced Backpacks: the workbench was not found, no recipes.");
				return;
			}
			string text = "AdvancedBackpack1";
			string text2 = "AdvancedBackpack2";
			string text3 = "AdvancedBackpack3";
			string result = "AdvancedBackpack4";
			Make(scene, val, text, 3, Need("LeatherScraps", 20), Need("DeerHide", 10), Need("Thistle", 20));
			Make(scene, val, text2, 4, Need(text, 1), Need("LeatherScraps", 20), Need("DeerHide", 10), Need("Dandelion", 20));
			Make(scene, val, text3, 4, Need(text2, 1), Need("LeatherScraps", 20), Need("DeerHide", 10), Need("Guck", 15));
			Make(scene, val, result, 5, Need(text3, 1), Need("LeatherScraps", 20), Need("DeerHide", 10), Need("Obsidian", 40));
			AdvancedBackpacksPlugin.Log.LogInfo((object)("Advanced Backpacks: " + all.Count + " workbench recipes built."));
		}

		internal static void Register(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_recipes == null || all.Count == 0)
			{
				return;
			}
			foreach (Recipe item in all)
			{
				if ((Object)(object)item != (Object)null && !db.m_recipes.Contains(item))
				{
					db.m_recipes.Add(item);
				}
			}
		}

		internal static void Forget()
		{
			if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_recipes != null)
			{
				ObjectDB.instance.m_recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || ours.Contains(r));
			}
			all.Clear();
			ours.Clear();
		}

		private static bool TierKnown(Player player, Recipe recipe)
		{
			if ((Object)(object)recipe.m_craftingStation == (Object)null || KnowLevel == null)
			{
				return true;
			}
			return (bool)KnowLevel.Invoke(player, new object[2]
			{
				recipe.m_craftingStation.m_name,
				recipe.m_minStationLevel
			});
		}
	}
}