Decompiled source of CarlosMMOAutoCollect v1.0.2

plugins/CarlosMMOAutoCollect.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CarlosMMOAutoCollect")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CarlosMMOAutoCollect")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("78250f8f-e66a-4775-9b29-f31579b8e727")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CarlosMMO.AutoCollect;

[BepInPlugin("carlos.mmo.autocollect", "Carlos MMO Auto Collect", "1.1.1")]
public class CarlosMMOAutoCollect : BaseUnityPlugin
{
	private float _tickTimer = 0f;

	private float _refreshTimer = 0f;

	private ConfigEntry<float> _updateInterval;

	private ConfigEntry<float> _containerRefreshInterval;

	private ConfigEntry<float> _pickupRadius;

	private ConfigEntry<int> _containersPerTick;

	private ConfigEntry<int> _maxItemsPerContainer;

	private ConfigEntry<bool> _preferExistingStacks;

	private ConfigEntry<bool> _enableLogs;

	private readonly List<Container> _containerCache = new List<Container>();

	private int _containerCursor = 0;

	private Collider[] _overlapResults;

	private void Awake()
	{
		_updateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "UpdateIntervalSeconds", 2f, "Intervalo entre ciclos de coleta.");
		_containerRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContainerRefreshIntervalSeconds", 15f, "Intervalo para atualizar a lista de baús.");
		_pickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PickupRadiusAroundContainer", 8f, "Raio ao redor do baú para puxar itens do chão.");
		_containersPerTick = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ContainersPerTick", 3, "Quantidade de baús processados por ciclo.");
		_maxItemsPerContainer = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxItemsPerContainerPerTick", 2, "Máximo de itens coletados por baú por ciclo.");
		_preferExistingStacks = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PreferExistingStacks", true, "Prioriza guardar em baús que já contenham o item.");
		_enableLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", true, "Ativa logs do mod.");
		_overlapResults = (Collider[])(object)new Collider[128];
		RefreshContainerCache();
		LogInfo("Carlos MMO Auto Collect 1.1.1 carregado.");
	}

	private void Update()
	{
		if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
		{
			return;
		}
		_refreshTimer += Time.deltaTime;
		if (_refreshTimer >= _containerRefreshInterval.Value)
		{
			_refreshTimer = 0f;
			RefreshContainerCache();
		}
		_tickTimer += Time.deltaTime;
		if (_tickTimer < _updateInterval.Value)
		{
			return;
		}
		_tickTimer = 0f;
		try
		{
			RunAutoCollect();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Erro no RunAutoCollect: " + ex));
		}
	}

	private void RefreshContainerCache()
	{
		_containerCache.Clear();
		Container[] array = Object.FindObjectsOfType<Container>();
		if (array == null || array.Length == 0)
		{
			return;
		}
		Container[] array2 = array;
		foreach (Container val in array2)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
			{
				Inventory inventory = val.GetInventory();
				if (inventory != null)
				{
					_containerCache.Add(val);
				}
			}
		}
		if (_containerCursor >= _containerCache.Count)
		{
			_containerCursor = 0;
		}
		LogInfo("[AutoCollect 1.1.1] Baús em cache: " + _containerCache.Count);
	}

	private void RunAutoCollect()
	{
		if (_containerCache.Count == 0)
		{
			return;
		}
		int num = 0;
		int num2 = 0;
		while (num < _containersPerTick.Value && num2 < _containerCache.Count && _containerCache.Count != 0)
		{
			if (_containerCursor >= _containerCache.Count)
			{
				_containerCursor = 0;
			}
			Container val = _containerCache[_containerCursor];
			_containerCursor++;
			num2++;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
			{
				Inventory inventory = val.GetInventory();
				if (inventory != null)
				{
					ProcessContainer(val, inventory);
					num++;
				}
			}
		}
	}

	private void ProcessContainer(Container container, Inventory inv)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		HashSet<int> hashSet = new HashSet<int>();
		int num2 = Physics.OverlapSphereNonAlloc(((Component)container).transform.position, _pickupRadius.Value, _overlapResults, -1, (QueryTriggerInteraction)2);
		if (num2 <= 0)
		{
			return;
		}
		for (int i = 0; i < num2; i++)
		{
			if (num >= _maxItemsPerContainer.Value)
			{
				break;
			}
			Collider val = _overlapResults[i];
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			ItemDrop val2 = ((Component)val).GetComponentInParent<ItemDrop>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)val).GetComponent<ItemDrop>();
			}
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			int instanceID = ((Object)val2).GetInstanceID();
			if (!hashSet.Contains(instanceID))
			{
				hashSet.Add(instanceID);
				if (CanCollect(val2) && TryStoreGroundItemInContainer(val2, container, inv))
				{
					num++;
				}
			}
		}
	}

	private bool CanCollect(ItemDrop itemDrop)
	{
		if ((Object)(object)itemDrop == (Object)null)
		{
			return false;
		}
		if ((Object)(object)((Component)itemDrop).gameObject == (Object)null || !((Component)itemDrop).gameObject.activeInHierarchy)
		{
			return false;
		}
		if (itemDrop.m_itemData == null)
		{
			return false;
		}
		if (itemDrop.m_itemData.m_shared == null)
		{
			return false;
		}
		if (itemDrop.m_itemData.m_stack <= 0)
		{
			return false;
		}
		if ((Object)(object)itemDrop.m_itemData.m_dropPrefab == (Object)null)
		{
			return false;
		}
		return true;
	}

	private bool TryStoreGroundItemInContainer(ItemDrop itemDrop, Container container, Inventory inv)
	{
		ItemData itemData = itemDrop.m_itemData;
		GameObject dropPrefab = itemData.m_dropPrefab;
		string name = ((Object)dropPrefab).name;
		int stack = itemData.m_stack;
		if (string.IsNullOrEmpty(name) || stack <= 0)
		{
			return false;
		}
		if (_preferExistingStacks.Value)
		{
			int num = inv.CountItems(name, -1, true);
			if (num > 0)
			{
			}
		}
		int num2 = inv.CountItems(name, -1, true);
		bool flag = inv.AddItem(dropPrefab, stack);
		int num3 = inv.CountItems(name, -1, true);
		if (!flag && num3 <= num2)
		{
			return false;
		}
		RemoveGroundItem(itemDrop);
		LogInfo("[AutoCollect 1.1.1] Recolhido: " + name + " x" + stack + " -> " + GetContainerLabel(container));
		return true;
	}

	private void RemoveGroundItem(ItemDrop itemDrop)
	{
		if (!((Object)(object)itemDrop == (Object)null))
		{
			ZNetView component = ((Component)itemDrop).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				component.Destroy();
			}
			else
			{
				Object.Destroy((Object)(object)((Component)itemDrop).gameObject);
			}
		}
	}

	private string GetContainerLabel(Container container)
	{
		if ((Object)(object)container == (Object)null)
		{
			return "(baú nulo)";
		}
		try
		{
			if (!string.IsNullOrEmpty(container.m_name))
			{
				return container.m_name;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)((Component)container).gameObject != (Object)null && !string.IsNullOrEmpty(((Object)((Component)container).gameObject).name))
			{
				return ((Object)((Component)container).gameObject).name;
			}
		}
		catch
		{
		}
		return "(baú sem nome)";
	}

	private void LogInfo(string msg)
	{
		if (_enableLogs == null || _enableLogs.Value)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)msg);
		}
	}
}