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 SmartStorage v0.2.0
plugins/SmartStorage.dll
Decompiled 2 months agousing System; 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 SmartStorage.Core; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SmartStorage")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Smart Storage for Valheim - automatic item sorting into chests")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("SmartStorage")] [assembly: AssemblyTitle("SmartStorage")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 SmartStorage { [BepInPlugin("com.macheon.smartstorage", "SmartStorage", "0.2.0")] public class SmartStoragePlugin : BaseUnityPlugin { public const string PluginGuid = "com.macheon.smartstorage"; public const string PluginName = "SmartStorage"; public const string PluginVersion = "0.2.0"; private Harmony? _harmony; internal static ManualLogSource? LogSource; internal static ConfigEntry<bool>? ModEnabled; internal static ConfigEntry<float>? ScanRadius; internal static ConfigEntry<bool>? ShowNotifications; internal static ConfigEntry<bool>? RequireOwnedContainers; internal static ConfigEntry<bool>? VerboseLogging; private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown LogSource = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Enable or disable the Smart Storage mod entirely."); ScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2. Detection", "ScanRadius", 10f, new ConfigDescription("Search radius (in meters) around the player to find matching containers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); ShowNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("3. UI", "ShowNotifications", true, "Show a HUD message when an item is auto-sorted."); RequireOwnedContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Multiplayer", "RequireOwnedContainers", true, "Only target containers you own (recommended in multiplayer to avoid issues)."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Debug", "VerboseLogging", false, "Log every Smart Storage transfer to the BepInEx console."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"======================================"); ((BaseUnityPlugin)this).Logger.LogInfo((object)" SmartStorage v0.2.0 loaded!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" Scan radius: {ScanRadius.Value}m | Notifications: {ShowNotifications.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"======================================"); _harmony = new Harmony("com.macheon.smartstorage"); _harmony.PatchAll(); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace SmartStorage.Patches { [HarmonyPatch] public static class InventoryPatches { private static string GetItemName(ItemData item) { return (Localization.instance != null) ? Localization.instance.Localize(item.m_shared.m_name) : item.m_shared.m_name; } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] [HarmonyPrefix] public static bool OnSelectedItem_Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<bool>? modEnabled = SmartStoragePlugin.ModEnabled; if (modEnabled != null && !modEnabled.Value) { return true; } if (item == null) { return true; } if ((int)mod != 2) { return true; } if (!__instance.IsContainerOpen()) { return true; } if (item.m_shared.m_questItem) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting()) { return true; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (grid.GetInventory() != inventory) { return true; } Container currentContainer = GetCurrentContainer(__instance); float radius = SmartStoragePlugin.ScanRadius?.Value ?? 10f; bool requireOwned = SmartStoragePlugin.RequireOwnedContainers?.Value ?? true; Container val = ContainerScanner.FindBestContainerForItem(item, ((Component)localPlayer).transform.position, currentContainer, radius, requireOwned); if ((Object)(object)val == (Object)null) { return true; } string itemName = GetItemName(item); int stack = item.m_stack; val.GetInventory().MoveItemToThis(inventory, item); ConfigEntry<bool>? showNotifications = SmartStoragePlugin.ShowNotifications; if (showNotifications != null && showNotifications.Value) { string text = $"\ud83d\udce6 {itemName} x{stack} → coffre intelligent"; MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false); } } ConfigEntry<bool>? verboseLogging = SmartStoragePlugin.VerboseLogging; if (verboseLogging != null && verboseLogging.Value) { ManualLogSource? logSource = SmartStoragePlugin.LogSource; if (logSource != null) { logSource.LogInfo((object)$"[SMART STORE] {itemName} x{stack} → {((Object)val).name} at {((Component)val).transform.position}"); } } return false; } private static Container? GetCurrentContainer(InventoryGui gui) { object? obj = typeof(InventoryGui).GetField("m_currentContainer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(gui); return (Container?)((obj is Container) ? obj : null); } } } namespace SmartStorage.Core { public static class ContainerScanner { public const float DefaultScanRadius = 10f; private const float CacheLifetimeSeconds = 2f; private static Container[]? _cachedContainers = null; private static float _cacheTimestamp = 0f; private static Vector3 _cachePosition = Vector3.zero; private const float CachePositionThreshold = 5f; public static Container? FindBestContainerForItem(ItemData item, Vector3 playerPosition, Container? excludeContainer = null, float radius = 10f, bool requireOwned = true) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (item == null) { return null; } string name = item.m_shared.m_name; float num = radius * radius; Container[] cachedOrFreshContainers = GetCachedOrFreshContainers(playerPosition); Container[] array = cachedOrFreshContainers; foreach (Container val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)excludeContainer) { continue; } Vector3 val2 = ((Component)val).transform.position - playerPosition; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude > num) && (!requireOwned || val.IsOwner())) { Inventory inventory = val.GetInventory(); if (inventory != null && inventory.HaveItem(name, false) && inventory.CanAddItem(item, item.m_stack)) { return val; } } } return null; } private static Container[] GetCachedOrFreshContainers(Vector3 playerPosition) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; Vector3 val = playerPosition - _cachePosition; float magnitude = ((Vector3)(ref val)).magnitude; if (_cachedContainers == null || !(time - _cacheTimestamp < 2f) || !(magnitude < 5f)) { _cachedContainers = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); _cacheTimestamp = time; _cachePosition = playerPosition; } return _cachedContainers; } } }