Decompiled source of XPortalSharedMapPins v0.2.0

plugins\XPortalSharedMapPins.dll

Decompiled 8 hours ago
using System;
using System.Collections;
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 Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("XPortalSharedMapPins")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("XPortalSharedMapPins")]
[assembly: AssemblyTitle("XPortalSharedMapPins")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace XPortalSharedMapPins
{
	[BepInPlugin("buldosik.XPortalSharedMapPins", "XPortal Shared Map Pins", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Minimap), "UpdatePins")]
		private static class MinimapUpdatePinsPatch
		{
			private static void Postfix()
			{
				Instance?.ReapplyPortalColors();
			}
		}

		public const string PluginGuid = "buldosik.XPortalSharedMapPins";

		public const string PluginName = "XPortal Shared Map Pins";

		public const string PluginVersion = "0.2.0";

		private const string PinPrefix = "";

		private static ManualLogSource Log = null;

		private static Plugin? Instance;

		private static readonly Dictionary<string, Vector3> ManagedPins = new Dictionary<string, Vector3>();

		private ConfigEntry<float> _refreshInterval;

		private ConfigEntry<bool> _includePrivatePortals;

		private ConfigEntry<bool> _showPortalPins;

		private ConfigEntry<bool> _showNetworkInPinName;

		private ConfigEntry<bool> _restoreXPortalPins;

		private ConfigEntry<Color> _pinColor;

		private float _nextRefresh;

		private bool _warnedAboutApi;

		private MethodInfo? _getList;

		private MethodInfo? _getPortalList;

		private PropertyInfo? _managerInstance;

		private MethodInfo? _addPin;

		private MethodInfo? _removePin;

		private FieldInfo? _pinsField;

		private FieldInfo? _pinNameField;

		private FieldInfo? _pinPositionField;

		private FieldInfo? _pinTypeField;

		private FieldInfo? _pinIconField;

		private FieldInfo? _pinIconElementField;

		private FieldInfo? _iconsField;

		private FieldInfo? _visibleIconTypesField;

		private FieldInfo? _spriteDataNameField;

		private FieldInfo? _spriteDataIconField;

		private object? _portalManager;

		private object? _customPinType;

		private Sprite? _portalIcon;

		private bool _customPinTypeInstalled;

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_refreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RefreshIntervalSeconds", 5f, "How often the local portal list is reflected onto the map.");
			_includePrivatePortals = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludePrivatePortals", false, "Also add pins for private and personal-network portals. Each player sees these locally.");
			_showPortalPins = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPortalPins", true, "Show XPortalNetworks portals on the map. Disable to remove only this mod's portal pins.");
			_showNetworkInPinName = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowNetworkInPinName", false, "Show the XPortalNetworks network name in generated map pin names.");
			_pinColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "PinColor", new Color(0.4f, 0.8f, 1f, 1f), "Color of the generated portal pin icon. Configuration Manager provides a color picker.");
			_restoreXPortalPins = ((BaseUnityPlugin)this).Config.Bind<bool>("Actions", "RestoreXPortalPins", false, "Set to true to recreate only XPortal-generated pins; vanilla player pins are not touched.");
			CacheXPortalApi();
			CacheMapApi();
			_harmony = new Harmony("buldosik.XPortalSharedMapPins");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Loaded. Portal pins are client-local and synchronized from XPortalNetworks.");
		}

		private void Update()
		{
			if (Time.unscaledTime < _nextRefresh || (Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			_nextRefresh = Time.unscaledTime + Mathf.Max(1f, _refreshInterval.Value);
			EnsureCustomPortalType();
			if (!_showPortalPins.Value)
			{
				RemoveAllManagedPins();
				ManagedPins.Clear();
				return;
			}
			if (_restoreXPortalPins.Value)
			{
				RestoreAllPins();
				_restoreXPortalPins.Value = false;
				((BaseUnityPlugin)this).Config.Save();
			}
			RefreshPins();
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if (Instance == this)
			{
				Instance = null;
			}
			RemoveAllManagedPins();
			ManagedPins.Clear();
		}

		private void CacheXPortalApi()
		{
			try
			{
				Type type = Type.GetType("XPortalNetworks.KnownPortalsManager, XPortalNetworks");
				if (type == null)
				{
					throw new InvalidOperationException("XPortalNetworks.KnownPortalsManager was not found");
				}
				_managerInstance = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
				_getList = type.GetMethod("GetList", BindingFlags.Instance | BindingFlags.Public);
				_portalManager = _managerInstance?.GetValue(null, null);
				_getPortalList = typeof(ZDOMan).GetMethod("GetPortalList", BindingFlags.Instance | BindingFlags.Public);
				if (_managerInstance == null || _getList == null || _portalManager == null)
				{
					throw new MissingMethodException("XPortalNetworks portal list API is unavailable");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not connect to XPortalNetworks: " + ex.GetBaseException().Message));
			}
		}

		private void CacheMapApi()
		{
			try
			{
				Type typeFromHandle = typeof(Minimap);
				_addPin = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo method) => method.Name == "AddPin" && IsAddPinSignature(method));
				_removePin = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo method) => method.Name == "RemovePin" && IsRemovePinSignature(method));
				Type nestedType = typeFromHandle.GetNestedType("PinData", BindingFlags.Public | BindingFlags.NonPublic);
				_pinsField = typeFromHandle.GetField("m_pins", BindingFlags.Instance | BindingFlags.NonPublic);
				_pinNameField = nestedType?.GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pinPositionField = nestedType?.GetField("m_pos", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pinTypeField = nestedType?.GetField("m_type", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pinIconField = nestedType?.GetField("m_icon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pinIconElementField = nestedType?.GetField("m_iconElement", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_iconsField = typeFromHandle.GetField("m_icons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_visibleIconTypesField = typeFromHandle.GetField("m_visibleIconTypes", BindingFlags.Instance | BindingFlags.NonPublic);
				Type nestedType2 = typeFromHandle.GetNestedType("SpriteData", BindingFlags.Public | BindingFlags.NonPublic);
				_spriteDataNameField = nestedType2?.GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_spriteDataIconField = nestedType2?.GetField("m_icon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (_addPin == null || _removePin == null || _pinsField == null || _pinNameField == null || _pinPositionField == null || _pinTypeField == null || _pinIconField == null || _iconsField == null || _visibleIconTypesField == null || _spriteDataNameField == null || _spriteDataIconField == null)
				{
					throw new MissingMethodException("Valheim Minimap pin API is unavailable");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not connect to Valheim map pin API: " + ex.GetBaseException().Message));
			}
		}

		private static bool IsAddPinSignature(MethodInfo method)
		{
			ParameterInfo[] parameters = method.GetParameters();
			if (parameters.Length >= 5 && parameters.Length <= 7 && parameters[0].ParameterType == typeof(Vector3) && parameters[1].ParameterType.IsEnum && parameters[2].ParameterType == typeof(string) && parameters[3].ParameterType == typeof(bool) && parameters[4].ParameterType == typeof(bool))
			{
				if (parameters.Length != 5 && parameters.Length != 6)
				{
					return parameters.Length == 7;
				}
				return true;
			}
			return false;
		}

		private static bool IsRemovePinSignature(MethodInfo method)
		{
			ParameterInfo[] parameters = method.GetParameters();
			Type nestedType = typeof(Minimap).GetNestedType("PinData", BindingFlags.Public | BindingFlags.NonPublic);
			if (parameters.Length == 1 && nestedType != null)
			{
				return parameters[0].ParameterType == nestedType;
			}
			return false;
		}

		private void RefreshPins()
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			if (_getList == null || _portalManager == null || _addPin == null || _removePin == null)
			{
				WarnOnce(ref _warnedAboutApi, "Portal or map APIs are unavailable; no pins will be created.");
				return;
			}
			try
			{
				Dictionary<string, Vector3> dictionary = new Dictionary<string, Vector3>();
				if (_getList.Invoke(_portalManager, null) is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						AddKnownPortalPin(dictionary, item);
					}
				}
				AddLocalPortalZdos(dictionary);
				foreach (KeyValuePair<string, Vector3> item2 in ManagedPins.ToList())
				{
					if (!dictionary.TryGetValue(item2.Key, out var value) || value != item2.Value)
					{
						RemovePin(item2.Key, item2.Value);
						ManagedPins.Remove(item2.Key);
					}
				}
				foreach (KeyValuePair<string, Vector3> item3 in dictionary)
				{
					if (!ManagedPins.ContainsKey(item3.Key))
					{
						AddPin(item3.Key, item3.Value);
						ManagedPins[item3.Key] = item3.Value;
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Refreshing portal pins failed: " + ex.GetBaseException().Message));
			}
		}

		private void AddKnownPortalPin(Dictionary<string, Vector3> wanted, object portal)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (TryReadPortal(portal, out string name, out Vector3 location, out long networkOwner, out bool isPrivate, out string networkName) && (_includePrivatePortals.Value || IsSharedPortal(networkOwner, isPrivate)))
			{
				AddWantedPin(wanted, name, location, networkName);
			}
		}

		private void AddLocalPortalZdos(Dictionary<string, Vector3> wanted)
		{
			//IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (_getPortalList == null || ZDOMan.instance == null || !(_getPortalList.Invoke(ZDOMan.instance, null) is IEnumerable enumerable))
			{
				return;
			}
			foreach (object item in enumerable)
			{
				Vector3 location = ((ZDO)item).GetPosition();
				if (!wanted.Values.Any(delegate(Vector3 existing)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val = existing - location;
					return ((Vector3)(ref val)).sqrMagnitude < 0.25f;
				}))
				{
					string name = ((ZDO)item).GetString("tag", string.Empty);
					AddWantedPin(wanted, name, location, "Global");
				}
			}
		}

		private void AddWantedPin(Dictionary<string, Vector3> wanted, string name, Vector3 location, string networkName)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			string text = (string.IsNullOrWhiteSpace(name) ? "Unnamed portal" : name.Trim());
			string text2 = ((_showNetworkInPinName.Value && !string.IsNullOrWhiteSpace(networkName)) ? ("[" + networkName + "] ") : string.Empty) + text;
			string key = text2;
			int num = 2;
			while (wanted.ContainsKey(key))
			{
				key = $"{text2} ({num++})";
			}
			wanted[key] = location;
		}

		private static bool IsSharedPortal(long networkOwner, bool isPrivate)
		{
			if (!isPrivate)
			{
				if (networkOwner != 0L)
				{
					if (networkOwner >= 1)
					{
						return networkOwner <= 15;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		private static bool TryReadPortal(object portal, out string name, out Vector3 location, out long networkOwner, out bool isPrivate, out string networkName)
		{
			//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_00c3: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			name = string.Empty;
			location = Vector3.zero;
			networkOwner = 0L;
			isPrivate = false;
			networkName = string.Empty;
			Type type = portal.GetType();
			PropertyInfo property = type.GetProperty("Name");
			PropertyInfo property2 = type.GetProperty("Location");
			PropertyInfo property3 = type.GetProperty("NetworkOwnerPlayerId");
			PropertyInfo property4 = type.GetProperty("NetworkOwnerDisplayName");
			PropertyInfo property5 = type.GetProperty("IsPrivate");
			if (property == null || property2 == null || property3 == null || property4 == null || property5 == null)
			{
				return false;
			}
			name = (property.GetValue(portal, null) as string) ?? string.Empty;
			location = (Vector3)(property2.GetValue(portal, null) ?? ((object)Vector3.zero));
			networkOwner = Convert.ToInt64(property3.GetValue(portal, null));
			isPrivate = Convert.ToBoolean(property5.GetValue(portal, null));
			networkName = (property4.GetValue(portal, null) as string) ?? string.Empty;
			if (networkOwner == 0L)
			{
				networkName = "Global";
			}
			else if (networkOwner >= 1 && networkOwner <= 15 && string.IsNullOrWhiteSpace(networkName))
			{
				networkName = $"Network {networkOwner}";
			}
			else if (string.IsNullOrWhiteSpace(networkName))
			{
				networkName = "Personal";
			}
			return true;
		}

		private void AddPin(string name, Vector3 location)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Type parameterType = _addPin.GetParameters()[1].ParameterType;
			object item = _customPinType ?? Enum.Parse(parameterType, "Icon3");
			ParameterInfo[] parameters = _addPin.GetParameters();
			List<object> list = new List<object> { location, item, name, false, false };
			if (parameters.Length >= 6)
			{
				list.Add(0L);
			}
			if (parameters.Length == 7)
			{
				list.Add(Activator.CreateInstance(parameters[6].ParameterType));
			}
			object pin = _addPin.Invoke(Minimap.instance, list.ToArray());
			ApplyPortalIcon(pin);
		}

		private void RemovePin(string name, Vector3 location)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			foreach (object item in GetMapPins().Cast<object>().ToList())
			{
				if (object.Equals(_pinNameField.GetValue(item), name) && (Vector3)_pinPositionField.GetValue(item) == location)
				{
					_removePin.Invoke(Minimap.instance, new object[1] { item });
					break;
				}
			}
		}

		private IEnumerable GetMapPins()
		{
			return (_pinsField?.GetValue(Minimap.instance) as IEnumerable) ?? Array.Empty<object>();
		}

		private void EnsureCustomPortalType()
		{
			if (_customPinTypeInstalled || (Object)(object)Minimap.instance == (Object)null || _iconsField == null || _visibleIconTypesField == null || _spriteDataNameField == null || _spriteDataIconField == null || !(_iconsField.GetValue(Minimap.instance) is IList list))
			{
				return;
			}
			foreach (object item in list)
			{
				object? value = _spriteDataIconField.GetValue(item);
				Sprite val = (Sprite)((value is Sprite) ? value : null);
				if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf("portal", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					_portalIcon = val;
					break;
				}
			}
			if (_portalIcon == null)
			{
				_portalIcon = CreateFallbackPortalIcon();
			}
			Type parameterType = _addPin.GetParameters()[1].ParameterType;
			int length = Enum.GetValues(parameterType).Length;
			_customPinType = Enum.ToObject(parameterType, length);
			object obj = Activator.CreateInstance(_spriteDataNameField.DeclaringType);
			_spriteDataNameField.SetValue(obj, _customPinType);
			_spriteDataIconField.SetValue(obj, _portalIcon);
			list.Add(obj);
			if (_visibleIconTypesField.GetValue(Minimap.instance) is bool[] array && array.Length <= length)
			{
				bool[] array2 = new bool[length + 1];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = i >= array.Length || array[i];
				}
				_visibleIconTypesField.SetValue(Minimap.instance, array2);
			}
			_customPinTypeInstalled = true;
		}

		private Sprite CreateFallbackPortalIcon()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
			{
				name = "XPortalSharedMapPins_PortalIcon",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color[] array = (Color[])(object)new Color[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(15.5f, 15.5f));
					float num2 = Mathf.Clamp01((0.9f - Mathf.Abs(num - 9.5f)) * 4f);
					array[i * 32 + j] = new Color(1f, 1f, 1f, num2);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 32f);
		}

		private void ApplyPortalIcon(object? pin)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (pin != null && !((Object)(object)_portalIcon == (Object)null))
			{
				_pinTypeField?.SetValue(pin, _customPinType);
				_pinIconField?.SetValue(pin, _portalIcon);
				object obj = _pinIconElementField?.GetValue(pin);
				SetImageSprite(obj, _portalIcon);
				(obj?.GetType().GetProperty("color"))?.SetValue(obj, _pinColor.Value, null);
			}
		}

		private static void SetImageSprite(object? image, Sprite sprite)
		{
			(image?.GetType().GetProperty("sprite"))?.SetValue(image, sprite, null);
		}

		private void RestoreAllPins()
		{
			RemoveAllManagedPins();
			ManagedPins.Clear();
		}

		private void RemoveAllManagedPins()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null || _removePin == null)
			{
				return;
			}
			foreach (KeyValuePair<string, Vector3> managedPin in ManagedPins)
			{
				try
				{
					RemovePin(managedPin.Key, managedPin.Value);
				}
				catch (Exception ex)
				{
					Log.LogDebug((object)("Could not remove managed map pin: " + ex.GetBaseException().Message));
				}
			}
		}

		private void ReapplyPortalColors()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (_pinTypeField == null || _pinIconElementField == null || _customPinType == null || (Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			foreach (object item in GetMapPins().Cast<object>())
			{
				if (object.Equals(_pinTypeField.GetValue(item), _customPinType))
				{
					object value = _pinIconElementField.GetValue(item);
					(value?.GetType().GetProperty("color"))?.SetValue(value, _pinColor.Value, null);
				}
			}
		}

		private static void WarnOnce(ref bool warned, string message)
		{
			if (!warned)
			{
				warned = true;
				Log.LogWarning((object)message);
			}
		}
	}
}