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 EpicLootChestBridge v1.0.0
EpicLootChestBridge.dll
Decompiled 2 weeks agousing System; using System.Collections; 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 UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")] [assembly: AssemblyCompany("EpicLootChestBridge")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EpicLootChestBridge")] [assembly: AssemblyTitle("EpicLootChestBridge")] [assembly: AssemblyVersion("1.0.0.0")] namespace EpicLootChestBridge; [BepInPlugin("burksheim.epiclootchestbridge", "Epic Loot Chest Bridge", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EpicLootChestBridgePlugin : BaseUnityPlugin { public const string PluginGuid = "burksheim.epiclootchestbridge"; public const string PluginName = "Epic Loot Chest Bridge"; public const string PluginVersion = "1.0.0"; public const string EpicLootGuid = "randyknapp.mods.epicloot"; public const string ValheimPlusGuid = "org.bepinex.plugins.valheim_plus"; private const string ProviderId = "ValheimPlus.CraftFromChest"; private ConfigEntry<bool> _enabled; private readonly ValheimPlusChests _chests = new ValheimPlusChests(); private MethodInfo _unregister; private bool _registered; private MethodInfo _tableVisible; private Func<object, object> _tableInstance; private Func<object, object> _tableSource; private FieldInfo _localPlayer; private void Awake() { _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Let the Epic Loot enchanting table use materials from chests in Valheim Plus's Craft From Chest range."); Type type = Reflect.FindType("EpicLoot.API"); Type type2 = Reflect.FindType("EpicLoot_UnityLib.EnchantingTableUI"); Type type3 = Reflect.FindType("Player"); if (type == null || type2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Epic Loot not found; nothing to do."); } else if (!(type3 == null) && _chests.TryResolve(((BaseUnityPlugin)this).Logger)) { _tableVisible = Reflect.Method(type2, "IsVisible"); _tableInstance = Reflect.Getter(type2, "instance"); _tableSource = Reflect.Getter(type2, "SourceTable"); _localPlayer = Reflect.Field(type3, "m_localPlayer"); if (_tableVisible == null || _localPlayer == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"This Epic Loot version's enchanting table can't be detected; bridge disabled."); } else { Register(type); } } } private void Register(Type api) { MethodInfo method = api.GetMethod("RegisterInventoryProvider", BindingFlags.Static | BindingFlags.Public); _unregister = api.GetMethod("UnregisterInventoryProvider", BindingFlags.Static | BindingFlags.Public); ParameterInfo[] array = method?.GetParameters(); if (array == null || array.Length != 5 || array[0].ParameterType != typeof(string)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Epic Loot's inventory provider API is missing or changed (needs Epic Loot 0.14+); bridge disabled."); return; } Type type = array[4].ParameterType.GetGenericArguments()[0]; Type typeFromHandle = typeof(EpicLootChestBridgePlugin); Delegate obj = Delegate.CreateDelegate(array[1].ParameterType, typeFromHandle.GetMethod("NoItems", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(type)); Delegate obj2 = Delegate.CreateDelegate(array[2].ParameterType, this, typeFromHandle.GetMethod("CountItem", BindingFlags.Instance | BindingFlags.NonPublic)); Delegate obj3 = Delegate.CreateDelegate(array[3].ParameterType, this, typeFromHandle.GetMethod("RemoveItem", BindingFlags.Instance | BindingFlags.NonPublic)); Delegate obj4 = Delegate.CreateDelegate(array[4].ParameterType, typeFromHandle.GetMethod("RemoveNothing", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(type)); _registered = (bool)method.Invoke(null, new object[5] { "ValheimPlus.CraftFromChest", obj, obj2, obj3, obj4 }); if (_registered) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Enchanting table can now use materials from Valheim Plus Craft From Chest chests."); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Epic Loot refused the chest provider registration."); } } private static List<T> NoItems<T>() { return new List<T>(); } private static int RemoveNothing<T>(T item, int amount) { return 0; } private int CountItem(string itemName) { if (!Active(out var origin)) { return 0; } return _chests.Count(origin, itemName); } private int RemoveItem(string itemName, int amount) { if (amount <= 0 || !Active(out var origin)) { return 0; } int num = _chests.Remove(origin, itemName, amount); if (num > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Took " + num + " x " + itemName + " from nearby chests.")); } return num; } private bool Active(out GameObject origin) { origin = null; if (!_enabled.Value || !_chests.Enabled) { return false; } if (!(bool)_tableVisible.Invoke(null, null)) { return false; } object? value = _localPlayer.GetValue(null); Component val = (Component)((value is Component) ? value : null); if ((Object)(object)val == (Object)null) { return false; } origin = val.gameObject; if (_chests.CheckFromWorkbench && _tableInstance != null && _tableSource != null) { object obj = _tableInstance(null); Component val2 = (Component)((obj != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 != (Object)null) { origin = val2.gameObject; } } return true; } private void OnDestroy() { if (_registered) { _unregister?.Invoke(null, new object[1] { "ValheimPlus.CraftFromChest" }); } } } internal sealed class ValheimPlusChests { private Func<object, object> _current; private Func<object, object> _section; private Func<object, object> _isEnabled; private Func<object, object> _range; private Func<object, object> _checkFromWorkbench; private Func<object, object> _ignoreWards; private Func<object, object> _lookupInterval; private MethodInfo _getNearbyChests; private MethodInfo _chestItems; private MethodInfo _removeFromChest; private FieldInfo _itemShared; private FieldInfo _sharedName; private FieldInfo _itemStack; private IList _cachedChests; private GameObject _cachedOrigin; private float _cachedAt = float.MinValue; public bool Enabled => Get(_isEnabled, fallback: false); public bool CheckFromWorkbench => Get(_checkFromWorkbench, fallback: false); public bool TryResolve(ManualLogSource log) { Type type = Reflect.FindType("ValheimPlus.Configurations.Configuration"); Type type2 = Reflect.FindType("ValheimPlus.InventoryAssistant"); Type type3 = Reflect.FindType("ItemDrop+ItemData"); Type type4 = Reflect.FindType("Container"); if (type == null || type2 == null) { log.LogWarning((object)"Valheim Plus not found; nothing to do."); return false; } _current = Reflect.Getter(type, "Current"); _section = Reflect.Getter(type, "CraftFromChest"); Type type5 = Reflect.FindType("ValheimPlus.Configurations.Sections.CraftFromChestConfiguration"); if (type5 != null) { _isEnabled = Reflect.Getter(type5, "IsEnabled"); _range = Reflect.Getter(type5, "range"); _checkFromWorkbench = Reflect.Getter(type5, "checkFromWorkbench"); _ignoreWards = Reflect.Getter(type5, "ignorePrivateAreaCheck"); _lookupInterval = Reflect.Getter(type5, "lookupInterval"); } _getNearbyChests = Reflect.Method(type2, "GetNearbyChests", typeof(GameObject), typeof(float), typeof(bool), typeof(bool)); if (type3 != null) { MethodInfo[] methods = type2.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (methodInfo.Name == "GetNearbyChestItemsByContainerList" && parameters.Length == 1) { _chestItems = methodInfo; } if (methodInfo.Name == "RemoveItemFromChest" && parameters.Length == 3 && parameters[1].ParameterType == typeof(string) && parameters[2].ParameterType == typeof(int) && (type4 == null || parameters[0].ParameterType == type4)) { _removeFromChest = methodInfo; } } _itemShared = Reflect.Field(type3, "m_shared"); _itemStack = Reflect.Field(type3, "m_stack"); if (_itemShared != null) { _sharedName = Reflect.Field(_itemShared.FieldType, "m_name"); } } if (_current == null || _section == null || _isEnabled == null || _range == null || _getNearbyChests == null || _chestItems == null || _removeFromChest == null || _sharedName == null || _itemStack == null) { log.LogWarning((object)"This Valheim Plus version's Craft From Chest API is different than expected; bridge disabled."); return false; } return true; } private object Section() { object obj = _current(null); if (obj == null) { return null; } return _section(obj); } private T Get<T>(Func<object, object> getter, T fallback) { object obj = Section(); if (obj == null || getter == null) { return fallback; } object obj2 = getter(obj); if (obj2 is T) { return (T)obj2; } return fallback; } private IList Chests(GameObject origin, bool forceRefresh) { float num = Math.Max(1, Math.Min(10, Get(_lookupInterval, 3))); if (!forceRefresh && _cachedChests != null && (Object)(object)_cachedOrigin == (Object)(object)origin && Time.time - _cachedAt < num) { return _cachedChests; } float num2 = Math.Max(1f, Math.Min(50f, Get(_range, 20f))); bool flag = !Get(_ignoreWards, fallback: false); _cachedChests = _getNearbyChests.Invoke(null, new object[4] { origin, num2, flag, true }) as IList; _cachedOrigin = origin; _cachedAt = Time.time; return _cachedChests; } public int Count(GameObject origin, string itemName) { IList list = Chests(origin, forceRefresh: false); if (list == null || list.Count == 0) { return 0; } if (!(_chestItems.Invoke(null, new object[1] { list }) is IList list2)) { return 0; } int num = 0; foreach (object item in list2) { object obj = ((item != null) ? _itemShared.GetValue(item) : null); if (obj != null && (string)_sharedName.GetValue(obj) == itemName) { num += (int)_itemStack.GetValue(item); } } return num; } public int Remove(GameObject origin, string itemName, int amount) { IList list = Chests(origin, forceRefresh: true); if (list == null) { return 0; } int num = amount; foreach (object item in list) { if (num <= 0) { break; } Object val = (Object)((item is Object) ? item : null); if (val == null || !(val == (Object)null)) { num -= (int)_removeFromChest.Invoke(null, new object[3] { item, itemName, num }); } } _cachedAt = float.MinValue; return amount - num; } } internal static class Reflect { private const BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; public static Type FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = null; try { type = assembly.GetType(fullName, throwOnError: false); } catch (Exception) { } if (type != null) { return type; } } return null; } public static FieldInfo Field(Type type, string name) { Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type2 = type2.BaseType; } return null; } public static Func<object, object> Getter(Type type, string name) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0 && property.GetGetMethod(nonPublic: true) != null) { MethodInfo g = property.GetGetMethod(nonPublic: true); return (object o) => g.Invoke(g.IsStatic ? null : o, null); } FieldInfo f = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (f != null) { return (object o) => f.GetValue(f.IsStatic ? null : o); } type2 = type2.BaseType; } return null; } public static MethodInfo Method(Type type, string name, params Type[] parameters) { Type type2 = type; while (type2 != null) { MethodInfo method = type2.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method != null) { return method; } type2 = type2.BaseType; } return null; } }