Decompiled source of SmugglersPouch v0.2.4

BepInEx/plugins/SmugglersPouch/SmugglersPouch.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SmugglersPouch;

internal static class Artwork
{
	internal static Sprite EmptyIcon;

	internal static Sprite LoadedIcon;

	internal static bool IsLoaded(ItemData item)
	{
		if (item != null && item.m_customData != null)
		{
			return item.m_customData.ContainsKey("au.tyvalheim.smugglerspouch.contents.v1");
		}
		return false;
	}

	private static Sprite LoadIcon(string path)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		if (!File.Exists(path))
		{
			return null;
		}
		Texture2D val = new Texture2D(2, 2);
		if (!(bool)typeof(ImageConversion).GetMethod("LoadImage", new Type[3]
		{
			typeof(Texture2D),
			typeof(byte[]),
			typeof(bool)
		}).Invoke(null, new object[3]
		{
			val,
			File.ReadAllBytes(path),
			false
		}))
		{
			Object.Destroy((Object)(object)val);
			return null;
		}
		((Texture)val).filterMode = (FilterMode)0;
		return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
	}

	internal static void Apply(GameObject prefab, ItemDrop drop)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		GameObject val = new GameObject("attach");
		val.transform.SetParent(prefab.transform, false);
		if ((int)SystemInfo.graphicsDeviceType == 4)
		{
			return;
		}
		string directoryName = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
		if (!Object.op_Implicit((Object)(object)EmptyIcon))
		{
			EmptyIcon = LoadIcon(Path.Combine(directoryName, "SP_SatchelEmpty-128.png"));
		}
		if (!Object.op_Implicit((Object)(object)LoadedIcon))
		{
			LoadedIcon = LoadIcon(Path.Combine(directoryName, "SP_SatchelLoaded-128.png"));
		}
		if (Object.op_Implicit((Object)(object)EmptyIcon))
		{
			drop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { EmptyIcon };
		}
		string text = Path.Combine(directoryName, "smugglerspouch-art");
		if (!File.Exists(text))
		{
			return;
		}
		AssetBundle val2 = AssetBundle.LoadFromFile(text);
		if (!Object.op_Implicit((Object)(object)val2))
		{
			return;
		}
		try
		{
			GameObject val3 = val2.LoadAsset<GameObject>("assets/collection/sp_satchelempty/sp_satchelempty.prefab");
			GameObject val4 = val2.LoadAsset<GameObject>("assets/collection/sp_satchelloaded/sp_satchelloaded.prefab");
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4))
			{
				return;
			}
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			Material native = null;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val5 in array)
			{
				if (!(val5 is MeshRenderer))
				{
					continue;
				}
				Material[] sharedMaterials = val5.sharedMaterials;
				foreach (Material val6 in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val6) && Object.op_Implicit((Object)(object)val6.shader))
					{
						native = val6;
					}
				}
			}
			GameObject val7 = Attach(val3, val, "SatchelEmpty", native);
			GameObject val8 = Attach(val4, val, "SatchelLoaded", native);
			val7.SetActive(true);
			val8.SetActive(false);
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer val9 in array2)
			{
				val9.enabled = false;
			}
			val.AddComponent<SatchelVisual>();
		}
		finally
		{
			val2.Unload(false);
		}
	}

	private static GameObject Attach(GameObject asset, GameObject prefab, string name, Material native)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(asset, prefab.transform, false);
		((Object)val).name = name;
		if (Object.op_Implicit((Object)(object)native))
		{
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				Material[] sharedMaterials = val2.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Texture mainTexture = sharedMaterials[j].mainTexture;
					Material val3 = new Material(native);
					val3.mainTexture = mainTexture;
					if (val3.HasProperty("_Color"))
					{
						val3.color = Color.white;
					}
					if (val3.HasProperty("_EmissionColor"))
					{
						val3.SetColor("_EmissionColor", Color.black);
					}
					sharedMaterials[j] = val3;
				}
				val2.sharedMaterials = sharedMaterials;
			}
		}
		return val;
	}
}
[HarmonyPatch(typeof(ItemData), "GetIcon")]
internal static class SatchelIcon
{
	private static void Postfix(ItemData __instance, ref Sprite __result)
	{
		if (Storage.IsPouch(__instance))
		{
			Sprite val = (Artwork.IsLoaded(__instance) ? Artwork.LoadedIcon : Artwork.EmptyIcon);
			if (Object.op_Implicit((Object)(object)val))
			{
				__result = val;
			}
		}
	}
}
public sealed class SatchelVisual : MonoBehaviour
{
	private ItemDrop drop;

	private ItemStand stand;

	private ZNetView view;

	private Transform empty;

	private Transform loaded;

	private float nextCheck;

	private uint revision = uint.MaxValue;

	private bool standFull;

	private void OnEnable()
	{
		drop = ((Component)this).GetComponentInParent<ItemDrop>();
		stand = ((Component)this).GetComponentInParent<ItemStand>();
		if (Object.op_Implicit((Object)(object)stand))
		{
			view = (Object.op_Implicit((Object)(object)stand.m_netViewOverride) ? stand.m_netViewOverride : ((Component)stand).GetComponent<ZNetView>());
		}
		empty = ((Component)this).transform.Find("SatchelEmpty");
		loaded = ((Component)this).transform.Find("SatchelLoaded");
		Refresh();
	}

	private void Update()
	{
		if (!(Time.unscaledTime < nextCheck))
		{
			nextCheck = Time.unscaledTime + 0.25f;
			Refresh();
		}
	}

