Decompiled source of EasyPortal v1.0.4

plugins/EasyPortal/EasyPortal.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("EasyPortal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4")]
[assembly: AssemblyProduct("EasyPortal")]
[assembly: AssemblyTitle("EasyPortal")]
[assembly: AssemblyVersion("1.0.4.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EasyPortal
{
	[BepInPlugin("easyportal.client.only", "EasyPortal", "1.0.4")]
	public class EasyPortalPlugin : BaseUnityPlugin
	{
		internal class ActivePortal
		{
			public TeleportWorld Portal;

			public string Tag;

			public Vector3 Pos;

			public float Distance;

			public float ExpireAt;

			internal int Id;
		}

		internal class PortalHit
		{
			public TeleportWorld Portal;

			public string Tag;

			public Vector3 Pos;

			public float Distance;

			public int Id;

			public ZDOID ZdoId;
		}

		public const string Guid = "easyportal.client.only";

		public const string PluginName = "EasyPortal";

		public const string PluginVersion = "1.0.4";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> Radius;

		internal static ConfigEntry<float> ScanInterval;

		internal static ConfigEntry<float> ActiveSeconds;

		internal static ConfigEntry<bool> RequireTag;

		internal static ConfigEntry<bool> Rehighlight;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<bool> SkipClusters;

		internal static ConfigEntry<float> ClusterRadius;

		internal static ConfigEntry<int> ClusterSkipMin;

		internal static ConfigEntry<bool> BeamEnabled;

		internal static ConfigEntry<string> BeamColorText;

		internal static ConfigEntry<float> BeamHeight;

		internal static ConfigEntry<float> BeamWidth;

		internal static ConfigEntry<bool> LightEnabled;

		internal static ConfigEntry<float> LightRange;

		internal static ConfigEntry<float> LightIntensity;

		internal static ConfigEntry<bool> MarkerEnabled;

		internal static ConfigEntry<int> MarkerMargin;

		internal static ConfigEntry<int> MarkerSize;

		internal static ConfigEntry<int> FontSize;

		internal static ConfigEntry<bool> ShowDistance;

		internal static ConfigEntry<string> LabelBackground;

		internal static ConfigEntry<string> LabelBoxColor;

		internal static ConfigEntry<bool> MapPinEnabled;

		internal static ConfigEntry<string> PinIconName;

		internal static ConfigEntry<bool> TakeOverSameName;

		internal static ConfigEntry<float> NearEpsilon;

		internal static ConfigEntry<bool> SavePin;

		internal static ConfigEntry<bool> SkipAlreadyPinned;

		internal static ConfigEntry<bool> Verbose;

		private static readonly List<ActivePortal> Actives = new List<ActivePortal>();

		private static readonly FieldInfo _nviewField = AccessTools.Field(typeof(TeleportWorld), "m_nview");

		private Harmony _harmony;

		private float _scanTimer;

		private void Awake()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0138: 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_01a4: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Expected O, but got Unknown
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Expected O, but got Unknown
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Expected O, but got Unknown
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Expected O, but got Unknown
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Expected O, but got Unknown
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Expected O, but got Unknown
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Detection", "Enabled", true, "总开关。关掉后不再探测,已有的高亮会立刻清除(地图图钉不动)。");
			Radius = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Detection", "Radius", 60f, new ConfigDescription("探测半径(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>()));
			ScanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Detection", "ScanInterval", 5f, new ConfigDescription("探测间隔(秒)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), Array.Empty<object>()));
			ActiveSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Detection", "ActiveSeconds", 10f, new ConfigDescription("每次探测到之后,高亮与屏幕箭头持续多少秒。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 120f), Array.Empty<object>()));
			RequireTag = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Detection", "RequireTag", true, "只处理「有标签(名字)」的传送门。\ntrue(默认)= 没起名字的门跳过,既不标记也不高亮。\nfalse = 没名字的门也处理,标签统一显示为 (untagged)。");
			Rehighlight = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Detection", "RehighlightOnRedetect", false, "每次重新探测到时是否把高亮时间续满。\nfalse(默认)= 每个传送门只高亮一次(10 秒),一直站在自己家门口也不会一直亮着。\ntrue = 只要还在范围内,每 5 秒就续一次,等于一直亮着。");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Detection", "ToggleKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "游戏里切换总开关的快捷键(默认未绑定)。\n写法如 F10 或 \"F9 + LeftControl\"。注意别和 OreFinder 的 F9 撞车。");
			SkipClusters = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Detection", "SkipClusters", true, "「传送门群」整体跳过:同一个地方聚着多个传送门时(例如家里那一片门),整片都不标记。\ntrue(默认)= 这类门群**不高亮、不画屏幕箭头、也不建地图图钉**,一片清静。\nfalse = 按普通规则逐个处理(家里那堆门会各自亮起来 + 各自建图钉)。\n判定「聚在一起」的距离与个数见下面两项。");
			ClusterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Detection", "ClusterRadius", 20f, new ConfigDescription("判定「聚在一起」的间距(米):**一个传送门周围这个距离内**有别的门,就算同一片。\n采用链式判定 —— 一排门只要彼此相邻,就会连成同一大片。\n默认 20 米(1.0.4 起;早期版本是 12 米)。调大 = 更容易判成门群、更不容易被标记。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()));
			ClusterSkipMin = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Detection", "ClusterSkipMin", 2, new ConfigDescription("一片里达到几个门就整体跳过。\n默认 2:探测到 2 个门聚在一起就都不标记(对应「家里那面是建在一起的」)。\n想让只有大群才跳过(小规模的两三个门照常标记)就把它调大。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), Array.Empty<object>()));
			BeamEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Highlight", "Beam", true, "高亮方式之一:从传送门向上射出一根光柱。");
			BeamColorText = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Highlight", "BeamColor", "0.95,0.62,0.10,0.75", "光柱与点光的颜色,格式 R,G,B,A(0-1 的小数,逗号分隔)。\n默认是琥珀色、半透明。");
			BeamHeight = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Highlight", "BeamHeight", 22f, new ConfigDescription("光柱高度(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 200f), Array.Empty<object>()));
			BeamWidth = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Highlight", "BeamWidth", 0.6f, new ConfigDescription("光柱宽度(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f), Array.Empty<object>()));
			LightEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Highlight", "Light", true, "高亮方式之二:在传送门处放一团脉动的点光,把它周围照亮。");
			LightRange = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Highlight", "LightRange", 12f, new ConfigDescription("点光的照亮半径(米)。调大更醒目、也更吃性能。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), Array.Empty<object>()));
			LightIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Highlight", "LightIntensity", 2f, new ConfigDescription("点光亮度。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			MarkerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Screen Marker", "Enabled", true, "在屏幕上画箭头指向传送门(箭头旁显示标签名与距离)。");
			MarkerMargin = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Screen Marker", "EdgeMargin", 60, new ConfigDescription("目标不在视野内时,箭头贴在屏幕边缘、距边多少像素。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 400), Array.Empty<object>()));
			MarkerSize = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Screen Marker", "ArrowSize", 26, new ConfigDescription("箭头大小(像素)。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 128), Array.Empty<object>()));
			FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Screen Marker", "FontSize", 16, new ConfigDescription("标签字号。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 48), Array.Empty<object>()));
			ShowDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Screen Marker", "ShowDistance", true, "标签里是否带上距离(米)。关闭则只显示标签名。");
			LabelBackground = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Screen Marker", "LabelBackground", "Outline", new ConfigDescription("标签文字的底衬样式。\n  Outline(默认)= **不画背景块**,用一圈黑色描边保证可读性 —— 与 OreFinder 完全一致\n  Box            = 半透明色块(本模组 1.0.2 及之前的样式)\n  None           = 什么都不加(纯文字)\n⚠\ufe0f 早期版本的标签看起来「整块发黑」,是因为画完底块后没有恢复 GUI.color,\n   导致随后的文字被乘黑 —— 该 bug 已修,现在三种样式都不会出现发暗。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Outline", "Box", "None" }), Array.Empty<object>()));
			LabelBoxColor = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Screen Marker", "LabelBoxColor", "0,0,0,0.55", "LabelBackground = Box 时的底块颜色,格式 R,G,B,A(0-1 小数)。\n默认半透明黑。想更清淡可试试 0,0,0,0.35。");
			MapPinEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Map Pin", "Enabled", true, "在地图上按传送门标签名自动建图钉。");
			SkipAlreadyPinned = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Map Pin", "SkipAlreadyPinned", true, "**已标记过就不再重复检测**(默认开)。\ntrue(默认)= 一个传送门被标记过之后,后续扫描直接略过它:\n              不再高亮、不再画屏幕箭头、不再重复建图钉。\nfalse        = 回到旧行为:每轮扫描都照常处理(配合 RehighlightOnRedetect\n              可以让范围内的门一直保持高亮)。\n\n识别「同一个门」用的是游戏的**网络对象 id(ZDOID)**,不是标签名 —— 所以:\n  · 同一个门:id 不变 → 只标记一次\n  · 门被拆掉重建 / 移到别处:新 id → 会被当作新门重新标记(符合「搬门要更新图标」)\n\n另外本项开启时,会自动检测**传送门是否已被拆除**:\n  若玩家在它附近、却连续两轮都探测不到 → 判定被拆 → **自动删除地图上的图钉**。\n(远处的门无法验证,所以只在玩家靠近时判定;玩家走远不会误删。)");
			PinIconName = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Map Pin", "PinIcon", "Portal", new ConfigDescription("图钉图标。可选:Fire / House / Hammer / Dot / Portal。\n默认 Portal —— 传送门用传送门图标最直观。\n(Dot 是原版 AddPin 自己的兜底图标,也是此前的默认值;两者都必然可用。)\n⚠\ufe0f 改这一项之后,**地图上已有的同名图钉会自动升级成新图标**\n   (实现上是删旧建新;受下面 TakeOverSameName 开关约束)。\n启动后日志里会打印一份「地图图钉可选图标」列表,可据此核对。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "Fire", "House", "Hammer", "Dot", "Portal" }), Array.Empty<object>()));
			TakeOverSameName = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Map Pin", "TakeOverSameName", true, "同名图钉接管:「标签名已在地图别处存在」时,把旧位置的图钉删掉、在新位置重建。\ntrue(默认)= 移动了同标签的传送门后,不用再去地图上手动删旧图标。\nfalse = 只补建、不删除,旧图标会留在原地。\n注意:开启时也会接管你手工放的同名图钉。\n另外本模组为「同标签多个传送门同时被探测到」的情况做了保护(见 README)——\n那种情况只各自补建,不会互相删。");
			NearEpsilon = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Map Pin", "NearEpsilon", 3f, new ConfigDescription("判断「这个位置已经有图钉了」的距离阈值(米)。\n落在该半径内即视为已标记、不再重复建。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 50f), Array.Empty<object>()));
			SavePin = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Map Pin", "Save", true, "图钉是否随地图存档保存(与原版手工放的图钉一致)。\n关掉的话,重进游戏这些图钉就没了。");
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Debug", "Verbose", false, "排查用:每次扫描/建图钉都打日志。");
			Log.LogInfo((object)"EasyPortal 1.0.4 开始挂载 Harmony 补丁……");
			ApplyPatches();
			VerifyPatches();
			LogEffectiveSettings();
		}

		private void LogEffectiveSettings()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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)
			try
			{
				PinType val = PortalMapPins.ResolvePinType(PinIconName.Value);
				Log.LogInfo((object)string.Format("配置生效值:探测 {0} 米 / 每 {1:0.#} 秒 / 高亮 {2:0.#} 秒;地图图钉={3}(PinIcon=\"{4}\" → {5});物理聚簇跳过={6}(半径 {7:0.#} 米,≥{8} 个);已标记不重复={9};标签样式={10}", Radius.Value, ScanInterval.Value, ActiveSeconds.Value, MapPinEnabled.Value ? "开" : "关", PinIconName.Value, val, SkipClusters.Value ? "开" : "关", ClusterRadius.Value, ClusterSkipMin.Value, SkipAlreadyPinned.Value ? "开" : "关", LabelBackground.Value));
				if (SkipAlreadyPinned.Value && _nviewField == null)
				{
					Log.LogError((object)"  !! 反射不到 TeleportWorld.m_nview —— 「已标记不重复」与「传送门被拆自动删图钉」都不会生效");
				}
				if (SkipAlreadyPinned.Value && LabelBackground.Value == "Box" && LabelBoxColor.Value.Length == 0)
				{
					Log.LogWarning((object)"  !! LabelBoxColor 为空,底块会用默认色");
				}
			}
			catch (Exception ex)
			{
				Log.LogDebug((object)("打印生效配置失败:" + ex.Message));
			}
		}

		private void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("easyportal.client.only");
			Type[] array = new Type[1] { typeof(TeleportWorldAwakePatch) };
			int num = 0;
			foreach (Type type in array)
			{
				try
				{
					_harmony.CreateClassProcessor(type).Patch();
					Log.LogInfo((object)("  已挂载补丁类:" + type.Name));
					num++;
				}
				catch (Exception ex)
				{
					Log.LogError((object)("  挂载失败 " + type.Name + ":" + ex.Message));
				}
			}
			Log.LogInfo((object)$"Harmony 补丁挂载完成:{num}/{array.Length} 成功。");
		}

		private void VerifyPatches()
		{
			List<MethodBase> list = new List<MethodBase>();
			MethodBase methodBase = AccessTools.Method(typeof(TeleportWorld), "Awake", (Type[])null, (Type[])null);
			if (methodBase == null)
			{
				Log.LogError((object)"  !! 找不到 TeleportWorld.Awake,传送门探测不会生效(游戏版本可能变了)");
			}
			else
			{
				list.Add(methodBase);
			}
			Log.LogInfo((object)"---- 补丁挂载自检 ----");
			for (int i = 0; i < list.Count; i++)
			{
				MethodBase methodBase2 = list[i];
				Patches patchInfo = Harmony.GetPatchInfo(methodBase2);
				int num = ((patchInfo != null && patchInfo.Prefixes != null) ? patchInfo.Prefixes.Count : 0);
				int num2 = ((patchInfo != null && patchInfo.Postfixes != null) ? patchInfo.Postfixes.Count : 0);
				string text = ((num + num2 > 0) ? "OK" : "!! 未挂上 !!");
				Log.LogInfo((object)$"  {methodBase2.DeclaringType.Name}.{methodBase2.Name}()  prefix={num} postfix={num2}  {text}");
			}
			Log.LogInfo((object)"-----------------------");
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			KeyboardShortcut value = ToggleKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ((KeyboardShortcut)(ref value)).IsDown())
			{
				Enabled.Value = !Enabled.Value;
				Log.LogInfo((object)("传送门探测已" + (Enabled.Value ? "开启" : "关闭") + "(配置已保存)"));
			}
			if (!Enabled.Value)
			{
				if (Actives.Count > 0)
				{
					ClearActives();
				}
				return;
			}
			float deltaTime = Time.deltaTime;
			_scanTimer += deltaTime;
			if (_scanTimer >= ScanInterval.Value)
			{
				_scanTimer = 0f;
				try
				{
					Scan();
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("扫描出错(本轮跳过):" + ex.Message));
				}
			}
			TickActives(Time.time);
		}

		private static string SafeTag(TeleportWorld portal)
		{
			try
			{
				string text = portal.GetText();
				return string.IsNullOrEmpty(text) ? string.Empty : text.Trim();
			}
			catch
			{
				return string.Empty;
			}
		}

		private static ZDOID ZdoIdOf(TeleportWorld portal)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			try
			{
				if (_nviewField == null)
				{
					return ZDOID.None;
				}
				object? value = _nviewField.GetValue(portal);
				ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					return ZDOID.None;
				}
				return val.GetZDO()?.m_uid ?? ZDOID.None;
			}
			catch
			{
				return ZDOID.None;
			}
		}

		private static ActivePortal FindActive(int id)
		{
			for (int i = 0; i < Actives.Count; i++)
			{
				if (Actives[i].Id == id)
				{
					return Actives[i];
				}
			}
			return null;
		}

		private void Scan()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float value = Radius.Value;
			float num = value * value;
			float value2 = NearEpsilon.Value;
			float num2 = value2 * value2;
			PortalRegistry.Prune();
			List<TeleportWorld> list = PortalRegistry.Snapshot();
			if (list.Count == 0)
			{
				PortalRegistry.TryFallbackScan();
				list = PortalRegistry.Snapshot();
			}
			Dictionary<string, List<Vector3>> dictionary = new Dictionary<string, List<Vector3>>();
			int num3 = 0;
			List<PortalHit> list2 = new List<PortalHit>();
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			Vector3 val2;
			for (int i = 0; i < list.Count; i++)
			{
				TeleportWorld val = list[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Vector3 position2;
				try
				{
					position2 = ((Component)val).transform.position;
				}
				catch
				{
					continue;
				}
				val2 = position2 - position;
				if (((Vector3)(ref val2)).sqrMagnitude > num)
				{
					continue;
				}
				num3++;
				ZDOID val3 = ZdoIdOf(val);
				if (!((ZDOID)(ref val3)).IsNone())
				{
					hashSet.Add(val3);
				}
				string text = SafeTag(val);
				if (string.IsNullOrEmpty(text))
				{
					if (RequireTag.Value)
					{
						continue;
					}
					text = "(untagged)";
				}
				list2.Add(new PortalHit
				{
					Portal = val,
					Tag = text,
					Pos = position2,
					Distance = Vector3.Distance(position, position2),
					Id = ((Object)val).GetInstanceID(),
					ZdoId = val3
				});
			}
			int num4 = 0;
			if (SkipAlreadyPinned.Value)
			{
				List<KeyValuePair<ZDOID, PortalTracker.Entry>> list3 = PortalTracker.FindVanished(position, value, hashSet);
				for (int j = 0; j < list3.Count; j++)
				{
					ZDOID key = list3[j].Key;
					PortalTracker.Entry value3 = list3[j].Value;
					if (MapPinEnabled.Value)
					{
						Minimap instance = Minimap.instance;
						if ((Object)(object)instance != (Object)null)
						{
							PortalMapPins.RemovePinsAt(instance, value3.Tag, value3.Pos, NearEpsilon.Value);
						}
					}
					PortalTracker.Forget(key);
					num4++;
					Log.LogInfo((object)$"传送门「{value3.Tag}」@ {value3.Pos.x:0},{value3.Pos.z:0} 已不存在(连续 {PortalTracker.ConfirmScans} 轮未探测到)→ 已删除地图标记");
				}
			}
			int num5 = 0;
			if (SkipAlreadyPinned.Value)
			{
				for (int num6 = list2.Count - 1; num6 >= 0; num6--)
				{
					if (PortalTracker.IsTracked(list2[num6].ZdoId))
					{
						list2.RemoveAt(num6);
						num5++;
					}
				}
			}
			bool[] array = ComputeClusterSkips(list2);
			int num7 = 0;
			for (int k = 0; k < list2.Count; k++)
			{
				PortalHit portalHit = list2[k];
				if (array[k])
				{
					num7++;
					ActivePortal activePortal = FindActive(portalHit.Id);
					if (activePortal != null)
					{
						PortalHighlight.Destroy(portalHit.Id);
						Actives.Remove(activePortal);
					}
					if (MapPinEnabled.Value && TakeOverSameName.Value)
					{
						Minimap instance2 = Minimap.instance;
						if ((Object)(object)instance2 != (Object)null)
						{
							PortalMapPins.RemovePinsAt(instance2, portalHit.Tag, portalHit.Pos, NearEpsilon.Value);
						}
					}
					if (Verbose.Value)
					{
						Log.LogInfo((object)$"「{portalHit.Tag}」@ {portalHit.Pos.x:0},{portalHit.Pos.z:0} 处有多个传送门聚在一起 → 整片跳过(不标记)");
					}
					continue;
				}
				ActivePortal activePortal2 = FindActive(portalHit.Id);
				if (activePortal2 == null)
				{
					activePortal2 = new ActivePortal
					{
						Portal = portalHit.Portal,
						Tag = portalHit.Tag,
						Pos = portalHit.Pos,
						Distance = portalHit.Distance,
						ExpireAt = Time.time + ActiveSeconds.Value,
						Id = portalHit.Id
					};
					Actives.Add(activePortal2);
					PortalHighlight.Ensure(portalHit.Id, portalHit.Pos, ParseColor(BeamColorText.Value));
					if (SkipAlreadyPinned.Value)
					{
						PortalTracker.Remember(portalHit.ZdoId, portalHit.Tag, portalHit.Pos);
					}
					if (Verbose.Value)
					{
						Log.LogInfo((object)$"探测到传送门「{portalHit.Tag}」@ {portalHit.Pos.x:0},{portalHit.Pos.z:0}({portalHit.Distance:0.#} 米)");
					}
				}
				else
				{
					activePortal2.Tag = portalHit.Tag;
					if (Rehighlight.Value)
					{
						activePortal2.ExpireAt = Time.time + ActiveSeconds.Value;
					}
				}
				if (!dictionary.TryGetValue(portalHit.Tag, out var value4))
				{
					value4 = new List<Vector3>();
					dictionary[portalHit.Tag] = value4;
				}
				bool flag = false;
				for (int l = 0; l < value4.Count; l++)
				{
					val2 = value4[l] - portalHit.Pos;
					if (((Vector3)(ref val2)).sqrMagnitude <= num2)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					value4.Add(portalHit.Pos);
				}
			}
			if (Verbose.Value)
			{
				Log.LogInfo((object)$"扫描完成:登记 {list.Count} 个传送门,范围内 {num3} 个,参与标记 {list2.Count} 个(已标记过略过 {num5} 个),其中因「传送门群」跳过 {num7} 个,判拆并清理 {num4} 个,命中标签 {dictionary.Count} 种;追踪表共 {PortalTracker.Count} 条。");
			}
			if (MapPinEnabled.Value && dictionary.Count > 0)
			{
				Minimap instance3 = Minimap.instance;
				if ((Object)(object)instance3 != (Object)null)
				{
					List<KeyValuePair<string, List<Vector3>>> groups = new List<KeyValuePair<string, List<Vector3>>>(dictionary);
					PortalMapPins.Sync(instance3, groups);
				}
			}
		}

		private static bool[] ComputeClusterSkips(List<PortalHit> hits)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			int count = hits.Count;
			bool[] array = new bool[count];
			if (!SkipClusters.Value || count < 2)
			{
				return array;
			}
			int value = ClusterSkipMin.Value;
			float value2 = ClusterRadius.Value;
			if (value < 2 || count < value || value2 <= 0f)
			{
				return array;
			}
			int[] array2 = new int[count];
			for (int i = 0; i < count; i++)
			{
				array2[i] = i;
			}
			float num = value2 * value2;
			for (int j = 0; j < count; j++)
			{
				for (int k = j + 1; k < count; k++)
				{
					Vector3 val = hits[j].Pos - hits[k].Pos;
					if (((Vector3)(ref val)).sqrMagnitude <= num)
					{
						int num2 = FindRoot(array2, j);
						int num3 = FindRoot(array2, k);
						if (num2 != num3)
						{
							array2[num3] = num2;
						}
					}
				}
			}
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			for (int l = 0; l < count; l++)
			{
				int key = FindRoot(array2, l);
				dictionary[key] = ((!dictionary.TryGetValue(key, out var value3)) ? 1 : (value3 + 1));
			}
			for (int m = 0; m < count; m++)
			{
				if (dictionary[FindRoot(array2, m)] >= value)
				{
					array[m] = true;
				}
			}
			return array;
		}

		private static int FindRoot(int[] parent, int i)
		{
			while (parent[i] != i)
			{
				parent[i] = parent[parent[i]];
				i = parent[i];
			}
			return i;
		}

		private void TickActives(float now)
		{
			//IL_005a: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Actives.Count - 1; num >= 0; num--)
			{
				ActivePortal activePortal = Actives[num];
				if ((Object)(object)activePortal.Portal == (Object)null || now > activePortal.ExpireAt)
				{
					PortalHighlight.Destroy(activePortal.Id);
					Actives.RemoveAt(num);
					continue;
				}
				try
				{
					activePortal.Pos = ((Component)activePortal.Portal).transform.position;
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer != (Object)null)
					{
						activePortal.Distance = Vector3.Distance(((Component)localPlayer).transform.position, activePortal.Pos);
					}
				}
				catch
				{
					PortalHighlight.Destroy(activePortal.Id);
					Actives.RemoveAt(num);
					continue;
				}
				PortalHighlight.Pulse(activePortal.Id, activePortal.Pos, now);
			}
		}

		private static void ClearActives()
		{
			for (int i = 0; i < Actives.Count; i++)
			{
				PortalHighlight.Destroy(Actives[i].Id);
			}
			Actives.Clear();
		}

		internal static Color ParseColor(string text)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			((Color)(ref result))..ctor(0.95f, 0.62f, 0.1f, 0.75f);
			if (string.IsNullOrEmpty(text))
			{
				return result;
			}
			try
			{
				string[] array = text.Split(new char[1] { ',' });
				if (array.Length < 3)
				{
					return result;
				}
				float num = float.Parse(array[0].Trim(), CultureInfo.InvariantCulture);
				float num2 = float.Parse(array[1].Trim(), CultureInfo.InvariantCulture);
				float num3 = float.Parse(array[2].Trim(), CultureInfo.InvariantCulture);
				float num4 = ((array.Length > 3) ? float.Parse(array[3].Trim(), CultureInfo.InvariantCulture) : 1f);
				return new Color(Mathf.Clamp01(num), Mathf.Clamp01(num2), Mathf.Clamp01(num3), Mathf.Clamp01(num4));
			}
			catch
			{
				return result;
			}
		}

		private void OnGUI()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0063: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled.Value || !MarkerEnabled.Value || Actives.Count == 0 || (Object)(object)Player.m_localPlayer == (Object)null || Event.current == null || (int)Event.current.type != 7)
			{
				return;
			}
			int depth = GUI.depth;
			GUI.depth = -1000;
			Color color = ParseColor(BeamColorText.Value);
			color.a = 1f;
			try
			{
				for (int i = 0; i < Actives.Count; i++)
				{
					ScreenMarker.DrawOne(Actives[i], MarkerMargin.Value, MarkerSize.Value, FontSize.Value, ShowDistance.Value, color);
				}
			}
			catch (Exception ex)
			{
				Log.LogDebug((object)("绘制屏幕箭头出错:" + ex.Message));
			}
			finally
			{
				GUI.depth = depth;
			}
		}

		private void OnDestroy()
		{
			ClearActives();
			PortalHighlight.DestroyAll();
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}
	}
	internal static class PortalHighlight
	{
		private class Fx
		{
			public GameObject Root;

			public LineRenderer Beam;

			public Material BeamMat;

			public Light Lamp;

			public Color Color;
		}

		private const string BeamName = "EasyPortal_Beam";

		private const string LightName = "EasyPortal_Light";

		private static bool _shaderWarned;

		private static readonly Dictionary<int, Fx> Cache = new Dictionary<int, Fx>();

		private static Shader FindBeamShader()
		{
			string[] array = new string[4] { "Sprites/Default", "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Color" };
			for (int i = 0; i < array.Length; i++)
			{
				try
				{
					Shader val = Shader.Find(array[i]);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static void SetMaterialColor(Material m, Color c)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m == (Object)null))
			{
				if (m.HasProperty("_Color"))
				{
					m.SetColor("_Color", c);
				}
				else if (m.HasProperty("_TintColor"))
				{
					m.SetColor("_TintColor", c);
				}
				m.renderQueue = 3000;
			}
		}

		internal static void Ensure(int portalId, Vector3 pos, Color color)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue(portalId, out var value) && value != null && (Object)(object)value.Root != (Object)null)
			{
				return;
			}
			Destroy(portalId);
			value = new Fx
			{
				Color = color
			};
			try
			{
				if (EasyPortalPlugin.BeamEnabled.Value)
				{
					Shader val = FindBeamShader();
					if ((Object)(object)val == (Object)null)
					{
						if (!_shaderWarned)
						{
							_shaderWarned = true;
							EasyPortalPlugin.Log.LogWarning((object)"找不到可用的光柱 shader,光柱已跳过(点光与屏幕箭头不受影响)。");
						}
					}
					else
					{
						GameObject val2 = new GameObject("EasyPortal_Beam");
						val2.transform.position = pos;
						LineRenderer val3 = val2.AddComponent<LineRenderer>();
						val3.useWorldSpace = true;
						val3.positionCount = 2;
						val3.SetPosition(0, pos);
						val3.SetPosition(1, pos + Vector3.up * EasyPortalPlugin.BeamHeight.Value);
						val3.startWidth = EasyPortalPlugin.BeamWidth.Value;
						val3.endWidth = EasyPortalPlugin.BeamWidth.Value * 0.35f;
						val3.alignment = (LineAlignment)0;
						val3.textureMode = (LineTextureMode)0;
						val3.startColor = color;
						val3.endColor = new Color(color.r, color.g, color.b, 0f);
						Material val4 = new Material(val);
						SetMaterialColor(val4, color);
						((Renderer)val3).material = val4;
						value.Root = val2;
						value.Beam = val3;
						value.BeamMat = val4;
					}
				}
				if (EasyPortalPlugin.LightEnabled.Value)
				{
					GameObject val5 = new GameObject("EasyPortal_Light");
					val5.transform.position = pos + Vector3.up * 1.5f;
					Light val6 = val5.AddComponent<Light>();
					val6.type = (LightType)2;
					val6.color = color;
					val6.range = EasyPortalPlugin.LightRange.Value;
					val6.intensity = EasyPortalPlugin.LightIntensity.Value;
					val6.shadows = (LightShadows)0;
					if ((Object)(object)value.Root == (Object)null)
					{
						value.Root = val5;
					}
					else
					{
						val5.transform.SetParent(value.Root.transform, true);
					}
					value.Lamp = val6;
				}
			}
			catch (Exception ex)
			{
				EasyPortalPlugin.Log.LogWarning((object)("创建高亮特效失败(功能其余部分不受影响):" + ex.Message));
			}
			if ((Object)(object)value.Root != (Object)null)
			{
				Cache[portalId] = value;
			}
		}

		internal static void Pulse(int portalId, Vector3 pos, float time)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (!Cache.TryGetValue(portalId, out var value) || value == null)
			{
				return;
			}
			float num = 0.65f + 0.35f * Mathf.Sin(time * 3.2f);
			try
			{
				if ((Object)(object)value.Beam != (Object)null)
				{
					value.Beam.SetPosition(0, pos);
					value.Beam.SetPosition(1, pos + Vector3.up * EasyPortalPlugin.BeamHeight.Value);
					Color color = value.Color;
					color.a = value.Color.a * num;
					value.Beam.startColor = color;
					value.Beam.endColor = new Color(color.r, color.g, color.b, 0f);
					SetMaterialColor(value.BeamMat, color);
				}
				if ((Object)(object)value.Lamp != (Object)null)
				{
					value.Lamp.intensity = EasyPortalPlugin.LightIntensity.Value * num;
				}
			}
			catch
			{
			}
		}

		internal static void Destroy(int portalId)
		{
			if (!Cache.TryGetValue(portalId, out var value))
			{
				return;
			}
			Cache.Remove(portalId);
			try
			{
				if ((Object)(object)value.BeamMat != (Object)null)
				{
					Object.Destroy((Object)(object)value.BeamMat);
				}
				if ((Object)(object)value.Root != (Object)null)
				{
					Object.Destroy((Object)(object)value.Root);
				}
			}
			catch
			{
			}
		}

		internal static void DestroyAll()
		{
			List<int> list = new List<int>(Cache.Keys);
			for (int i = 0; i < list.Count; i++)
			{
				Destroy(list[i]);
			}
		}
	}
	internal static class PortalMapPins
	{
		private static FieldInfo _pinsField;

		private static bool _pinTypeLogged;

		private static readonly string[] _friendlyNames = new string[5] { "Fire", "House", "Hammer", "Dot", "Portal" };

		private static readonly HashSet<string> IconUpgradeTried = new HashSet<string>(StringComparer.Ordinal);

		internal static PinType ResolvePinType(string name)
		{
			return (PinType)((name ?? string.Empty).Trim().ToLowerInvariant() switch
			{
				"fire" => 0, 
				"house" => 1, 
				"hammer" => 2, 
				"dot" => 3, 
				"portal" => 6, 
				_ => 3, 
			});
		}

		private static List<PinData> GetPins(Minimap map)
		{
			if (_pinsField == null)
			{
				_pinsField = AccessTools.Field(typeof(Minimap), "m_pins");
			}
			if (_pinsField == null)
			{
				return null;
			}
			return _pinsField.GetValue(map) as List<PinData>;
		}

		private static void LogAvailableIcons(Minimap map)
		{
			if (_pinTypeLogged)
			{
				return;
			}
			_pinTypeLogged = true;
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(Minimap), "m_icons");
				IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(map) as IEnumerable));
				if (enumerable == null)
				{
					return;
				}
				List<string> list = new List<string>();
				foreach (object item in enumerable)
				{
					if (item != null)
					{
						FieldInfo field = item.GetType().GetField("m_name");
						list.Add((field == null) ? "?" : Convert.ToString(field.GetValue(item)));
					}
				}
				List<string> list2 = new List<string>();
				for (int i = 0; i < list.Count; i++)
				{
					string text = ((i < _friendlyNames.Length) ? _friendlyNames[i] : null);
					list2.Add((text != null) ? $"{text}(={list[i]})" : $"{list[i]}");
				}
				EasyPortalPlugin.Log.LogInfo((object)("地图图钉图标可选(可读名(=运行时资源名)): " + string.Join(", ", list2.ToArray())));
				EasyPortalPlugin.Log.LogInfo((object)"  提示:配置项 PinIcon 请填**可读名**(Fire / House / Hammer / Dot / Portal);它们在内部按位置对应,不是同名字符串。");
			}
			catch
			{
			}
		}

		internal static int Sync(Minimap map, List<KeyValuePair<string, List<Vector3>>> groups)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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)
			List<PinData> pins = GetPins(map);
			if (pins == null)
			{
				return 0;
			}
			LogAvailableIcons(map);
			float value = EasyPortalPlugin.NearEpsilon.Value;
			float num = value * value;
			PinType val = ResolvePinType(EasyPortalPlugin.PinIconName.Value);
			bool value2 = EasyPortalPlugin.SavePin.Value;
			int num2 = 0;
			int num3 = 0;
			for (int i = 0; i < groups.Count; i++)
			{
				string key = groups[i].Key;
				List<Vector3> value3 = groups[i].Value;
				if (string.IsNullOrEmpty(key) || value3 == null || value3.Count == 0)
				{
					continue;
				}
				List<PinData> list = new List<PinData>();
				List<PinData> list2 = new List<PinData>();
				Vector3 val3;
				for (int j = 0; j < pins.Count; j++)
				{
					PinData val2 = pins[j];
					if (val2 == null || val2.m_name != key)
					{
						continue;
					}
					bool flag = false;
					for (int k = 0; k < value3.Count; k++)
					{
						val3 = val2.m_pos - value3[k];
						if (((Vector3)(ref val3)).sqrMagnitude <= num)
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						list.Add(val2);
					}
					else
					{
						list2.Add(val2);
					}
				}
				if (EasyPortalPlugin.TakeOverSameName.Value && list.Count > 0 && IconUpgradeTried.Add(key))
				{
					for (int num4 = list.Count - 1; num4 >= 0; num4--)
					{
						PinData val4 = list[num4];
						if (val4 == null || val4.m_type != val)
						{
							try
							{
								map.RemovePin(val4);
								list.RemoveAt(num4);
								num3++;
								if (EasyPortalPlugin.Verbose.Value)
								{
									EasyPortalPlugin.Log.LogInfo((object)$"图钉图标已按配置更新(删旧建新):{key} @ {val4.m_pos.x:0},{val4.m_pos.z:0} → {val}");
								}
							}
							catch (Exception ex)
							{
								EasyPortalPlugin.Log.LogDebug((object)("更新图钉图标失败(不影响标记):" + ex.Message));
							}
						}
					}
				}
				if (value3.Count == 1)
				{
					if (EasyPortalPlugin.TakeOverSameName.Value)
					{
						for (int l = 0; l < list2.Count; l++)
						{
							try
							{
								map.RemovePin(list2[l]);
								if (EasyPortalPlugin.Verbose.Value)
								{
									EasyPortalPlugin.Log.LogInfo((object)$"已移除旧位置的同名图钉:{key} @ {list2[l].m_pos.x:0},{list2[l].m_pos.z:0}");
								}
							}
							catch (Exception ex2)
							{
								EasyPortalPlugin.Log.LogDebug((object)("移除旧图钉失败:" + ex2.Message));
							}
						}
					}
					if (list.Count <= 0)
					{
						AddOne(map, value3[0], val, key, value2);
						num2++;
					}
					continue;
				}
				for (int m = 0; m < value3.Count; m++)
				{
					Vector3 val5 = value3[m];
					bool flag2 = false;
					for (int n = 0; n < list.Count; n++)
					{
						val3 = list[n].m_pos - val5;
						if (((Vector3)(ref val3)).sqrMagnitude <= num)
						{
							flag2 = true;
							break;
						}
					}
					if (!flag2)
					{
						AddOne(map, val5, val, key, value2);
						num2++;
					}
				}
			}
			if (num3 > 0)
			{
				EasyPortalPlugin.Log.LogInfo((object)$"已把 {num3} 个图钉的图标更新为 {val}(改 PinIcon 后会自动迁移已有图钉;打开 Verbose 可看逐个明细)。");
			}
			return num2;
		}

		private static PinData AddOne(Minimap map, Vector3 pos, PinType type, string tag, bool save)
		{
			//IL_0001: 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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PinData val = map.AddPin(pos, type, tag, save, false, 0L, default(PlatformUserID));
				if (val != null && val.m_type != type)
				{
					EasyPortalPlugin.Log.LogWarning((object)string.Format("图钉「{0}」的图标类型被游戏改写了:请求 {1},实际 {2}。\n  说明 {1} 在当前版本的地图图标列表里不可用(原版会退回 Dot)。\n  请改用日志里「地图图钉可选图标」列出的其它名字,或接受 Dot。", tag, type, val.m_type));
				}
				if (EasyPortalPlugin.Verbose.Value)
				{
					EasyPortalPlugin.Log.LogInfo((object)$"地图标记:{tag} @ {pos.x:0},{pos.z:0}(图标 {type},保存 {save})");
				}
				return val;
			}
			catch (Exception ex)
			{
				EasyPortalPlugin.Log.LogWarning((object)("添加地图图钉失败(不影响高亮与箭头):" + ex.Message));
				return null;
			}
		}

		internal static int RemovePinsAt(Minimap map, string tag, Vector3 pos, float eps)
		{
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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)
			List<PinData> pins = GetPins(map);
			if (pins == null || string.IsNullOrEmpty(tag))
			{
				return 0;
			}
			float num = eps * eps;
			int num2 = 0;
			for (int num3 = pins.Count - 1; num3 >= 0; num3--)
			{
				PinData val = pins[num3];
				if (val != null && !(val.m_name != tag))
				{
					Vector3 val2 = val.m_pos - pos;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num))
					{
						try
						{
							map.RemovePin(val);
							num2++;
							if (EasyPortalPlugin.Verbose.Value)
							{
								EasyPortalPlugin.Log.LogInfo((object)$"传送门群清理:移除图钉 {tag} @ {pos.x:0},{pos.z:0}");
							}
						}
						catch (Exception ex)
						{
							EasyPortalPlugin.Log.LogDebug((object)("移除图钉失败:" + ex.Message));
						}
					}
				}
			}
			return num2;
		}
	}
	internal static class PortalRegistry
	{
		private static readonly List<TeleportWorld> All = new List<TeleportWorld>();

		private const float FALLBACK_COOLDOWN = 20f;

		private static float _lastFallbackAt = -999f;

		internal static int RawCount => All.Count;

		internal static void Register(TeleportWorld portal)
		{
			if (!((Object)(object)portal == (Object)null) && !All.Contains(portal))
			{
				All.Add(portal);
			}
		}

		internal static int Prune()
		{
			int num = 0;
			for (int num2 = All.Count - 1; num2 >= 0; num2--)
			{
				if ((Object)(object)All[num2] == (Object)null)
				{
					All.RemoveAt(num2);
					num++;
				}
			}
			return num;
		}

		internal static List<TeleportWorld> Snapshot()
		{
			return All;
		}

		internal static void TryFallbackScan()
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup - _lastFallbackAt < 20f)
			{
				return;
			}
			_lastFallbackAt = realtimeSinceStartup;
			try
			{
				ZNetScene instance = ZNetScene.instance;
				if ((Object)(object)instance == (Object)null)
				{
					_lastFallbackAt = 0f;
					return;
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetScene), "m_instances");
				if (fieldInfo == null)
				{
					EasyPortalPlugin.Log.LogWarning((object)"兜底扫描失败:找不到 ZNetScene.m_instances。若传送门探测不生效,请把日志发给作者。");
				}
				else
				{
					if (!(fieldInfo.GetValue(instance) is IDictionary dictionary))
					{
						return;
					}
					int num = 0;
					foreach (DictionaryEntry item in dictionary)
					{
						object? value = item.Value;
						ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
						if (!((Object)(object)val == (Object)null))
						{
							TeleportWorld component = ((Component)val).GetComponent<TeleportWorld>();
							if ((Object)(object)component != (Object)null && !All.Contains(component))
							{
								All.Add(component);
								num++;
							}
						}
					}
					if (num > 0)
					{
						EasyPortalPlugin.Log.LogWarning((object)$"登记册为空,但兜底扫描补登记了 {num} 个传送门 ⇒ TeleportWorld.Awake 挂载点未生效,请把日志发给作者。");
					}
					else if (EasyPortalPlugin.Verbose.Value)
					{
						EasyPortalPlugin.Log.LogInfo((object)"登记册为空且附近无传送门实例(正常:ZDO 按距离流式加载,远处的不在场景里)。");
					}
				}
			}
			catch (Exception ex)
			{
				EasyPortalPlugin.Log.LogWarning((object)("兜底扫描出错(不影响其它功能):" + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld), "Awake")]
	internal static class TeleportWorldAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(TeleportWorld __instance)
		{
			PortalRegistry.Register(__instance);
		}
	}
	internal static class PortalTracker
	{
		internal class Entry
		{
			internal string Tag;

			internal Vector3 Pos;

			internal int MissingScans;
		}

		private const int ConfirmMissingScans = 2;

		private static readonly Dictionary<ZDOID, Entry> Tracked = new Dictionary<ZDOID, Entry>();

		internal static int Count => Tracked.Count;

		internal static int ConfirmScans => 2;

		internal static bool IsTracked(ZDOID id)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (((ZDOID)(ref id)).IsNone())
			{
				return false;
			}
			return Tracked.ContainsKey(id);
		}

		internal static void Remember(ZDOID id, string tag, Vector3 pos)
		{
			//IL_000f: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((ZDOID)(ref id)).IsNone())
			{
				Tracked[id] = new Entry
				{
					Tag = tag,
					Pos = pos,
					MissingScans = 0
				};
			}
		}

		internal static void Forget(ZDOID id)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!((ZDOID)(ref id)).IsNone())
			{
				Tracked.Remove(id);
			}
		}

		internal static void Clear()
		{
			Tracked.Clear();
		}

		internal static List<KeyValuePair<ZDOID, Entry>> FindVanished(Vector3 playerPos, float radius, HashSet<ZDOID> presentIds)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<ZDOID, Entry>> list = new List<KeyValuePair<ZDOID, Entry>>();
			float num = radius * radius;
			foreach (KeyValuePair<ZDOID, Entry> item in Tracked)
			{
				Entry value = item.Value;
				Vector3 val = value.Pos - playerPos;
				if (((Vector3)(ref val)).sqrMagnitude > num)
				{
					value.MissingScans = 0;
					continue;
				}
				if (presentIds != null && presentIds.Contains(item.Key))
				{
					value.MissingScans = 0;
					continue;
				}
				value.MissingScans++;
				if (value.MissingScans >= 2)
				{
					list.Add(item);
				}
			}
			return list;
		}
	}
	internal static class ScreenMarker
	{
		private static Texture2D _arrowTex;

		private static Texture2D _boxTex;

		private static Font _font;

		private static bool _fontTried;

		private static GUIStyle _style;

		internal static Font UiFont()
		{
			if (_fontTried)
			{
				return _font;
			}
			_fontTried = true;
			string[] array = new string[12]
			{
				"Microsoft YaHei UI", "Microsoft YaHei", "微软雅黑", "SimHei", "黑体", "SimSun", "宋体", "DengXian", "等线", "Noto Sans CJK SC",
				"Source Han Sans SC", "Arial Unicode MS"
			};
			try
			{
				string[] oSInstalledFontNames = Font.GetOSInstalledFontNames();
				if (oSInstalledFontNames != null && oSInstalledFontNames.Length != 0)
				{
					for (int i = 0; i < array.Length; i++)
					{
						for (int j = 0; j < oSInstalledFontNames.Length; j++)
						{
							if (string.Equals(oSInstalledFontNames[j], array[i], StringComparison.OrdinalIgnoreCase))
							{
								_font = Font.CreateDynamicFontFromOSFont(oSInstalledFontNames[j], 16);
								if ((Object)(object)_font != (Object)null)
								{
									return _font;
								}
							}
						}
					}
					_font = Font.CreateDynamicFontFromOSFont(oSInstalledFontNames[0], 16);
				}
			}
			catch (Exception ex)
			{
				EasyPortalPlugin.Log.LogDebug((object)("创建系统字体失败(中文可能显示为方块,英文正常):" + ex.Message));
			}
			return _font;
		}

		private static Texture2D ArrowTex()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_arrowTex != (Object)null)
			{
				return _arrowTex;
			}
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			Color32[] array = (Color32[])(object)new Color32[1024];
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0);
			float num = 15.5f;
			for (int i = 0; i < 32; i++)
			{
				float num2 = num * ((float)i / 31f) * 0.92f;
				int num3 = 31 - i;
				for (int j = 0; j < 32; j++)
				{
					float num4 = Mathf.Abs((float)j - num);
					bool flag = num4 <= num2 || (i <= 1 && num4 <= 1.5f);
					array[num3 * 32 + j] = (flag ? val2 : val3);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			_arrowTex = val;
			return _arrowTex;
		}

		private static Texture2D BoxTex()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_boxTex != (Object)null)
			{
				return _boxTex;
			}
			_boxTex = new Texture2D(1, 1, (TextureFormat)4, false);
			_boxTex.SetPixels32((Color32[])(object)new Color32[1]
			{
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			});
			_boxTex.Apply();
			((Texture)_boxTex).wrapMode = (TextureWrapMode)1;
			return _boxTex;
		}

		private static GUIStyle Style(int fontSize)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label);
				_style.alignment = (TextAnchor)4;
				_style.fontStyle = (FontStyle)1;
				_style.wordWrap = false;
				_style.padding = new RectOffset(0, 0, 0, 0);
			}
			_style.font = UiFont();
			_style.fontSize = fontSize;
			return _style;
		}

		private static void DrawArrow(Vector2 center, float angleDeg, float size, Color color)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = ArrowTex();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Matrix4x4 matrix = GUI.matrix;
			Color color2 = GUI.color;
			try
			{
				GUIUtility.RotateAroundPivot(angleDeg, center);
				GUI.color = color;
				GUI.DrawTexture(new Rect(center.x - size * 0.5f, center.y - size * 0.5f, size, size), (Texture)(object)val);
			}
			catch
			{
			}
			finally
			{
				GUI.matrix = matrix;
				GUI.color = color2;
			}
		}

		private static void DrawLabel(Vector2 center, string text, int fontSize, Color textColor)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			GUIStyle val = Style(fontSize);
			GUIContent val2 = new GUIContent(text);
			Vector2 val3 = default(Vector2);
			try
			{
				val3 = val.CalcSize(val2);
			}
			catch
			{
				((Vector2)(ref val3))..ctor((float)(text.Length * fontSize) * 0.6f, (float)fontSize + 4f);
			}
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(center.x - val3.x * 0.5f - 5f, center.y - val3.y * 0.5f - 3f, val3.x + 10f, val3.y + 6f);
			Color color = GUI.color;
			try
			{
				bool num = EasyPortalPlugin.LabelBackground.Value == "Outline";
				if (EasyPortalPlugin.LabelBackground.Value == "Box")
				{
					GUI.color = LabelBackColor();
					GUI.DrawTexture(val4, (Texture)(object)BoxTex());
				}
				if (num)
				{
					GUI.color = new Color(0f, 0f, 0f, 0.85f);
					val.normal.textColor = Color.white;
					for (int i = -1; i <= 1; i++)
					{
						for (int j = -1; j <= 1; j++)
						{
							if (i != 0 || j != 0)
							{
								GUI.Label(new Rect(((Rect)(ref val4)).x + (float)i, ((Rect)(ref val4)).y + (float)j, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height), text, val);
							}
						}
					}
				}
				GUI.color = textColor;
				val.normal.textColor = Color.white;
				GUI.Label(val4, text, val);
			}
			finally
			{
				GUI.color = color;
			}
		}

		private static Color LabelBackColor()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return EasyPortalPlugin.ParseColor(EasyPortalPlugin.LabelBoxColor.Value);
		}

		internal static void DrawOne(EasyPortalPlugin.ActivePortal a, int margin, int arrowSize, int fontSize, bool showDistance, Color color)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: 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_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null || a == null)
			{
				return;
			}
			string text = a.Tag;
			if (showDistance)
			{
				text = $"{a.Tag}  {a.Distance:0} m";
			}
			Vector3 val;
			try
			{
				val = main.WorldToViewportPoint(a.Pos);
			}
			catch
			{
				return;
			}
			float num = Screen.width;
			float num2 = Screen.height;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(num * 0.5f, num2 * 0.5f);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(val.x * num, (1f - val.y) * num2);
			bool num3 = val.z < 0f;
			if (num3)
			{
				((Vector2)(ref val3))..ctor(val2.x * 2f - val3.x, val2.y * 2f - val3.y);
			}
			if (!num3 && val.x >= 0f && val.x <= 1f && val.y >= 0f && val.y <= 1f)
			{
				DrawArrow(new Vector2(val3.x, val3.y - 34f), 180f, arrowSize, color);
				DrawLabel(new Vector2(val3.x, val3.y + 14f), text, fontSize, color);
				return;
			}
			float num4 = Mathf.Max(8f, (float)margin);
			Vector2 val4 = new Vector2(Mathf.Clamp(val3.x, num4, num - num4), Mathf.Clamp(val3.y, num4, num2 - num4));
			Vector2 val5 = val4 - val2;
			if (((Vector2)(ref val5)).sqrMagnitude < 0.0001f)
			{
				((Vector2)(ref val5))..ctor(0f, -1f);
			}
			DrawArrow(angleDeg: Mathf.Atan2(val5.x, 0f - val5.y) * 57.29578f, center: val4 - ((Vector2)(ref val5)).normalized * ((float)arrowSize * 0.6f), size: arrowSize, color: color);
			DrawLabel(val4, text, fontSize, color);
		}
	}
}