Decompiled source of SwiftPickup v1.3.3

SwiftPickup.dll

Decompiled 3 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 BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("SwiftPickup")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SwiftPickup")]
[assembly: AssemblyTitle("SwiftPickup")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SwiftPickup;

[BepInPlugin("user.swiftpickup", "SwiftPickup", "1.3.3")]
[BepInProcess("valheim.exe")]
public class SwiftPickupPlugin : BaseUnityPlugin
{
	private struct Candidate
	{
		public ItemDrop Drop;

		public float Distance;
	}

	[HarmonyPatch(typeof(Player), "Update")]
	private static class PlayerUpdatePatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				if (IsPickupEnabled() && MagnetItems.Count > 0)
				{
					MoveMagnets(__instance);
				}
				else if (MagnetItems.Count > 0 && !IsPickupEnabled())
				{
					MagnetItems.Clear();
				}
				KeyboardShortcut value = _toggleKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					bool flag = !_modEnabled.Value;
					_modEnabled.Value = flag;
					((Character)__instance).Message((MessageType)1, "SwiftPickup подбор: " + (flag ? "вкл" : "выкл") + " (множитель и кучки — независимо)", 0, (Sprite)null, false);
					_log.LogInfo((object)$"Pickup toggled to {flag}");
				}
			}
		}
	}

	[HarmonyPatch(typeof(Player), "AutoPickup")]
	private static class AutoPickupPatch
	{
		private static bool Prefix(Player __instance, float __0)
		{
			try
			{
				if (((Character)__instance).IsTeleporting())
				{
					return false;
				}
				HandleScan(__instance, __0);
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"AutoPickup patch error: {arg}");
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Humanoid), "Pickup")]
	private static class HumanoidPickupPatch
	{
		private static void Prefix(Humanoid __instance, GameObject __0)
		{
			_handMultiplyPending = false;
			try
			{
				if ((Object)(object)__0 == (Object)null || _lootMultiplier.Value <= 1 || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsTeleporting())
				{
					return;
				}
				ItemDrop component = __0.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null || !component.m_autoPickup)
				{
					return;
				}
				object? obj = _humanoidInventory?.GetValue(__instance);
				Inventory val = (Inventory)((obj is Inventory) ? obj : null);
				if (val == null)
				{
					return;
				}
				component.Load();
				ItemData itemData = component.m_itemData;
				if (itemData == null || itemData.m_shared == null || itemData.m_shared.m_questItem || IsIgnored(itemData) || val.ContainsItem(itemData))
				{
					return;
				}
				int stack = itemData.m_stack;
				if (stack > 0)
				{
					int handMultiplyTarget = (itemData.m_stack = stack * _lootMultiplier.Value);
					if (!val.CanAddItem(itemData, -1) || itemData.GetWeight(-1) + val.GetTotalWeight() > Player.m_localPlayer.GetMaxCarryWeight())
					{
						itemData.m_stack = stack;
						return;
					}
					_handMultiplyTarget = handMultiplyTarget;
					_handMultiplyPending = true;
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("Hand pickup multiply failed: " + ex.Message));
			}
		}

		private static void Postfix()
		{
			_handMultiplyPending = false;
		}
	}

	[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
	private static class InventoryAddItemPatch
	{
		private static void Prefix(Inventory __instance, ItemData __0)
		{
			if (!_handMultiplyPending)
			{
				return;
			}
			_handMultiplyPending = false;
			try
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && __instance == ((Humanoid)localPlayer).GetInventory() && __0 != null && __0.m_shared != null)
				{
					int stack = __0.m_stack;
					__0.m_stack = _handMultiplyTarget;
					if (!__instance.CanAddItem(__0, -1) || __0.GetWeight(-1) + __instance.GetTotalWeight() > localPlayer.GetMaxCarryWeight())
					{
						__0.m_stack = stack;
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("AddItem multiply failed: " + ex.Message));
			}
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "RemoveObjects")]
	private static class ZNetSceneRemoveObjectsGuard
	{
		private static float _nextLog;

		private static readonly List<ZDO> GhostKeys = new List<ZDO>(16);

		private static Exception Finalizer(Exception __exception)
		{
			if (__exception == null)
			{
				return null;
			}
			try
			{
				ZNetScene instance = ZNetScene.instance;
				Dictionary<ZDO, ZNetView> dictionary = (((Object)(object)instance != (Object)null && _znetInstances != null) ? (_znetInstances.GetValue(instance) as Dictionary<ZDO, ZNetView>) : null);
				if (dictionary != null && dictionary.Count > 0)
				{
					GhostKeys.Clear();
					foreach (KeyValuePair<ZDO, ZNetView> item in dictionary)
					{
						if ((Object)(object)item.Value == (Object)null || item.Value.GetZDO() == null)
						{
							GhostKeys.Add(item.Key);
						}
					}
					int num = 0;
					foreach (ZDO ghostKey in GhostKeys)
					{
						if (dictionary.TryGetValue(ghostKey, out var value) && (!((Object)(object)value != (Object)null) || value.GetZDO() == null))
						{
							dictionary.Remove(ghostKey);
							if ((Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null)
							{
								Object.Destroy((Object)(object)((Component)value).gameObject);
							}
							num++;
						}
					}
					if (num > 0 && Time.time > _nextLog)
					{
						_nextLog = Time.time + 30f;
						_log.LogWarning((object)($"ZNetScene: fixed net race, removed {num} ghost instance(s) " + "(null ZDO). Exception suppressed, object cycle continues."));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("ZNetScene ghost cleanup failed: " + ex.Message));
			}
			return null;
		}
	}

	public const string PluginGuid = "user.swiftpickup";

	public const string PluginName = "SwiftPickup";

	public const string PluginVersion = "1.3.3";

	private static ConfigEntry<bool> _modEnabled;

	private static ConfigEntry<float> _pickupRange;

	private static ConfigEntry<float> _scanInterval;

	private static ConfigEntry<int> _maxPickupsPerScan;

	private static ConfigEntry<float> _magnetSpeed;

	private static ConfigEntry<bool> _skipPickupEffects;

	private static ConfigEntry<bool> _showPickupMessages;

	private static ConfigEntry<string> _ignoreList;

	private static ConfigEntry<KeyboardShortcut> _toggleKey;

	private static ConfigEntry<int> _lootMultiplier;

	private static ConfigEntry<bool> _mergeDrops;

	private static ConfigEntry<float> _mergeRadius;

	private static ConfigEntry<int> _mergeMinCount;

	private static ConfigEntry<int> _maxMergesPerScan;

	private static ManualLogSource _log;

	private static FieldInfo _maskField;

	private static MethodInfo _itemDropSave;

	private static FieldInfo _humanoidInventory;

	private static FieldInfo _znetInstances;

	private static readonly Collider[] Buffer = (Collider[])(object)new Collider[256];

	private static HashSet<string> _ignore = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	private static bool _bufferWarned;

	private static readonly List<Candidate> Candidates = new List<Candidate>(64);

	private static float _nextScan;

	private static readonly List<ItemDrop> MagnetItems = new List<ItemDrop>(32);

	private static bool _handMultiplyPending;

	private static int _handMultiplyTarget;

	private static readonly Dictionary<string, List<ItemDrop>> Groups = new Dictionary<string, List<ItemDrop>>(32);

	private void Awake()
	{
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		_log = ((BaseUnityPlugin)this).Logger;
		_modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Включён ли автоподбор при старте. Клавиша ниже переключает только подбор; множитель и кучки настраиваются отдельно.");
		_pickupRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PickupRange", 3.5f, "Радиус автоподбора в метрах (игровых юнитах). Ваниль ~2.");
		_scanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScanIntervalSeconds", 0.15f, "Как часто (сек) сканировать окружение на предметы. Больше значение = меньше нагрузки.");
		_maxPickupsPerScan = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPickupsPerScan", 2, "Сколько предметов максимум подбирать за один скан (распределяет нагрузку по кадрам). 0 = без ограничения.");
		_magnetSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MagnetSpeed", 15f, "Скорость магнитного притяжения предметов к игроку (как в ванили, 15).");
		_skipPickupEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "SkipPickupEffects", true, "Не создавать частицы/эффекты при подборе. Главная экономия кадров при массовом подборе.");
		_showPickupMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "ShowPickupMessages", true, "Показывать всплывающие сообщения '+Древесина xN'. Очень дёшево, но можно отключить.");
		_lootMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Loot", "LootMultiplier", 5, "Во сколько раз умножать количество предметов при подборе (авто и ручной). На земле лежит ванильное число объектов — умножение происходит в момент подбора. 1 = без умножения.");
		_ignoreList = ((BaseUnityPlugin)this).Config.Bind<string>("General", "IgnoreItems", "", "Имена префабов предметов (через запятую), которые НЕ автоподбирать. Пример: Wood,Stone.");
		_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Клавиша переключения автоподбора в игре.");
		_mergeDrops = ((BaseUnityPlugin)this).Config.Bind<bool>("Merge", "MergeNearbyDrops", true, "Склеивать одинаковые предметы, лежащие рядом, в один стак (как при выбросе игроком). Резко снижает количество объектов на земле.");
		_mergeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Merge", "MergeRadius", 3f, "Радиус (м), внутри которого одинаковые предметы считаются 'лежащими рядом' и склеиваются.");
		_mergeMinCount = ((BaseUnityPlugin)this).Config.Bind<int>("Merge", "MergeMinCount", 2, "Минимум одинаковых предметов рядом, чтобы запустить склейку в кучку.");
		_maxMergesPerScan = ((BaseUnityPlugin)this).Config.Bind<int>("Merge", "MaxMergesPerScan", 2, "Максимум операций склейки за один скан (нагрузка распределяется по кадрам).");
		_maskField = AccessTools.Field(typeof(Player), "m_autoPickupMask");
		_itemDropSave = AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null);
		_znetInstances = AccessTools.Field(typeof(ZNetScene), "m_instances");
		_humanoidInventory = AccessTools.Field(typeof(Humanoid), "m_inventory");
		ParseIgnoreList();
		new Harmony("user.swiftpickup").PatchAll(typeof(SwiftPickupPlugin).Assembly);
		_log.LogInfo((object)string.Format("{0} v{1} загружен. Клавиша {2} переключает только автоподбор; множитель и кучки настроены в конфиге.", "SwiftPickup", "1.3.3", _toggleKey.Value));
	}

	private static void ParseIgnoreList()
	{
		_ignore = new HashSet<string>(from s in (_ignoreList.Value ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
			select s.Trim() into s
			where s.Length > 0
			select s, StringComparer.OrdinalIgnoreCase);
	}

	private static bool IsPickupEnabled()
	{
		return _modEnabled.Value;
	}

	private static int GetMask(Player player)
	{
		try
		{
			if (_maskField != null && _maskField.GetValue(player) is int num && num != 0)
			{
				return num;
			}
		}
		catch
		{
		}
		return LayerMask.GetMask(new string[1] { "item" });
	}

	private static bool IsIgnored(ItemData data)
	{
		if (_ignore.Count == 0 || data == null)
		{
			return false;
		}
		if ((Object)(object)data.m_dropPrefab != (Object)null && _ignore.Contains(((Object)data.m_dropPrefab).name))
		{
			return true;
		}
		if (data.m_shared != null && _ignore.Contains(data.m_shared.m_name))
		{
			return true;
		}
		return false;
	}

	private static void HandleScan(Player player, float dt)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		bool flag = IsPickupEnabled();
		float num = (flag ? _pickupRange.Value : 0f);
		if (_mergeDrops.Value)
		{
			num = Mathf.Max(num, _mergeRadius.Value);
		}
		if (num <= 0f)
		{
			return;
		}
		float time = Time.time;
		if (time - _nextScan < _scanInterval.Value)
		{
			return;
		}
		_nextScan = time + _scanInterval.Value;
		Vector3 val = ((Component)player).transform.position + Vector3.up;
		int mask = GetMask(player);
		int num2;
		try
		{
			num2 = Physics.OverlapSphereNonAlloc(val, num, Buffer, mask);
		}
		catch (Exception arg)
		{
			_log.LogError((object)$"OverlapSphere failed: {arg}");
			return;
		}
		if (num2 >= Buffer.Length && !_bufferWarned)
		{
			_bufferWarned = true;
			_log.LogWarning((object)"Буфер переполнен (256 коллайдеров), часть предметов не сканируется.");
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return;
		}
		Candidates.Clear();
		Groups.Clear();
		for (int i = 0; i < num2; i++)
		{
			Collider val2 = Buffer[i];
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Rigidbody attachedRigidbody = val2.attachedRigidbody;
			if ((Object)(object)attachedRigidbody == (Object)null)
			{
				continue;
			}
			ItemDrop component = ((Component)attachedRigidbody).GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				FloatingTerrainDummy component2 = ((Component)attachedRigidbody).GetComponent<FloatingTerrainDummy>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)component2.m_parent != (Object)null)
				{
					component = ((Component)component2.m_parent).gameObject.GetComponent<ItemDrop>();
				}
			}
			if ((Object)(object)component == (Object)null || !component.m_autoPickup || component.IsPiece())
			{
				continue;
			}
			SharedData val3 = ((component.m_itemData != null) ? component.m_itemData.m_shared : null);
			if (val3 == null || ((Humanoid)player).HaveUniqueKey(val3.m_name) || IsIgnored(component.m_itemData))
			{
				continue;
			}
			ZNetView component3 = ((Component)component).GetComponent<ZNetView>();
			if ((Object)(object)component3 == (Object)null || !component3.IsValid())
			{
				continue;
			}
			if (!component.CanPickup(true))
			{
				component.RequestOwn();
			}
			else
			{
				if (component.InTar())
				{
					continue;
				}
				if (_mergeDrops.Value)
				{
					string key = (((Object)(object)component.m_itemData.m_dropPrefab != (Object)null) ? ((Object)component.m_itemData.m_dropPrefab).name : component.m_itemData.m_shared.m_name);
					if (!Groups.TryGetValue(key, out var value))
					{
						value = new List<ItemDrop>();
						Groups[key] = value;
					}
					value.Add(component);
				}
				if (!flag)
				{
					continue;
				}
				float num3 = Vector3.Distance(((Component)component).transform.position, val);
				if (!(num3 > _pickupRange.Value))
				{
					if (num3 < 0.3f)
					{
						Candidates.Add(new Candidate
						{
							Drop = component,
							Distance = num3
						});
					}
					else if (!MagnetItems.Contains(component))
					{
						MagnetItems.Add(component);
					}
				}
			}
		}
		if (_mergeDrops.Value)
		{
			TryMergeNearby();
		}
		if (!flag || Candidates.Count <= 0)
		{
			return;
		}
		if (Candidates.Count > 1)
		{
			Candidates.Sort((Candidate a, Candidate b) => a.Distance.CompareTo(b.Distance));
		}
		int num4 = ((_maxPickupsPerScan.Value <= 0) ? Candidates.Count : _maxPickupsPerScan.Value);
		int num5 = 0;
		for (int num6 = 0; num6 < Candidates.Count; num6++)
		{
			if (num5 >= num4)
			{
				break;
			}
			ItemDrop drop = Candidates[num6].Drop;
			if (!((Object)(object)drop == (Object)null) && PickupOne(player, inventory, drop))
			{
				num5++;
			}
		}
	}

	private static void MoveMagnets(Player player)
	{
		//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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		Inventory inventory = ((Humanoid)player).GetInventory();
		Vector3 val = ((Component)player).transform.position + Vector3.up;
		float deltaTime = Time.deltaTime;
		int num = 1;
		for (int num2 = MagnetItems.Count - 1; num2 >= 0; num2--)
		{
			ItemDrop val2 = MagnetItems[num2];
			if ((Object)(object)val2 == (Object)null)
			{
				MagnetItems.RemoveAt(num2);
			}
			else
			{
				float num3 = Vector3.Distance(((Component)val2).transform.position, val);
				if (num3 > _pickupRange.Value * 1.5f)
				{
					MagnetItems.RemoveAt(num2);
				}
				else if (num3 < 0.3f)
				{
					if (num > 0 && inventory != null && PickupOne(player, inventory, val2))
					{
						num--;
						MagnetItems.RemoveAt(num2);
					}
					else if (num > 0)
					{
						MagnetItems.RemoveAt(num2);
					}
				}
				else
				{
					Vector3 val3 = val - ((Component)val2).transform.position;
					Vector3 normalized = ((Vector3)(ref val3)).normalized;
					float num4 = Mathf.Min(_magnetSpeed.Value * deltaTime, num3 - 0.25f);
					Transform transform = ((Component)val2).transform;
					transform.position += normalized * num4;
				}
			}
		}
	}

	private static void TryMergeNearby()
	{
		int num = _maxMergesPerScan.Value;
		foreach (KeyValuePair<string, List<ItemDrop>> group in Groups)
		{
			if (num <= 0)
			{
				break;
			}
			List<ItemDrop> value = group.Value;
			if (value == null || value.Count < _mergeMinCount.Value)
			{
				continue;
			}
			ItemDrop target = value[0];
			int num2 = value.Count - 1;
			while (num2 >= 1 && num > 0)
			{
				ItemDrop val = value[num2];
				if (!((Object)(object)val == (Object)null))
				{
					if (MergePair(target, val))
					{
						value.RemoveAt(num2);
						num--;
					}
					else if (num2 > 1)
					{
						target = val;
					}
				}
				num2--;
			}
		}
	}

	private static bool MergePair(ItemDrop target, ItemDrop source)
	{
		try
		{
			ZNetView component = ((Component)target).GetComponent<ZNetView>();
			ZNetView component2 = ((Component)source).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || !component.IsValid() || !component2.IsValid())
			{
				return false;
			}
			if (component.GetZDO() == null || component2.GetZDO() == null)
			{
				return false;
			}
			if (!component.IsOwner() || !component2.IsOwner())
			{
				return false;
			}
			target.Load();
			source.Load();
			ItemData itemData = target.m_itemData;
			ItemData itemData2 = source.m_itemData;
			if (itemData == null || itemData2 == null || itemData.m_shared == null || itemData2.m_shared == null)
			{
				return false;
			}
			if (itemData.m_shared.m_name != itemData2.m_shared.m_name)
			{
				return false;
			}
			if (itemData.m_variant != itemData2.m_variant || itemData.m_quality != itemData2.m_quality)
			{
				return false;
			}
			int maxStackSize = itemData.m_shared.m_maxStackSize;
			if (maxStackSize <= 1)
			{
				return false;
			}
			int num = Mathf.Min(maxStackSize - itemData.m_stack, itemData2.m_stack);
			if (num <= 0)
			{
				return false;
			}
			itemData.m_stack += num;
			itemData2.m_stack -= num;
			_itemDropSave?.Invoke(target, null);
			if (itemData2.m_stack <= 0)
			{
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					ZNetScene.instance.Destroy(((Component)source).gameObject);
				}
				return true;
			}
			_itemDropSave?.Invoke(source, null);
			return false;
		}
		catch (Exception ex)
		{
			_log.LogWarning((object)("Merge failed: " + ex.Message));
			return false;
		}
	}

	private static bool PickupOne(Player player, Inventory inventory, ItemDrop drop)
	{
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		if (!drop.CanPickup(true))
		{
			return false;
		}
		ZNetView component = ((Component)drop).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid() || component.GetZDO() == null)
		{
			return false;
		}
		drop.Load();
		ItemData itemData = drop.m_itemData;
		if (itemData == null || itemData.m_shared == null)
		{
			return false;
		}
		if (itemData.m_shared.m_questItem && ((Humanoid)player).HaveUniqueKey(itemData.m_shared.m_name))
		{
			return false;
		}
		if (inventory.ContainsItem(itemData))
		{
			return false;
		}
		int stack = itemData.m_stack;
		int value = _lootMultiplier.Value;
		if (value > 1 && stack > 0)
		{
			itemData.m_stack = stack * value;
		}
		int stack2 = itemData.m_stack;
		if (!inventory.CanAddItem(itemData, -1))
		{
			itemData.m_stack = stack;
			return false;
		}
		if (itemData.GetWeight(-1) + inventory.GetTotalWeight() > player.GetMaxCarryWeight())
		{
			itemData.m_stack = stack;
			return false;
		}
		if (!inventory.AddItem(itemData))
		{
			return false;
		}
		if (itemData.m_shared.m_questItem)
		{
			((Humanoid)player).AddUniqueKey(itemData.m_shared.m_name);
		}
		if ((Object)(object)ZNetScene.instance != (Object)null && component.IsOwner() && component.GetZDO() != null)
		{
			ZNetScene.instance.Destroy(((Component)drop).gameObject);
		}
		if (!_skipPickupEffects.Value)
		{
			try
			{
				if ((Object)(object)player != (Object)null && ((Humanoid)player).m_pickupEffects != null)
				{
					((Humanoid)player).m_pickupEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID());
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("Effect create failed: " + ex.Message));
			}
		}
		if (_showPickupMessages.Value)
		{
			((Character)player).ShowPickupMessage(itemData, stack2 - itemData.m_stack);
		}
		return true;
	}
}