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 RunicDisplayStands v1.2.4
RunicDisplayStands.dll
Decompiled a day agousing 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<ContainerBridge>(); if ((Object)(object)component != (Object)null) { return component; } component = go.AddComponent<ContainerBridge>(); 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<ItemStand>(); _armorStand = ((Component)this).GetComponent<ArmorStand>(); 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<ZNetView>(); 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<StandVirtualContainer>(); } ((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<ItemData> 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<ItemData> allItems = _inventory.GetAllItems(); ItemStandAdapter.SetPlacedItem(_itemStand, (allItems.Count > 0) ? allItems[0] : null); } else { List<ItemData> 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<TMP_Text>(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<byte>(); } 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<ItemData> 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<ConfigEntryBase> _synced = new List<ConfigEntryBase>(); 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<string>("RunicDisplayStands_ConfigSync", (Action<long, string>)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<string> list = new List<string>(); 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<ItemData> GetPlacedItems(ArmorStand stand) { int slotCount = GetSlotCount(stand); List<ItemData> list = new List<ItemData>((IEnumerable<ItemData>)(object)new ItemData[slotCount]); ZNetView component = ((Component)stand).GetComponent<ZNetView>(); 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<ItemDrop>().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<ItemData> items) { ZNetView component = ((Component)stand).GetComponent<ZNetView>(); 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<byte>()); 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<ItemData> equippedItems = inventory.GetEquippedItems(); int slotCount = GetSlotCount(stand); ItemData[] array = (ItemData[])(object)new ItemData[slotCount]; List<ItemData> 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<ItemData> 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<ItemData> 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<ItemType> 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<ArmorStand>(); 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<ZNetView>(); 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<ItemDrop>().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<ZNetView>(); 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<byte>()); 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<ItemType> WeaponTypes = new HashSet<ItemType> { (ItemType)3, (ItemType)14, (ItemType)22, (ItemType)4 }; public static readonly HashSet<ItemType> ShieldTypes = new HashSet<ItemType> { (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<string> CfgStandPrefabs; public static ConfigEntry<bool> CfgGamepadSupport; public static ConfigEntry<KeyboardShortcut> CfgTakeOneKey; public static HashSet<string> StandPrefabSet = new HashSet<string>(); 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<string>("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<bool>("General", "Gamepad Support", true, "Enable controller-friendly interact prompts and alt-take binding."); CfgTakeOneKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Take One Item Key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "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<string>(StringComparer.OrdinalIgnoreCase); } } public class ConfigurationManagerAttributes { public bool IsAdminOnly; } }