	private void Refresh()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)empty) || !Object.op_Implicit((Object)(object)loaded))
		{
			return;
		}
		bool flag = false;
		if (Object.op_Implicit((Object)(object)drop))
		{
			flag = Artwork.IsLoaded(drop.m_itemData);
		}
		else if (Object.op_Implicit((Object)(object)view) && view.IsValid())
		{
			ZDO zDO = view.GetZDO();
			if (revision != zDO.DataRevision)
			{
				revision = zDO.DataRevision;
				ItemData val = new ItemData();
				ItemDrop.LoadFromZDO(val, zDO, -1);
				standFull = Artwork.IsLoaded(val);
			}
			flag = standFull;
		}
		if (((Component)empty).gameObject.activeSelf == flag)
		{
			((Component)empty).gameObject.SetActive(!flag);
		}
		if (((Component)loaded).gameObject.activeSelf != flag)
		{
			((Component)loaded).gameObject.SetActive(flag);
		}
	}
}
[HarmonyPatch(typeof(ItemStand), "CanAttach")]
internal static class SatchelStandAllowed
{
	private static void Postfix(ItemData __0, ref bool __result)
	{
		if (Storage.IsPouch(__0) && Object.op_Implicit((Object)(object)__0.m_dropPrefab.transform.Find("attach")))
		{
			__result = true;
		}
	}
}
[HarmonyPatch(typeof(ItemStand), "SetVisualItem")]
internal static class SatchelStandOrientation
{
	private static void Postfix(ItemStand __instance, int __0, GameObject ___m_visualItem)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (__0 == StringExtensionMethods.GetStableHashCode("SP_SmugglersPouch") && Object.op_Implicit((Object)(object)___m_visualItem))
		{
			Transform transform = ___m_visualItem.transform;
			transform.position = transform.parent.position;
			transform.rotation = ((Component)__instance).transform.rotation;
		}
	}
}
[HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")]
internal static class CraftLimitMessage
{
	private static readonly FieldInfo RecipeField = AccessTools.Field(typeof(InventoryGui), "m_craftRecipe");

	internal static string Message(InventoryGui gui)
	{
		object? value = RecipeField.GetValue(gui);
		Recipe val = (Recipe)((value is Recipe) ? value : null);
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.m_item) || !Storage.IsPouch(val.m_item.m_itemData) || !Object.op_Implicit((Object)(object)localPlayer) || Storage.Count(((Humanoid)localPlayer).GetInventory()) <= 0)
		{
			return "$inventory_full";
		}
		return "Only one Smuggler's Pouch allowed";
	}

	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		int replaced = 0;
		foreach (CodeInstruction instruction in instructions)
		{
			if (instruction.opcode == OpCodes.Ldstr && (string)instruction.operand == "$inventory_full")
			{
				instruction.opcode = OpCodes.Ldarg_0;
				instruction.operand = null;
				yield return instruction;
				yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CraftLimitMessage), "Message", (Type[])null, (Type[])null));
				replaced++;
			}
			else
			{
				yield return instruction;
			}
		}
		if (replaced != 1)
		{
			throw new InvalidOperationException("Expected one native crafting inventory-full message; found " + replaced);
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "UseItem")]
internal static class OpenPouch
{
	private static bool Prefix(Humanoid __instance, ItemData __1)
	{
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Storage.IsPouch(__1))
		{
			return true;
		}
		if (!InventoryGui.IsVisible())
		{
			return true;
		}
		PouchWindow.Open(__1);
		return false;
	}
}
[HarmonyPatch(typeof(ItemData), "GetWeight")]
internal static class Weight
{
	private static bool reported;

