Decompiled source of EasyTeleport v1.3.0

plugins/EasyTeleport/EasyTeleport.dll

Decompiled 5 days ago
using System;
using System.Diagnostics;
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;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[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("EasyTeleport")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: AssemblyProduct("EasyTeleport")]
[assembly: AssemblyTitle("EasyTeleport")]
[assembly: AssemblyVersion("1.3.0.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 EasyTeleport
{
	[BepInPlugin("easyteleport.client.only", "EasyTeleport", "1.3.0")]
	public class EasyTeleportPlugin : BaseUnityPlugin
	{
		public const string Guid = "easyteleport.client.only";

		public const string PluginName = "EasyTeleport";

		public const string PluginVersion = "1.3.0";

		internal static EasyTeleportPlugin Instance;

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> BackToBedText;

		internal static ConfigEntry<string> AnywhereText;

		internal static ConfigEntry<string> ArmedText;

		internal static ConfigEntry<Color> ArmedColor;

		internal static ConfigEntry<bool> UseGameStyle;

		internal static ConfigEntry<bool> AllowDrag;

		internal static ConfigEntry<float> LeftAnchor;

		internal static ConfigEntry<float> TopAnchor;

		internal static ConfigEntry<float> ButtonWidth;

		internal static ConfigEntry<float> ButtonHeight;

		internal static ConfigEntry<float> Spacing;

		internal static ConfigEntry<int> FontSize;

		internal static ConfigEntry<string> FontName;

		internal static ConfigEntry<bool> CloseMapOnTeleport;

		internal static ConfigEntry<bool> UseDistantTeleport;

		internal static ConfigEntry<bool> ShowMessages;

		internal static ConfigEntry<bool> Verbose;

		private Harmony harmony;

		private bool warnedTick;

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			Teleporter.Init();
			ApplyPatches();
			VerifyPatches();
			Log.LogInfo((object)"EasyTeleport 1.3.0 已就绪:打开大地图后,画面左上角出现「传送回床 / 任意传送」两个按钮。");
		}

		private void OnDestroy()
		{
			MapTeleportButtons.Destroy();
			if (harmony != null)
			{
				try
				{
					harmony.UnpatchSelf();
				}
				catch
				{
				}
			}
		}

		private void Update()
		{
			try
			{
				MapTeleportButtons.Tick();
			}
			catch (Exception ex)
			{
				if (!warnedTick)
				{
					warnedTick = true;
					Log.LogError((object)("地图按钮刷新出错(已停止重复报错):" + ex));
				}
			}
		}

		private void BindConfig()
		{
			//IL_00b0: 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_013c: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "总开关。关掉后地图上的两个按钮会立刻消失,也不会执行任何传送。");
			BackToBedText = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Buttons", "BackToBedText", "传送回床", "「传送回床」按钮上的文字。");
			AnywhereText = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Buttons", "AnywhereText", "任意传送", "「任意传送」按钮在**平时**显示的文字。\n点一下它,按钮会变成 ArmedText 那个样子;这时候再点地图上任意位置就会传送过去。");
			ArmedText = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Buttons", "ArmedText", "取消 · 点地图选点", "「任意传送」按钮在**待选状态**下显示的文字。\n待选时再点一次这个按钮 = 取消。");
			ArmedColor = ((BaseUnityPlugin)this).Config.Bind<Color>("2 - Buttons", "ArmedColor", new Color(0.16f, 0.4f, 0.2f, 0.95f), "「任意传送」按钮在待选状态下的底色(默认偏绿,表示\"正在等你点地图\")。\n⚠\ufe0f 仅当 UseGameStyle = false(纯色底)时生效;\n   开启 UseGameStyle 时会改为给原版底图**叠一层绿色调**,效果一致但保留纹理。");
			UseGameStyle = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Buttons", "UseGameStyle", true, "按钮外观与游戏原生 UI 同化:\ntrue(默认)= 运行时从大地图上已有的控件里挑一个面板/按钮底图 sprite 过来用,\n   这样圆角、渐变、描边都跟原版控件一致,看起来是游戏自带的按钮;\nfalse = 退回纯色半透明深灰底(更朴素,但绝对不会出现\"底图拉伸变形\")。\n打开 Verbose 可以在日志里看到底图具体取自哪个控件。");
			AllowDrag = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Buttons", "AllowDrag", true, "允许**按住 Ctrl 左键拖拽**把按钮组整体挪到任意位置,松手时自动把新位置写进本文件。\ntrue(默认)= 可以拖;false = 锁死位置,防止手滑挪走。\n按住 Ctrl 时按钮文字会变成淡黄色,表示\"现在可以拖\"。");
			LeftAnchor = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Buttons", "LeftAnchor", 0.084f, new ConfigDescription("按钮组左上角在画面上的**横向比例位置**:0 = 屏幕最左,1 = 屏幕最右。\n默认 0.084(≈1920 宽下的第 162 像素),对齐你截图里画的那个位置。\n用比例而不是像素,是为了换分辨率时位置不会跑偏。\n⭐ 平时不用手改这一项 —— 按住 Ctrl 拖动按钮组,它会自动被写入。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			TopAnchor = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Buttons", "TopAnchor", 0.392f, new ConfigDescription("按钮组左上角在画面上的**纵向比例位置**:0 = 屏幕最上,1 = 屏幕最下。\n默认 0.392(≈1080 高下的第 423 像素),对齐你截图里画的那个位置。\n往下调 = 按钮更靠下。\n⭐ 平时不用手改这一项 —— 按住 Ctrl 拖动按钮组,它会自动被写入。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ButtonWidth = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Buttons", "ButtonWidth", 190f, new ConfigDescription("按钮宽度(像素)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(80f, 600f), Array.Empty<object>()));
			ButtonHeight = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Buttons", "ButtonHeight", 40f, new ConfigDescription("按钮高度(像素)。原版控件的行高大约就在 36~44 之间。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 120f), Array.Empty<object>()));
			Spacing = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Buttons", "Spacing", 6f, new ConfigDescription("两个按钮之间的间距(像素)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Buttons", "FontSize", 16, new ConfigDescription("按钮文字字号。原版 UI 正文大约 14~18。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(6, 72), Array.Empty<object>()));
			FontName = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Buttons", "FontName", "Microsoft YaHei UI", "按钮字体名。按顺序尝试:① 系统已装字体(精确名 → 包含匹配)→ ② 游戏内置字体 → ③ 已加载的任意字体。\n默认 Microsoft YaHei UI(微软雅黑)—— 系统字体里带中文字形,能保证按钮上的中文正常显示。\n游戏内置字体 AveriaSansLibre 只有拉丁字形,换成它按钮上的中文会变方块。");
			CloseMapOnTeleport = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Teleport", "CloseMapOnTeleport", true, "点了按钮之后自动关掉大地图(回到小地图)。\ntrue(推荐)= 和原版传送门一样,能看见黑屏淡入淡出的过程;\nfalse = 地图一直开着(传送照样生效,但你只能盯着地图)。");
			UseDistantTeleport = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Teleport", "UseDistantTeleport", true, "走「远距离传送」模式 —— 传的就是 Player.TeleportTo 的第三个参数(原版传送门传 true)。\ntrue(推荐)= 黑屏 → 等目标区域加载好 → 落到地面再亮屏。**这一条同时是落地安全的前提**:\n   只有它为 true,原版才会在目标区域加载完成后用 ZoneSystem 校正落点高度,\n   否则跨半张地图传送会出现\"人到了但地面还没来\"或埋在石头里。\n除非你很清楚自己在做什么,否则别关。");
			ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Teleport", "ShowMessages", true, "在屏幕左上角弹提示(传送成功 / 为什么被拒绝 / 进入待选)。");
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Debug", "Verbose", false, "打详细信息到 BepInEx 日志(字体来源、底图取自哪个控件、坐标换算、owner 判断等),排查问题用。");
		}

		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("easyteleport.client.only");
			Type[] array = new Type[2]
			{
				typeof(MinimapAwakePatch),
				typeof(MinimapLeftClickPatch)
			};
			foreach (Type type in array)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
					Log.LogInfo((object)("  已挂载补丁类:" + type.Name));
				}
				catch (Exception ex)
				{
					Log.LogError((object)("  补丁类 " + type.Name + " 挂载失败:" + ex));
				}
			}
		}

		private void VerifyPatches()
		{
			int num = 0;
			int num2 = 0;
			Log.LogInfo((object)"---- 补丁挂载自检 ----");
			MethodBase[] array = new MethodBase[2]
			{
				AccessTools.Method(typeof(Minimap), "Awake", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(Minimap), "OnMapLeftClick", (Type[])null, (Type[])null)
			};
			foreach (MethodBase methodBase in array)
			{
				if (methodBase == null)
				{
					Log.LogError((object)"  找不到目标方法(游戏版本可能已变更)—— 对应功能会不可用。");
					continue;
				}
				num2++;
				Patches patchInfo = Harmony.GetPatchInfo(methodBase);
				int num3 = ((patchInfo != null && patchInfo.Prefixes != null) ? patchInfo.Prefixes.Count : 0);
				int num4 = ((patchInfo != null && patchInfo.Postfixes != null) ? patchInfo.Postfixes.Count : 0);
				bool flag = num3 + num4 >= 1;
				if (flag)
				{
					num++;
				}
				Log.LogInfo((object)string.Format("  {0}.{1}()  prefix={2} postfix={3}  {4}", methodBase.DeclaringType.Name, methodBase.Name, num3, num4, flag ? "OK" : "!! 没挂上"));
			}
			Log.LogInfo((object)$"Harmony 补丁挂载完成:{num}/{num2} 成功。");
			Log.LogInfo((object)"-----------------------");
		}
	}
	internal static class MapTeleportButtons
	{
		private const string PanelName = "EasyTeleportPanel";

		private const float RefreshInterval = 0.2f;

		private static readonly Color PlainBg = new Color(0.08f, 0.08f, 0.08f, 0.82f);

		private static readonly Color PlainText = new Color(0.96f, 0.94f, 0.89f, 1f);

		private static readonly Color ArmedTint = new Color(0.55f, 0.95f, 0.55f, 1f);

		private static readonly Color DraggableTint = new Color(1f, 0.88f, 0.52f, 1f);

		private const string DefaultBuiltinFont = "AveriaSansLibre";

		private static readonly string[] CjkFallbacks = new string[8] { "Microsoft YaHei UI", "Microsoft YaHei", "微软雅黑", "SimHei", "SimSun", "DengXian", "Noto Sans CJK SC", "Source Han Sans SC" };

		private static Minimap minimap;

		private static GameObject panel;

		private static RectTransform panelRt;

		private static GameObject bedGo;

		private static Text bedLabel;

		private static Image bedBg;

		private static GameObject anywhereGo;

		private static Text anywhereLabel;

		private static Image anywhereBg;

		private static bool armed;

		private static bool dragging;

		private static float dragGrabX;

		private static float dragGrabY;

		private static float liveAnchorX;

		private static float liveAnchorY;

		private static float lastDragEndTime = -10f;

		private static float timer;

		private static bool loggedBuild;

		private static bool loggedError;

		private static Font fontCache;

		private static string fontCacheKey;

		private static int fontCacheSize;

		private static Sprite gameSprite;

		private static bool gameSpriteResolved;

		internal static bool IsArmed => armed;

		internal static void OnMinimapAwake(Minimap m)
		{
			minimap = m;
			armed = false;
			if ((Object)(object)panel != (Object)null)
			{
				Object.Destroy((Object)(object)panel);
			}
			ClearRefs();
			loggedBuild = false;
			gameSprite = null;
			gameSpriteResolved = false;
		}

		internal static void Destroy()
		{
			if ((Object)(object)panel != (Object)null)
			{
				Object.Destroy((Object)(object)panel);
			}
			ClearRefs();
			minimap = null;
			armed = false;
			fontCache = null;
			fontCacheKey = null;
			gameSprite = null;
			gameSpriteResolved = false;
		}

		private static void ClearRefs()
		{
			panel = null;
			panelRt = null;
			bedGo = null;
			bedLabel = null;
			bedBg = null;
			anywhereGo = null;
			anywhereLabel = null;
			anywhereBg = null;
			dragging = false;
		}

		internal static void Tick()
		{
			try
			{
				if (!EasyTeleportPlugin.Enabled.Value)
				{
					SetArmed(value: false);
					if ((Object)(object)panel != (Object)null && panel.activeSelf)
					{
						panel.SetActive(false);
					}
					return;
				}
				if ((Object)(object)minimap == (Object)null)
				{
					minimap = Minimap.instance;
				}
				if (armed && (Object)(object)minimap != (Object)null && (Object)(object)minimap.m_largeRoot != (Object)null && !minimap.m_largeRoot.activeSelf)
				{
					SetArmed(value: false);
				}
				if ((Object)(object)panel == (Object)null)
				{
					if ((Object)(object)minimap == (Object)null || (Object)(object)minimap.m_largeRoot == (Object)null)
					{
						return;
					}
					Build();
					if ((Object)(object)panel == (Object)null)
					{
						return;
					}
				}
				timer += Time.unscaledDeltaTime;
				if (!(timer < 0.2f))
				{
					timer = 0f;
					Refresh();
				}
			}
			catch (Exception ex)
			{
				if (!loggedError)
				{
					loggedError = true;
					EasyTeleportPlugin.Log.LogError((object)("刷新地图按钮时出错(已停止重复报错):" + ex));
				}
			}
		}

		private static void Build()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_009c: 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)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			try
			{
				Font val = ResolveFont();
				float num = Mathf.Max(80f, EasyTeleportPlugin.ButtonWidth.Value);
				float num2 = Mathf.Max(20f, EasyTeleportPlugin.ButtonHeight.Value);
				float value = EasyTeleportPlugin.Spacing.Value;
				panel = new GameObject("EasyTeleportPanel");
				panel.layer = 5;
				panel.transform.SetParent(minimap.m_largeRoot.transform, false);
				panelRt = panel.AddComponent<RectTransform>();
				ApplyAnchors(panelRt);
				panelRt.sizeDelta = new Vector2(num, num2 * 2f + value);
				Image obj = panel.AddComponent<Image>();
				((Graphic)obj).color = new Color(0f, 0f, 0f, 0f);
				((Graphic)obj).raycastTarget = true;
				EventTrigger et = panel.AddComponent<EventTrigger>();
				AddTrigger(et, (EventTriggerType)13, OnBeginDrag);
				AddTrigger(et, (EventTriggerType)5, OnDrag);
				AddTrigger(et, (EventTriggerType)14, OnEndDrag);
				bedGo = MakeButton(panel.transform, "BedButton", EasyTeleportPlugin.BackToBedText.Value, val, 0f, out bedLabel, out bedBg);
				((UnityEvent)bedGo.GetComponent<Button>().onClick).AddListener(new UnityAction(OnBedClicked));
				anywhereGo = MakeButton(panel.transform, "AnywhereButton", EasyTeleportPlugin.AnywhereText.Value, val, num2 + value, out anywhereLabel, out anywhereBg);
				((UnityEvent)anywhereGo.GetComponent<Button>().onClick).AddListener(new UnityAction(OnAnywhereClicked));
				if (!loggedBuild)
				{
					loggedBuild = true;
					EasyTeleportPlugin.Log.LogInfo((object)string.Format("地图按钮已创建:父节点 {0},锚点 ({1:0.###}, {2:0.###})(画面左上区域),尺寸 {3}×{4},字体 {5},底图 {6}。", "EasyTeleportPanel", EasyTeleportPlugin.LeftAnchor.Value, EasyTeleportPlugin.TopAnchor.Value, num, num2 * 2f + value, ((Object)(object)val == (Object)null) ? "(null)" : ((Object)val).name, ((Object)(object)ResolveGameSprite() == (Object)null) ? "纯色(未找到原版 sprite)" : "继承原版 sprite"));
				}
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogError((object)("创建地图按钮失败(游戏本身不受影响):" + ex));
				ClearRefs();
			}
		}

		private static void ApplyAnchors(RectTransform rt)
		{
			//IL_003e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			float num;
			float num2;
			if (dragging)
			{
				num = liveAnchorX;
				num2 = liveAnchorY;
			}
			else
			{
				num = Mathf.Clamp01(EasyTeleportPlugin.LeftAnchor.Value);
				num2 = 1f - Mathf.Clamp01(EasyTeleportPlugin.TopAnchor.Value);
			}
			rt.anchorMin = new Vector2(num, num2);
			rt.anchorMax = new Vector2(num, num2);
			rt.pivot = new Vector2(0f, 1f);
			rt.anchoredPosition = Vector2.zero;
		}

		private static GameObject MakeButton(Transform parent, string name, string text, Font font, float yOffset, out Text label, out Image background)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00c6: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(20f, EasyTeleportPlugin.ButtonHeight.Value);
			GameObject val = new GameObject(name);
			val.layer = 5;
			val.transform.SetParent(parent, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0f, 0f);
			obj.anchorMax = new Vector2(1f, 0f);
			obj.pivot = new Vector2(0.5f, 0f);
			obj.sizeDelta = new Vector2(0f, num);
			obj.anchoredPosition = new Vector2(0f, yOffset);
			background = val.AddComponent<Image>();
			ApplyButtonSkin(background);
			((Graphic)background).raycastTarget = true;
			Button obj2 = val.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)background;
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.72f, 0.72f, 0.72f, 1f);
			((ColorBlock)(ref colors)).selectedColor = Color.white;
			((ColorBlock)(ref colors)).disabledColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
			((ColorBlock)(ref colors)).fadeDuration = 0.08f;
			((Selectable)obj2).colors = colors;
			GameObject val2 = new GameObject("Label");
			val2.layer = 5;
			val2.transform.SetParent(val.transform, false);
			RectTransform obj3 = val2.AddComponent<RectTransform>();
			obj3.anchorMin = Vector2.zero;
			obj3.anchorMax = Vector2.one;
			obj3.offsetMin = new Vector2(8f, 0f);
			obj3.offsetMax = new Vector2(-8f, 0f);
			label = val2.AddComponent<Text>();
			label.font = font;
			label.fontSize = Mathf.Max(6, EasyTeleportPlugin.FontSize.Value);
			((Graphic)label).color = PlainText;
			label.alignment = (TextAnchor)4;
			label.horizontalOverflow = (HorizontalWrapMode)1;
			label.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)label).raycastTarget = false;
			label.supportRichText = false;
			label.text = text;
			Outline obj4 = val2.AddComponent<Outline>();
			((Shadow)obj4).effectColor = new Color(0f, 0f, 0f, 0.85f);
			((Shadow)obj4).effectDistance = new Vector2(1f, -1f);
			((Shadow)obj4).useGraphicAlpha = true;
			return val;
		}

		private static void ApplyButtonSkin(Image img)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)img == (Object)null))
			{
				Sprite val = (EasyTeleportPlugin.UseGameStyle.Value ? ResolveGameSprite() : null);
				if ((Object)(object)val == (Object)null)
				{
					img.sprite = null;
					img.type = (Type)0;
					((Graphic)img).color = PlainBg;
				}
				else
				{
					img.sprite = val;
					img.type = (Type)((val.border != Vector4.zero) ? 1 : 0);
					((Graphic)img).color = new Color(1f, 1f, 1f, 0.92f);
				}
			}
		}

		private static Sprite ResolveGameSprite()
		{
			//IL_0134: 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)
			if (gameSpriteResolved)
			{
				return gameSprite;
			}
			gameSpriteResolved = true;
			gameSprite = null;
			try
			{
				Transform val = (((Object)(object)minimap != (Object)null && (Object)(object)minimap.m_largeRoot != (Object)null) ? minimap.m_largeRoot.transform : null);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return null;
				}
				Image val2 = null;
				Image val3 = null;
				foreach (Image val4 in componentsInChildren)
				{
					if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4.sprite == (Object)null))
					{
						string text = ((Object)((Component)val4).gameObject).name.ToLowerInvariant();
						if (text.Contains("button") || text.Contains("panel") || text.Contains("background") || text.Contains("_bg") || text.Contains("frame"))
						{
							gameSprite = val4.sprite;
							LogSprite(val4, "名字像按钮/面板");
							return gameSprite;
						}
						if ((Object)(object)val2 == (Object)null && val4.sprite.border != Vector4.zero)
						{
							val2 = val4;
						}
						if ((Object)(object)val3 == (Object)null)
						{
							val3 = val4;
						}
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					gameSprite = val2.sprite;
					LogSprite(val2, "九宫格图");
					return gameSprite;
				}
				if ((Object)(object)val3 != (Object)null)
				{
					gameSprite = val3.sprite;
					LogSprite(val3, "任意带图控件");
					return gameSprite;
				}
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("查找原版 UI sprite 失败:" + ex.Message));
			}
			return null;
		}

		private static void LogSprite(Image im, string why)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			if (EasyTeleportPlugin.Verbose.Value)
			{
				Rect rect = im.sprite.rect;
				EasyTeleportPlugin.Log.LogInfo((object)$"按钮底图取自 {((Object)((Component)im).gameObject).name}({why}):sprite={((Object)im.sprite).name} {(int)((Rect)(ref rect)).width}×{(int)((Rect)(ref rect)).height},九宫格={im.sprite.border != Vector4.zero}");
			}
		}

		private static void Refresh()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(20f, EasyTeleportPlugin.ButtonHeight.Value);
			float num2 = Mathf.Max(80f, EasyTeleportPlugin.ButtonWidth.Value);
			float value = EasyTeleportPlugin.Spacing.Value;
			float num3 = num * 2f + value;
			if ((Object)(object)panelRt != (Object)null)
			{
				if (Mathf.Abs(panelRt.sizeDelta.x - num2) > 0.5f || Mathf.Abs(panelRt.sizeDelta.y - num3) > 0.5f)
				{
					panelRt.sizeDelta = new Vector2(num2, num3);
				}
				if (!dragging)
				{
					float num4 = Mathf.Clamp01(EasyTeleportPlugin.LeftAnchor.Value);
					float num5 = 1f - Mathf.Clamp01(EasyTeleportPlugin.TopAnchor.Value);
					if (Mathf.Abs(panelRt.anchorMin.x - num4) > 0.0005f || Mathf.Abs(panelRt.anchorMin.y - num5) > 0.0005f)
					{
						ApplyAnchors(panelRt);
					}
				}
			}
			if ((Object)(object)anywhereGo != (Object)null)
			{
				Transform transform = anywhereGo.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val != (Object)null && Mathf.Abs(val.anchoredPosition.y - (num + value)) > 0.5f)
				{
					val.anchoredPosition = new Vector2(0f, num + value);
				}
			}
			ApplyArmedVisual();
			if ((Object)(object)bedLabel != (Object)null && bedLabel.text != EasyTeleportPlugin.BackToBedText.Value)
			{
				bedLabel.text = EasyTeleportPlugin.BackToBedText.Value;
			}
			if (!armed && (Object)(object)anywhereLabel != (Object)null && anywhereLabel.text != EasyTeleportPlugin.AnywhereText.Value)
			{
				anywhereLabel.text = EasyTeleportPlugin.AnywhereText.Value;
			}
		}

		internal static void SetArmed(bool value)
		{
			if (armed != value)
			{
				armed = value;
				ApplyArmedVisual();
				if (EasyTeleportPlugin.Verbose.Value)
				{
					EasyTeleportPlugin.Log.LogInfo((object)(value ? "「任意传送」已进入待选 —— 现在点地图上任意位置即可传送过去。" : "「任意传送」待选已取消。"));
				}
			}
		}

		private static void ApplyArmedVisual()
		{
			//IL_0037: 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_0030: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			bool flag = CtrlDown() && EasyTeleportPlugin.AllowDrag.Value && !armed;
			Color color = (armed ? ArmedTint : (flag ? DraggableTint : PlainText));
			if ((Object)(object)anywhereLabel != (Object)null)
			{
				string text = (armed ? EasyTeleportPlugin.ArmedText.Value : EasyTeleportPlugin.AnywhereText.Value);
				if (anywhereLabel.text != text)
				{
					anywhereLabel.text = text;
				}
				((Graphic)anywhereLabel).color = color;
			}
			if ((Object)(object)bedLabel != (Object)null)
			{
				((Graphic)bedLabel).color = color;
			}
			if ((Object)(object)anywhereBg != (Object)null)
			{
				bool flag2 = (Object)(object)anywhereBg.sprite != (Object)null;
				if (armed)
				{
					((Graphic)anywhereBg).color = (Color)(flag2 ? new Color(0.62f, 1f, 0.62f, 0.97f) : EasyTeleportPlugin.ArmedColor.Value);
				}
				else
				{
					((Graphic)anywhereBg).color = (Color)(flag2 ? new Color(1f, 1f, 1f, 0.92f) : PlainBg);
				}
			}
		}

		private static void OnBedClicked()
		{
			if (SuppressClick())
			{
				return;
			}
			try
			{
				SetArmed(value: false);
				Teleporter.BackToBed();
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogError((object)("处理「回床」点击时出错:" + ex));
			}
		}

		private static void OnAnywhereClicked()
		{
			if (SuppressClick())
			{
				return;
			}
			try
			{
				SetArmed(!armed);
				if (armed && EasyTeleportPlugin.ShowMessages.Value)
				{
					Teleporter.Message("点地图上任意位置,就会传送到那里。");
				}
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogError((object)("处理「任意传送」点击时出错:" + ex));
			}
		}

		internal static bool HandleMapLeftClick()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!armed)
			{
				return true;
			}
			try
			{
				if (Teleporter.TeleportToScreenPoint(Teleporter.PointerScreenPos()))
				{
					SetArmed(value: false);
				}
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogError((object)("处理地图点击传送时出错:" + ex));
				SetArmed(value: false);
			}
			return false;
		}

		private static void AddTrigger(EventTrigger et, EventTriggerType type, UnityAction<BaseEventData> callback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Entry val = new Entry();
			val.eventID = type;
			((UnityEvent<BaseEventData>)(object)val.callback).AddListener(callback);
			et.triggers.Add(val);
		}

		private static bool CtrlDown()
		{
			try
			{
				return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
			}
			catch
			{
				return false;
			}
		}

		private static bool SuppressClick()
		{
			if (dragging)
			{
				return true;
			}
			return Time.unscaledTime - lastDragEndTime < 0.25f;
		}

		private static void OnBeginDrag(BaseEventData data)
		{
			//IL_0022: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			if (EasyTeleportPlugin.AllowDrag.Value && CtrlDown() && !((Object)(object)panelRt == (Object)null) && TryScreenToAnchor(PointerPos(data), out var ratioX, out var ratioY))
			{
				dragging = true;
				liveAnchorX = panelRt.anchorMin.x;
				liveAnchorY = panelRt.anchorMin.y;
				dragGrabX = ratioX - liveAnchorX;
				dragGrabY = ratioY - liveAnchorY;
				if (EasyTeleportPlugin.Verbose.Value)
				{
					EasyTeleportPlugin.Log.LogInfo((object)$"开始拖拽按钮组(当前锚点 {liveAnchorX:0.####}, {liveAnchorY:0.####})");
				}
			}
		}

		private static void OnDrag(BaseEventData data)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (dragging && !((Object)(object)panelRt == (Object)null) && TryScreenToAnchor(PointerPos(data), out var ratioX, out var ratioY))
			{
				liveAnchorX = Mathf.Clamp01(ratioX - dragGrabX);
				liveAnchorY = Mathf.Clamp01(ratioY - dragGrabY);
				ApplyAnchors(panelRt);
			}
		}

		private static void OnEndDrag(BaseEventData data)
		{
			if (dragging)
			{
				dragging = false;
				lastDragEndTime = Time.unscaledTime;
				liveAnchorX = Mathf.Clamp01(liveAnchorX);
				liveAnchorY = Mathf.Clamp01(liveAnchorY);
				EasyTeleportPlugin.LeftAnchor.Value = liveAnchorX;
				EasyTeleportPlugin.TopAnchor.Value = 1f - liveAnchorY;
				EasyTeleportPlugin.Log.LogInfo((object)$"按钮位置已保存:LeftAnchor = {EasyTeleportPlugin.LeftAnchor.Value:0.####},TopAnchor = {EasyTeleportPlugin.TopAnchor.Value:0.####}(已写入 easyteleport.client.only.cfg)");
				if (EasyTeleportPlugin.ShowMessages.Value)
				{
					Teleporter.Message("按钮位置已保存。");
				}
			}
		}

		private static Vector3 PointerPos(BaseEventData data)
		{
			//IL_0016: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = (PointerEventData)(object)((data is PointerEventData) ? data : null);
			if (val != null)
			{
				return Vector2.op_Implicit(val.position);
			}
			return Input.mousePosition;
		}

		private static bool TryScreenToAnchor(Vector3 screenPos, out float ratioX, out float ratioY)
		{
			//IL_0039: 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_007f: 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_0070: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			ratioX = (ratioY = 0f);
			if ((Object)(object)panelRt == (Object)null)
			{
				return false;
			}
			Transform parent = ((Transform)panelRt).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Rect rect = val.rect;
			if (((Rect)(ref rect)).width < 1f || ((Rect)(ref rect)).height < 1f)
			{
				return false;
			}
			Camera val2 = null;
			Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0)
			{
				val2 = componentInParent.worldCamera;
			}
			Vector2 val3 = default(Vector2);
			if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.op_Implicit(screenPos), val2, ref val3))
			{
				return false;
			}
			Vector2 val4 = val3 - ((Rect)(ref rect)).min;
			ratioX = val4.x / ((Rect)(ref rect)).width;
			ratioY = val4.y / ((Rect)(ref rect)).height;
			return true;
		}

		private static Font ResolveFont()
		{
			string value = EasyTeleportPlugin.FontName.Value;
			int num = Mathf.Max(6, EasyTeleportPlugin.FontSize.Value);
			if ((Object)(object)fontCache != (Object)null && fontCacheKey == value && fontCacheSize == num)
			{
				return fontCache;
			}
			Font val = FindOsFont(value, num);
			if ((Object)(object)val == (Object)null)
			{
				string[] cjkFallbacks = CjkFallbacks;
				for (int i = 0; i < cjkFallbacks.Length; i++)
				{
					val = FindOsFont(cjkFallbacks[i], num);
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = FindBuiltinFont(value);
			}
			if ((Object)(object)val == (Object)null)
			{
				val = FindBuiltinFont("AveriaSansLibre");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = AnyBuiltinFont();
			}
			if ((Object)(object)val == (Object)null)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("找不到字体「" + value + "」,地图按钮的文字可能不显示。可在配置里改 FontName。"));
			}
			else if (EasyTeleportPlugin.Verbose.Value)
			{
				EasyTeleportPlugin.Log.LogInfo((object)("按钮字体 = " + ((Object)val).name));
			}
			fontCache = val;
			fontCacheKey = value;
			fontCacheSize = num;
			return val;
		}

		private static Font FindBuiltinFont(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			try
			{
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				if (array == null)
				{
					return null;
				}
				foreach (Font val in array)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static Font FindOsFont(string name, int size)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			string[] oSInstalledFontNames;
			try
			{
				oSInstalledFontNames = Font.GetOSInstalledFontNames();
			}
			catch
			{
				return null;
			}
			if (oSInstalledFontNames == null || oSInstalledFontNames.Length == 0)
			{
				return null;
			}
			for (int i = 0; i < oSInstalledFontNames.Length; i++)
			{
				if (oSInstalledFontNames[i] != null && string.Equals(oSInstalledFontNames[i], name, StringComparison.OrdinalIgnoreCase))
				{
					return Font.CreateDynamicFontFromOSFont(oSInstalledFontNames[i], size);
				}
			}
			for (int j = 0; j < oSInstalledFontNames.Length; j++)
			{
				if (oSInstalledFontNames[j] != null && oSInstalledFontNames[j].IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return Font.CreateDynamicFontFromOSFont(oSInstalledFontNames[j], size);
				}
			}
			return null;
		}

		private static Font AnyBuiltinFont()
		{
			try
			{
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				if (array != null)
				{
					for (int i = 0; i < array.Length; i++)
					{
						if ((Object)(object)array[i] != (Object)null)
						{
							return array[i];
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(Minimap), "Awake")]
	internal static class MinimapAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Minimap __instance)
		{
			MapTeleportButtons.OnMinimapAwake(__instance);
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class MinimapLeftClickPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return MapTeleportButtons.HandleMapLeftClick();
		}
	}
	internal static class Teleporter
	{
		private const float MinTeleportDistance = 2f;

		private const float Epsilon = 0.01f;

		private const float FallbackWaterLevel = 30f;

		private static MethodInfo miMessage;

		private static Type messageType;

		private static MethodInfo miScreenToWorld;

		private static PropertyInfo piPointer;

		private static bool warnedScreenToWorld;

		private static bool warnedPointer;

		internal static void Init()
		{
			try
			{
				miMessage = AccessTools.Method(typeof(Character), "Message", (Type[])null, (Type[])null);
				if (miMessage != null)
				{
					messageType = miMessage.GetParameters()[0].ParameterType;
				}
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("定位 Character.Message 失败(只影响屏幕提示):" + ex.Message));
			}
			try
			{
				miScreenToWorld = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", (Type[])null, (Type[])null);
				if (miScreenToWorld == null)
				{
					EasyTeleportPlugin.Log.LogWarning((object)"找不到 Minimap.ScreenToWorldPoint —— 地图点击传送可能不可用(游戏版本可能已变更)。");
				}
			}
			catch (Exception ex2)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("定位 Minimap.ScreenToWorldPoint 失败:" + ex2.Message));
			}
			try
			{
				Type type = AccessTools.TypeByName("ZInput");
				if (type != null)
				{
					piPointer = type.GetProperty("pointerPosition", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
			}
			catch (Exception ex3)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("定位 ZInput.pointerPosition 失败:" + ex3.Message));
			}
		}

		internal static bool BackToBed()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!ReadyToTeleport(localPlayer, out var why))
			{
				Warn(why);
				return false;
			}
			PlayerProfile profile = GetProfile();
			if (profile == null)
			{
				Warn("读不到角色档案,无法传送。");
				return false;
			}
			if (!profile.HaveCustomSpawnPoint())
			{
				Warn("还没有记录过床 —— 请在床边上按 E 睡一觉,之后再回来点这个按钮。");
				EasyTeleportPlugin.Log.LogInfo((object)"传送回床被拒绝:HaveCustomSpawnPoint() = false。");
				return false;
			}
			Vector3 customSpawnPoint = profile.GetCustomSpawnPoint();
			if (!IsUsable(customSpawnPoint))
			{
				Warn("床的坐标无效(" + Fmt(customSpawnPoint) + "),已取消传送。");
				EasyTeleportPlugin.Log.LogWarning((object)("传送回床被拒绝:出生点坐标异常 " + Fmt(customSpawnPoint)));
				return false;
			}
			if (!Send(localPlayer, customSpawnPoint, "回床"))
			{
				Warn("传送被游戏拒绝 —— 通常是因为刚传送过,游戏要求间隔约 2 秒。");
				return false;
			}
			AfterTeleport("已传送回床。");
			return true;
		}

		internal static bool TeleportToScreenPoint(Vector3 screenPos)
		{
			//IL_0018: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004d: 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_0059: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!ReadyToTeleport(localPlayer, out var why))
			{
				Warn(why);
				return false;
			}
			if (!TryScreenToWorld(screenPos, out var world))
			{
				Warn("读取地图坐标失败,请重试。");
				return false;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			Vector2 val = new Vector2(world.x - position.x, world.z - position.z);
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (magnitude < 2f)
			{
				Warn("目标点离你太近了,换个地方点。");
				return false;
			}
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(world.x, SafeLandingY(), world.z);
			if (!Send(localPlayer, val2, "地图选点"))
			{
				Warn("传送被游戏拒绝 —— 通常是因为刚传送过,游戏要求间隔约 2 秒。");
				return false;
			}
			EasyTeleportPlugin.Log.LogInfo((object)$"地图点击传送:{Fmt(position)} → {Fmt(val2)}(水平距离 {magnitude:0.#} 米,Y={val2.y:0.#} 由原版落地校正)");
			AfterTeleport("已传送到地图上选中的位置。");
			return true;
		}

		private static float SafeLandingY()
		{
			try
			{
				return 30f;
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("读 ZoneSystem.c_WaterLevel 失败,用兜底值: " + ex.Message));
				return 30f;
			}
		}

		internal static Vector3 PointerScreenPos()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (piPointer != null)
				{
					if (piPointer.GetValue(null) is Vector3 result)
					{
						return result;
					}
				}
				else if (!warnedPointer)
				{
					warnedPointer = true;
					EasyTeleportPlugin.Log.LogWarning((object)"ZInput.pointerPosition 不可用,改用 Input.mousePosition。");
				}
			}
			catch (Exception ex)
			{
				if (!warnedPointer)
				{
					warnedPointer = true;
					EasyTeleportPlugin.Log.LogWarning((object)("读 ZInput.pointerPosition 出错,改用 Input.mousePosition:" + ex.Message));
				}
			}
			try
			{
				return Input.mousePosition;
			}
			catch
			{
				return Vector3.zero;
			}
		}

		private static bool TryScreenToWorld(Vector3 screenPos, out Vector3 world)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//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)
			world = Vector3.zero;
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || miScreenToWorld == null)
			{
				return false;
			}
			try
			{
				object obj = miScreenToWorld.Invoke(instance, new object[1] { screenPos });
				if (obj is Vector3)
				{
					world = (Vector3)obj;
					return true;
				}
			}
			catch (Exception ex)
			{
				if (!warnedScreenToWorld)
				{
					warnedScreenToWorld = true;
					EasyTeleportPlugin.Log.LogError((object)("ScreenToWorldPoint 调用失败:" + ex));
				}
			}
			return false;
		}

		private static bool ReadyToTeleport(Player player, out string why)
		{
			why = null;
			if ((Object)(object)player == (Object)null)
			{
				why = "找不到本地玩家(还没进入世界?)";
				return false;
			}
			if (((Character)player).IsDead())
			{
				why = "角色已死亡,无法传送。";
				return false;
			}
			if (((Character)player).IsTeleporting())
			{
				why = "正在传送中,请稍候再点。";
				return false;
			}
			return true;
		}

		private static bool Send(Player player, Vector3 pos, string what)
		{
			//IL_0022: 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_009d: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			try
			{
				ZNetView component = ((Component)player).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null)
				{
					flag = component.IsOwner();
				}
			}
			catch
			{
				flag = true;
			}
			bool flag2;
			try
			{
				flag2 = ((Character)player).TeleportTo(pos, ((Component)player).transform.rotation, EasyTeleportPlugin.UseDistantTeleport.Value);
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogError((object)("调用 TeleportTo 抛异常:" + ex));
				return false;
			}
			if (!flag && EasyTeleportPlugin.Verbose.Value)
			{
				EasyTeleportPlugin.Log.LogInfo((object)"本机不是该角色的网络对象主人,已发出 RPC_TeleportTo(返回值不作为判据)。");
			}
			int num;
			if (!flag2)
			{
				num = ((!flag) ? 1 : 0);
				if (num == 0)
				{
					goto IL_00c3;
				}
			}
			else
			{
				num = 1;
			}
			EasyTeleportPlugin.Log.LogInfo((object)$"传送受理({what})→ {Fmt(pos)},直线距离 {Vector3.Distance(((Component)player).transform.position, pos):0.#} 米");
			goto IL_00c3;
			IL_00c3:
			return (byte)num != 0;
		}

		private static void AfterTeleport(string message)
		{
			if (EasyTeleportPlugin.CloseMapOnTeleport.Value)
			{
				try
				{
					Minimap instance = Minimap.instance;
					if ((Object)(object)instance != (Object)null)
					{
						instance.SetMapMode((MapMode)1);
					}
				}
				catch (Exception ex)
				{
					EasyTeleportPlugin.Log.LogWarning((object)("关闭大地图失败(不影响传送):" + ex.Message));
				}
			}
			if (EasyTeleportPlugin.ShowMessages.Value)
			{
				Message(message);
			}
		}

		private static PlayerProfile GetProfile()
		{
			try
			{
				Game instance = Game.instance;
				return ((Object)(object)instance == (Object)null) ? null : instance.GetPlayerProfile();
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogWarning((object)("读取角色档案失败:" + ex.Message));
				return null;
			}
		}

		private static bool IsUsable(Vector3 p)
		{
			//IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if (float.IsNaN(p.x) || float.IsNaN(p.y) || float.IsNaN(p.z))
			{
				return false;
			}
			return ((Vector3)(ref p)).sqrMagnitude > 0.01f;
		}

		private static string Fmt(Vector3 v)
		{
			//IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({v.x:0.#}, {v.y:0.#}, {v.z:0.#})";
		}

		internal static void Message(string text)
		{
			try
			{
				Player localPlayer = Player.m_localPlayer;
				if (miMessage == null || messageType == null || (Object)(object)localPlayer == (Object)null)
				{
					EasyTeleportPlugin.Log.LogInfo((object)("[提示] " + text));
					return;
				}
				object obj = Enum.ToObject(messageType, 2);
				miMessage.Invoke(localPlayer, new object[5] { obj, text, 0, null, null });
			}
			catch (Exception ex)
			{
				EasyTeleportPlugin.Log.LogInfo((object)("[提示] " + text + "(屏幕提示发送失败:" + ex.Message + ")"));
			}
		}

		private static void Warn(string text)
		{
			if (EasyTeleportPlugin.ShowMessages.Value)
			{
				Message(text);
			}
			EasyTeleportPlugin.Log.LogInfo((object)("[拒绝] " + text));
		}
	}
}