Decompiled source of Smartpickup v1.0.7

BepInEx\plugins\SmartPickup.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SmartPickup")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SmartPickup")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1c4fa49b-2311-4587-a0a0-1095f2b4d1c3")]
[assembly: AssemblyFileVersion("1.0.7.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.7.0")]
namespace SmartAutopickupMod;

internal static class PluginInfo
{
	internal const string Guid = "com.b0n3.smartpickup";

	internal const string LegacyGuid = "com.yourname.valheim.smartautopickup";

	internal const string Name = "SmartPickup";

	internal const string Version = "1.0.7";

	internal const string ModeMessagePrefix = "Auto-Pickup:";
}
public enum AutopickupMode
{
	Normal,
	Smart,
	Off
}
[BepInPlugin("com.b0n3.smartpickup", "SmartPickup", "1.0.7")]
public class SmartAutopickup : BaseUnityPlugin
{
	private const float MinPickupRange = 0.5f;

	private const float MaxPickupRange = 100f;

	private static readonly FieldInfo VanillaAutopickupEnabledField = AccessTools.Field(typeof(Player), "m_enableAutoPickup");

	private static readonly FieldInfo VanillaAutopickupRangeField = AccessTools.Field(typeof(Player), "m_autoPickupRange");

	private static Player trackedUpdatePlayer;

	private static bool trackedVanillaAutopickupState;

	private static bool hasWarnedMissingVanillaAutopickupField;

	private static bool hasWarnedMissingVanillaAutopickupRangeField;

	private static Player trackedRangePlayer;

	private static float trackedOriginalVanillaAutopickupRange;

	private static bool hasTrackedOriginalVanillaAutopickupRange;

	public static AutopickupMode CurrentMode;

	public static ManualLogSource Log;

	public static ConfigEntry<AutopickupMode> DefaultMode;

	public static ConfigEntry<int> PickupRange;

	public static ConfigEntry<bool> ApplyCustomRangeInNormalMode;

	private const string LegacyMigrationMarkerFileName = "com.b0n3.smartpickup.migrated";