	private static void Postfix(ItemData __instance, ref float __result)
	{
		if (!Storage.IsPouch(__instance))
		{
			return;
		}
		try
		{
			__result = ((!Storage.Read(__instance, out var content)) ? 1000f : ((content == null) ? 0f : content.GetWeight(-1)));
		}
		catch (Exception ex)
		{
			__result = 1000f;
			if (!reported)
			{
				reported = true;
				Plugin.Report("Pouch weight could not be evaluated; contents retained: " + ex);
			}
		}
	}
}
[HarmonyPatch(typeof(Inventory), "IsTeleportable")]
internal static class Portal
{
	private static void Postfix(Inventory __instance, ref bool __result)
	{
		List<ItemData> list = __instance.GetAllItems().Where(Storage.IsPouch).ToList();
		if (list.Count != 0)
		{
			ItemData content;
			bool readable = Storage.Read(list[0], out content);
			__result = __result && Rules.CanTeleport(list.Sum((ItemData i) => i.m_stack), readable, content?.m_stack ?? 0, Plugin.Instance.Capacity.Value);
		}
	}
}
[HarmonyPatch]
internal static class CarryLimit
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		return from m in typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
			where (m.Name == "CanAddItem" || (m.Name == "AddItem" && m.GetParameters().Length == 1)) && m.ReturnType == typeof(bool) && m.GetParameters().Length > 0 && (m.GetParameters()[0].ParameterType == typeof(ItemData) || m.GetParameters()[0].ParameterType == typeof(GameObject))
			select m;
	}

	private static bool Prefix(Inventory __instance, object __0, object[] __args, MethodBase __originalMethod, ref bool __result)
	{
		if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || __instance != ((Humanoid)Player.m_localPlayer).GetInventory())
		{
			return true;
		}
		ItemData val = (ItemData)((__0 is ItemData) ? __0 : null);
		GameObject val2 = (GameObject)((__0 is GameObject) ? __0 : null);
		if (val == null && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.GetComponent<ItemDrop>()))
		{
			val = val2.GetComponent<ItemDrop>().m_itemData;
		}
		if (!Storage.IsPouch(val))
		{
			return true;
		}
		int incoming = ((__args.Length > 1 && __args[1] is int && (int)__args[1] > 0) ? ((int)__args[1]) : val.m_stack);
		if (Rules.CanReceive(Storage.Count(__instance), incoming, __instance.ContainsItem(val)))
		{
			return true;
		}
		if (__originalMethod.Name == "AddItem")
		{
			PouchLimitNotice.Show();
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch]
internal static class CraftLimit
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		return from m in typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
			where m.Name == "AddItem" && m.ReturnType == typeof(ItemData) && m.GetParameters().Length > 0 && m.GetParameters()[0].ParameterType == typeof(string)
			select m;
	}

	private static bool Prefix(Inventory __instance, string __0, int __1, ref ItemData __result)
	{
		if (__0 != "SP_SmugglersPouch" || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || __instance != ((Humanoid)Player.m_localPlayer).GetInventory() || Rules.CanReceive(Storage.Count(__instance), __1, rearranging: false))
		{
			return true;
		}
		__result = null;
		return false;
	}
}
[BepInPlugin("au.tyvalheim.smugglerspouch", "Smuggler's Pouch", "0.2.4")]
public sealed class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	private static class DB
	{
		private static void Prefix(ObjectDB __instance)
		{
			Instance.Register(__instance);
		}

		private static void Postfix()
		{
			Instance.Network(ZNetScene.instance);
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	private static class Copy
	{
		private static void Postfix(ObjectDB __instance)
		{
			Instance.Register(__instance);
			AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(__instance, null);
			Instance.Network(ZNetScene.instance);
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	private static class NetworkInit
	{
		private static void Prefix(ZNetScene __instance)
		{
			if (Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				Instance.Register(ObjectDB.instance);
			}
			if (Object.op_Implicit((Object)(object)Instance.prefab) && !Instance.failed && !__instance.m_prefabs.Contains(Instance.prefab))
			{
				__instance.m_prefabs.Add(Instance.prefab);
			}
		}

		private static void Postfix(ZNetScene __instance)
		{
			Instance.Network(__instance);
		}
	}

	public const string Id = "au.tyvalheim.smugglerspouch";

	public const string Version = "0.2.4";

	public const string PrefabName = "SP_SmugglersPouch";

	internal static Plugin Instance;

	internal ConfigEntry<int> Capacity;

	internal ConfigEntry<float> PanelX;

	internal ConfigEntry<float> PanelY;

	private GameObject root;

	private GameObject prefab;

	private Recipe recipe;

	private bool failed;

	internal static void Report(string message)
	{
		if (Object.op_Implicit((Object)(object)Instance))
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)message);
		}
	}

	private void Awake()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Capacity = ((BaseUnityPlugin)this).Config.Bind<int>("Balance", "Capacity", 5, new ConfigDescription("Item count, one type. Restart required; use the same value on all clients/server. Lowering this never deletes existing contents; over-capacity pouches must be emptied before portals.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), new object[0]));
		PanelX = ((BaseUnityPlugin)this).Config.Bind<float>("Interface", "PanelX", 0f, "Pouch window horizontal position; drag the title to move it.");
		PanelY = ((BaseUnityPlugin)this).Config.Bind<float>("Interface", "PanelY", 0f, "Pouch window vertical position.");
		root = new GameObject("SmugglersPouch_Prefabs");
		root.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)root);
		new Harmony("au.tyvalheim.smugglerspouch").PatchAll();
		((Component)this).gameObject.AddComponent<PouchWindow>();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Smuggler's Pouch 0.2.4 TEST: install on all clients and server. Back up saves before testing.");
	}

	internal void Register(ObjectDB db)
	{
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		Storage.ClearCache();
		if (failed)
		{
			return;
		}
		try
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				GameObject val = ((IEnumerable<GameObject>)db.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == "Resin"));
				CraftingStation val2 = (from x in db.m_recipes
					where Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)x.m_craftingStation)
					select x.m_craftingStation).FirstOrDefault((Func<CraftingStation, bool>)((CraftingStation x) => ((Object)x).name == "piece_workbench"));
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
				{
					return;
				}
				prefab = Object.Instantiate<GameObject>(val, root.transform, false);
				((Object)prefab).name = "SP_SmugglersPouch";
				prefab.SetActive(true);
				ItemDrop component = prefab.GetComponent<ItemDrop>();
				component.m_itemData = val.GetComponent<ItemDrop>().m_itemData.Clone();
				component.m_itemData.m_shared = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(component.m_itemData.m_shared, null);
				SharedData shared = component.m_itemData.m_shared;
				shared.m_name = "Smuggler's Pouch";
				shared.m_description = "A resin-sealed hide pouch that conceals a few portal-restricted items from portals. Right-click in your inventory to open. One pouch per traveller. Empty before uninstalling this mod.";
				shared.m_maxStackSize = 1;
				shared.m_weight = 0f;
				shared.m_teleportable = true;
				shared.m_maxQuality = 1;
				shared.m_value = 0;
				component.m_itemData.m_stack = 1;
				component.m_itemData.m_dropPrefab = prefab;
				try
				{
					Artwork.Apply(prefab, component);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Pouch artwork could not load; keeping native fallback: " + ex.Message));
				}
				recipe = ScriptableObject.CreateInstance<Recipe>();
				((Object)recipe).name = "Recipe_SmugglersPouch";
				recipe.m_item = component;
				recipe.m_amount = 1;
				recipe.m_enabled = true;
				recipe.m_craftingStation = val2;
				recipe.m_minStationLevel = 1;
				recipe.m_resources = (Requirement[])(object)new Requirement[3]
				{
					Requirement(db, "Resin", 10),
					Requirement(db, "DeerHide", 6),
					Requirement(db, "Chain", 2)
				};
			}
			if (!db.m_items.Contains(prefab))
			{
				db.m_items.Add(prefab);
			}
			if (!db.m_recipes.Contains(recipe))
			{
				db.m_recipes.Add(recipe);
			}
		}
		catch (Exception ex2)
		{
			failed = true;
			((BaseUnityPlugin)this).Logger.LogError((object)("Pouch registration failed: " + ex2));
		}
	}

	private static Requirement Requirement(ObjectDB db, string name, int amount)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Requirement val = new Requirement();
		val.m_resItem = db.m_items.First((GameObject x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == name).GetComponent<ItemDrop>();
		val.m_amount = amount;
		val.m_recover = true;
		return val;
	}

	internal void Network(ZNetScene scene)
	{
		if (Object.op_Implicit((Object)(object)scene) && Object.op_Implicit((Object)(object)prefab) && !failed)
		{
			Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene);
			int stableHashCode = StringExtensionMethods.GetStableHashCode("SP_SmugglersPouch");
			if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value != (Object)(object)prefab)
			{
				throw new InvalidOperationException("Smuggler's Pouch prefab collision");
			}
			if (!scene.m_prefabs.Contains(prefab))
			{
				scene.m_prefabs.Add(prefab);
			}
			dictionary[stableHashCode] = prefab;
		}
	}
}
public sealed class PouchWindow : MonoBehaviour
{
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	private static class DropContents
	{
		private static bool Prefix(InventoryGrid __0, Vector2i __2)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Instance))
			{
				return !Instance.DropTo(__0, __2);
			}
			return true;
		}
	}

	internal static PouchWindow Instance;

	private ItemData pouch;

	private RectTransform panel;

	private InventoryElement slot;

	private TMP_Text details;

	private TMP_Text message;

	private TMP_FontAsset font;

	private Image dragIcon;

	private string dragPayload;

	private int suppressClick;

	private bool lifting;

	private static readonly FieldInfo DragItem = AccessTools.Field(typeof(InventoryGui), "m_dragItem");

	private static readonly FieldInfo DragInventory = AccessTools.Field(typeof(InventoryGui), "m_dragInventory");

	private static readonly FieldInfo DragAmount = AccessTools.Field(typeof(InventoryGui), "m_dragAmount");

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

	private static readonly MethodInfo ElementPos = AccessTools.Method(typeof(InventoryGrid), "GetElementPos", (Type[])null, (Type[])null);

	private void Awake()
	{
		Instance = this;
	}

	internal static void Open(ItemData item)
	{
		if (Object.op_Implicit((Object)(object)Instance) && Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.IsVisible() && Storage.Owned(((Humanoid)Player.m_localPlayer).GetInventory(), item))
		{
			ClearNative();
			Instance.CancelLift();
			Instance.pouch = item;
			Instance.Build();
			Instance.Draw();
		}
	}

	private static void ClearNative()
	{
		if (Object.op_Implicit((Object)(object)InventoryGui.instance))
		{
			SetupDrag.Invoke(InventoryGui.instance, new object[3] { null, null, 0 });
		}
	}

	private void Close()
	{
		CancelLift();
		pouch = null;
		if (Object.op_Implicit((Object)(object)panel))
		{
			((Component)panel).gameObject.SetActive(false);
			Object.Destroy((Object)(object)((Component)panel).gameObject);
		}
		panel = null;
	}

	private void OnDestroy()
	{
		Close();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	private void Update()
	{
		//IL_006b: 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)
		if (pouch == null)
		{
			return;
		}
		if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !InventoryGui.IsVisible() || !Storage.Owned(((Humanoid)Player.m_localPlayer).GetInventory(), pouch))
		{
			Close();
		}
		else if (lifting && Object.op_Implicit((Object)(object)dragIcon))
		{
			if (Mouse.current != null)
			{
				((Component)dragIcon).transform.position = Vector2.op_Implicit(((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue());
			}
			if ((Keyboard.current != null && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame) || (Mouse.current != null && Mouse.current.rightButton.wasPressedThisFrame))
			{
				CancelLift();
			}
		}
	}

	private RectTransform Box(string name, Transform parent, float x, float y, float w, float h, Color colour)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[2]
		{
			typeof(RectTransform),
			typeof(Image)
		});
		RectTransform val2 = (RectTransform)val.transform;
		((Transform)val2).SetParent(parent, false);
		Vector2 val3 = (val2.pivot = new Vector2(0f, 1f));
		Vector2 anchorMin = (val2.anchorMax = val3);
		val2.anchorMin = anchorMin;
		val2.anchoredPosition = new Vector2(x, 0f - y);
		val2.sizeDelta = new Vector2(w, h);
		((Graphic)val.GetComponent<Image>()).color = colour;
		return val2;
	}

	private TMP_Text Label(Transform parent, string text, float x, float y, float w, float h, int size)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0048: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: 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_006b: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Label", new Type[1] { typeof(RectTransform) });
		val.SetActive(false);
		RectTransform val2 = (RectTransform)val.transform;
		((Transform)val2).SetParent(parent, false);
		Vector2 val3 = (val2.pivot = new Vector2(0f, 1f));
		Vector2 anchorMin = (val2.anchorMax = val3);
		val2.anchorMin = anchorMin;
		val2.anchoredPosition = new Vector2(x, 0f - y);
		val2.sizeDelta = new Vector2(w, h);
		TextMeshProUGUI val6 = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val6).font = font;
		((TMP_Text)val6).text = text;
		((TMP_Text)val6).fontSize = size;
		((Graphic)val6).color = new Color(0.85f, 0.75f, 0.52f);
		((Graphic)val6).raycastTarget = false;
		((TMP_Text)val6).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val6).textWrappingMode = (TextWrappingModes)1;
		val.SetActive(true);
		return (TMP_Text)(object)val6;
	}

	private void Button(Transform parent, string text, float x, float y, float w, Action action)
	{
		//IL_002f: 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_0069: Expected O, but got Unknown
		RectTransform val = Box(text, parent, x, y, w, 30f, new Color(0.23f, 0.16f, 0.1f, 1f));
		Button val2 = ((Component)val).gameObject.AddComponent<Button>();
		((Selectable)val2).targetGraphic = (Graphic)(object)((Component)val).GetComponent<Image>();
		((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
		{
			action();
		});
		Label((Transform)(object)val, text, 0f, 3f, w, 25f, 16);
	}

	private void Build()
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Expected O, but got Unknown
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Expected O, but got Unknown
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0406: Expected O, but got Unknown
		//IL_0411: Unknown result type (might be due to invalid IL or missing references)
		//IL_0416: Unknown result type (might be due to invalid IL or missing references)
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		//IL_055e: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)panel))
		{
			((Component)panel).gameObject.SetActive(false);
			Object.Destroy((Object)(object)((Component)panel).gameObject);
		}
		InventoryGui instance = InventoryGui.instance;
		font = instance.m_playerName.font;
		panel = Box("Smuggler's Pouch", ((Transform)instance.m_player).parent, 0f, 0f, 280f, 280f, new Color(0.2f, 0.14f, 0.1f, 0.99f));
		RectTransform obj = panel;
		RectTransform obj2 = panel;
		Vector2 val = (panel.pivot = new Vector2(0.5f, 0.5f));
		Vector2 anchorMin = (obj2.anchorMax = val);
		obj.anchorMin = anchorMin;
		panel.anchoredPosition = new Vector2(Plugin.Instance.PanelX.Value, Plugin.Instance.PanelY.Value);
		Image val4 = ((Component)instance.m_player).GetComponent<Image>();
		if (!Object.op_Implicit((Object)(object)val4) || !Object.op_Implicit((Object)(object)val4.sprite))
		{
			val4 = ((IEnumerable<Image>)((Component)instance.m_player).GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image i) => Object.op_Implicit((Object)(object)i.sprite) && (((Object)i).name.Equals("bkg", StringComparison.OrdinalIgnoreCase) || ((Object)i).name.Equals("background", StringComparison.OrdinalIgnoreCase))));
		}
		if (Object.op_Implicit((Object)(object)val4))
		{
			Image component = ((Component)panel).GetComponent<Image>();
			component.sprite = val4.sprite;
			component.type = val4.type;
			((Graphic)component).material = ((Graphic)val4).material;
			((Graphic)component).color = ((Graphic)val4).color;
		}
		((Transform)panel).SetAsLastSibling();
		if (((Transform)panel).parent.lossyScale.x != 0f)
		{
			float num = ((Transform)instance.m_playerGrid.m_gridRoot).lossyScale.x / ((Transform)panel).parent.lossyScale.x;
			((Transform)panel).localScale = Vector3.one * num;
		}
		RectTransform val5 = Box("Move window", (Transform)(object)panel, 0f, 0f, 246f, 35f, Color.clear);
		Label((Transform)(object)val5, "SMUGGLER'S POUCH", 5f, 6f, 235f, 26f, 19);
		PouchTitleDrag pouchTitleDrag = ((Component)val5).gameObject.AddComponent<PouchTitleDrag>();
		pouchTitleDrag.Target = panel;
		Button((Transform)(object)panel, "×", 248f, 2f, 30f, Close);
		GameObject val6 = new GameObject("Slot holder", new Type[1] { typeof(RectTransform) });
		val6.SetActive(false);
		val6.transform.SetParent((Transform)(object)panel, false);
		GameObject val7 = Object.Instantiate<GameObject>(instance.m_playerGrid.m_elementPrefab, val6.transform);
		RectTransform val8 = (RectTransform)val7.transform;
		Vector2 val9 = (val8.pivot = new Vector2(0f, 1f));
		Vector2 anchorMin2 = (val8.anchorMax = val9);
		val8.anchorMin = anchorMin2;
		val8.anchoredPosition = new Vector2(100f, -45f);
		val8.sizeDelta = new Vector2(80f, 80f);
		((Transform)val8).localScale = Vector3.one;
		UIInputHandler[] componentsInChildren = val7.GetComponentsInChildren<UIInputHandler>(true);
		foreach (UIInputHandler val12 in componentsInChildren)
		{
			Object.DestroyImmediate((Object)(object)val12);
		}
		UIDragHandler[] componentsInChildren2 = val7.GetComponentsInChildren<UIDragHandler>(true);
		foreach (UIDragHandler val13 in componentsInChildren2)
		{
			Object.DestroyImmediate((Object)(object)val13);
		}
		UITooltip[] componentsInChildren3 = val7.GetComponentsInChildren<UITooltip>(true);
		foreach (UITooltip val14 in componentsInChildren3)
		{
			Object.DestroyImmediate((Object)(object)val14);
		}
		slot = val7.GetComponent<InventoryElement>();
		slot.Initialize(0, 0);
		slot.m_button.onClick = new ButtonClickedEvent();
		Navigation navigation = ((Selectable)slot.m_button).navigation;
		((Navigation)(ref navigation)).mode = (Mode)0;
		((Selectable)slot.m_button).navigation = navigation;
		Graphic[] componentsInChildren4 = val7.GetComponentsInChildren<Graphic>(true);
		foreach (Graphic val15 in componentsInChildren4)
		{
			val15.raycastTarget = false;
		}
		((Selectable)slot.m_button).targetGraphic.raycastTarget = true;
		Image equiped = slot.m_equiped;
		Image queued = slot.m_queued;
		Image noteleport = slot.m_noteleport;
		Image food = slot.m_food;
		bool flag = (((Behaviour)slot.m_quality).enabled = false);
		bool flag3 = (((Behaviour)food).enabled = flag);
		bool flag5 = (((Behaviour)noteleport).enabled = flag3);
		bool enabled = (((Behaviour)queued).enabled = flag5);
		((Behaviour)equiped).enabled = enabled;
		slot.m_selected.SetActive(false);
		((Component)slot.m_durability).gameObject.SetActive(false);
		Transform val16 = val7.transform.Find("binding");
		if (Object.op_Implicit((Object)(object)val16))
		{
			((Component)val16).gameObject.SetActive(false);
		}
		((Component)slot.m_button).gameObject.AddComponent<PouchSlotInput>().Window = this;
		((Transform)val8).SetParent((Transform)(object)panel, false);
		val8.anchoredPosition = new Vector2(100f, -45f);
		Object.Destroy((Object)(object)val6);
		details = Label((Transform)(object)panel, "", 10f, 132f, 260f, 44f, 16);
		message = Label((Transform)(object)panel, "Drag restricted items in; drag contents to an empty inventory slot. Right-click contents or use Empty pouch.", 10f, 179f, 260f, 60f, 14);
		Button((Transform)(object)panel, "Empty pouch", 60f, 244f, 160f, delegate
		{
			ClearNative();
			CancelLift();
			message.text = Storage.Unpack(((Humanoid)Player.m_localPlayer).GetInventory(), pouch);
			Draw();
		});
		PouchTitleDrag.Clamp(panel);
	}

	private void Draw()
	{
		ItemData content;
		bool flag = Storage.Read(pouch, out content);
		((Behaviour)slot.m_icon).enabled = flag && content != null;
		if (((Behaviour)slot.m_icon).enabled)
		{
			slot.m_icon.sprite = content.GetIcon();
		}
		((Behaviour)slot.m_amount).enabled = flag && content != null;
		if (((Behaviour)slot.m_amount).enabled)
		{
			slot.m_amount.text = content.m_stack.ToString();
		}
		details.text = ((!flag) ? "Unreadable contents — preserved" : ((content == null) ? ("Empty · capacity " + Plugin.Instance.Capacity.Value) : (Localization.instance.Localize(content.m_shared.m_name) + " × " + content.m_stack + " / " + Plugin.Instance.Capacity.Value + "\nWeight " + pouch.GetWeight(-1).ToString("0.0"))));
	}

	internal void Accept()
	{
		if (!pouchOrAlive())
		{
			return;
		}
		InventoryGui instance = InventoryGui.instance;
		object? value = DragItem.GetValue(instance);
		ItemData val = (ItemData)((value is ItemData) ? value : null);
		object? value2 = DragInventory.GetValue(instance);
		Inventory val2 = (Inventory)((value2 is Inventory) ? value2 : null);
		if (val != null)
		{
			if (val2 != ((Humanoid)Player.m_localPlayer).GetInventory())
			{
				message.text = "Move the items to your inventory first.";
				return;
			}
			int requestedAmount = (int)DragAmount.GetValue(instance);
			ClearNative();
			CancelLift();
			message.text = Storage.Pack(val2, pouch, val, requestedAmount);
			Draw();
		}
	}

	private bool pouchOrAlive()
	{
		if (pouch != null && Object.op_Implicit((Object)(object)Player.m_localPlayer))
		{
			return Storage.Owned(((Humanoid)Player.m_localPlayer).GetInventory(), pouch);
		}
		return false;
	}

	internal void Click(PointerEventData e)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		if (Time.frameCount > suppressClick && pouchOrAlive())
		{
			if ((int)e.button == 1)
			{
				ClearNative();
				CancelLift();
				message.text = Storage.Unpack(((Humanoid)Player.m_localPlayer).GetInventory(), pouch);
				Draw();
			}
			else if (DragItem.GetValue(InventoryGui.instance) != null)
			{
				Accept();
			}
			else if (lifting)
			{
				CancelLift();
			}
			else
			{
				BeginLift(e);
			}
		}
	}

	internal void BeginLift(PointerEventData e)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		if ((int)e.button == 0 && pouchOrAlive() && DragItem.GetValue(InventoryGui.instance) == null && Storage.Read(pouch, out var content) && content != null)
		{
			CancelLift();
			lifting = true;
			dragPayload = pouch.m_customData["au.tyvalheim.smugglerspouch.contents.v1"];
			Canvas rootCanvas = ((Component)panel).GetComponentInParent<Canvas>().rootCanvas;
			RectTransform val = Box("Pouch contents preview", ((Component)rootCanvas).transform, 0f, 0f, 64f, 64f, Color.white);
			dragIcon = ((Component)val).GetComponent<Image>();
			dragIcon.sprite = content.GetIcon();
			((Graphic)dragIcon).raycastTarget = false;
			dragIcon.preserveAspect = true;
			((Component)dragIcon).transform.position = Vector2.op_Implicit(e.position);
		}
	}

	internal void EndLift(PointerEventData e)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if (lifting)
		{
			RaycastResult pointerCurrentRaycast = e.pointerCurrentRaycast;
			GameObject gameObject = ((RaycastResult)(ref pointerCurrentRaycast)).gameObject;
			InventoryGrid val = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponentInParent<InventoryGrid>() : null);
			InventoryElement val2 = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponentInParent<InventoryElement>() : null);
			if ((Object)(object)val == (Object)(object)InventoryGui.instance.m_playerGrid && Object.op_Implicit((Object)(object)val2))
			{
				DropTo(val, (Vector2i)ElementPos.Invoke(val, new object[1] { val2 }));
			}
			else
			{
				CancelLift();
			}
			suppressClick = Time.frameCount + 1;
		}
	}

	internal bool DropTo(InventoryGrid grid, Vector2i pos)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		if (!lifting)
		{
			return false;
		}
		string text = dragPayload;
		CancelLift();
		if (pouchOrAlive() && (Object)(object)grid == (Object)(object)InventoryGui.instance.m_playerGrid && pouch.m_customData.ContainsKey("au.tyvalheim.smugglerspouch.contents.v1") && pouch.m_customData["au.tyvalheim.smugglerspouch.contents.v1"] == text)
		{
			message.text = Storage.Unpack(((Humanoid)Player.m_localPlayer).GetInventory(), pouch, pos);
			Draw();
		}
		return true;
	}

	internal void CancelLift()
	{
		lifting = false;
		dragPayload = null;
		if (Object.op_Implicit((Object)(object)dragIcon))
		{
			Object.Destroy((Object)(object)((Component)dragIcon).gameObject);
		}
		dragIcon = null;
	}
}
public sealed class PouchSlotInput : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IEventSystemHandler
{
	internal PouchWindow Window;

