using System; using System.Collections.Generic; using System.Diagnostics; 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 UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NoSwapDrop")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("No Swap Drop")] [assembly: AssemblyTitle("NoSwapDrop")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 NoSwapDrop { [BepInPlugin("tomo.repo.noswapdrop", "No Swap Drop", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "tomo.repo.noswapdrop"; public const string PluginName = "No Swap Drop"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry ModEnabled; internal static ConfigEntry PreferOriginalSlot; internal static ConfigEntry MaxSwapDelay; private void Awake() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a0: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "インベントリのスロットを切り替えたとき、手に持っているアイテムを落とさず空きスロットへ戻す。"); PreferOriginalSlot = ((BaseUnityPlugin)this).Config.Bind("General", "PreferOriginalSlot", true, "元々入っていたスロットが空いていればそこへ戻す。false の場合は常に一番若い空きスロットへ戻す。"); MaxSwapDelay = ((BaseUnityPlugin)this).Config.Bind("General", "MaxSwapDelay", 1f, new ConfigDescription("高速で切り替えたとき、手持ちアイテムが収納可能になるまで取り出しを待つ最大秒数。これを過ぎたらバニラの挙動(落とす)に戻す。0 にすると待たない。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3f), Array.Empty())); GameObject val = new GameObject("No Swap Drop SwapGuard") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); SwapGuard.Instance = val.AddComponent(); new Harmony("tomo.repo.noswapdrop").PatchAll(); Log.LogInfo((object)"No Swap Drop 1.0.0 loaded."); } } internal static class SwapTools { internal static ItemEquippable GetItemInHand() { PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null) { return null; } PhysGrabObject val = null; if (instance.grabbed && (Object)(object)instance.grabbedPhysGrabObject != (Object)null) { val = instance.grabbedPhysGrabObject; } else if ((Object)(object)instance.overrideGrabTarget != (Object)null) { val = instance.overrideGrabTarget; } if (!((Object)(object)val == (Object)null)) { return ((Component)val).GetComponent(); } return null; } internal static bool CanStow(ItemEquippable item) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) Inventory instance = Inventory.instance; if ((Object)(object)item != (Object)null && (Object)(object)instance != (Object)null && instance.spotsFeched && (int)item.currentState == 0 && !item.isEquipping && !item.isUnequipping && !instance.IsItemEquipped(item)) { return FindSpot(item) >= 0; } return false; } internal static bool IsSettling(ItemEquippable item) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if ((Object)(object)item != (Object)null) { if ((int)item.currentState != 3 && (int)item.currentState != 1 && !item.isEquipping) { return item.isUnequipping; } return true; } return false; } internal static bool HasFreeSpot(ItemEquippable item) { return FindSpot(item) >= 0; } internal static bool Stow(ItemEquippable item) { PhysGrabber instance = PhysGrabber.instance; int num = FindSpot(item); if ((Object)(object)instance == (Object)null || num < 0) { return false; } item.RequestEquip(num, instance.photonView.ViewID); Plugin.Log.LogDebug((object)("Stowing held item into inventory spot " + num + ".")); return true; } internal static bool IsStowed(ItemEquippable item) { Inventory instance = Inventory.instance; if (!((Object)(object)item == (Object)null)) { if ((Object)(object)instance != (Object)null) { return instance.IsItemEquipped(item); } return false; } return true; } private static int FindSpot(ItemEquippable item) { Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null || !instance.spotsFeched) { return -1; } List allSpots = instance.GetAllSpots(); if (Plugin.PreferOriginalSlot.Value) { int inventorySpotIndex = item.inventorySpotIndex; if (inventorySpotIndex >= 0 && inventorySpotIndex < allSpots.Count && (Object)(object)allSpots[inventorySpotIndex] != (Object)null && !allSpots[inventorySpotIndex].IsOccupied()) { return inventorySpotIndex; } } for (int i = 0; i < allSpots.Count; i++) { if ((Object)(object)allSpots[i] != (Object)null && !allSpots[i].IsOccupied()) { return i; } } return -1; } } internal class SwapGuard : MonoBehaviour { internal static SwapGuard Instance; internal static bool Bypass; private ItemEquippable pendingTake; private ItemEquippable stowing; private bool waitingForStow; private float deadline; internal void Defer(ItemEquippable itemToTakeOut) { pendingTake = itemToTakeOut; stowing = null; waitingForStow = false; deadline = Time.time + Plugin.MaxSwapDelay.Value; } private void Clear() { pendingTake = null; stowing = null; waitingForStow = false; } private void Update() { if ((Object)(object)pendingTake == (Object)null) { return; } if (!pendingTake.IsEquipped()) { Clear(); return; } if (Time.time >= deadline) { TakeOutNow(); return; } if (waitingForStow) { if (SwapTools.IsStowed(stowing)) { TakeOutNow(); } return; } ItemEquippable itemInHand = SwapTools.GetItemInHand(); if ((Object)(object)itemInHand == (Object)null || (Object)(object)itemInHand == (Object)(object)pendingTake) { TakeOutNow(); } else if (SwapTools.CanStow(itemInHand)) { if (SwapTools.Stow(itemInHand)) { stowing = itemInHand; waitingForStow = true; } else { TakeOutNow(); } } } private void TakeOutNow() { ItemEquippable val = pendingTake; Clear(); if ((Object)(object)val == (Object)null || !val.IsEquipped()) { return; } Bypass = true; try { val.RequestUnequip(); } finally { Bypass = false; } } } [HarmonyPatch(typeof(ItemEquippable), "RequestUnequip")] internal static class RequestUnequipPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(ItemEquippable __instance) { try { return Handle(__instance); } catch (Exception ex) { Plugin.Log.LogError((object)("No Swap Drop failed, falling back to vanilla behaviour: " + ex)); return true; } } private static bool Handle(ItemEquippable itemBeingTakenOut) { if (SwapGuard.Bypass || !Plugin.ModEnabled.Value) { return true; } if ((Object)(object)itemBeingTakenOut == (Object)null || !itemBeingTakenOut.IsEquipped()) { return true; } Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null || !instance.spotsFeched) { return true; } ItemEquippable itemInHand = SwapTools.GetItemInHand(); if ((Object)(object)itemInHand == (Object)null || (Object)(object)itemInHand == (Object)(object)itemBeingTakenOut) { return true; } if (!SwapTools.HasFreeSpot(itemInHand)) { return true; } if (SwapTools.CanStow(itemInHand)) { SwapTools.Stow(itemInHand); return true; } if (SwapTools.IsSettling(itemInHand) && Plugin.MaxSwapDelay.Value > 0f && (Object)(object)SwapGuard.Instance != (Object)null) { SwapGuard.Instance.Defer(itemBeingTakenOut); return false; } return true; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }