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 McAutoStore v1.2.2
McAutoStore.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; 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 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: AssemblyCompany("McAutoStore")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+59e8d89f319f7d2464e44dc09be4e1b16a5cb9f0")] [assembly: AssemblyProduct("McAutoStore")] [assembly: AssemblyTitle("McAutoStore")] [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 McAutoStore { [BepInPlugin("joaorodrigues.valheim.mcautostore", "McAutoStore", "1.2.2")] [BepInProcess("valheim.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class McAutoStorePlugin : BaseUnityPlugin { public const string Guid = "joaorodrigues.valheim.mcautostore"; public const string Name = "McAutoStore"; public const string Version = "1.2.2"; internal static ManualLogSource Log; internal static ConfigEntry<KeyboardShortcut> StoreKey; internal static ConfigEntry<float> Range; internal static ConfigEntry<bool> OnlyMatchingContainers; internal static ConfigEntry<bool> SkipHotbar; internal static ConfigEntry<bool> SkipEquipped; internal static ConfigEntry<string> IgnoredItems; internal static ConfigEntry<bool> ShowMessage; internal static ConfigEntry<bool> PullFromGround; internal static ConfigEntry<float> GroundRange; internal static ConfigEntry<float> GroundScanInterval; internal static ConfigEntry<float> GroundMinAge; private float _nextScan; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; StoreKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "StoreKey", new KeyboardShortcut((KeyCode)46, Array.Empty<KeyCode>()), "Key that stores your inventory into nearby containers."); Range = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "Range", 12f, new ConfigDescription("Search radius for containers, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 64f), Array.Empty<object>())); OnlyMatchingContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Rules", "OnlyMatchingContainers", true, "true: only store into a container that already holds that item (quick stack behaviour). false: store into any container with free space."); SkipHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Rules", "SkipHotbar", true, "Never store items from the hotbar (first inventory row)."); SkipEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Rules", "SkipEquipped", true, "Never store equipped items."); IgnoredItems = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Rules", "IgnoredItems", "Hammer,Hoe,Cultivator,SledgeStagbreaker", "Comma separated prefab names that are never stored."); ShowMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Interface", "ShowMessage", true, "Show a centered message with how many items were stored."); PullFromGround = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Ground pickup", "PullFromGround", true, "Automatically pull items lying on the ground into nearby containers. An item is only pulled when a container already holds that same item; otherwise it stays on the ground."); GroundRange = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Ground pickup", "GroundRange", 12f, new ConfigDescription("Radius around you scanned for dropped items, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 64f), Array.Empty<object>())); GroundScanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Ground pickup", "GroundScanInterval", 2f, new ConfigDescription("Seconds between ground scans.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); GroundMinAge = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Ground pickup", "GroundMinAgeSeconds", 3f, new ConfigDescription("How long an item must lie on the ground before it can be pulled. Keeps items you just dropped on purpose from being vacuumed instantly.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); SlotCompat.Init(); new Harmony("joaorodrigues.valheim.mcautostore").PatchAll(); Log.LogInfo((object)("McAutoStore 1.2.2 loaded. Key: " + ((object)StoreKey.Value/*cast due to .constrained prefix*/).ToString() + " Range: " + Range.Value + "m GroundPickup: " + PullFromGround.Value)); } private void Update() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!Player.m_localPlayerExists) { return; } if (!InventoryGui.IsVisible() && !Menu.IsVisible()) { Chat instance = Chat.instance; if (instance == null || !instance.HasFocus()) { KeyboardShortcut value = StoreKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { StoreRunner.StoreInventory(); } } } if (PullFromGround.Value && Time.time >= _nextScan) { _nextScan = Time.time + GroundScanInterval.Value; StoreRunner.PullGroundItems(); } } } internal static class SlotCompat { private static Func<ItemData, bool> _isInSlot; private static bool _resolved; private static float _nextAttempt; private const float RetrySeconds = 2f; internal static void Init() { _isInSlot = null; _resolved = false; _nextAttempt = 0f; TryResolve(startup: true); if (!_resolved) { McAutoStorePlugin.Log.LogInfo((object)"SlotCompat: no slot mod loaded yet, will look again on first use."); } } private static void TryResolve(bool startup) { if (!_resolved && (startup || !(Time.realtimeSinceStartup < _nextAttempt))) { _nextAttempt = Time.realtimeSinceStartup + 2f; Func<ItemData, bool> func = Bind("ExtraSlots.API", "IsItemInSlot") ?? Bind("AzuExtendedPlayerInventory.API", "IsSlotItem") ?? Bind("AzuExtendedPlayerInventory.API", "IsAzuSlot"); if (func != null) { _isInSlot = func; _resolved = true; McAutoStorePlugin.Log.LogInfo((object)"SlotCompat: extra-slot detection active."); } } } private static Func<ItemData, bool> Bind(string typeName, string method) { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(typeName, throwOnError: false); if (!(type == null)) { MethodInfo method2 = type.GetMethod(method, BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); if (!(method2 == null) && !(method2.ReturnType != typeof(bool))) { return (Func<ItemData, bool>)Delegate.CreateDelegate(typeof(Func<ItemData, bool>), method2); } } } } catch (Exception ex) { McAutoStorePlugin.Log.LogWarning((object)("SlotCompat bind failed for " + typeName + "." + method + ": " + ex.Message)); } return null; } internal static bool IsInModSlot(ItemData item) { if (item == null) { return false; } if (!_resolved) { TryResolve(startup: false); } if (_isInSlot == null) { return false; } try { return _isInSlot(item); } catch { return false; } } } internal static class StoreRunner { private static readonly FieldRef<Container, ZNetView> ContainerNview = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview"); private static readonly FieldRef<Container, uint> ContainerLastRevision = AccessTools.FieldRefAccess<Container, uint>("m_lastRevision"); private static readonly FieldRef<Container, Piece> ContainerPiece = AccessTools.FieldRefAccess<Container, Piece>("m_piece"); private static readonly MethodInfo ContainerLoad = AccessTools.Method(typeof(Container), "Load", (Type[])null, (Type[])null); private static readonly FieldRef<ItemDrop, ZNetView> DropNview = AccessTools.FieldRefAccess<ItemDrop, ZNetView>("m_nview"); private static readonly MethodInfo DropTimeSinceSpawned = AccessTools.Method(typeof(ItemDrop), "GetTimeSinceSpawned", (Type[])null, (Type[])null); private static readonly Collider[] PieceBuffer = (Collider[])(object)new Collider[512]; private static readonly Collider[] ItemBuffer = (Collider[])(object)new Collider[512]; private static int _pieceMask = -1; private static int _itemMask = -1; internal static void StoreInventory() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene()) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null) { return; } List<Container> list = FindContainers(((Component)localPlayer).transform.position, McAutoStorePlugin.Range.Value); if (list.Count == 0) { if (McAutoStorePlugin.ShowMessage.Value) { ((Character)localPlayer).Message((MessageType)2, "No container nearby", 0, (Sprite)null, false); } return; } HashSet<string> ignored = BuildIgnoreSet(); int num = 0; foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (!Storable(localPlayer, item, ignored)) { continue; } foreach (Container item2 in list) { if (TryStore(item2, inventory, item, McAutoStorePlugin.OnlyMatchingContainers.Value)) { num++; break; } } } if (McAutoStorePlugin.ShowMessage.Value) { ((Character)localPlayer).Message((MessageType)2, (num > 0) ? (num + " item(s) stored") : "Nothing to store", 0, (Sprite)null, false); } McAutoStorePlugin.Log.LogInfo((object)("StoreInventory: " + num + " item(s) into " + list.Count + " container(s) in range.")); } internal static void PullGroundItems() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene()) { return; } Vector3 position = ((Component)localPlayer).transform.position; if (_itemMask < 0) { _itemMask = LayerMask.GetMask(new string[1] { "item" }); } int num = Physics.OverlapSphereNonAlloc(position, McAutoStorePlugin.GroundRange.Value, ItemBuffer, _itemMask); if (num == 0) { return; } List<Container> list = null; int num2 = 0; HashSet<ItemDrop> hashSet = new HashSet<ItemDrop>(); for (int i = 0; i < num; i++) { ItemDrop componentInParent = ((Component)ItemBuffer[i]).GetComponentInParent<ItemDrop>(); if ((Object)(object)componentInParent == (Object)null || !hashSet.Add(componentInParent) || componentInParent.m_itemData?.m_shared == null) { continue; } ZNetView val = DropNview.Invoke(componentInParent); if ((Object)(object)val == (Object)null || !val.IsValid() || !componentInParent.CanPickup(true) || (double)(DropTimeSinceSpawned?.Invoke(componentInParent, null) ?? ((object)0.0)) < (double)McAutoStorePlugin.GroundMinAge.Value) { continue; } if (list == null) { list = FindContainers(position, McAutoStorePlugin.Range.Value); if (list.Count == 0) { return; } } foreach (Container item in list) { Inventory inventory = item.GetInventory(); if (inventory == null || !inventory.ContainsItemByName(componentInParent.m_itemData.m_shared.m_name) || !inventory.CanAddItem(componentInParent.m_itemData, -1) || !PrepareContainer(item)) { continue; } if (!val.IsOwner()) { val.ClaimOwnership(); if (!val.IsOwner()) { break; } } if (inventory.AddItem(componentInParent.m_itemData)) { val.Destroy(); num2++; break; } } } if (num2 > 0) { McAutoStorePlugin.Log.LogInfo((object)("PullGroundItems: " + num2 + " item(s) pulled from the ground.")); } } private static HashSet<string> BuildIgnoreSet() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string[] array = (McAutoStorePlugin.IgnoredItems.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { hashSet.Add(text); } } return hashSet; } private static bool Storable(Player player, ItemData item, HashSet<string> ignored) { if (item?.m_shared == null) { return false; } if (McAutoStorePlugin.SkipEquipped.Value && ((Humanoid)player).IsItemEquiped(item)) { return false; } if (SlotCompat.IsInModSlot(item)) { return false; } if (McAutoStorePlugin.SkipHotbar.Value && item.m_gridPos.y == 0) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && ignored.Contains(((Object)item.m_dropPrefab).name)) { return false; } if (ignored.Contains(item.m_shared.m_name)) { return false; } return true; } private static bool PrepareContainer(Container c) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Invalid comparison between Unknown and I4 //IL_00e1: Unknown result type (might be due to invalid IL or missing references) ZNetView val = ContainerNview.Invoke(c); if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } if (c.GetInventory() == null) { return false; } if (val.IsOwner() ? c.IsInUse() : (val.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1)) { return false; } if (c.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)c).transform.position, 0f, false, false)) { return false; } if ((int)c.m_privacy == 0) { Piece val2 = ContainerPiece.Invoke(c); long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); if ((Object)(object)val2 == (Object)null || val2.GetCreator() != playerID) { return false; } } else if ((int)c.m_privacy == 1) { return false; } if (!val.IsOwner()) { val.ClaimOwnership(); if (!val.IsOwner()) { return false; } ZDOMan.instance.ForceSendZDO(ZDOMan.GetSessionID(), val.GetZDO().m_uid); ContainerLastRevision.Invoke(c) = uint.MaxValue; ContainerLoad?.Invoke(c, null); } return true; } private static bool TryStore(Container c, Inventory from, ItemData item, bool requireMatch) { Inventory inventory = c.GetInventory(); if (inventory == null) { return false; } if (requireMatch && !inventory.ContainsItemByName(item.m_shared.m_name)) { return false; } if (!inventory.CanAddItem(item, -1)) { return false; } if (!PrepareContainer(c)) { return false; } if (!inventory.AddItem(item)) { return false; } from.RemoveItem(item); return true; } private static List<Container> FindContainers(Vector3 pos, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (_pieceMask < 0) { _pieceMask = LayerMask.GetMask(new string[3] { "piece", "piece_nonsolid", "vehicle" }); } HashSet<Container> hashSet = new HashSet<Container>(); List<Container> list = new List<Container>(); int num = Physics.OverlapSphereNonAlloc(pos, range, PieceBuffer, _pieceMask); for (int i = 0; i < num; i++) { Container componentInParent = ((Component)PieceBuffer[i]).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(componentInParent)) { list.Add(componentInParent); } } list.Sort(delegate(Container a, Container b) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)a).transform.position - pos; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; val = ((Component)b).transform.position - pos; return sqrMagnitude.CompareTo(((Vector3)(ref val)).sqrMagnitude); }); return list; } } }