	public void OnPointerClick(PointerEventData e)
	{
		Window.Click(e);
	}

	public void OnBeginDrag(PointerEventData e)
	{
		Window.BeginLift(e);
	}

	public void OnDrag(PointerEventData e)
	{
	}

	public void OnEndDrag(PointerEventData e)
	{
		Window.EndLift(e);
	}

	public void OnDrop(PointerEventData e)
	{
		Window.Accept();
	}
}
public sealed class PouchTitleDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IEventSystemHandler
{
	internal RectTransform Target;

	private Vector2 start;

	private Vector2 mouse;

	public void OnBeginDrag(PointerEventData e)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		start = Target.anchoredPosition;
		mouse = e.position;
	}

	public void OnDrag(PointerEventData e)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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)
		Target.anchoredPosition = start + (e.position - mouse) / ((Transform)Target).parent.lossyScale.x;
		Clamp(Target);
	}

	public void OnEndDrag(PointerEventData e)
	{
		//IL_0010: 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)
		Plugin.Instance.PanelX.Value = Target.anchoredPosition.x;
		Plugin.Instance.PanelY.Value = Target.anchoredPosition.y;
	}

	internal static void Clamp(RectTransform t)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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)
		//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		Transform parent = ((Transform)t).parent;
		RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
		if (Object.op_Implicit((Object)(object)val))
		{
			Rect rect = t.rect;
			Vector2 val2 = Vector2.Scale(((Rect)(ref rect)).size, Vector2.op_Implicit(((Transform)t).localScale)) * 0.5f;
			float x = t.anchoredPosition.x;
			Rect rect2 = val.rect;
			float num = (0f - ((Rect)(ref rect2)).width) * 0.5f + val2.x;
			Rect rect3 = val.rect;
			float num2 = Mathf.Clamp(x, num, ((Rect)(ref rect3)).width * 0.5f - val2.x);
			float y = t.anchoredPosition.y;
			Rect rect4 = val.rect;
			float num3 = (0f - ((Rect)(ref rect4)).height) * 0.5f + val2.y;
			Rect rect5 = val.rect;
			t.anchoredPosition = new Vector2(num2, Mathf.Clamp(y, num3, ((Rect)(ref rect5)).height * 0.5f - val2.y));
		}
	}
}
internal static class Rules
{
	internal static bool CanReceive(int carried, int incoming, bool rearranging)
	{
		if (!rearranging)
		{
			if (carried == 0)
			{
				return incoming == 1;
			}
			return false;
		}
		return true;
	}

	internal static bool CanTeleport(int carried, bool readable, int packed, int capacity)
	{
		if (carried != 0)
		{
			if (carried == 1 && readable && packed >= 0)
			{
				return packed <= capacity;
			}
			return false;
		}
		return true;
	}
}
internal static class Storage
{
	internal const string Key = "au.tyvalheim.smugglerspouch.contents.v1";

	private static readonly Dictionary<string, ItemData> decoded = new Dictionary<string, ItemData>();

	internal static readonly HashSet<string> Metals = new HashSet<string>
	{
		"CopperOre", "Copper", "TinOre", "Tin", "Bronze", "IronScrap", "Iron", "SilverOre", "Silver", "BlackMetalScrap",
		"BlackMetal", "FlametalOre", "Flametal", "FlametalOreNew", "FlametalNew", "CopperScrap"
	};

	internal static void ClearCache()
	{
		decoded.Clear();
	}

	internal static bool IsPouch(ItemData i)
	{
		if (i != null && Object.op_Implicit((Object)(object)i.m_dropPrefab))
		{
			return ((Object)i.m_dropPrefab).name == "SP_SmugglersPouch";
		}
		return false;
	}

	internal static string Id(ItemData i)
	{
		if (i == null || !Object.op_Implicit((Object)(object)i.m_dropPrefab))
		{
			return "";
		}
		return ((Object)i.m_dropPrefab).name;
	}

