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 CtrlClickSort v1.0.0
plugins/CtrlClickSort.dll
Decompiled 2 weeks agousing 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 HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CtrlClickSort")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CtrlClickSort")] [assembly: AssemblyTitle("CtrlClickSort")] [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 CtrlClickSort { internal static class ContainerTracker { private static readonly HashSet<Container> Containers = new HashSet<Container>(); internal static void Add(Container container) { Containers.Add(container); } internal static List<ChestCandidate> FindAccessibleChests(Vector3 point, float range, long playerId) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) Containers.RemoveWhere((Container c) => !Object.op_Implicit((Object)(object)c)); List<ChestCandidate> list = new List<ChestCandidate>(); foreach (Container container in Containers) { if (IsPlayerChest(container)) { float num = Vector3.Distance(point, ((Component)container).transform.position); if (!(num > range) && HasAccess(container, playerId)) { list.Add(new ChestCandidate(container, num)); } } } list.Sort(delegate(ChestCandidate a, ChestCandidate b) { float distance = a.Distance; return distance.CompareTo(b.Distance); }); return list; } private static bool IsPlayerChest(Container container) { if (!Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.IsValid() || container.GetInventory() == null) { return false; } if (!Object.op_Implicit((Object)(object)container.m_piece) || !container.m_piece.IsPlacedByPlayer()) { return false; } if (!Object.op_Implicit((Object)(object)((Component)container).GetComponent<TombStone>())) { return !Object.op_Implicit((Object)(object)((Component)container).GetComponentInParent<Player>()); } return false; } private static bool HasAccess(Container container, long playerId) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)) { return false; } return container.CheckAccess(playerId); } internal static bool IsInUse(Container container) { if (Object.op_Implicit((Object)(object)container.m_wagon) && container.m_wagon.InUse()) { return true; } ZNetView nview = container.m_nview; if (nview.IsOwner()) { return container.IsInUse(); } if (nview.HasOwner()) { return nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1; } return false; } } internal readonly struct ChestCandidate { public readonly Container Container; public readonly float Distance; public ChestCandidate(Container container, float distance) { Container = container; Distance = distance; } } [HarmonyPatch(typeof(Container), "Awake")] internal static class ContainerAwakePatch { private static void Postfix(Container __instance) { if (__instance.GetInventory() != null) { ContainerTracker.Add(__instance); } } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class InventoryGuiOnSelectedItemPatch { private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (!ShouldHandle(__instance, grid, item, mod)) { return true; } return !StackToChest.TryStore(__instance, Player.m_localPlayer, item); } private static bool ShouldHandle(InventoryGui gui, InventoryGrid grid, ItemData item, Modifier mod) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_002e: 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) if (Object.op_Implicit((Object)(object)gui.m_dragGo) || item == null || (Object)(object)gui.m_currentContainer != (Object)null) { return false; } if ((int)mod != 2 && (int)mod != 0) { return false; } if (!ZInput.GetKey(Plugin.ModifierKey.Value, true)) { return false; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsTeleporting() || grid.GetInventory() != ((Humanoid)localPlayer).GetInventory()) { return false; } return !item.m_shared.m_questItem; } } internal sealed class Messages { public string Moved; public string Remaining; public string Equipped; public string NoChestHasItem; public string InUse; public string NoSpace; private static readonly Messages English = new Messages { Moved = "{0} x{1} → {2} ({3} m)", Remaining = "{0} x{1} left in inventory", Equipped = "{0}: equipped items are not moved", NoChestHasItem = "No nearby chest contains {0}", InUse = "The chest with {0} is being used by another player", NoSpace = "No room for {0} in nearby chests" }; private static readonly Messages Slovak = new Messages { Moved = "{0} x{1} → {2} ({3} m)", Remaining = "{0} x{1} zostáva v inventári", Equipped = "{0}: vybavené predmety sa nepresúvajú", NoChestHasItem = "Žiadna truhlica v okolí neobsahuje {0}", InUse = "Truhlicu s {0} práve používa iný hráč", NoSpace = "V truhliciach s {0} nie je miesto" }; private static readonly Messages Czech = new Messages { Moved = "{0} x{1} → {2} ({3} m)", Remaining = "{0} x{1} zůstává v inventáři", Equipped = "{0}: vybavené předměty se nepřesouvají", NoChestHasItem = "Žádná truhla v okolí neobsahuje {0}", InUse = "Truhlu s {0} právě používá jiný hráč", NoSpace = "V truhlách s {0} není místo" }; internal static Messages Current { get { string selectedLanguage = Localization.instance.GetSelectedLanguage(); if (!(selectedLanguage == "Slovak")) { if (selectedLanguage == "Czech") { return Czech; } return English; } return Slovak; } } } [BepInPlugin("lukas.CtrlClickSort", "CtrlClickSort", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "lukas.CtrlClickSort"; public const string PluginName = "CtrlClickSort"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry<float> Radius; internal static ConfigEntry<KeyCode> ModifierKey; internal static ConfigEntry<bool> ShowMessages; private Harmony _harmony; private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown Radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 15f, new ConfigDescription("Radius in metres to search for chests.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>())); ModifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ModifierKey", (KeyCode)306, "Key to hold while left-clicking an item in your inventory. Don't use Shift, vanilla uses it to split stacks."); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMessages", true, "Show on-screen messages about what was moved (or why nothing was)."); _harmony = new Harmony("lukas.CtrlClickSort"); _harmony.PatchAll(typeof(Plugin).Assembly); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class StackToChest { internal static bool TryStore(InventoryGui gui, Player player, ItemData item) { //IL_0016: 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) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); List<ChestCandidate> list = ContainerTracker.FindAccessibleChests(((Component)player).transform.position, Plugin.Radius.Value, playerID); if (list.Count == 0) { return false; } string text = Localize(item.m_shared.m_name); Messages current = Messages.Current; if (((Humanoid)player).IsItemEquiped(item)) { ShowMessage(player, string.Format(current.Equipped, text)); return true; } Inventory inventory = ((Humanoid)player).GetInventory(); List<string> list2 = new List<string>(); bool flag = false; bool flag2 = false; foreach (ChestCandidate item2 in list) { Container container = item2.Container; container.Load(); if (!container.GetInventory().ContainsItemByName(item.m_shared.m_name)) { continue; } flag = true; if (ContainerTracker.IsInUse(container)) { flag2 = true; continue; } int num = MoveInto(container, inventory, item); if (num > 0) { list2.Add(string.Format(current.Moved, text, num, Localize(container.m_name), Mathf.RoundToInt(item2.Distance))); } if (inventory.ContainsItem(item)) { continue; } break; } if (list2.Count > 0) { gui.m_moveItemEffects.Create(((Component)gui).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); if (inventory.ContainsItem(item)) { list2.Add(string.Format(current.Remaining, text, item.m_stack)); } ShowMessage(player, string.Join("\n", list2)); } else if (!flag) { ShowMessage(player, string.Format(current.NoChestHasItem, text)); } else if (flag2) { ShowMessage(player, string.Format(current.InUse, text)); } else { ShowMessage(player, string.Format(current.NoSpace, text)); } return true; } private static int MoveInto(Container container, Inventory playerInventory, ItemData item) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) container.m_nview.ClaimOwnership(); int stack = item.m_stack; bool num = container.GetInventory().AddItem(item); int num2 = (num ? stack : (stack - item.m_stack)); if (num) { playerInventory.RemoveItem(item); } else if (num2 > 0) { playerInventory.Changed(false, false); } if (num2 > 0) { ZDOMan.instance.ForceSendZDO(container.m_nview.GetZDO().m_uid); } return num2; } private static string Localize(string text) { return Localization.instance.Localize(text); } private static void ShowMessage(Player player, string message) { if (Plugin.ShowMessages.Value) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }