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 SmartDeposit v0.1.2
BepInEx/plugins/SmartDeposit.dll
Decompiled an hour 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 HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("SmartDeposit")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: AssemblyInformationalVersion("0.1.2")] [assembly: AssemblyProduct("SmartDeposit")] [assembly: AssemblyTitle("SmartDeposit")] [assembly: AssemblyVersion("0.1.2.0")] namespace SmartDeposit; [BepInPlugin("local.valheim.smartdeposit", "Smart Deposit", "0.1.2")] public sealed class Plugin : BaseUnityPlugin { private sealed class Request { public Player Player; public bool Done; public bool Cancelled; public float Deadline; } [HarmonyPatch(typeof(Container), "RPC_StackResponse")] private static class ResponsePatch { private static bool Prefix(Container __instance, bool __1) { if (!Object.op_Implicit((Object)(object)instance) || !instance.pending.TryGetValue(__instance, out var value)) { return true; } instance.pending.Remove(__instance); instance.Response(__instance, __1, value); return false; } } [HarmonyPatch(typeof(Container), "StackAll")] private static class StackPatch { private static bool Prefix(Container __instance) { if (Object.op_Implicit((Object)(object)instance) && instance.pending.ContainsKey(__instance)) { return (Object)(object)instance.dispatching == (Object)(object)__instance; } return true; } } private static class CommandPatch { internal static bool Prefix(Terminal __instance, string __0) { string[] array = (__0 ?? "").Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0 || !array[0].Equals("smartdeposit", StringComparison.OrdinalIgnoreCase)) { return true; } if (!Object.op_Implicit((Object)(object)instance) || !((Behaviour)instance).enabled) { __instance.AddString("Smart Deposit unavailable."); return false; } if (array.Length == 1) { instance.Begin(); return false; } if (array.Length == 3 && (array[1].Equals("keep", StringComparison.OrdinalIgnoreCase) || array[1].Equals("unkeep", StringComparison.OrdinalIgnoreCase))) { HashSet<string> hashSet = new HashSet<string>(from s in instance.keep.Value.Split(',') select s.Trim() into s where s.Length > 0 select s, StringComparer.OrdinalIgnoreCase); if (array[1].Equals("keep", StringComparison.OrdinalIgnoreCase)) { hashSet.Add(array[2]); } else { hashSet.Remove(array[2]); } instance.keep.Value = string.Join(",", hashSet.OrderBy((string s) => s)); __instance.AddString("Smart Deposit keep list: " + instance.keep.Value); return false; } __instance.AddString("Usage: /smartdeposit; /smartdeposit keep Wood; /smartdeposit unkeep Wood. Keep list: " + instance.keep.Value); return false; } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Container, bool> <>9__20_2; public static ConsoleEvent <>9__25_0; internal bool <Deposit>b__20_2(Container c) { return !Object.op_Implicit((Object)(object)c); } internal void <RegisterCommand>b__25_0(ConsoleEventArgs args) { CommandPatch.Prefix(args.Context, args.FullLine); } } public const string Id = "local.valheim.smartdeposit"; private static Plugin instance; private Harmony harmony; private ConfigEntry<KeyboardShortcut> key; private ConfigEntry<float> range; private ConfigEntry<string> keep; private bool busy; private Container dispatching; private int moved; private int chests; private readonly Dictionary<Container, Request> pending = new Dictionary<Container, Request>(); private static readonly MethodInfo Load = AccessTools.Method(typeof(Container), "Load", (Type[])null, (Type[])null); private static readonly MethodInfo CheckAccess = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null); private void Awake() { //IL_0021: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown instance = this; key = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "DepositKey", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Deposit matching items into nearby chests."); range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range", 10f, new ConfigDescription("Search range in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); keep = ((BaseUnityPlugin)this).Config.Bind<string>("General", "KeepItems", "", "Comma-separated item prefab names to protect. Use /smartdeposit keep Wood, or /smartdeposit unkeep Wood."); harmony = new Harmony("local.valheim.smartdeposit"); try { harmony.PatchAll(); RegisterCommand(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Smart Deposit 0.1.2 loaded: F10 or /smartdeposit."); } catch (Exception ex) { harmony.UnpatchSelf(); ((Behaviour)this).enabled = false; ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void Update() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible()) { KeyboardShortcut value = key.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Begin(); } } } private void Say(string message) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Smart Deposit: " + message, 0, (Sprite)null, false); } } private void Begin() { if (busy) { Say("already working."); } else if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || ((Character)Player.m_localPlayer).IsDead() || InventoryGui.IsVisible()) { Say("close your inventory first."); } else { ((MonoBehaviour)this).StartCoroutine(Deposit()); } } private bool Allowed(Container c, Player p) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)c) || !Object.op_Implicit((Object)(object)p) || (Object)(object)p != (Object)(object)Player.m_localPlayer || ((Character)p).IsDead() || InventoryGui.IsVisible()) { return false; } if (Vector3.Distance(((Component)c).transform.position, ((Component)p).transform.position) > range.Value || c.IsInUse()) { return false; } Piece component = ((Component)c).GetComponent<Piece>(); if (!Object.op_Implicit((Object)(object)component) || component.GetCreator() == 0L || Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<Vagon>())) { return false; } ZNetView component2 = ((Component)c).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component2) && component2.IsValid() && (bool)CheckAccess.Invoke(c, new object[1] { p.GetPlayerID() })) { return PrivateArea.CheckAccess(((Component)c).transform.position, 0f, false, false); } return false; } private bool Eligible(ItemData item, Player p) { if (item.m_gridPos.y == 0 || item.m_equipped || ((Humanoid)p).IsItemEquiped(item) || item.m_stack <= 0) { return false; } if (item.m_customData != null && item.m_customData.Count > 0) { return false; } string prefab = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : ""); return !keep.Value.Split(',').Any((string x) => x.Trim().Equals(prefab, StringComparison.OrdinalIgnoreCase)); } private IEnumerator Deposit() { busy = true; moved = 0; chests = 0; Player p = Player.m_localPlayer; try { Container[] array = pending.Keys.Where((Container val2) => !Object.op_Implicit((Object)(object)val2)).ToArray(); foreach (Container val in array) { pending.Remove(val); } Container[] array2 = (from val2 in Object.FindObjectsByType<Container>((FindObjectsSortMode)0) where Allowed(val2, p) orderby Vector3.Distance(((Component)val2).transform.position, ((Component)p).transform.position) select val2).ToArray(); Container[] array3 = array2; foreach (Container c in array3) { if (!Allowed(c, p) || pending.ContainsKey(c)) { continue; } Request request = new Request { Player = p, Deadline = Time.realtimeSinceStartup + 4f }; pending.Add(c, request); try { dispatching = c; c.StackAll(); } catch (Exception ex) { request.Cancelled = true; request.Done = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)ex); } finally { dispatching = null; } while (!request.Done && Object.op_Implicit((Object)(object)c) && Time.realtimeSinceStartup < request.Deadline) { yield return null; } if (!request.Done) { request.Cancelled = true; } yield return null; } Say((moved > 0) ? $"deposited {moved} items into {chests} chests." : "nothing deposited. No accessible matching space, or all items protected."); } finally { busy = false; } } private void Response(Container c, bool granted, Request request) { try { if (!granted || request.Cancelled || Time.realtimeSinceStartup > request.Deadline || !Allowed(c, request.Player)) { return; } ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (!component.IsOwner()) { return; } Load.Invoke(c, null); if (Allowed(c, request.Player) && component.IsOwner()) { Inventory inventory = ((Humanoid)request.Player).GetInventory(); Inventory inventory2 = c.GetInventory(); int num = Transfer(inventory, inventory2, (ItemData item) => Eligible(item, request.Player)); moved += num; if (num > 0) { chests++; } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Say("transfer stopped; check the BepInEx log."); } finally { request.Done = true; } } internal static int Transfer(Inventory source, Inventory target, Func<ItemData, bool> eligible) { int num = 0; ItemData[] array = source.GetAllItems().ToArray(); foreach (ItemData item in array) { if (!eligible(item) || !target.GetAllItems().Any((ItemData t) => t.IsSameType(item))) { continue; } ItemData[] array2 = (from t in target.GetAllItems() where t.IsSameType(item) select t).ToArray(); foreach (ItemData val in array2) { int num3 = Math.Min(item.m_stack, Math.Max(0, val.m_shared.m_maxStackSize - val.m_stack)); if (num3 > 0) { int stack = item.m_stack; target.MoveItemToThis(source, item, num3, val.m_gridPos.x, val.m_gridPos.y); num += stack - item.m_stack; } } for (int num4 = 0; num4 < target.GetHeight(); num4++) { if (item.m_stack <= 0) { break; } for (int num5 = 0; num5 < target.GetWidth(); num5++) { if (item.m_stack <= 0) { break; } if (target.GetItemAt(num5, num4) == null) { int stack2 = item.m_stack; target.MoveItemToThis(source, item, Math.Min(item.m_stack, item.m_shared.m_maxStackSize), num5, num4); num += stack2 - item.m_stack; } } } } return num; } private static void RegisterCommand() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__25_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { CommandPatch.Prefix(args.Context, args.FullLine); }; <>c.<>9__25_0 = val; obj = (object)val; } new ConsoleCommand("smartdeposit", "Deposit nearby matching items. Usage: smartdeposit [keep|unkeep ItemPrefab]", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } instance = null; } }