	internal static bool Allowed(ItemData i)
	{
		if (i != null && Object.op_Implicit((Object)(object)i.m_dropPrefab) && i.m_shared != null && !IsPouch(i) && i.m_stack > 0)
		{
			if (!Metals.Contains(Id(i)))
			{
				return !i.m_shared.m_teleportable;
			}
			return true;
		}
		return false;
	}

	internal static int Count(Inventory inv)
	{
		return inv.GetAllItems().Where(IsPouch).Sum((ItemData i) => i.m_stack);
	}

	internal static bool Read(ItemData pouch, out ItemData content)
	{
		content = null;
		if (pouch == null || pouch.m_customData == null)
		{
			return false;
		}
		if (!pouch.m_customData.TryGetValue("au.tyvalheim.smugglerspouch.contents.v1", out var value))
		{
			return true;
		}
		if (string.IsNullOrEmpty(value) || value.Length > 131072)
		{
			return false;
		}
		if (decoded.TryGetValue(value, out var value2))
		{
			content = value2.Clone();
			return true;
		}
		try
		{
			content = StorageCodec.Decode(value);
			if (content == null || content.m_shared == null || !Allowed(content))
			{
				return false;
			}
			if (decoded.Count >= 128)
			{
				decoded.Clear();
			}
			decoded[value] = content.Clone();
			return true;
		}
		catch
		{
			return false;
		}
	}

