using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RunicDisplayStands")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RunicDisplayStands")] [assembly: AssemblyTitle("RunicDisplayStands")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RunicDisplayStands { public class ContainerBridge : MonoBehaviour { private static ContainerBridge _opened; private static StandVirtualContainer _virtualContainer; private static readonly FieldInfo ContainerInventoryField = AccessTools.Field(typeof(Container), "m_inventory"); private static readonly MethodInfo InventoryChangedMethod = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null); private Inventory _inventory; private ItemStand _itemStand; private ArmorStand _armorStand; private bool _refreshing; internal static ContainerBridge Opened => _opened; public static ContainerBridge GetOrCreate(GameObject go) { ContainerBridge component = go.GetComponent(); if ((Object)(object)component != (Object)null) { return component; } component = go.AddComponent(); component.Initialize(); return component; } private void Initialize() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown _itemStand = ((Component)this).GetComponent(); _armorStand = ((Component)this).GetComponent(); int num = ((!((Object)(object)_armorStand != (Object)null)) ? 1 : ArmorStandAdapter.GetSlotCount(_armorStand)); string text = (((Object)(object)_itemStand != (Object)null) ? _itemStand.GetHoverName() : "$piece_armorstand"); _inventory = new Inventory(text, (Sprite)null, num, 1); Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); } public bool OpenAsContainer(Humanoid user) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!(user is Player) || (Object)(object)InventoryGui.instance == (Object)null) { return false; } if ((Object)(object)_opened != (Object)null) { return false; } ZNetView component = ((Component)this).GetComponent(); if (component != null) { component.ClaimOwnership(); } RefreshInventory(); _opened = this; if ((Object)(object)_virtualContainer == (Object)null) { GameObject val = new GameObject("RunicDisplayStandsVirtualContainer"); val.SetActive(false); _virtualContainer = val.AddComponent(); } ((Container)_virtualContainer).m_name = _inventory.GetName(); ((Container)_virtualContainer).m_width = _inventory.GetWidth(); ((Container)_virtualContainer).m_height = _inventory.GetHeight(); ContainerInventoryField.SetValue(_virtualContainer, _inventory); ((Component)_virtualContainer).transform.SetParent(((Component)this).transform, false); InventoryGui.instance.Show((Container)(object)_virtualContainer, 1); SetUseEquipButton(useEquip: true); return true; } public bool TakeOne(Humanoid user) { RefreshInventory(); ItemData itemAt = _inventory.GetItemAt(0, 0); if (itemAt == null) { return false; } ItemData val = itemAt.Clone(); val.m_stack = 1; if (!user.GetInventory().CanAddItem(val, 1)) { return false; } user.GetInventory().AddItem(val); _inventory.RemoveOneItem(itemAt); PushInventoryToStand(); return true; } internal void SwapEquip() { if ((Object)(object)_armorStand != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null) { ArmorStandAdapter.SwapWithPlayer(_armorStand, Player.m_localPlayer); } else if ((Object)(object)_itemStand != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null) { ItemStandAdapter.SwapWithPlayer(_itemStand, Player.m_localPlayer); } RefreshInventory(); } internal static void Closed() { if (!((Object)(object)_opened == (Object)null)) { _opened.PushInventoryToStand(); _opened = null; SetUseEquipButton(useEquip: false); if ((Object)(object)_virtualContainer != (Object)null) { Object.Destroy((Object)(object)((Component)_virtualContainer).gameObject); _virtualContainer = null; } } } private void RefreshInventory() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) _refreshing = true; _inventory.RemoveAll(); if ((Object)(object)_itemStand != (Object)null) { ItemData placedItem = ItemStandAdapter.GetPlacedItem(_itemStand); if (placedItem != null) { _inventory.AddItem(placedItem); } } else { List placedItems = ArmorStandAdapter.GetPlacedItems(_armorStand); for (int i = 0; i < placedItems.Count; i++) { if (placedItems[i] != null) { _inventory.AddItem(placedItems[i], new Vector2i(i, 0)); } } } InventoryChangedMethod.Invoke(_inventory, null); _refreshing = false; } private void OnInventoryChanged() { if (!_refreshing) { PushInventoryToStand(); } } private void PushInventoryToStand() { if ((Object)(object)_itemStand != (Object)null) { List allItems = _inventory.GetAllItems(); ItemStandAdapter.SetPlacedItem(_itemStand, (allItems.Count > 0) ? allItems[0] : null); } else { List allItems2 = _inventory.GetAllItems(); ArmorStandAdapter.SetPlacedItems(_armorStand, allItems2); } } internal static void SetUseEquipButton(bool useEquip) { if (!((Object)(object)InventoryGui.instance == (Object)null) && !((Object)(object)InventoryGui.instance.m_stackAllButton == (Object)null)) { Button stackAllButton = InventoryGui.instance.m_stackAllButton; ((Component)stackAllButton).gameObject.SetActive(useEquip); TMP_Text componentInChildren = ((Component)stackAllButton).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = (useEquip ? "Use/equip" : "$inventory_stackall"); } } } } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer")] [HarmonyPriority(0)] internal static class InventoryGui_UpdateContainer_Stand_Patch { private static void Postfix() { if ((Object)(object)ContainerBridge.Opened != (Object)null) { ContainerBridge.SetUseEquipButton(useEquip: true); } } } [HarmonyPatch(typeof(InventoryGui), "OnStackAll")] [HarmonyPriority(800)] internal static class InventoryGui_OnStackAll_Stand_Patch { private static bool Prefix() { if ((Object)(object)ContainerBridge.Opened == (Object)null) { return true; } ContainerBridge.Opened.SwapEquip(); return false; } } internal sealed class StandVirtualContainer : Container { } [HarmonyPatch(typeof(Container), "IsOwner")] internal static class VirtualContainer_IsOwner_Patch { private static bool Prefix(Container __instance, ref bool __result) { if (!(__instance is StandVirtualContainer)) { return true; } __result = (Object)(object)ContainerBridge.Opened != (Object)null; return false; } } [HarmonyPatch(typeof(Container), "SetInUse")] internal static class VirtualContainer_SetInUse_Patch { private static bool Prefix(Container __instance) { return !(__instance is StandVirtualContainer); } } [HarmonyPatch(typeof(Container), "StackAll")] internal static class VirtualContainer_StackAll_Patch { private static bool Prefix(Container __instance) { if (!(__instance is StandVirtualContainer)) { return true; } ContainerBridge.Opened?.SwapEquip(); return false; } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide_Stand_Patch { private static void Prefix() { ContainerBridge.Closed(); } } [HarmonyPatch(typeof(InventoryGui), "CloseContainer")] internal static class InventoryGui_CloseContainer_Stand_Patch { private static void Prefix() { ContainerBridge.Closed(); } } internal static class ItemDataSerializer { internal static byte[] Serialize(ItemData item) { //IL_0011: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (item == null) { return Array.Empty(); } Inventory val = new Inventory("RunicDisplayStands", (Sprite)null, 1, 1); ItemData val2 = item.Clone(); val2.m_stack = 1; val.AddItem(val2, new Vector2i(0, 0)); ZPackage val3 = new ZPackage(); val.Save(val3); return val3.GetArray(); } internal static ItemData Deserialize(byte[] bytes) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (bytes == null || bytes.Length == 0) { return null; } try { Inventory val = new Inventory("RunicDisplayStands", (Sprite)null, 1, 1); val.Load(new ZPackage(bytes)); List allItems = val.GetAllItems(); if (allItems.Count == 0) { return null; } ItemData obj = allItems[0]; obj.m_stack = 1; return obj; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Could not restore complete stand item data; using vanilla fallback. " + ex.Message)); } return null; } } } internal static class ConfigSync { private const string RpcName = "RunicDisplayStands_ConfigSync"; private static readonly List _synced = new List(); private static bool _rpcRegistered; public static void RegisterSyncedConfig(ConfigEntryBase entry) { _synced.Add(entry); EnsureRpcRegistered(); } internal static void EnsureRpcRegistered() { if (!_rpcRegistered && ZRoutedRpc.instance != null) { _rpcRegistered = true; ZRoutedRpc.instance.Register("RunicDisplayStands_ConfigSync", (Action)OnConfigReceived); } } public static void NotifyNewConnection(ZNetPeer peer) { EnsureRpcRegistered(); if (_rpcRegistered && ZNet.instance.IsServer()) { string text = Serialize(); ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "RunicDisplayStands_ConfigSync", new object[1] { text }); } } private static void OnConfigReceived(long sender, string payload) { if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { Deserialize(payload); Plugin.RebuildStandPrefabSet(); Plugin.Log.LogInfo((object)"Received admin config from server; local Stand Prefabs list updated."); } } private static string Serialize() { List list = new List(); foreach (ConfigEntryBase item in _synced) { list.Add($"{item.Definition.Key}={item.BoxedValue}"); } return string.Join("|", list); } private static void Deserialize(string payload) { string[] array = payload.Split('|'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }, 2); if (array2.Length != 2) { continue; } foreach (ConfigEntryBase item in _synced) { if (item.Definition.Key == array2[0]) { item.BoxedValue = array2[1]; } } } } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class ZNet_Awake_ConfigSync_Patch { private static void Postfix() { ConfigSync.EnsureRpcRegistered(); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] internal static class ZNet_OnNewConnection_Patch { private static void Postfix(ZNetPeer peer) { ConfigSync.NotifyNewConnection(peer); } } internal static class ArmorStandAdapter { public const int SlotCount = 6; public const int SlotHelmet = 0; public const int SlotChest = 1; public const int SlotLegs = 2; public const int SlotCape = 3; public const int SlotWeapon = 4; public const int SlotShield = 5; private static readonly FieldInfo SlotsField = AccessTools.Field(typeof(ArmorStand), "m_slots"); private static readonly MethodInfo CanAttachMethod = AccessTools.Method(typeof(ArmorStand), "CanAttach", (Type[])null, (Type[])null); public static int GetSlotCount(ArmorStand stand) { return ((ICollection)SlotsField.GetValue(stand)).Count; } public static List GetPlacedItems(ArmorStand stand) { int slotCount = GetSlotCount(stand); List list = new List((IEnumerable)(object)new ItemData[slotCount]); ZNetView component = ((Component)stand).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return list; } for (int i = 0; i < slotCount; i++) { string attachedItem = stand.GetAttachedItem(i); if (string.IsNullOrEmpty(attachedItem)) { continue; } ItemData val = ItemDataSerializer.Deserialize(component.GetZDO().GetByteArray(ItemDataKey(i), (byte[])null)); if (val != null) { list[i] = val; continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(attachedItem); if (!((Object)(object)itemPrefab == (Object)null)) { ItemData val2 = itemPrefab.GetComponent().m_itemData.Clone(); val2.m_variant = component.GetZDO().GetInt(VariantKey(i), 0); val2.m_stack = 1; list[i] = val2; } } return list; } public static void SetPlacedItems(ArmorStand stand, IList items) { ZNetView component = ((Component)stand).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } int slotCount = GetSlotCount(stand); ItemData[] array = MapItemsToSlots(stand, items); for (int i = 0; i < slotCount; i++) { ItemData val = array[i]; if (val != null) { string name = ((Object)val.m_dropPrefab).name; component.GetZDO().Set(ItemKey(i), name); component.GetZDO().Set(VariantKey(i), val.m_variant, false); component.GetZDO().Set(ItemDataKey(i), ItemDataSerializer.Serialize(val)); component.InvokeRPC(ZNetView.Everybody, "RPC_SetVisualItem", new object[3] { i, name, val.m_variant }); } else { component.GetZDO().Set(ItemKey(i), ""); component.GetZDO().Set(VariantKey(i), 0, false); component.GetZDO().Set(ItemDataKey(i), Array.Empty()); component.InvokeRPC(ZNetView.Everybody, "RPC_SetVisualItem", new object[3] { i, "", 0 }); } } } public static void SwapWithPlayer(ArmorStand stand, Player player) { //IL_015d: 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) Inventory inventory = ((Humanoid)player).GetInventory(); List equippedItems = inventory.GetEquippedItems(); int slotCount = GetSlotCount(stand); ItemData[] array = (ItemData[])(object)new ItemData[slotCount]; List list = equippedItems.ToList(); ItemData val = FindFirstHotbarItem(inventory, StandSlotValidator.WeaponTypes); ItemData val2 = FindFirstHotbarItem(inventory, StandSlotValidator.ShieldTypes); if (val != null && !list.Contains(val)) { list.Add(val); } if (val2 != null && !list.Contains(val2)) { list.Add(val2); } foreach (ItemData item in list) { for (int i = 0; i < slotCount; i++) { if (array[i] == null && CanAttachAt(stand, i, item)) { array[i] = item; break; } } } List placedItems = GetPlacedItems(stand); ItemData[] array2 = array; foreach (ItemData val3 in array2) { if (val3 != null && val3.m_equipped) { ((Humanoid)player).UnequipItem(val3, false); } } array2 = array; foreach (ItemData val4 in array2) { if (val4 != null) { inventory.RemoveItem(val4); } } SetPlacedItems(stand, array); for (int k = 0; k < slotCount; k++) { ItemData val5 = placedItems[k]; if (val5 != null) { if (!inventory.CanAddItem(val5, val5.m_stack)) { ItemDrop.DropItem(val5, val5.m_stack, ((Component)player).transform.position, ((Component)player).transform.rotation); continue; } inventory.AddItem(val5); ((Humanoid)player).EquipItem(val5, false); } } } private static int ItemKey(int index) { return StringExtensionMethods.GetStableHashCode($"{index}_item"); } private static int VariantKey(int index) { return StringExtensionMethods.GetStableHashCode($"{index}_variant"); } private static int ItemDataKey(int index) { return StringExtensionMethods.GetStableHashCode($"RunicDisplayStands_itemdata_{index}"); } private static bool CanAttachAt(ArmorStand stand, int index, ItemData item) { IList list = (IList)SlotsField.GetValue(stand); return (bool)CanAttachMethod.Invoke(stand, new object[2] { list[index], item }); } public static ItemData[] MapItemsToSlots(ArmorStand stand, IEnumerable items) { int slotCount = GetSlotCount(stand); ItemData[] array = (ItemData[])(object)new ItemData[slotCount]; foreach (ItemData item in items) { if (item == null) { continue; } for (int i = 0; i < slotCount; i++) { if (array[i] == null && CanAttachAt(stand, i, item)) { array[i] = item; break; } } } return array; } private static ItemData FindFirstHotbarItem(Inventory inv, HashSet types) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 8; i++) { ItemData itemAt = inv.GetItemAt(i, 0); if (itemAt != null && types.Contains(itemAt.m_shared.m_itemType)) { return itemAt; } } return null; } } [HarmonyPatch(typeof(ItemStand), "Interact")] internal static class ItemStand_Interact_Patch { private static bool Prefix(ItemStand __instance, Humanoid __0, bool __1, bool __2, ref bool __result) { if (!Plugin.StandPrefabSet.Contains(((Object)((Component)__instance).gameObject).name.Replace("(Clone)", ""))) { return true; } if (__1) { return true; } if (__2 || IsTakeOneHeld()) { ContainerBridge orCreate = ContainerBridge.GetOrCreate(((Component)__instance).gameObject); __result = orCreate.TakeOne(__0); } else { ContainerBridge orCreate2 = ContainerBridge.GetOrCreate(((Component)__instance).gameObject); __result = orCreate2.OpenAsContainer(__0); } return false; } private static bool IsTakeOneHeld() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Plugin.CfgTakeOneKey.Value; return ((KeyboardShortcut)(ref value)).IsDown(); } } [HarmonyPatch(typeof(Switch), "Interact")] internal static class ArmorStand_Switch_Interact_Patch { private static bool Prefix(Switch __instance, Humanoid __0, bool __1, ref bool __result) { ArmorStand componentInParent = ((Component)__instance).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return true; } if (!Plugin.StandPrefabSet.Contains(((Object)((Component)componentInParent).gameObject).name.Replace("(Clone)", ""))) { return true; } if (__1) { return true; } ContainerBridge orCreate = ContainerBridge.GetOrCreate(((Component)componentInParent).gameObject); __result = orCreate.OpenAsContainer(__0); return false; } } [HarmonyPatch(typeof(InventoryGrid), "GetElement")] [HarmonyPriority(800)] internal static class InventoryGrid_GetElement_Bounds_Patch { private static readonly FieldInfo ElementsField = AccessTools.Field(typeof(InventoryGrid), "m_elements"); private static bool Prefix(int x, int y, int width, InventoryGrid __instance) { if (!(ElementsField?.GetValue(__instance) is IList list)) { return true; } long num = (long)y * (long)width + x; if (x >= 0 && y >= 0 && width > 0 && num >= 0 && num < list.Count) { return true; } return false; } } internal static class ItemStandAdapter { private static readonly MethodInfo GetOrientationMethod = AccessTools.Method(typeof(ItemStand), "GetOrientation", (Type[])null, (Type[])null); private static readonly int ItemDataKey = StringExtensionMethods.GetStableHashCode("RunicDisplayStands_itemdata"); public static ItemData GetPlacedItem(ItemStand stand) { ZNetView component = ((Component)stand).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return null; } string attachedItem = stand.GetAttachedItem(); if (string.IsNullOrEmpty(attachedItem)) { return null; } ItemData val = ItemDataSerializer.Deserialize(component.GetZDO().GetByteArray(ItemDataKey, (byte[])null)); if (val != null) { return val; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(attachedItem); if ((Object)(object)itemPrefab == (Object)null) { return null; } ItemData obj = itemPrefab.GetComponent().m_itemData.Clone(); obj.m_quality = component.GetZDO().GetInt(ZDOVars.s_quality, 1); obj.m_variant = component.GetZDO().GetInt(ZDOVars.s_variant, 0); obj.m_stack = 1; return obj; } public static void SetPlacedItem(ItemStand stand, ItemData item) { ZNetView component = ((Component)stand).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (item == null) { component.GetZDO().Set(ZDOVars.s_item, ""); component.GetZDO().Set(ZDOVars.s_variant, 0, false); component.GetZDO().Set(ZDOVars.s_quality, 1, false); component.GetZDO().Set(ItemDataKey, Array.Empty()); int orientation = GetOrientation(stand); component.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[4] { "", 0, 1, orientation }); } else { string name = ((Object)item.m_dropPrefab).name; component.GetZDO().Set(ZDOVars.s_item, name); component.GetZDO().Set(ZDOVars.s_quality, item.m_quality, false); component.GetZDO().Set(ZDOVars.s_variant, item.m_variant, false); component.GetZDO().Set(ItemDataKey, ItemDataSerializer.Serialize(item)); int orientation2 = GetOrientation(stand); component.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[4] { name, item.m_variant, item.m_quality, orientation2 }); } } } private static int GetOrientation(ItemStand stand) { return (int)GetOrientationMethod.Invoke(stand, null); } public static void SwapWithPlayer(ItemStand stand, Player player) { ItemData placedItem = GetPlacedItem(stand); if (placedItem != null) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory.CanAddItem(placedItem, placedItem.m_stack)) { SetPlacedItem(stand, null); inventory.AddItem(placedItem); ((Humanoid)player).EquipItem(placedItem, false); } } } } internal static class StandSlotValidator { public static readonly HashSet WeaponTypes = new HashSet { (ItemType)3, (ItemType)14, (ItemType)22, (ItemType)4 }; public static readonly HashSet ShieldTypes = new HashSet { (ItemType)5 }; public static bool IsValidForItemStand(ItemData item) { return item != null; } public static bool IsValidForArmorSlot(ItemData item, int slotIndex) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0076: 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) if (item == null) { return false; } return slotIndex switch { 0 => (int)item.m_shared.m_itemType == 6, 1 => (int)item.m_shared.m_itemType == 7, 2 => (int)item.m_shared.m_itemType == 11, 3 => (int)item.m_shared.m_itemType == 17, 4 => WeaponTypes.Contains(item.m_shared.m_itemType), 5 => ShieldTypes.Contains(item.m_shared.m_itemType), _ => false, }; } } [BepInPlugin("chazman.RunicDisplayStands", "RunicDisplayStands", "1.2.4")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "chazman.RunicDisplayStands"; public const string PluginName = "RunicDisplayStands"; public const string PluginVersion = "1.2.4"; public static Plugin Instance; internal static ManualLogSource Log; public static ConfigEntry CfgStandPrefabs; public static ConfigEntry CfgGamepadSupport; public static ConfigEntry CfgTakeOneKey; public static HashSet StandPrefabSet = new HashSet(); private readonly Harmony _harmony = new Harmony("chazman.RunicDisplayStands"); private void Awake() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; CfgStandPrefabs = ((BaseUnityPlugin)this).Config.Bind("Admin", "Stand Prefabs", "itemstand,itemstandh,ArmorStand", new ConfigDescription("Comma separated list of prefab names that should be treated as item/armor stands.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { IsAdminOnly = true } })); CfgGamepadSupport = ((BaseUnityPlugin)this).Config.Bind("General", "Gamepad Support", true, "Enable controller-friendly interact prompts and alt-take binding."); CfgTakeOneKey = ((BaseUnityPlugin)this).Config.Bind("General", "Take One Item Key", new KeyboardShortcut((KeyCode)308, Array.Empty()), "Hold this while interacting with a stand to take a single item instead of opening it."); RebuildStandPrefabSet(); CfgStandPrefabs.SettingChanged += delegate { RebuildStandPrefabSet(); }; ConfigSync.RegisterSyncedConfig((ConfigEntryBase)(object)CfgStandPrefabs); _harmony.PatchAll(); Log.LogInfo((object)"RunicDisplayStands v1.2.4 loaded."); } internal static void RebuildStandPrefabSet() { StandPrefabSet = (from s in CfgStandPrefabs.Value.Split(',') select s.Trim() into s where s.Length > 0 select s).ToHashSet(StringComparer.OrdinalIgnoreCase); } } public class ConfigurationManagerAttributes { public bool IsAdminOnly; } }