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 SafeItemMove v1.0.0
SafeItemMove.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; 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.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("SafeItemMove")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SafeItemMove")] [assembly: AssemblyTitle("SafeItemMove")] [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 SafeItemMove { [BepInPlugin("pieter.valheim.safeitemmove", "Safe Item Move", "1.0.0")] public class Plugin : BaseUnityPlugin { private sealed class Snapshot { public Inventory From; public Inventory To; public readonly Dictionary<string, int> Counts = new Dictionary<string, int>(); public readonly Dictionary<string, ItemData> Samples = new Dictionary<string, ItemData>(); public bool Container; public string Description; } public const string Guid = "pieter.valheim.safeitemmove"; public const string Name = "Safe Item Move"; public const string Version = "1.0.0"; private static ManualLogSource _log; private static readonly FieldRef<InventoryGui, Container> CurrentContainer = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer"); private void Awake() { _log = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(typeof(Plugin), "pieter.valheim.safeitemmove"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Watching inventory drag and drop for vanished items."); } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] [HarmonyPrefix] [HarmonyPriority(800)] private static void Before(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, out Snapshot __state) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) __state = null; Inventory val = ((__instance != null) ? __instance.GetInventory() : null); if (val == null || fromInventory == null || item?.m_shared == null) { return; } try { ItemData itemAt = val.GetItemAt(pos.x, pos.y); Snapshot snapshot = new Snapshot { From = fromInventory, To = val }; ItemData[] array = (ItemData[])(object)new ItemData[2] { item, itemAt }; foreach (ItemData val2 in array) { if (val2?.m_shared != null && !snapshot.Counts.ContainsKey(val2.m_shared.m_name)) { snapshot.Counts[val2.m_shared.m_name] = Count(snapshot, val2.m_shared.m_name); snapshot.Samples[val2.m_shared.m_name] = val2.Clone(); } } Container val3 = (((Object)(object)InventoryGui.instance != (Object)null) ? CurrentContainer.Invoke(InventoryGui.instance) : null); Inventory val4 = (((Object)(object)val3 != (Object)null) ? val3.GetInventory() : null); snapshot.Container = val4 != null && (fromInventory == val4 || val == val4); snapshot.Description = $"{item.m_shared.m_name} x{amount} from ({item.m_gridPos.x},{item.m_gridPos.y}) " + $"to ({pos.x},{pos.y})" + ((itemAt != null) ? $" holding {itemAt.m_shared.m_name} x{itemAt.m_stack}" : ""); __state = snapshot; } catch (Exception ex) { _log.LogWarning((object)("Could not snapshot a drop: " + ex.Message)); } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] [HarmonyFinalizer] [HarmonyPriority(0)] private static Exception After(Exception __exception, Snapshot __state) { if (__state == null) { return __exception; } try { foreach (KeyValuePair<string, int> count in __state.Counts) { int num = count.Value - Count(__state, count.Key); if (num > 0) { string key = count.Key; if (__state.Container) { _log.LogWarning((object)$"{key} x{num} not back yet after moving {__state.Description} (container, left alone)"); continue; } _log.LogWarning((object)$"{key} x{num} vanished while moving {__state.Description}; giving it back."); GiveBack(__state, __state.Samples[count.Key], num); } } } catch (Exception ex) { _log.LogWarning((object)("Could not check a drop: " + ex.Message)); } return __exception; } private static int Count(Snapshot s, string name) { int num = Sum(s.From, name); if (s.To != s.From) { num += Sum(s.To, name); } return num; } private static int Sum(Inventory inventory, string name) { int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem?.m_shared != null && allItem.m_shared.m_name == name) { num += allItem.m_stack; } } return num; } private static void GiveBack(Snapshot s, ItemData sample, int missing) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) int val = Math.Max(1, sample.m_shared.m_maxStackSize); while (missing > 0) { ItemData val2 = sample.Clone(); val2.m_stack = Math.Min(val, missing); missing -= val2.m_stack; if (!s.From.AddItem(val2) && (s.To == s.From || !s.To.AddItem(val2))) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Vector3 val3 = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + Vector3.up; ItemDrop.DropItem(val2, val2.m_stack, val3, Quaternion.identity); _log.LogWarning((object)$"No room for {val2.m_shared.m_name} x{val2.m_stack}; dropped it at your feet."); } } } } } }