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 MySix ArmorStandSwap v1.0.2
MySix.ArmorStandSwap.dll
Decompiled 22 minutes agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using MySix.Core; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace MySix { internal static class SuiteVersion { public const string Value = "1.0.2"; } } namespace MySix.ArmorStandSwap { [HarmonyPatch(typeof(ArmorStand), "UseItem")] public static class UseItemPatch { private struct Exchange { public int Slot; public ItemData FromStand; public ItemData FromPlayer; } public static Setting<bool> Enabled; private static readonly FieldRef<ArmorStand, List<ArmorStandSlot>> Slots = AccessTools.FieldRefAccess<ArmorStand, List<ArmorStandSlot>>("m_slots"); private static readonly FieldRef<ArmorStand, ZNetView> NView = AccessTools.FieldRefAccess<ArmorStand, ZNetView>("m_nview"); private static readonly FieldRef<ArmorStand, ItemData> QueuedItem = AccessTools.FieldRefAccess<ArmorStand, ItemData>("m_queuedItem"); private static readonly FieldRef<ArmorStand, int> QueuedSlot = AccessTools.FieldRefAccess<ArmorStand, int>("m_queuedSlot"); private static readonly MethodInfo UpdateAttach = AccessTools.Method(typeof(ArmorStand), "UpdateAttach", (Type[])null, (Type[])null); private static readonly MethodInfo CanAttach = AccessTools.Method(typeof(ArmorStand), "CanAttach", (Type[])null, (Type[])null); private static readonly string[] WornFields = new string[7] { "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem", "m_rightItem", "m_leftItem" }; private static readonly Dictionary<string, FieldRef<Humanoid, ItemData>> WornRefs = WornFields.ToDictionary((string n) => n, (string n) => AccessTools.FieldRefAccess<Humanoid, ItemData>(n)); private static bool Prefix(ArmorStand __instance, Switch caller, Humanoid user, ItemData item, ref bool __result) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (Enabled == null || !Enabled.Value || item != null) { return true; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false)) { return true; } ZNetView val2 = NView.Invoke(__instance); if ((Object)(object)val2 == (Object)null || !val2.IsValid()) { return true; } if (!val2.IsOwner()) { val2.ClaimOwnership(); } __result = Swap(__instance, val, val2); return false; } private static bool Swap(ArmorStand stand, Player player, ZNetView nview) { List<ArmorStandSlot> list = Slots.Invoke(stand); Inventory inventory = ((Humanoid)player).GetInventory(); List<Exchange> list2 = new List<Exchange>(); List<ItemData> list3 = new List<ItemData>(); for (int i = 0; i < list.Count; i++) { ItemData val = ReadAttachedItem(stand, nview, i); ItemData val2 = FindWornFor(player, stand, list[i], list3); if (val != null || val2 != null) { if (val2 != null) { list3.Add(val2); } list2.Add(new Exchange { Slot = i, FromStand = val, FromPlayer = val2 }); } } if (list2.Count == 0) { ((Character)player).Message((MessageType)2, "Nothing to swap", 0, (Sprite)null, false); return false; } if (list2.Count((Exchange p) => p.FromStand != null) > inventory.GetEmptySlots()) { ((Character)player).Message((MessageType)2, "Not enough room in your inventory to swap", 0, (Sprite)null, false); return false; } int num = 0; foreach (Exchange item in list2) { ItemData val3 = null; if (item.FromStand != null) { if (inventory.AddItem(item.FromStand)) { val3 = item.FromStand; } if (val3 == null) { ((Character)player).Message((MessageType)2, "Not enough room in your inventory to swap", 0, (Sprite)null, false); break; } stand.DestroyAttachment(item.Slot); } if (item.FromPlayer != null) { QueuedItem.Invoke(stand) = item.FromPlayer; QueuedSlot.Invoke(stand) = item.Slot; UpdateAttach.Invoke(stand, null); } if (val3 != null) { ((Humanoid)player).EquipItem(val3, true); } num++; } if (num > 0) { CorePlugin.Log.LogInfo((object)$"ArmorStandSwap: swapped {num} slot(s)"); ((Character)player).Message((MessageType)2, (num == 1) ? "Swapped 1 piece" : $"Swapped {num} pieces", 0, (Sprite)null, false); } return num > 0; } private static ItemData ReadAttachedItem(ArmorStand stand, ZNetView nview, int slot) { int attachedItem = stand.GetAttachedItem(slot); if (attachedItem == 0) { return null; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(attachedItem) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { CorePlugin.Log.LogWarning((object)$"ArmorStandSwap: unknown item {attachedItem} on stand slot {slot}; leaving it alone"); return null; } ItemData obj = val2.m_itemData.Clone(); obj.m_dropPrefab = val; ItemDrop.LoadFromZDO(obj, nview.GetZDO(), slot); obj.m_stack = 1; obj.m_equipped = false; return obj; } private static ItemData FindWornFor(Player player, ArmorStand stand, ArmorStandSlot slot, List<ItemData> alreadyClaimed) { foreach (ItemData item in Worn(player)) { if (item != null && !alreadyClaimed.Contains(item) && (bool)CanAttach.Invoke(stand, new object[2] { slot, item })) { return item; } } return null; } private static IEnumerable<ItemData> Worn(Player player) { string[] wornFields = WornFields; foreach (string key in wornFields) { yield return WornRefs[key].Invoke((Humanoid)(object)player); } } } [BepInPlugin("com.mysix.armorstandswap", "MySix Armor Stand Swap", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ArmorStandSwapPlugin : BaseUnityPlugin { public const string PluginGuid = "com.mysix.armorstandswap"; public const string PluginName = "MySix Armor Stand Swap"; public const string PluginVersion = "1.0.2"; private const int RequiredCoreApi = 1; private Harmony _harmony; private void Awake() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown if (CorePlugin.RequireApi("MySix Armor Stand Swap", 1)) { UseItemPatch.Enabled = Settings.Register<bool>("MySix Armor Stand Swap", ((BaseUnityPlugin)this).Config.Bind<bool>("ArmorStandSwap", "Enabled", true, "Pressing E on an armour stand with empty hands swaps your whole outfit with the stand's. Using a hotbar item on the stand (keys 1-8) is unchanged."), (Scope)0, (string)null); _harmony = new Harmony("com.mysix.armorstandswap"); _harmony.PatchAll(typeof(ArmorStandSwapPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"MySix Armor Stand Swap 1.0.2 loaded"); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }