Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EasyPortal v1.0.4
plugins/EasyPortal/EasyPortal.dll
Decompiled 2 months agousing 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); } } }