	private static string Encode(ItemData content)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Expected O, but got Unknown
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		Inventory val = new Inventory("Smuggler", (Sprite)null, 1, 1);
		ItemData val2 = content.Clone();
		val2.m_gridPos = new Vector2i(0, 0);
		val.GetAllItems().Add(val2);
		ZPackage val3 = new ZPackage();
		val.Save(val3);
		return Convert.ToBase64String(val3.GetArray());
	}

	internal static bool Owned(Inventory inv, ItemData pouch)
	{
		if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && inv == ((Humanoid)Player.m_localPlayer).GetInventory() && inv.ContainsItem(pouch) && IsPouch(pouch))
		{
			return !((Character)Player.m_localPlayer).IsDead();
		}
		return false;
	}

	internal static string Pack(Inventory inv, ItemData pouch, ItemData source, int requestedAmount = int.MaxValue)
	{
		if (!Owned(inv, pouch) || Count(inv) != 1)
		{
			return "Carry exactly one pouch to pack items.";
		}
		if (!inv.ContainsItem(source) || !Allowed(source))
		{
			return "Only portal-restricted items and supported metals fit.";
		}
		if (!Read(pouch, out var content))
		{
			return "Contents could not be read. Nothing changed.";
		}
		if (content != null)
		{
			return "Empty the pouch before loading another stack.";
		}
		int num = Math.Min(Math.Min(Plugin.Instance.Capacity.Value, source.m_stack), requestedAmount);
		if (num <= 0)
		{
			return "No items selected.";
		}
		ItemData val = source.Clone();
		val.m_stack = num;
		string value = Encode(val);
		ItemData val2 = pouch.Clone();
		val2.m_customData["au.tyvalheim.smugglerspouch.contents.v1"] = value;
		if (!Read(val2, out var content2) || content2 == null || content2.m_stack != num || Id(content2) != Id(source))
		{
			return "This stack cannot be safely stored. Nothing changed.";
		}
		source.m_stack -= num;
		if (source.m_stack == 0)
		{
			inv.GetAllItems().Remove(source);
		}
		pouch.m_customData["au.tyvalheim.smugglerspouch.contents.v1"] = value;
		pouch.m_cheated |= source.m_cheated;
		Notify(inv);
		return "Packed " + num + " × " + Localization.instance.Localize(source.m_shared.m_name) + ".";
	}

	internal static string Unpack(Inventory inv, ItemData pouch, Vector2i? destination = null)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		if (!Owned(inv, pouch))
		{
			return "Pouch is no longer in your inventory.";
		}
		if (!Read(pouch, out var content))
		{
			return "Contents could not be read. Nothing changed.";
		}
		if (content == null)
		{
			return "The pouch is empty.";
		}
		Vector2i free = (Vector2i)(((??)destination) ?? new Vector2i(-1, -1));
		if (destination.HasValue && (free.x < 0 || free.y < 0 || free.x >= inv.GetWidth() || free.y >= inv.GetHeight() || inv.GetAllItems().Any((ItemData i) => i.m_gridPos.x == free.x && i.m_gridPos.y == free.y)))
		{
			return "Drop onto an empty inventory slot.";
		}
		for (int y = 0; y < inv.GetHeight(); y++)
		{
			if (free.x >= 0)
			{
				break;
			}
			int x;
			for (x = 0; x < inv.GetWidth(); x++)
			{
				if (!inv.GetAllItems().Any((ItemData i) => i.m_gridPos.x == x && i.m_gridPos.y == y))
				{
					ref Vector2i reference = ref free;
					reference = new Vector2i(x, y);
					break;
				}
			}
		}
		if (free.x < 0)
		{
			return "Free one inventory slot before unpacking.";
		}
		content.m_gridPos = free;
		inv.GetAllItems().Add(content);
		pouch.m_customData.Remove("au.tyvalheim.smugglerspouch.contents.v1");
		Notify(inv);
		return "Pouch emptied.";
	}

	internal static void Notify(Inventory inv)
	{
		try
		{
			AccessToolsShim.Changed(inv);
		}
		catch (Exception ex)
		{
			Plugin.Report("Inventory change notification failed after a committed transfer: " + ex);
		}
	}
}
internal static class AccessToolsShim
{
	private static readonly MethodInfo ChangedMethod = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null);

	internal static void Changed(Inventory inv)
	{
		ChangedMethod.Invoke(inv, new object[2] { false, false });
	}
}
internal static class StorageCodec
{
	internal static ItemData Decode(string raw)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		ZPackage val = new ZPackage(Convert.FromBase64String(raw));
		int num = val.ReadInt();
		if (num < 108 || num > 109 || val.ReadUShort() != 1)
		{
			throw new InvalidOperationException("Unsupported pouch contents format.");
		}
		ItemData val2 = new ItemData();
		int num2 = ItemData.Load(val, val2, (Item)num);
		GameObject val3 = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(num2) : null);
		ItemDrop val4 = (Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<ItemDrop>() : null);
		if (!Object.op_Implicit((Object)(object)val4) || val4.m_itemData.m_shared == null || val2.m_stack < 1 || val2.m_stack > val4.m_itemData.m_shared.m_maxStackSize)
		{
			throw new InvalidOperationException("Missing or invalid stored item.");
		}
		val2.m_dropPrefab = val3;
		val2.m_shared = val4.m_itemData.m_shared;
		val2.m_equipped = false;
		return val2;
	}
}
[HarmonyPatch(typeof(Inventory), "MoveAll")]
internal static class PouchTakeAllGuard
{
	private static readonly MethodInfo Add = AccessTools.Method(typeof(Inventory), "AddItem", new Type[5]
	{
		typeof(ItemData),
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(bool)
	}, (Type[])null);

