Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SmugglersPouch v0.2.4
BepInEx/plugins/SmugglersPouch/SmugglersPouch.dll
Decompiled 2 days agousing 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; } }