Decompiled source of CLGMMOStorage v1.0.1

plugins/CLGMMOStorage.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CLGMMOStorage")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CLGMMOStorage")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4fd18c7b-49ba-4801-8d26-5d061fdd9643")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CLGMMO;

[BepInPlugin("clgmmo.storage", "CLGMMO Storage", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class CLGMMOStorage : BaseUnityPlugin
{
	public const string ModGuid = "clgmmo.storage";

	public const string ModName = "CLGMMO Storage";

	public const string ModVersion = "1.0.0";

	internal static ManualLogSource Log;

	internal static CLGMMOStorage Instance;

	internal static Harmony HarmonyInstance;

	internal static ConfigEntry<float> SearchRadius;

	internal static ConfigEntry<int> MaxDistinctTypesPerChest;

	internal static ConfigEntry<int> WoodCost;

	internal static ConfigEntry<int> FineWoodCost;

	internal static ConfigEntry<int> IronCost;

	internal static ConfigEntry<string> PieceName;

	internal static ConfigEntry<string> PieceDescription;

	internal static ConfigEntry<bool> ShowDebugLogs;

	private void Awake()
	{
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		SearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "SearchRadius", 12f, "Raio máximo de busca dos baús próximos ao núcleo. Recomendado 12 a 20.");
		MaxDistinctTypesPerChest = ((BaseUnityPlugin)this).Config.Bind<int>("1 - General", "MaxDistinctTypesPerChest", 2, "Quantidade máxima de grupos diferentes por baú.");
		WoodCost = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Craft", "WoodCost", 20, "Custo de Madeira.");
		FineWoodCost = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Craft", "FineWoodCost", 10, "Custo de Madeira Fina.");
		IronCost = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Craft", "IronCost", 5, "Custo de Ferro.");
		PieceName = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Piece", "PieceName", "Núcleo Inteligente CLGMMO Storage", "Nome exibido da peça.");
		PieceDescription = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Piece", "PieceDescription", "Organiza automaticamente os itens do jogador nos baús próximos.", "Descrição exibida da peça.");
		ShowDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("9 - Debug", "ShowDebugLogs", false, "Ativa logs extras de depuração.");
		try
		{
			HarmonyInstance = new Harmony("clgmmo.storage");
			HarmonyInstance.PatchAll();
			PrefabManager.OnVanillaPrefabsAvailable += RegisterStoragePiece;
			Log.LogInfo((object)"CLGMMO Storage 1.0.0 carregado.");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Falha ao inicializar CLGMMO Storage: " + ex));
		}
	}

	private void OnDestroy()
	{
		try
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterStoragePiece;
		}
		catch
		{
		}
		try
		{
			if (HarmonyInstance != null)
			{
				HarmonyInstance.UnpatchSelf();
				HarmonyInstance = null;
			}
		}
		catch
		{
		}
	}

	private void RegisterStoragePiece()
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Expected O, but got Unknown
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Expected O, but got Unknown
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Expected O, but got Unknown
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Expected O, but got Unknown
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Expected O, but got Unknown
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("CLGMMO_StorageCore");
			if ((Object)(object)prefab != (Object)null)
			{
				LogDebug("Prefab do Storage já existe, ignorando novo registro.");
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("CLGMMO_StorageCore", "piece_workbench");
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Não foi possível clonar prefab base piece_workbench.");
				return;
			}
			((Object)val).name = "CLGMMO_StorageCore";
			CraftingStation component = val.GetComponent<CraftingStation>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			StationExtension component2 = val.GetComponent<StationExtension>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
			Piece component3 = val.GetComponent<Piece>();
			if ((Object)(object)component3 == (Object)null)
			{
				Log.LogError((object)"Prefab clonado não contém componente Piece.");
				return;
			}
			component3.m_name = PieceName.Value;
			component3.m_description = PieceDescription.Value;
			component3.m_category = (PieceCategory)1;
			CLGMMOStorageCore cLGMMOStorageCore = val.GetComponent<CLGMMOStorageCore>();
			if ((Object)(object)cLGMMOStorageCore == (Object)null)
			{
				cLGMMOStorageCore = val.AddComponent<CLGMMOStorageCore>();
			}
			cLGMMOStorageCore.SetPieceName(PieceName.Value);
			StorageVisualTweaks.Apply(val);
			PieceConfig val2 = new PieceConfig();
			val2.Name = PieceName.Value;
			val2.Description = PieceDescription.Value;
			val2.PieceTable = "_HammerPieceTable";
			val2.Category = "Crafting";
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig
				{
					Item = "Wood",
					Amount = Mathf.Max(1, WoodCost.Value),
					Recover = true
				},
				new RequirementConfig
				{
					Item = "FineWood",
					Amount = Mathf.Max(1, FineWoodCost.Value),
					Recover = true
				},
				new RequirementConfig
				{
					Item = "Iron",
					Amount = Mathf.Max(1, IronCost.Value),
					Recover = true
				}
			};
			PieceConfig val3 = val2;
			CustomPiece val4 = new CustomPiece(val, false, val3);
			PieceManager.Instance.AddPiece(val4);
			Log.LogInfo((object)(PieceName.Value + " registrado com sucesso."));
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Erro ao registrar peça do Storage: " + ex));
		}
	}

	internal static void LogDebug(string message)
	{
		try
		{
			if (ShowDebugLogs != null && ShowDebugLogs.Value && Log != null)
			{
				Log.LogInfo((object)("[DEBUG] " + message));
			}
		}
		catch
		{
		}
	}
}
internal static class StorageVisualTweaks
{
	public static void Apply(GameObject root)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		try
		{
			root.transform.localScale = new Vector3(0.94f, 0.94f, 0.94f);
			HideWorkbenchLookingParts(root.transform);
			AdjustCoreShape(root.transform);
			ApplyEnergyTheme(root);
			AddEnergyLights(root);
			AddEnergyOrb(root);
		}
		catch
		{
		}
	}

	private static void HideWorkbenchLookingParts(Transform root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		string[] names = new string[11]
		{
			"forge", "anvil", "tools", "vice", "bellows", "shelf", "table", "workbench", "bench", "wood",
			"barrel"
		};
		MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				string name = ((Object)((Component)val).gameObject).name;
				if (ContainsAnyName(name, names))
				{
					((Renderer)val).enabled = false;
				}
			}
		}
	}

	private static void AdjustCoreShape(Transform root)
	{
		//IL_003e: 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_005f: 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)
		if (!((Object)(object)root == (Object)null))
		{
			Transform val = FindChildRecursive(root, "top");
			if ((Object)(object)val != (Object)null)
			{
				val.localScale = new Vector3(0.72f, 0.4f, 0.72f);
				val.localPosition += new Vector3(0f, 0.1f, 0f);
			}
			Transform val2 = FindChildRecursive(root, "smoke");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			Transform val3 = FindChildRecursive(root, "fire");
			if ((Object)(object)val3 != (Object)null)
			{
				((Component)val3).gameObject.SetActive(false);
			}
			Transform val4 = FindChildRecursive(root, "forge");
			if ((Object)(object)val4 != (Object)null)
			{
				((Component)val4).gameObject.SetActive(false);
			}
			Transform val5 = FindChildRecursive(root, "anvil");
			if ((Object)(object)val5 != (Object)null)
			{
				((Component)val5).gameObject.SetActive(false);
			}
		}
	}

	private static void ApplyEnergyTheme(GameObject root)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		MeshRenderer[] componentsInChildren = root.GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null || ((Renderer)val).materials == null)
			{
				continue;
			}
			Material[] materials = ((Renderer)val).materials;
			foreach (Material val2 in materials)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				try
				{
					if (val2.HasProperty("_Color"))
					{
						Color color = val2.color;
						if (color.r > 0.35f || color.g > 0.3f || color.b > 0.25f)
						{
							val2.color = Color.Lerp(color, new Color(0.22f, 0.4f, 0.52f), 0.45f);
						}
						else
						{
							val2.color = Color.Lerp(color, new Color(0.1f, 0.18f, 0.24f), 0.3f);
						}
					}
					if (val2.HasProperty("_EmissionColor"))
					{
						val2.EnableKeyword("_EMISSION");
						val2.SetColor("_EmissionColor", new Color(0.04f, 0.25f, 0.34f));
					}
				}
				catch
				{
				}
			}
		}
	}

	private static void AddEnergyLights(GameObject root)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Light[] componentsInChildren = root.GetComponentsInChildren<Light>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			try
			{
				Object.DestroyImmediate((Object)(object)((Component)componentsInChildren[i]).gameObject);
			}
			catch
			{
			}
		}
		GameObject val = new GameObject("CLGMMO_StorageCore_MainLight");
		val.transform.SetParent(root.transform, false);
		val.transform.localPosition = new Vector3(0f, 1.25f, 0f);
		Light val2 = val.AddComponent<Light>();
		val2.type = (LightType)2;
		val2.range = 5.5f;
		val2.intensity = 1.85f;
		val2.color = new Color(0.2f, 0.82f, 1f);
		val2.shadows = (LightShadows)0;
		GameObject val3 = new GameObject("CLGMMO_StorageCore_TopGlow");
		val3.transform.SetParent(root.transform, false);
		val3.transform.localPosition = new Vector3(0f, 1.55f, 0f);
		Light val4 = val3.AddComponent<Light>();
		val4.type = (LightType)2;
		val4.range = 2.8f;
		val4.intensity = 1.25f;
		val4.color = new Color(0.55f, 1f, 1f);
		val4.shadows = (LightShadows)0;
	}

	private static void AddEnergyOrb(GameObject root)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)root == (Object)null))
		{
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val).name = "CLGMMO_StorageCore_Orb";
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = new Vector3(0f, 1.18f, 0f);
			val.transform.localScale = new Vector3(0.34f, 0.34f, 0.34f);
			Collider component = val.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			MeshRenderer component2 = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Material val2 = new Material(Shader.Find("Standard"));
				val2.color = new Color(0.22f, 0.8f, 0.95f);
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", new Color(0.1f, 0.55f, 0.7f));
				((Renderer)component2).material = val2;
				((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component2).receiveShadows = false;
			}
		}
	}

	private static bool ContainsAnyName(string text, string[] names)
	{
		if (string.IsNullOrEmpty(text) || names == null || names.Length == 0)
		{
			return false;
		}
		foreach (string value in names)
		{
			if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	private static Transform FindChildRecursive(Transform parent, string childName)
	{
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		for (int i = 0; i < parent.childCount; i++)
		{
			Transform child = parent.GetChild(i);
			if (((Object)child).name.Equals(childName, StringComparison.OrdinalIgnoreCase))
			{
				return child;
			}
			Transform val = FindChildRecursive(child, childName);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return null;
	}
}
public sealed class CLGMMOStorageCore : MonoBehaviour, Hoverable, Interactable
{
	private string _pieceName = "Núcleo Inteligente CLGMMO Storage";

	public void SetPieceName(string pieceName)
	{
		_pieceName = (string.IsNullOrWhiteSpace(pieceName) ? "Núcleo Inteligente CLGMMO Storage" : pieceName);
	}

	public string GetHoverName()
	{
		return _pieceName;
	}

	public string GetHoverText()
	{
		return _pieceName + "\n[Use] Depositar Tudo";
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		if (hold)
		{
			return false;
		}
		Player val = (Player)(object)((user is Player) ? user : null);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		try
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogInfo((object)"Storage Interact iniciado.");
			}
			StorageTransferReport storageTransferReport = StorageLogic.DepositAll(val, ((Component)this).transform.position);
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogInfo((object)("Storage Interact finalizado. Containers=" + storageTransferReport.ScannedContainers + ", Itens=" + storageTransferReport.MovedItems + ", Pilhas=" + storageTransferReport.MovedStacks + ", Restantes=" + storageTransferReport.LeftOnPlayer));
			}
			if (storageTransferReport.MovedStacks > 0 || storageTransferReport.MovedItems > 0)
			{
				((Character)val).Message((MessageType)2, "Storage: " + storageTransferReport.MovedItems + " itens movidos em " + storageTransferReport.MovedStacks + " pilhas.", 0, (Sprite)null);
			}
			else
			{
				((Character)val).Message((MessageType)2, "Storage: Nenhum item elegível encontrou destino nos baús próximos.", 0, (Sprite)null);
			}
			if (storageTransferReport.LeftOnPlayer > 0)
			{
				((Character)val).Message((MessageType)1, "Storage: " + storageTransferReport.LeftOnPlayer + " itens permaneceram no inventário.", 0, (Sprite)null);
			}
			CLGMMOStorage.LogDebug("Depósito concluído. Itens movidos=" + storageTransferReport.MovedItems + ", pilhas movidas=" + storageTransferReport.MovedStacks + ", restantes=" + storageTransferReport.LeftOnPlayer + ", containers=" + storageTransferReport.ScannedContainers);
			return true;
		}
		catch (Exception ex)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogError((object)("Erro ao usar núcleo de storage: " + ex));
			}
			((Character)val).Message((MessageType)2, "Storage: erro ao organizar itens.", 0, (Sprite)null);
			return true;
		}
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}
}
internal static class StorageLogic
{
	public static StorageTransferReport DepositAll(Player player, Vector3 center)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		StorageTransferReport storageTransferReport = new StorageTransferReport();
		if ((Object)(object)player == (Object)null)
		{
			return storageTransferReport;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return storageTransferReport;
		}
		List<Container> list = FindNearbyContainers(center, CLGMMOStorage.SearchRadius.Value);
		storageTransferReport.ScannedContainers = list.Count;
		if (CLGMMOStorage.Log != null)
		{
			CLGMMOStorage.Log.LogInfo((object)("Storage DepositAll: containers encontrados = " + storageTransferReport.ScannedContainers));
		}
		if (list.Count == 0)
		{
			return storageTransferReport;
		}
		List<ItemData> source = new List<ItemData>(inventory.GetAllItems());
		List<ItemData> list2 = source.Where(CanMoveThisItem).OrderBy(GetSortableGroupKey).ThenBy(GetSortableName)
			.ToList();
		for (int i = 0; i < list2.Count; i++)
		{
			ItemData val = list2[i];
			if (val == null || val.m_stack <= 0)
			{
				continue;
			}
			string displayName = GetDisplayName(val);
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogInfo((object)("Storage analisando item: " + displayName + " x" + val.m_stack));
			}
			Container val2 = FindBestTargetContainer(val, list);
			if ((Object)(object)val2 == (Object)null)
			{
				if (CLGMMOStorage.Log != null)
				{
					CLGMMOStorage.Log.LogInfo((object)"Storage: nenhum container elegível encontrado para este item.");
				}
				storageTransferReport.LeftOnPlayer += Mathf.Max(0, val.m_stack);
				continue;
			}
			Inventory inventory2 = val2.GetInventory();
			if (inventory2 == null)
			{
				storageTransferReport.LeftOnPlayer += Mathf.Max(0, val.m_stack);
				continue;
			}
			if (!InventoryCompat.CanAcceptFullStack(inventory2, val))
			{
				CLGMMOStorage.LogDebug("Container escolhido não aceita pilha completa: " + displayName);
				storageTransferReport.LeftOnPlayer += Mathf.Max(0, val.m_stack);
				continue;
			}
			int stack = val.m_stack;
			if (InventoryCompat.TryMoveFullStack(inventory, inventory2, val))
			{
				storageTransferReport.MovedItems += stack;
				storageTransferReport.MovedStacks++;
				if (CLGMMOStorage.Log != null)
				{
					CLGMMOStorage.Log.LogInfo((object)("Storage moveu item com sucesso: " + displayName + " x" + stack));
				}
			}
			else
			{
				storageTransferReport.LeftOnPlayer += Mathf.Max(0, stack);
				if (CLGMMOStorage.Log != null)
				{
					CLGMMOStorage.Log.LogWarning((object)("Storage falhou ao mover item: " + displayName + " x" + stack));
				}
			}
		}
		return storageTransferReport;
	}

	private static List<Container> FindNearbyContainers(Vector3 center, float radius)
	{
		//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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		List<Container> list = new List<Container>();
		try
		{
			Container[] array = Object.FindObjectsOfType<Container>();
			if (array == null || array.Length == 0)
			{
				return list;
			}
			float num = Mathf.Max(1f, radius);
			foreach (Container val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null))
				{
					float num2 = Vector3.Distance(center, ((Component)val).transform.position);
					if (!(num2 > num) && IsContainerUsable(val))
					{
						list.Add(val);
					}
				}
			}
			list = list.OrderBy((Container c) => Vector3.Distance(center, ((Component)c).transform.position)).ToList();
		}
		catch (Exception ex)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogError((object)("Erro ao procurar containers próximos: " + ex));
			}
		}
		return list;
	}

	private static bool IsContainerUsable(Container container)
	{
		if ((Object)(object)container == (Object)null)
		{
			return false;
		}
		try
		{
			if (!((Component)container).gameObject.activeInHierarchy)
			{
				return false;
			}
			Inventory inventory = container.GetInventory();
			if (inventory == null)
			{
				return false;
			}
			ZNetView component = ((Component)container).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && !component.IsValid())
			{
				return false;
			}
			return true;
		}
		catch
		{
			return false;
		}
	}

	private static bool CanMoveThisItem(ItemData item)
	{
		if (item == null)
		{
			return false;
		}
		try
		{
			if (item.m_stack <= 0)
			{
				return false;
			}
			if (item.m_equipped)
			{
				return false;
			}
			if (item.m_shared == null)
			{
				return false;
			}
			if (item.m_shared.m_questItem)
			{
				return false;
			}
			if (StorageItemRules.IsProtectedEquipment(item))
			{
				return false;
			}
			return true;
		}
		catch
		{
			return false;
		}
	}

	private static Container FindBestTargetContainer(ItemData item, List<Container> containers)
	{
		if (item == null || containers == null || containers.Count == 0)
		{
			return null;
		}
		string key = StorageItemKey.GetKey(item);
		Container val = null;
		Container val2 = null;
		Container val3 = null;
		for (int i = 0; i < containers.Count; i++)
		{
			Container val4 = containers[i];
			if ((Object)(object)val4 == (Object)null)
			{
				continue;
			}
			Inventory inventory = val4.GetInventory();
			if (inventory == null)
			{
				continue;
			}
			ContainerFitInfo containerFitInfo = AnalyzeContainerFit(inventory, key, item);
			if (containerFitInfo.CanAccept)
			{
				if (containerFitInfo.HasPartialStack)
				{
					val = val4;
					break;
				}
				if (containerFitInfo.HasSameType && (Object)(object)val2 == (Object)null)
				{
					val2 = val4;
				}
				else if (containerFitInfo.CanOpenNewTypeSlot && (Object)(object)val3 == (Object)null)
				{
					val3 = val4;
				}
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		if ((Object)(object)val2 != (Object)null)
		{
			return val2;
		}
		if ((Object)(object)val3 != (Object)null)
		{
			return val3;
		}
		return null;
	}

	private static ContainerFitInfo AnalyzeContainerFit(Inventory inventory, string itemKey, ItemData item)
	{
		ContainerFitInfo result = default(ContainerFitInfo);
		if (inventory == null || string.IsNullOrEmpty(itemKey) || item == null)
		{
			return result;
		}
		try
		{
			List<ItemData> allItems = inventory.GetAllItems();
			HashSet<string> hashSet = new HashSet<string>();
			bool flag = false;
			bool hasPartialStack = false;
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (val == null)
				{
					continue;
				}
				string key = StorageItemKey.GetKey(val);
				if (string.IsNullOrEmpty(key))
				{
					continue;
				}
				hashSet.Add(key);
				if (key == itemKey)
				{
					flag = true;
					if (val.m_shared != null && val.m_stack < val.m_shared.m_maxStackSize)
					{
						hasPartialStack = true;
					}
				}
			}
			bool flag2 = flag || hashSet.Count < Mathf.Max(1, CLGMMOStorage.MaxDistinctTypesPerChest.Value);
			result.HasSameType = flag;
			result.HasPartialStack = hasPartialStack;
			result.CanOpenNewTypeSlot = flag2;
			result.CanAccept = flag2 && InventoryCompat.CanAcceptFullStack(inventory, item);
			return result;
		}
		catch
		{
			return result;
		}
	}

	private static string GetDisplayName(ItemData item)
	{
		if (item == null)
		{
			return "null";
		}
		if (item.m_shared != null && !string.IsNullOrEmpty(item.m_shared.m_name))
		{
			return item.m_shared.m_name;
		}
		if ((Object)(object)item.m_dropPrefab != (Object)null)
		{
			return ((Object)item.m_dropPrefab).name;
		}
		return "item_sem_nome";
	}

	private static string GetSortableName(ItemData item)
	{
		return GetDisplayName(item) ?? string.Empty;
	}

	private static string GetSortableGroupKey(ItemData item)
	{
		return StorageItemKey.GetKey(item) ?? string.Empty;
	}
}
internal static class InventoryCompat
{
	private static MethodInfo _canAddItemTwoArgs;