	private void Awake()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		NormalizePickupRangeConfigIfNeeded();
		DefaultMode = ((BaseUnityPlugin)this).Config.Bind<AutopickupMode>("General", "DefaultMode", AutopickupMode.Normal, new ConfigDescription("Default autopickup mode at startup. Changing it at runtime also applies it immediately.", (AcceptableValueBase)null, Array.Empty<object>()));
		PickupRange = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PickupRange", 5, "Pickup range for smart mode in whole game units. Valid values are 1 through 100.");
		ApplyCustomRangeInNormalMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ApplyCustomRangeInNormalMode", false, "When enabled, normal mode uses SmartPickup's configurable pull range instead of Valheim's default autopickup range.");
		TryImportLegacyConfigValues();
		DefaultMode.SettingChanged += OnDefaultModeChanged;
		PickupRange.SettingChanged += OnPickupRangeChanged;
		ApplyCustomRangeInNormalMode.SettingChanged += OnApplyCustomRangeInNormalModeChanged;
		PickupRange.Value = Mathf.RoundToInt(GetConfiguredPickupRange());
		CurrentMode = DefaultMode.Value;
		ApplyVanillaAutopickupState();
		try
		{
			new Harmony("com.b0n3.smartpickup").PatchAll();
			Log.LogInfo((object)$"Smart Autopickup mod loaded. Mode: {CurrentMode}, Pickup Range: {PickupRange.Value}, Custom Range In Normal Mode: {ApplyCustomRangeInNormalMode.Value}");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Error in Awake: " + ex));
		}
	}

	private void TryImportLegacyConfigValues()
	{
		string text = Path.Combine(Paths.ConfigPath, "com.yourname.valheim.smartautopickup.cfg");
		if (!HasCompletedLegacyMigration() && File.Exists(text))
		{
			string legacyConfigValue = GetLegacyConfigValue(text, "DefaultMode");
			if (!string.IsNullOrEmpty(legacyConfigValue) && Enum.TryParse<AutopickupMode>(legacyConfigValue, ignoreCase: true, out var result))
			{
				DefaultMode.Value = result;
			}
			string legacyConfigValue2 = GetLegacyConfigValue(text, "PickupRange");
			if (!string.IsNullOrEmpty(legacyConfigValue2) && (float.TryParse(legacyConfigValue2, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || float.TryParse(legacyConfigValue2, NumberStyles.Float, CultureInfo.CurrentCulture, out result2)))
			{
				PickupRange.Value = Mathf.Clamp(Mathf.RoundToInt(result2), (int)Math.Ceiling(0.5), 100);
			}
			string legacyConfigValue3 = GetLegacyConfigValue(text, "ApplyCustomRangeInNormalMode");
			if (!string.IsNullOrEmpty(legacyConfigValue3) && bool.TryParse(legacyConfigValue3, out var result3))
			{
				ApplyCustomRangeInNormalMode.Value = result3;
			}
			MarkLegacyMigrationComplete();
			Log.LogInfo((object)"Migrated SmartPickup config from 'com.yourname.valheim.smartautopickup' to 'com.b0n3.smartpickup'.");
		}
	}

	private static bool HasCompletedLegacyMigration()
	{
		return File.Exists(Path.Combine(Paths.ConfigPath, "com.b0n3.smartpickup.migrated"));
	}

	private static void MarkLegacyMigrationComplete()
	{
		File.WriteAllText(Path.Combine(Paths.ConfigPath, "com.b0n3.smartpickup.migrated"), "1.0.7");
	}

	private static string GetLegacyConfigValue(string configPath, string key)
	{
		bool flag = false;
		foreach (string item in File.ReadLines(configPath))
		{
			string text = item.Trim();
			if (text.Length == 0 || text.StartsWith("#") || text.StartsWith("##"))
			{
				continue;
			}
			if (text.StartsWith("[") && text.EndsWith("]"))
			{
				flag = string.Equals(text, "[General]", StringComparison.OrdinalIgnoreCase);
			}
			else if (flag && text.StartsWith(key + " ", StringComparison.Ordinal))
			{
				int num = text.IndexOf('=');
				if (num < 0)
				{
					return null;
				}
				return text.Substring(num + 1).Trim();
			}
		}
		return null;
	}

	private static void NormalizePickupRangeConfigIfNeeded()
	{
		string path = Path.Combine(Paths.ConfigPath, "com.b0n3.smartpickup.cfg");
		if (!File.Exists(path))
		{
			return;
		}
		string[] array = File.ReadAllLines(path);
		bool flag = false;
		for (int i = 0; i < array.Length; i++)
		{
			if (!array[i].StartsWith("PickupRange ="))
			{
				continue;
			}
			string s = array[i].Substring("PickupRange =".Length).Trim();
			if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && !float.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out result))
			{
				return;
			}
			string text = "PickupRange = " + Mathf.Clamp(Mathf.RoundToInt(result), (int)Math.Ceiling(0.5), 100).ToString(CultureInfo.InvariantCulture);
			if (!string.Equals(array[i], text, StringComparison.Ordinal))
			{
				array[i] = text;
				flag = true;
			}
			break;
		}
		if (flag)
		{
			File.WriteAllLines(path, array);
			Log.LogInfo((object)"Normalized PickupRange to a whole-number value for stepped slider behavior.");
		}
	}

	private void OnDefaultModeChanged(object sender, EventArgs e)
	{
		CurrentMode = DefaultMode.Value;
		ApplyVanillaAutopickupState();
		Log.LogInfo((object)("Default autopickup mode updated. Active mode is now: " + CurrentMode));
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			string text = ((CurrentMode == AutopickupMode.Normal) ? "On" : CurrentMode.ToString());
			((Character)Player.m_localPlayer).Message((MessageType)1, "Auto-Pickup:" + text, 0, (Sprite)null);
		}
	}

	private void OnPickupRangeChanged(object sender, EventArgs e)
	{
		int num = Mathf.RoundToInt(GetConfiguredPickupRange());
		if (PickupRange.Value != num)
		{
			PickupRange.Value = num;
			return;
		}
		ApplyVanillaAutopickupState();
		Log.LogInfo((object)("Smart pickup range updated to: " + PickupRange.Value));
	}

	private void OnApplyCustomRangeInNormalModeChanged(object sender, EventArgs e)
	{
		ApplyVanillaAutopickupState();
		Log.LogInfo((object)("Custom range in normal mode is now: " + ApplyCustomRangeInNormalMode.Value));
	}

	private static AutopickupMode GetNextMode(AutopickupMode currentMode)
	{
		return currentMode switch
		{
			AutopickupMode.Normal => AutopickupMode.Smart, 
			AutopickupMode.Smart => AutopickupMode.Off, 
			_ => AutopickupMode.Normal, 
		};
	}

	internal static void CycleModeFromVanillaToggle(Player player)
	{
		CurrentMode = GetNextMode(CurrentMode);
		ApplyVanillaAutopickupState();
		Log.LogInfo((object)("Autopickup mode switched to: " + CurrentMode));
		if ((Object)(object)player != (Object)null)
		{
			string text = ((CurrentMode == AutopickupMode.Normal) ? "On" : CurrentMode.ToString());
			((Character)player).Message((MessageType)1, "Auto-Pickup:" + text, 0, (Sprite)null);
		}
	}

	internal static float GetConfiguredPickupRange()
	{
		return Mathf.Clamp((float)PickupRange.Value, 0.5f, 100f);
	}

	internal static void BeginTrackingVanillaAutopickupState(Player player)
	{
		if ((Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			trackedUpdatePlayer = null;
			return;
		}
		trackedUpdatePlayer = player;
		trackedVanillaAutopickupState = GetVanillaAutopickupEnabled();
	}

	internal static void EndTrackingVanillaAutopickupState(Player player)
	{
		if ((Object)(object)trackedUpdatePlayer == (Object)(object)player)
		{
			trackedUpdatePlayer = null;
		}
	}

	internal static bool ShouldHandleVanillaAutopickupToggleMessage(Player player)
	{
		if ((Object)(object)trackedUpdatePlayer == (Object)(object)player)
		{
			return GetVanillaAutopickupEnabled() != trackedVanillaAutopickupState;
		}
		return false;
	}

	internal static void ApplyVanillaAutopickupStateForLifecycle()
	{
		ApplyVanillaAutopickupState();
	}

	private static void ApplyVanillaAutopickupState()
	{
		TrackOriginalVanillaAutopickupRange(Player.m_localPlayer);
		bool flag = CurrentMode != AutopickupMode.Off;
		if (GetVanillaAutopickupEnabled() != flag)
		{
			SetVanillaAutopickupEnabled(flag);
		}
		ApplyVanillaAutopickupRange(Player.m_localPlayer);
	}

	private static bool GetVanillaAutopickupEnabled()
	{
		if (VanillaAutopickupEnabledField == null)
		{
			WarnMissingVanillaAutopickupField();
			return false;
		}
		return (bool)VanillaAutopickupEnabledField.GetValue(null);
	}

	private static void SetVanillaAutopickupEnabled(bool enabled)
	{
		if (VanillaAutopickupEnabledField == null)
		{
			WarnMissingVanillaAutopickupField();
		}
		else
		{
			VanillaAutopickupEnabledField.SetValue(null, enabled);
		}
	}

	private static void WarnMissingVanillaAutopickupField()
	{
		if (!hasWarnedMissingVanillaAutopickupField && Log != null)
		{
			hasWarnedMissingVanillaAutopickupField = true;
			Log.LogWarning((object)"SmartPickup could not resolve Player.m_enableAutoPickup. Valheim may have changed and autopickup mode syncing may not work correctly.");
		}
	}

	private static void TrackOriginalVanillaAutopickupRange(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			trackedRangePlayer = null;
			hasTrackedOriginalVanillaAutopickupRange = false;
		}
		else if (!((Object)(object)trackedRangePlayer == (Object)(object)player) || !hasTrackedOriginalVanillaAutopickupRange)
		{
			trackedRangePlayer = player;
			if (TryGetVanillaAutopickupRange(player, out var range))
			{
				trackedOriginalVanillaAutopickupRange = range;
				hasTrackedOriginalVanillaAutopickupRange = true;
			}
			else
			{
				hasTrackedOriginalVanillaAutopickupRange = false;
			}
		}
	}

	private static void ApplyVanillaAutopickupRange(Player player)
	{
		if (!((Object)(object)player == (Object)null) && TryGetVanillaAutopickupRange(player, out var range))
		{
			float num = range;
			if (CurrentMode == AutopickupMode.Normal && ApplyCustomRangeInNormalMode.Value)
			{
				num = GetConfiguredPickupRange();
			}
			else if (hasTrackedOriginalVanillaAutopickupRange)
			{
				num = trackedOriginalVanillaAutopickupRange;
			}
			if (!Mathf.Approximately(range, num))
			{
				SetVanillaAutopickupRange(player, num);
			}
		}
	}

	private static bool TryGetVanillaAutopickupRange(Player player, out float range)
	{
		if (VanillaAutopickupRangeField == null)
		{
			WarnMissingVanillaAutopickupRangeField();
			range = 0f;
			return false;
		}
		range = (float)VanillaAutopickupRangeField.GetValue(player);
		return true;
	}

	private static void SetVanillaAutopickupRange(Player player, float range)
	{
		if (VanillaAutopickupRangeField == null)
		{
			WarnMissingVanillaAutopickupRangeField();
		}
		else
		{
			VanillaAutopickupRangeField.SetValue(player, range);
		}
	}

	private static void WarnMissingVanillaAutopickupRangeField()
	{
		if (!hasWarnedMissingVanillaAutopickupRangeField && Log != null)
		{
			hasWarnedMissingVanillaAutopickupRangeField = true;
			Log.LogWarning((object)"SmartPickup could not resolve Player.m_autoPickupRange. Custom range syncing may not work correctly.");
		}
	}
}
[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
public class Player_SetLocalPlayer_Patch
{
	private static void Postfix(Player __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			SmartAutopickup.ApplyVanillaAutopickupStateForLifecycle();
		}
	}
}
[HarmonyPatch(typeof(Player), "Update")]
public class Player_Update_Patch
{
	private static void Prefix(Player __instance)
	{
		SmartAutopickup.BeginTrackingVanillaAutopickupState(__instance);
	}

