Decompiled source of EpicLootContainerBridge v1.0.0

plugins/EpicLootContainerBridge/EpicLootContainerBridge.dll

Decompiled 2 weeks ago
using System;
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 Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("EpicLootContainerBridge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EpicLootContainerBridge")]
[assembly: AssemblyTitle("EpicLootContainerBridge")]
[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 EpicLootContainerBridge
{
	[BepInPlugin("KlownKiller.EpicLootContainerBridge", "EpicLoot Container Bridge", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private const string ProviderId = "KlownKiller.EpicLootContainerBridge.InventoryProvider";

		private ConfigEntry<float> _containerRange;

		private bool _registered;

		private bool _errorLogged;

		private float _nextRegisterAttempt;

		private static Type _enchantingTableUIType;

		private static FieldInfo _uiInstanceField;

		private static PropertyInfo _uiInstanceProperty;

		private static FieldInfo _sourceTableField;

		private static PropertyInfo _sourceTableProperty;

		private static MethodInfo _unregisterProvider;

		private static readonly MethodInfo ContainerSaveMethod = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private void Awake()
		{
			_containerRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContainerRange", 10f, "Rayon autour de la station EpicLoot dans lequel les coffres sont utilises.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"EpicLoot Container Bridge 1.0.0 loaded.");
		}

		private void Update()
		{
			if (!_registered && !(Time.unscaledTime < _nextRegisterAttempt))
			{
				_nextRegisterAttempt = Time.unscaledTime + 1f;
				TryRegister();
			}
		}

		private void OnDestroy()
		{
			if (!_registered || _unregisterProvider == null)
			{
				return;
			}
			try
			{
				_unregisterProvider.Invoke(null, new object[1] { "KlownKiller.EpicLootContainerBridge.InventoryProvider" });
			}
			catch
			{
			}
		}

		private void TryRegister()
		{
			Type type = FindType("EpicLoot.API");
			_enchantingTableUIType = FindType("EpicLoot_UnityLib.EnchantingTableUI");
			if (type == null || _enchantingTableUIType == null)
			{
				return;
			}
			_uiInstanceField = _enchantingTableUIType.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			_uiInstanceProperty = _enchantingTableUIType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			_sourceTableField = _enchantingTableUIType.GetField("SourceTable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_sourceTableProperty = _enchantingTableUIType.GetProperty("SourceTable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if ((_uiInstanceField == null && _uiInstanceProperty == null) || (_sourceTableField == null && _sourceTableProperty == null))
			{
				LogErrorOnce("Impossible de trouver EnchantingTableUI.instance ou SourceTable.");
				return;
			}
			MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo x) => x.Name == "RegisterInventoryProvider" && x.GetParameters().Length == 5);
			_unregisterProvider = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo x) => x.Name == "UnregisterInventoryProvider" && x.GetParameters().Length == 1);
			if (methodInfo == null)
			{
				LogErrorOnce("EpicLoot.RegisterInventoryProvider introuvable.");
				return;
			}
			try
			{
				object obj = methodInfo.Invoke(null, new object[5]
				{
					"KlownKiller.EpicLootContainerBridge.InventoryProvider",
					new Func<List<ItemData>>(GetContainerItems),
					new Func<string, int>(CountContainerItem),
					new Func<string, int, int>(RemoveContainerItem),
					new Func<ItemData, int, int>(RemoveExactContainerItem)
				});
				if (methodInfo.ReturnType == typeof(bool) && obj is bool && !(bool)obj)
				{
					LogErrorOnce("EpicLoot a refuse le provider.");
					return;
				}
				_registered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Provider EpicLoot / coffres autour de la station enregistre.");
			}
			catch (Exception ex)
			{
				LogErrorOnce("Erreur enregistrement EpicLoot: " + ex);
			}
		}

		private static Component GetCurrentEpicLootStation()
		{
			if (_enchantingTableUIType == null)
			{
				return null;
			}
			try
			{
				object obj = null;
				if (_uiInstanceField != null)
				{
					obj = _uiInstanceField.GetValue(null);
				}
				else if (_uiInstanceProperty != null)
				{
					obj = _uiInstanceProperty.GetValue(null, null);
				}
				Component val = (Component)((obj is Component) ? obj : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val.gameObject == (Object)null || !val.gameObject.activeInHierarchy)
				{
					return null;
				}
				object obj2 = null;
				if (_sourceTableField != null)
				{
					obj2 = _sourceTableField.GetValue(obj);
				}
				else if (_sourceTableProperty != null)
				{
					obj2 = _sourceTableProperty.GetValue(obj, null);
				}
				return (Component)((obj2 is Component) ? obj2 : null);
			}
			catch
			{
				return null;
			}
		}

		private static List<Container> GetNearbyContainers()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			Plugin plugin = Object.FindObjectOfType<Plugin>();
			if ((Object)(object)plugin == (Object)null)
			{
				return list;
			}
			Component currentEpicLootStation = GetCurrentEpicLootStation();
			if ((Object)(object)currentEpicLootStation == (Object)null)
			{
				return list;
			}
			float num = Mathf.Max(0f, plugin._containerRange.Value);
			float num2 = num * num;
			Vector3 position = currentEpicLootStation.transform.position;
			Container[] array = Object.FindObjectsOfType<Container>();
			foreach (Container val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
				{
					Vector3 val2 = ((Component)val).transform.position - position;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num2) && val.GetInventory() != null)
					{
						list.Add(val);
					}
				}
			}
			return list;
		}

		private static List<ItemData> GetContainerItems()
		{
			List<ItemData> list = new List<ItemData>();
			foreach (Container nearbyContainer in GetNearbyContainers())
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				List<ItemData> allItems = inventory.GetAllItems();
				if (allItems == null)
				{
					continue;
				}
				foreach (ItemData item in allItems)
				{
					if (item != null)
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		private static int CountContainerItem(string itemName)
		{
			if (string.IsNullOrEmpty(itemName))
			{
				return 0;
			}
			int num = 0;
			foreach (Container nearbyContainer in GetNearbyContainers())
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory != null)
				{
					num += Math.Max(0, inventory.CountItems(itemName, -1, true));
				}
			}
			return num;
		}

		private static int RemoveContainerItem(string itemName, int amount)
		{
			if (string.IsNullOrEmpty(itemName) || amount <= 0)
			{
				return 0;
			}
			int num = amount;
			int num2 = 0;
			foreach (Container nearbyContainer in GetNearbyContainers())
			{
				if (num <= 0)
				{
					break;
				}
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				int num3 = Math.Max(0, inventory.CountItems(itemName, -1, true));
				if (num3 > 0)
				{
					int num4 = Math.Min(num, num3);
					inventory.RemoveItem(itemName, num4, -1, true);
					int num5 = Math.Max(0, inventory.CountItems(itemName, -1, true));
					int num6 = Math.Max(0, num3 - num5);
					if (num6 > 0)
					{
						num2 += num6;
						num -= num6;
						SaveContainer(nearbyContainer);
					}
				}
			}
			return num2;
		}

		private static int RemoveExactContainerItem(ItemData item, int amount)
		{
			if (item == null || amount <= 0)
			{
				return 0;
			}
			foreach (Container nearbyContainer in GetNearbyContainers())
			{
				Inventory inventory = nearbyContainer.GetInventory();
				if (inventory != null && inventory.ContainsItem(item))
				{
					int stack = item.m_stack;
					if (stack <= 0)
					{
						return 0;
					}
					int num = Math.Min(amount, stack);
					inventory.RemoveItem(item, num);
					int num2 = (inventory.ContainsItem(item) ? item.m_stack : 0);
					int num3 = Math.Max(0, stack - num2);
					if (num3 > 0)
					{
						SaveContainer(nearbyContainer);
					}
					return Math.Min(amount, num3);
				}
			}
			return 0;
		}

		private static void SaveContainer(Container container)
		{
			if ((Object)(object)container == (Object)null || ContainerSaveMethod == null)
			{
				return;
			}
			try
			{
				ContainerSaveMethod.Invoke(container, null);
			}
			catch
			{
			}
		}

		private static Type FindType(string fullName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType(fullName, throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private void LogErrorOnce(string message)
		{
			if (!_errorLogged)
			{
				_errorLogged = true;
				((BaseUnityPlugin)this).Logger.LogError((object)message);
			}
		}
	}
}