	private static MethodInfo _canAddItemOneArg;

	private static MethodInfo _addItemItemData;

	private static MethodInfo _removeItemItemDataInt;

	private static bool _reflectionReady;

	private static void EnsureReflection()
	{
		if (_reflectionReady)
		{
			return;
		}
		_reflectionReady = true;
		MethodInfo[] methods = typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo in methods)
		{
			if (methodInfo == null)
			{
				continue;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (methodInfo.Name == "CanAddItem")
			{
				if (parameters.Length == 2 && parameters[0].ParameterType == typeof(ItemData) && parameters[1].ParameterType == typeof(int))
				{
					_canAddItemTwoArgs = methodInfo;
				}
				else if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ItemData))
				{
					_canAddItemOneArg = methodInfo;
				}
			}
			else if (methodInfo.Name == "AddItem")
			{
				if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ItemData))
				{
					_addItemItemData = methodInfo;
				}
			}
			else if (methodInfo.Name == "RemoveItem" && parameters.Length == 2 && parameters[0].ParameterType == typeof(ItemData) && parameters[1].ParameterType == typeof(int))
			{
				_removeItemItemDataInt = methodInfo;
			}
		}
	}

	public static bool CanAcceptFullStack(Inventory inventory, ItemData item)
	{
		if (inventory == null || item == null || item.m_stack <= 0)
		{
			return false;
		}
		EnsureReflection();
		try
		{
			if (_canAddItemTwoArgs != null)
			{
				object obj = _canAddItemTwoArgs.Invoke(inventory, new object[2] { item, item.m_stack });
				if (obj is bool)
				{
					return (bool)obj;
				}
			}
		}
		catch
		{
		}
		try
		{
			if (_canAddItemOneArg != null)
			{
				ItemData val = item.Clone();
				if (val != null)
				{
					val.m_stack = item.m_stack;
					object obj3 = _canAddItemOneArg.Invoke(inventory, new object[1] { val });
					if (obj3 is bool)
					{
						return (bool)obj3;
					}
				}
			}
		}
		catch
		{
		}
		return HasExistingPartialStackSpace(inventory, item) || HasLikelyFreeSlot(inventory);
	}

	public static bool TryMoveFullStack(Inventory sourceInventory, Inventory targetInventory, ItemData sourceItem)
	{
		if (sourceInventory == null || targetInventory == null || sourceItem == null || sourceItem.m_stack <= 0)
		{
			return false;
		}
		EnsureReflection();
		int stack = sourceItem.m_stack;
		ItemData val = sourceItem.Clone();
		if (val == null)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogWarning((object)"InventoryCompat: falha ao clonar ItemData.");
			}
			return false;
		}
		val.m_stack = stack;
		if (!TryAddItemData(targetInventory, val))
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogWarning((object)"InventoryCompat: AddItem(ItemData) falhou.");
			}
			return false;
		}
		if (!TryRemoveFromSource(sourceInventory, sourceItem, stack))
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogWarning((object)"InventoryCompat: RemoveItem(ItemData, int) falhou após AddItem.");
			}
			return false;
		}
		return true;
	}

	private static bool TryAddItemData(Inventory inventory, ItemData item)
	{
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Invalid comparison between Unknown and O
		if (inventory == null || item == null || item.m_stack <= 0)
		{
			return false;
		}
		EnsureReflection();
		if (_addItemItemData == null)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogWarning((object)"InventoryCompat: overload AddItem(ItemData) não encontrada.");
			}
			return false;
		}
		try
		{
			object obj = _addItemItemData.Invoke(inventory, new object[1] { item });
			if (obj == null)
			{
				return true;
			}
			if (!(obj is bool result))
			{
				if (obj is ItemData)
				{
					return (object)(ItemData)obj != null;
				}
				return true;
			}
			return result;
		}
		catch (Exception ex)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogError((object)("InventoryCompat: erro em AddItem(ItemData): " + ex));
			}
			return false;
		}
	}

	private static bool TryRemoveFromSource(Inventory sourceInventory, ItemData sourceItem, int amount)
	{
		if (sourceInventory == null || sourceItem == null || amount <= 0)
		{
			return false;
		}
		EnsureReflection();
		try
		{
			if (_removeItemItemDataInt != null)
			{
				object obj = _removeItemItemDataInt.Invoke(sourceInventory, new object[2] { sourceItem, amount });
				if (obj == null)
				{
					return true;
				}
				if (!(obj is bool result))
				{
					return true;
				}
				return result;
			}
		}
		catch (Exception ex)
		{
			if (CLGMMOStorage.Log != null)
			{
				CLGMMOStorage.Log.LogError((object)("InventoryCompat: erro em RemoveItem(ItemData, int): " + ex));
			}
		}
		return false;
	}

	private static bool HasExistingPartialStackSpace(Inventory inventory, ItemData sourceItem)
	{
		try
		{
			List<ItemData> allItems = inventory.GetAllItems();
			string key = StorageItemKey.GetKey(sourceItem);
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (val != null && val.m_shared != null && !(StorageItemKey.GetKey(val) != key) && val.m_stack < val.m_shared.m_maxStackSize)
				{
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool HasLikelyFreeSlot(Inventory inventory)
	{
		try
		{
			int num = ReadIntField(inventory, "m_width", 0);
			int num2 = ReadIntField(inventory, "m_height", 0);
			int num3 = num * num2;
			if (num3 <= 0)
			{
				return true;
			}
			int count = inventory.GetAllItems().Count;
			return count < num3;
		}
		catch
		{
			return true;
		}
	}

	private static int ReadIntField(object instance, string name, int fallback)
	{
		if (instance == null)
		{
			return fallback;
		}
		try
		{
			FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(instance);
				if (value is int)
				{
					return (int)value;
				}
			}
		}
		catch
		{
		}
		return fallback;
	}
}
internal static class StorageItemRules
{
	public static bool IsProtectedEquipment(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return false;
		}
		string itemName = GetItemName(item);
		string prefabName = GetPrefabName(item);
		string searchKey = GetSearchKey(item);
		if (IsArmorType(item))
		{
			return true;
		}
		if (IsWeaponType(item))
		{
			return true;
		}
		if (IsToolType(item))
		{
			return true;
		}
		if (ContainsAny(itemName, "helmet", "capa", "cape", "armor", "armour", "chest", "legs", "greaves", "elmo", "peitoral", "calcas", "calças", "ombro", "shoulder", "utility", "belt", "cinto"))
		{
			return true;
		}
		if (ContainsAny(prefabName, "helmet", "cape", "armor", "armour", "chest", "legs", "greaves", "shoulder", "belt"))
		{
			return true;
		}
		if (ContainsAny(searchKey, "sword", "espada", "axe", "machado", "battleaxe", "bow", "arco", "knife", "faca", "adaga", "spear", "lança", "lanca", "polearm", "atgeir", "mace", "maça", "maca", "shield", "escudo", "crossbow", "besta", "staff", "cajado", "gun", "rifle", "pistol", "shotgun", "sniper", "firearm", "weapon", "arma"))
		{
			return true;
		}
		if (ContainsAny(searchKey, "ammo", "ammunition", "bullet", "bullets", "shell", "cartridge", "round", "municao", "munição", "bala", "balas", "cartucho", "projétil", "projetil"))
		{
			return true;
		}
		if (ContainsAny(searchKey, "tool", "fishing rod", "vara", "picareta", "pickaxe", "hoe", "cultivator", "hammer", "martelo", "build tool"))
		{
			return true;
		}
		return false;
	}

	public static bool IsArmorType(ItemData item)
	{
		//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_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		try
		{
			ItemType itemType = item.m_shared.m_itemType;
			return (int)itemType == 6 || (int)itemType == 7 || (int)itemType == 11 || (int)itemType == 17 || (int)itemType == 18;
		}
		catch
		{
			return false;
		}
	}

	public static bool IsWeaponType(ItemData item)
	{
		//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_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Invalid comparison between Unknown and I4
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Invalid comparison between Unknown and I4
		try
		{
			ItemType itemType = item.m_shared.m_itemType;
			return (int)itemType == 4 || (int)itemType == 3 || (int)itemType == 5 || (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 15;
		}
		catch
		{
			return false;
		}
	}

	public static bool IsToolType(ItemData item)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		try
		{
			return (int)item.m_shared.m_itemType == 19;
		}
		catch
		{
			return false;
		}
	}

	public static bool IsWood(ItemData item)
	{
		string searchKey = GetSearchKey(item);
		return ContainsAny(searchKey, "wood", "roundlog", "branch", "elderbark", "finwood", "finewood", "corewood", "yggdrasilwood", "blackwood", "ancientbark", "madeira", "tronco", "galho", "casca antiga", "cascaantiga", "madeira fina", "madeirafina", "madeira nobre", "madeira de cerne", "cerne", "yggdrasil", "lenha");
	}

	public static bool IsRawOre(ItemData item)
	{
		string searchKey = GetSearchKey(item);
		if (IsMetalBar(item))
		{
			return false;
		}
		return ContainsAny(searchKey, "ore", "scrapiron", "copperscrap", "tinore", "copperore", "silverore", "blackmetalscrap", "flametalore", "iron scrap", "metal scrap", "sucata", "minerio", "minério", "mineriode", "ore_", "copper ore", "tin ore", "silver ore");
	}

	public static bool IsMetalBar(ItemData item)
	{
		string searchKey = GetSearchKey(item);
		return ContainsAny(searchKey, "ingot", "bar", "bronze", "iron", "silver", "blackmetal", "copper", "tin", "flametal", "metal bar", "barra", "barra de", "lingote", "metal refinado") && !ContainsAny(searchKey, "ore", "scrap", "sucata", "minerio", "minério");
	}

	public static bool IsRawFood(ItemData item)
	{
		string searchKey = GetSearchKey(item);
		if (IsCookedFood(item))
		{
			return false;
		}
		return ContainsAny(searchKey, "raw", "uncooked", "uncooked_", "meatraw", "fishraw", "necktail", "serpentmeat", "haremeat", "wolfmeat", "loxmeat", "boarmeat", "deermeat", "chickenmeat", "egg", "mushroom", "berries", "raspberries", "blueberries", "cloudberries", "onion", "carrot", "turnip", "barley", "flour", "rawfood", "cru", "crua", "crus", "cruas", "carne crua", "peixe cru", "ovo", "cogumelo", "frutas", "bagas", "cebola", "cenoura", "nabo", "cevada", "farinha");
	}

	public static bool IsCookedFood(ItemData item)
	{
		string searchKey = GetSearchKey(item);
		return ContainsAny(searchKey, "cooked", "cook", "roasted", "baked", "pie", "soup", "stew", "bread", "sausage", "jerky", "omelette", "honeyglazed", "feast", "cookedmeat", "cookedfish", "assado", "assada", "assados", "assadas", "cozido", "cozida", "cozidos", "cozidas", "torta", "sopa", "ensopado", "pão", "pao", "linguiça", "linguica", "omelete", "banquete");
	}

	public static string GetItemName(ItemData item)
	{
		if (item == null || item.m_shared == null || string.IsNullOrEmpty(item.m_shared.m_name))
		{
			return string.Empty;
		}
		return item.m_shared.m_name.ToLowerInvariant();
	}

	public static string GetPrefabName(ItemData item)
	{
		if (item == null || (Object)(object)item.m_dropPrefab == (Object)null || string.IsNullOrEmpty(((Object)item.m_dropPrefab).name))
		{
			return string.Empty;
		}
		return ((Object)item.m_dropPrefab).name.ToLowerInvariant();
	}

	public static string GetSearchKey(ItemData item)
	{
		return (GetItemName(item) + " " + GetPrefabName(item)).Trim();
	}

	private static bool ContainsAny(string text, params string[] terms)
	{
		if (string.IsNullOrEmpty(text) || terms == null || terms.Length == 0)
		{
			return false;
		}
		foreach (string value in terms)
		{
			if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}
}
internal static class StorageItemKey
{
	public static string GetKey(ItemData item)
	{
		if (item == null)
		{
			return string.Empty;
		}
		try
		{
			if (StorageItemRules.IsWood(item))
			{
				return "group_wood";
			}
			if (StorageItemRules.IsRawOre(item))
			{
				return "group_raw_ore";
			}
			if (StorageItemRules.IsMetalBar(item))
			{
				return "group_metal_bar";
			}
			if (StorageItemRules.IsRawFood(item))
			{
				return "group_food_raw";
			}
			if (StorageItemRules.IsCookedFood(item))
			{
				return "group_food_cooked";
			}
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return ((Object)item.m_dropPrefab).name;
			}
			if (item.m_shared != null && !string.IsNullOrEmpty(item.m_shared.m_name))
			{
				return item.m_shared.m_name;
			}
		}
		catch
		{
		}
		return string.Empty;
	}
}
internal struct ContainerFitInfo
{
	public bool CanAccept;

	public bool HasSameType;

	public bool HasPartialStack;

	public bool CanOpenNewTypeSlot;
}
internal sealed class StorageTransferReport
{
	public int ScannedContainers;

	public int MovedItems;

	public int MovedStacks;

	public int LeftOnPlayer;
}