using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Valheim Overhaul")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("EpicLoot enchanting pouch with JamesJones progression, magic-blue world glow, no AzuEPI slot.")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("EnchantingPouch")] [assembly: AssemblyTitle("EnchantingPouch")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnchantingPouch { internal static class MatFilter { private static readonly HashSet Exact = new HashSet(StringComparer.OrdinalIgnoreCase) { "ForestToken", "IronBountyToken", "GoldBountyToken", "EtchedRunestoneMagic", "EtchedRunestoneRare", "EtchedRunestoneEpic", "EtchedRunestoneLegendary", "EtchedRunestoneMythic" }; internal static bool IsEnchantingMat(ItemData item) { if (item == null) { return false; } string text = null; if ((Object)(object)item.m_dropPrefab != (Object)null) { text = Utils.GetPrefabName(item.m_dropPrefab); } if (string.IsNullOrEmpty(text) && item.m_shared != null) { text = item.m_shared.m_name; } return IsEnchantingMatName(text); } internal static bool IsEnchantingMatName(string prefabOrToken) { if (string.IsNullOrEmpty(prefabOrToken)) { return false; } string text = prefabOrToken; if (text.StartsWith("$item_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(6); } if (Exact.Contains(text)) { return true; } if (text.StartsWith("Dust", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Essence", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Reagent", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Shard", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Runestone", StringComparison.OrdinalIgnoreCase) || text.StartsWith("EtchedRunestone", StringComparison.OrdinalIgnoreCase)) { return true; } if (text.IndexOf("_Unidentified", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return false; } } [HarmonyPatch(typeof(Humanoid), "UseItem")] internal static class Humanoid_UseItem_Patch { private static bool Prefix(Humanoid __instance, ItemData item) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!PouchItem.IsPouch(item)) { return true; } PouchItem.ToggleEquip(val, item); return false; } } [HarmonyPatch(typeof(InventoryGui), "Update")] internal static class InventoryGui_Update_OpenPouch_Patch { internal static bool SuppressHideOnce; internal static int BlockShowFrames; private static void Prefix(InventoryGui __instance) { if (!Plugin.OpenWithE.Value || (Object)(object)__instance == (Object)null || !InventoryGui.IsVisible() || (Object)(object)__instance.m_dragGo != (Object)null || (!ZInput.GetButtonDown("Use") && !ZInput.GetButtonDown("JoyUse"))) { return; } ItemData val = GetHoveredItem(__instance.m_playerGrid) ?? GetHoveredItem(__instance.m_containerGrid); if (val != null && PouchItem.IsPouch(val)) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ZInput.ResetButtonStatus("Use"); ZInput.ResetButtonStatus("JoyUse"); SuppressHideOnce = true; PouchContainer.Toggle(localPlayer, val); } } } private static void Postfix() { SuppressHideOnce = false; if (BlockShowFrames > 0) { BlockShowFrames--; } } private static ItemData GetHoveredItem(InventoryGrid grid) { //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_0022: 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_009e: Unknown result type (might be due to invalid IL or missing references) if (grid?.m_elements == null || grid.m_inventory == null) { return null; } Vector2 val = Vector2.op_Implicit(ZInput.mousePosition); foreach (Element element in grid.m_elements) { if ((Object)(object)element?.m_go == (Object)null || !element.m_go.activeInHierarchy) { continue; } Transform transform = element.m_go.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val2 != null) { Canvas componentInParent = element.m_go.GetComponentInParent(); Camera val3 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null); if (RectTransformUtility.RectangleContainsScreenPoint(val2, val, val3)) { return grid.m_inventory.GetItemAt(element.m_pos.x, element.m_pos.y); } } } return null; } } [HarmonyPatch(typeof(Container), "IsOwner")] internal static class Container_IsOwner_Patch { private static void Postfix(Container __instance, ref bool __result) { if (!__result && PouchContainer.IsOurContainer(__instance)) { __result = true; } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide_Patch { private static bool Prefix() { bool flag = ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("Inventory") || ZInput.GetButtonDown("JoyButtonB") || ZInput.GetButtonDown("JoyButtonY"); if (InventoryGui_Update_OpenPouch_Patch.SuppressHideOnce) { InventoryGui_Update_OpenPouch_Patch.SuppressHideOnce = false; if (!flag) { return false; } } if (PouchContainer.IsOpen || PouchContainer.BoundItem != null) { PouchContainer.Close(save: true); } PouchCloseButton.SetVisible(visible: false); InventoryGui_Update_OpenPouch_Patch.BlockShowFrames = 5; return true; } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class InventoryGui_Show_Patch { private static bool Prefix(InventoryGui __instance, Container container) { if (PouchContainer.OpeningGuarded) { return true; } if (InventoryGui_Update_OpenPouch_Patch.BlockShowFrames <= 0) { return true; } if (InventoryGui.IsVisible()) { return true; } return false; } } [HarmonyPatch(typeof(InventoryGui), "CloseContainer")] internal static class InventoryGui_CloseContainer_Patch { private static void Prefix(InventoryGui __instance) { if (PouchContainer.IsBoundContainer(((Object)(object)__instance != (Object)null) ? __instance.m_currentContainer : null)) { PouchContainer.OnContainerClosing(); } } } [HarmonyPatch(typeof(Player), "GetAvailableRecipes")] internal static class Player_GetAvailableRecipes_Patch { private static void Postfix(Player __instance, ref List available) { PouchItem.EnsureAvailable(__instance, available); } } [HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")] internal static class Player_UpdateKnownRecipesList_Patch { private static void Postfix(Player __instance) { PouchItem.UnlockKnownRecipe(__instance); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class Player_OnSpawned_Patch { private static void Postfix(Player __instance) { PouchItem.UnlockKnownRecipe(__instance); if ((Object)(object)ObjectDB.instance != (Object)null) { PouchItem.TryRegister(ObjectDB.instance); } PouchItem.FixDropPrefabs(((Humanoid)__instance).GetInventory()); } } internal static class WorldPickupGuard { [ThreadStatic] private static int _depth; internal static bool IsWorldPickup => _depth > 0; internal static void Enter() { _depth++; } internal static void Exit() { if (_depth > 0) { _depth--; } } } [HarmonyPatch(typeof(ItemDrop), "Pickup")] internal static class ItemDrop_Pickup_Patch { private static void Prefix() { WorldPickupGuard.Enter(); } private static void Finally() { WorldPickupGuard.Exit(); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] internal static class Inventory_AddItem_Patch { [ThreadStatic] private static bool _busy; private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { if (_busy || !Plugin.AutoDeposit.Value || !WorldPickupGuard.IsWorldPickup || item == null || !MatFilter.IsEnchantingMat(item)) { return true; } if (PouchContainer.IsOpen && PouchContainer.GetInventory() == __instance) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory()) { return true; } ItemData val = PouchItem.FindEquipped(localPlayer); if (val == null) { return true; } return TryDeposit(localPlayer, val, item, ref __result); } private static bool TryDeposit(Player player, ItemData pouch, ItemData item, ref bool __result) { Inventory val = ((PouchContainer.IsOpen && PouchContainer.BoundItem == pouch) ? PouchContainer.GetInventory() : null); _busy = true; try { if (val != null) { if (!val.CanAddItem(item, -1)) { return true; } val.AddItem(item); __result = true; return false; } Inventory val2 = PouchContainer.PeekInventory(pouch); if (!val2.CanAddItem(item, -1)) { return true; } val2.AddItem(item); PouchContainer.CommitPeek(pouch, val2); __result = true; return false; } finally { _busy = false; } } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(string), typeof(int), typeof(int), typeof(int), typeof(long), typeof(string), typeof(bool) })] internal static class Inventory_AddItem_Prefab_Patch { [ThreadStatic] private static bool _busy; private static bool Prefix(Inventory __instance, string name, int stack, int quality, int variant, long crafterID, string crafterName, ref ItemData __result) { if (_busy || !Plugin.AutoDeposit.Value || !WorldPickupGuard.IsWorldPickup || !MatFilter.IsEnchantingMatName(name)) { return true; } if (PouchContainer.IsOpen && PouchContainer.GetInventory() == __instance) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory()) { return true; } ItemData val = PouchItem.FindEquipped(localPlayer); if (val == null) { return true; } GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(name) : null); if ((Object)(object)val2 == (Object)null) { return true; } ItemData val3 = val2.GetComponent().m_itemData.Clone(); val3.m_stack = stack; val3.m_quality = quality; val3.m_variant = variant; val3.m_crafterID = crafterID; val3.m_crafterName = crafterName; val3.m_dropPrefab = val2; Inventory val4 = ((PouchContainer.IsOpen && PouchContainer.BoundItem == val) ? PouchContainer.GetInventory() : null); _busy = true; try { if (val4 != null) { if (!val4.CanAddItem(val3, -1)) { return true; } val4.AddItem(val3); __result = val3; return false; } Inventory val5 = PouchContainer.PeekInventory(val); if (!val5.CanAddItem(val3, -1)) { return true; } val5.AddItem(val3); PouchContainer.CommitPeek(val, val5); __result = val3; return false; } finally { _busy = false; } } } [BepInPlugin("valheimoverhaul.enchantingpouch", "Enchanting Pouch", "1.2.11")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "valheimoverhaul.enchantingpouch"; public const string PluginName = "Enchanting Pouch"; public const string PluginVersion = "1.2.11"; internal const string PrefabName = "VO_EnchantingPouch"; internal const string ItemToken = "$item_vo_enchantingpouch"; internal const string DescToken = "$item_vo_enchantingpouch_desc"; internal const string CustomDataKey = "valheimoverhaul.enchantingpouch.inv"; internal const string WeightCacheKey = "valheimoverhaul.enchantingpouch.weight"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry Columns; internal static ConfigEntry Rows; internal static ConfigEntry AutoDeposit; internal static ConfigEntry OpenWithE; internal static ConfigEntry OpenOnInventory; private void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Columns = ((BaseUnityPlugin)this).Config.Bind("Storage", "Columns", 2, new ConfigDescription("Fallback columns if quality size fails (normal size comes from upgrade level).", (AcceptableValueBase)(object)new AcceptableValueRange(2, 8), Array.Empty())); Rows = ((BaseUnityPlugin)this).Config.Bind("Storage", "Rows", 4, new ConfigDescription("Fallback rows if quality size fails (normal size comes from upgrade level).", (AcceptableValueBase)(object)new AcceptableValueRange(2, 8), Array.Empty())); AutoDeposit = ((BaseUnityPlugin)this).Config.Bind("Storage", "Auto Deposit", true, "While the pouch is equipped, auto-store EpicLoot mats picked up from the ground only."); OpenWithE = ((BaseUnityPlugin)this).Config.Bind("Controls", "Open With E", true, "Press E (Use) while hovering the pouch in the inventory to open it. Vanilla E closes inventory; this intercepts that when the pouch is under the cursor."); OpenOnInventory = ((BaseUnityPlugin)this).Config.Bind("Controls", "Open With Inventory", false, "Unused/legacy. Opening is via E hover; right-click equips."); Harmony val = new Harmony("valheimoverhaul.enchantingpouch"); Type[] types = typeof(Plugin).Assembly.GetTypes(); foreach (Type type in types) { try { val.CreateClassProcessor(type).Patch(); } catch (Exception ex) { Log.LogError((object)("Failed to patch " + type.Name + ": " + ex.Message)); } } Log.LogInfo((object)"Enchanting Pouch 1.2.11 loaded."); } } internal static class PouchCloseButton { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnClicked; } private static GameObject _root; private static Button _button; internal static void Ensure(InventoryGui gui) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown if (!((Object)(object)gui?.m_container == (Object)null) && !((Object)(object)gui.m_tabUpgrade == (Object)null) && (!((Object)(object)_root != (Object)null) || ((object)_root).Equals((object?)null))) { _root = Object.Instantiate(((Component)gui.m_tabUpgrade).gameObject, (Transform)(object)gui.m_container, false); ((Object)_root).name = "VO_PouchCloseX"; RectTransform component = _root.GetComponent(); if ((Object)(object)component != (Object)null) { component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(-6f, -6f); component.sizeDelta = new Vector2(36f, 36f); ((Transform)component).localScale = Vector3.one; ((Transform)component).SetAsLastSibling(); } TMP_Text[] componentsInChildren = _root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = "X"; } Text[] componentsInChildren2 = _root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].text = "X"; } _button = _root.GetComponent