	private static bool Insert(Inventory inventory, ItemData item, int amount, int x, int y, bool flag)
	{
		if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && inventory == ((Humanoid)Player.m_localPlayer).GetInventory() && Storage.IsPouch(item) && !Rules.CanReceive(Storage.Count(inventory), amount, inventory.ContainsItem(item)))
		{
			PouchLimitNotice.Show();
			return false;
		}
		return (bool)Add.Invoke(inventory, new object[5] { item, amount, x, y, flag });
	}

	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		int count = 0;
		foreach (CodeInstruction instruction in instructions)
		{
			if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, Add))
			{
				instruction.opcode = OpCodes.Call;
				instruction.operand = AccessTools.Method(typeof(PouchTakeAllGuard), "Insert", (Type[])null, (Type[])null);
				count++;
			}
			yield return instruction;
		}
		if (count != 1)
		{
			throw new InvalidOperationException("Expected one positional Take All insertion; found " + count);
		}
	}
}
internal static class PouchLimitNotice
{
	internal const string Text = "Only one Smuggler's Pouch allowed";

	private static float nextNotice;

	internal static void Show()
	{
		Player localPlayer = Player.m_localPlayer;
		if (Object.op_Implicit((Object)(object)localPlayer) && !(Time.unscaledTime < nextNotice))
		{
			nextNotice = Time.unscaledTime + 2f;
			((Character)localPlayer).Message((MessageType)2, "Only one Smuggler's Pouch allowed", 0, (Sprite)null, false);
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "Pickup")]
internal static class PouchPickupNotice
{
	private static bool Prefix(Humanoid __instance, GameObject __0, ref bool __result)
	{
		if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)__0))
		{
			return true;
		}
		ItemDrop component = __0.GetComponent<ItemDrop>();
		if (!Object.op_Implicit((Object)(object)component) || !Storage.IsPouch(component.m_itemData))
		{
			return true;
		}
		Inventory inventory = __instance.GetInventory();
		if (Rules.CanReceive(Storage.Count(inventory), component.m_itemData.m_stack, inventory.ContainsItem(component.m_itemData)))
		{
			return true;
		}
		PouchLimitNotice.Show();
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
internal static class PouchSwapGuard
{
	internal static bool CanSwap(Inventory from, Inventory to, ItemData item, int amount, ItemData target)
	{
		if (from == to)
		{
			return true;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer))
		{
			return true;
		}
		Inventory inventory = ((Humanoid)localPlayer).GetInventory();
		if (to == inventory && Storage.IsPouch(item) && !Rules.CanReceive(Storage.Count(to) - ((Storage.IsPouch(target) && amount == item.m_stack) ? target.m_stack : 0), amount, rearranging: false))
		{
			return false;
		}
		if (from == inventory && Storage.IsPouch(target) && amount == item.m_stack && !Rules.CanReceive(Storage.Count(from) - (Storage.IsPouch(item) ? item.m_stack : 0), target.m_stack, rearranging: false))
		{
			return false;
		}
		return true;
	}

	private static bool Prefix(InventoryGrid __instance, Inventory __0, ItemData __1, int __2, Vector2i __3, ref bool __result)
	{
		Inventory inventory = __instance.GetInventory();
		if (CanSwap(__0, inventory, __1, __2, inventory.GetItemAt(__3.x, __3.y)))
		{
			return true;
		}
		PouchLimitNotice.Show();
		__result = false;
		return false;
	}
}
[HarmonyPatch]
internal static class PouchMoveGuard
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		return from m in typeof(Inventory).GetMethods()
			where m.Name == "MoveItemToThis"
			select m;
	}

	private static bool Prefix(Inventory __instance, Inventory __0, ItemData __1)
	{
		bool flag = __instance == __0 || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || __instance != ((Humanoid)Player.m_localPlayer).GetInventory() || !Storage.IsPouch(__1) || Rules.CanReceive(Storage.Count(__instance), __1.m_stack, rearranging: false);
		if (!flag)
		{
			PouchLimitNotice.Show();
		}
		return flag;
	}
}