	private static void Postfix(Player __instance)
	{
		SmartAutopickup.EndTrackingVanillaAutopickupState(__instance);
	}
}
[HarmonyPatch(typeof(Player), "AutoPickup")]
public class Player_AutoPickup_Patch
{
	private const int OverlapBufferSize = 128;

	private const float PullSpeed = 15f;

	private const float DirectPickupDistance = 0.3f;

	private const float DirectPickupDistanceSqr = 0.09f;

	private static readonly Collider[] OverlapBuffer = (Collider[])(object)new Collider[128];

	private static readonly HashSet<string> InventoryItemIdsBuffer = new HashSet<string>();

	private static readonly FieldInfo AutoPickupMaskField = AccessTools.Field(typeof(Player), "m_autoPickupMask");

	private static readonly FieldInfo ItemDropPrefabField = AccessTools.Field(typeof(ItemData), "m_dropPrefab");

	private static bool hasWarnedMissingAutoPickupMaskField;

	private static bool Prefix(Player __instance, float dt)
	{
		try
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (SmartAutopickup.CurrentMode == AutopickupMode.Normal)
			{
				return true;
			}
			if (SmartAutopickup.CurrentMode == AutopickupMode.Off)
			{
				return false;
			}
			if (SmartAutopickup.CurrentMode == AutopickupMode.Smart)
			{
				return RunCustomAutoPickup(__instance, dt, requireExistingInventoryItem: true);
			}
		}
		catch (Exception ex)
		{
			SmartAutopickup.Log.LogError((object)("Error in Player_AutoPickup_Patch Prefix: " + ex));
		}
		return true;
	}

	private static bool RunCustomAutoPickup(Player player, float dt, bool requireExistingInventoryItem)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		if (((Character)player).IsTeleporting())
		{
			return false;
		}
		Vector3 val = ((Component)player).transform.position + Vector3.up;
		int autoPickupMask = GetAutoPickupMask(player);
		Inventory inventory = ((Humanoid)player).GetInventory();
		float configuredPickupRange = SmartAutopickup.GetConfiguredPickupRange();
		float num = configuredPickupRange * configuredPickupRange;
		HashSet<string> hashSet = (requireExistingInventoryItem ? GetInventoryItemIds(inventory) : null);
		Collider[] array = OverlapBuffer;
		int num2 = Physics.OverlapSphereNonAlloc(val, configuredPickupRange, OverlapBuffer, autoPickupMask);
		if (num2 >= OverlapBuffer.Length)
		{
			array = Physics.OverlapSphere(val, configuredPickupRange, autoPickupMask);
			num2 = array.Length;
		}
		for (int i = 0; i < num2; i++)
		{
			Collider val2 = array[i];
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.attachedRigidbody == (Object)null || !TryGetItemDrop(val2, out var itemDrop, out var floatingTerrainDummy) || !CanCustomPickupItem(player, itemDrop))
			{
				continue;
			}
			string itemIdentifier = GetItemIdentifier(itemDrop.m_itemData);
			if ((requireExistingInventoryItem && (string.IsNullOrEmpty(itemIdentifier) || hashSet == null || !hashSet.Contains(itemIdentifier))) || !itemDrop.CanPickup(true) || itemDrop.InTar())
			{
				continue;
			}
			itemDrop.Load();
			if (!inventory.CanAddItem(itemDrop.m_itemData, -1) || inventory.GetTotalWeight() + itemDrop.m_itemData.GetWeight(-1) > player.GetMaxCarryWeight())
			{
				continue;
			}
			Vector3 val3 = val - ((Component)itemDrop).transform.position;
			float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
			if (sqrMagnitude > num)
			{
				continue;
			}
			if (sqrMagnitude < 0.09f)
			{
				((Humanoid)player).Pickup(((Component)itemDrop).gameObject, true, true);
			}
			else if (CanAttractItem(itemDrop))
			{
				Vector3 val4 = ((Vector3)(ref val3)).normalized * 15f * dt;
				Transform transform = ((Component)itemDrop).transform;
				transform.position += val4;
				if ((Object)(object)floatingTerrainDummy != (Object)null)
				{
					Transform transform2 = ((Component)floatingTerrainDummy).transform;
					transform2.position += val4;
				}
			}
		}
		return false;
	}

	private static HashSet<string> GetInventoryItemIds(Inventory inventory)
	{
		InventoryItemIdsBuffer.Clear();
		foreach (ItemData allItem in inventory.GetAllItems())
		{
			string itemIdentifier = GetItemIdentifier(allItem);
			if (!string.IsNullOrEmpty(itemIdentifier))
			{
				InventoryItemIdsBuffer.Add(itemIdentifier);
			}
		}
		return InventoryItemIdsBuffer;
	}

	private static int GetAutoPickupMask(Player player)
	{
		if (AutoPickupMaskField == null)
		{
			WarnMissingAutoPickupMaskField();
			return 0;
		}
		return (int)AutoPickupMaskField.GetValue(player);
	}

	private static string GetItemIdentifier(ItemData itemData)
	{
		object? obj = ItemDropPrefabField?.GetValue(itemData);
		GameObject val = (GameObject)((obj is GameObject) ? obj : null);
		if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name))
		{
			return ((Object)val).name;
		}
		return GetItemName(itemData);
	}

	private static string GetItemName(ItemData itemData)
	{
		return itemData?.m_shared?.m_name;
	}

	private static bool CanCustomPickupItem(Player player, ItemDrop itemDrop)
	{
		if ((Object)(object)itemDrop == (Object)null || !itemDrop.m_autoPickup || itemDrop.IsPiece())
		{
			return false;
		}
		string itemName = GetItemName(itemDrop.m_itemData);
		if (string.IsNullOrEmpty(itemName) || ((Humanoid)player).HaveUniqueKey(itemName))
		{
			return false;
		}
		ZNetView component = ((Component)itemDrop).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null)
		{
			return component.IsValid();
		}
		return false;
	}

	private static bool TryGetItemDrop(Collider collider, out ItemDrop itemDrop, out FloatingTerrainDummy floatingTerrainDummy)
	{
		itemDrop = null;
		floatingTerrainDummy = null;
		Rigidbody attachedRigidbody = collider.attachedRigidbody;
		if ((Object)(object)attachedRigidbody == (Object)null)
		{
			return false;
		}
		itemDrop = ((Component)attachedRigidbody).GetComponent<ItemDrop>();
		if ((Object)(object)itemDrop != (Object)null)
		{
			return true;
		}
		floatingTerrainDummy = ((Component)attachedRigidbody).GetComponent<FloatingTerrainDummy>();
		if ((Object)(object)floatingTerrainDummy != (Object)null && (Object)(object)floatingTerrainDummy.m_parent != (Object)null)
		{
			itemDrop = ((Component)floatingTerrainDummy.m_parent).gameObject.GetComponent<ItemDrop>();
		}
		return (Object)(object)itemDrop != (Object)null;
	}

	private static bool CanAttractItem(ItemDrop itemDrop)
	{
		ZNetView component = ((Component)itemDrop).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null)
		{
			return component.IsOwner();
		}
		return false;
	}

	private static void WarnMissingAutoPickupMaskField()
	{
		if (!hasWarnedMissingAutoPickupMaskField && SmartAutopickup.Log != null)
		{
			hasWarnedMissingAutoPickupMaskField = true;
			SmartAutopickup.Log.LogWarning((object)"SmartPickup could not resolve Player.m_autoPickupMask. Custom pickup scanning may not work correctly on this Valheim version.");
		}
	}
}
[HarmonyPatch(typeof(Player), "Message")]
public class Player_Message_Patch
{
	private static bool Prefix(Player __instance, MessageType type, string msg, int amount, Sprite icon)
	{
		try
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (msg != null && msg.StartsWith("$hud_autopickup:"))
			{
				if (!SmartAutopickup.ShouldHandleVanillaAutopickupToggleMessage(__instance))
				{
					return true;
				}
				SmartAutopickup.CycleModeFromVanillaToggle(__instance);
				return false;
			}
		}
		catch (Exception ex)
		{
			SmartAutopickup.Log.LogError((object)("Error in Player_Message_Patch Prefix: " + ex));
		}
		return true;
	}
}