using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Guilds; using HarmonyLib; using Microsoft.CodeAnalysis; using ServerSync; using Splatform; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 PotalMap { public static class PlayerIdentity { public static string Normalize(object platformUserId) { return platformUserId?.ToString().Replace("Steam_", "") ?? ""; } public static string GetMyNormalizedId() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Normalize(UserInfo.GetLocalUser().UserId); } public static bool TryGetOnlinePlayerIdentity(long senderPeerId, out long playerId, out string name) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0035: 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_004a: 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_006e: Unknown result type (might be due to invalid IL or missing references) playerId = 0L; name = ""; if ((Object)(object)ZNet.instance == (Object)null) { return false; } foreach (PlayerInfo player in ZNet.instance.m_players) { ZDOID characterID = player.m_characterID; if (((ZDOID)(ref characterID)).UserID == senderPeerId) { ZDO zDO = ZDOMan.instance.GetZDO(player.m_characterID); if (zDO == null) { return false; } playerId = zDO.GetLong(ZDOVars.s_playerID, 0L); name = player.m_name; return true; } } return false; } public static bool TryGetOnlineNormalizedId(long senderPeerId, out string normalizedId) { //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_0031: 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) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) normalizedId = ""; if ((Object)(object)ZNet.instance == (Object)null) { return false; } foreach (PlayerInfo player in ZNet.instance.m_players) { ZDOID characterID = player.m_characterID; if (((ZDOID)(ref characterID)).UserID == senderPeerId) { normalizedId = Normalize(player.m_userInfo.m_id); return true; } } return false; } } public static class PortalAccessEvaluator { public static bool HasAccess(ZDO zdo) { return HasAccess(zdo, SnapshotMyGuildMemberIds()); } public static bool HasAccess(ZDO zdo, HashSet? myGuildMemberIds) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } return PortalZdoFields.GetMode(zdo) switch { PortalMode.Public => true, PortalMode.Private => PortalZdoFields.GetOwnerCharId(zdo) == Player.m_localPlayer.GetPlayerID(), PortalMode.Guild => HasGuildAccess(zdo, myGuildMemberIds), _ => false, }; } public static HashSet? SnapshotMyGuildMemberIds() { if (!API.IsLoaded()) { return null; } Guild ownGuild = API.GetOwnGuild(); if (ownGuild == null) { return null; } return new HashSet(ownGuild.Members.Keys.Select((PlayerReference m) => PlayerIdentity.Normalize(m.id))); } private static bool HasGuildAccess(ZDO zdo, HashSet? myGuildMemberIds) { return HasGuildAccessFor(zdo, PlayerIdentity.GetMyNormalizedId(), myGuildMemberIds); } private static bool HasGuildAccessFor(ZDO zdo, string normalizedId, HashSet? myGuildMemberIds) { if (myGuildMemberIds == null) { return false; } string ownerIdNormalized = PortalZdoFields.GetOwnerIdNormalized(zdo); if (!myGuildMemberIds.Contains(ownerIdNormalized)) { return false; } return myGuildMemberIds.Contains(normalizedId); } public static bool CanManage(ZDO zdo, long playerId, string normalizedId) { if (PortalZdoFields.GetOwnerCharId(zdo) != playerId) { if (PortalZdoFields.GetMode(zdo) == PortalMode.Guild) { return HasGuildAccessFor(zdo, normalizedId, SnapshotMyGuildMemberIds()); } return false; } return true; } } public static class PortalFavorites { private static ConfigEntry _stored = null; private static readonly HashSet Favorites = new HashSet(); public static void Init(ConfigFile config) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) _stored = PotalMapConfig.Bind(config, "1 - General", "Favorite portals (internal)", "", "즐겨찾기한 포탈 ID 목록 - 자동 관리됨, 직접 수정하지 마세요.", synchronized: false); foreach (string item in ZdoStringListField.SplitRaw(_stored.Value)) { if (TryParse(item, out var id)) { Favorites.Add(id); } } } public static bool IsFavorite(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Favorites.Contains(id); } public unsafe static void Toggle(ZDOID id) { //IL_0005: 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) if (!Favorites.Remove(id)) { Favorites.Add(id); } _stored.Value = ZdoStringListField.JoinRaw(Favorites.Select((ZDOID f) => ((object)(*(ZDOID*)(&f))/*cast due to .constrained prefix*/).ToString())); } private static bool TryParse(string token, out ZDOID id) { //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_0044: 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) id = ZDOID.None; int num = token.IndexOf(':'); if (num < 0) { return false; } if (!long.TryParse(token.Substring(0, num), out var result)) { return false; } if (!uint.TryParse(token.Substring(num + 1), out var result2)) { return false; } id = new ZDOID(result, result2); return true; } } public static class PortalFuel { public static ConfigEntry Enabled; public static ConfigEntry ItemPrefab; public static ConfigEntry Cost; public static void Init(ConfigFile config) { Enabled = PotalMapConfig.Bind(config, "3 - Portal Fuel", "Enable portal fuel cost", value: false, "If on, teleporting through a portal consumes an item from your inventory. Off by default."); ItemPrefab = PotalMapConfig.Bind(config, "3 - Portal Fuel", "Fuel item prefab name", "GreydwarfEye", "Prefab name (not display name) of the item consumed per teleport. Default is Greydwarf eye."); Cost = PotalMapConfig.Bind(config, "3 - Portal Fuel", "Fuel cost per use", 1, "Number of the fuel item consumed per teleport."); } public static bool TryConsume(Player player) { if (!Enabled.Value || Cost.Value <= 0) { return true; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory.CountItems(ItemPrefab.Value, -1, true) < Cost.Value) { ((Character)player).Message((MessageType)2, $"Not enough {ItemPrefab.Value} ({Cost.Value} required).", 0, (Sprite)null); return false; } inventory.RemoveItem(ItemPrefab.Value, Cost.Value, -1, true); return true; } } [HarmonyPatch] public static class PortalFullSync { [HarmonyPatch(typeof(ZDOMan), "AddPeer")] [HarmonyPostfix] private static void OnPeerConnected(ZNetPeer netPeer) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null) { return; } foreach (ZDO portal in ZDOMan.instance.GetPortals()) { if (PotalMapGeneralConfig.IsEligiblePortal(portal)) { ZDOMan.instance.ForceSendZDO(netPeer.m_uid, portal.m_uid); } } } [HarmonyPatch(typeof(ZDOMan), "AddPortal")] [HarmonyPostfix] private static void OnPortalRegistered(ZDO zdo) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZDOMan.instance != null && PotalMapGeneralConfig.IsEligiblePortal(zdo)) { ZDOMan.instance.ForceSendZDO(zdo.m_uid); } } } [HarmonyPatch] public static class PortalHoverHints { [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] [HarmonyPostfix] private static void Postfix(TeleportWorld __instance, ref string __result) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = __instance.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)Player.m_localPlayer == (Object)null || !PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { return; } ZDO zDO = nview.GetZDO(); if (PortalZdoFields.IsInitialized(zDO)) { long playerID = Player.m_localPlayer.GetPlayerID(); string myNormalizedId = PlayerIdentity.GetMyNormalizedId(); bool flag = PortalAccessEvaluator.CanManage(zDO, playerID, myNormalizedId); bool flag2 = IsKorean(); PortalMode mode = PortalZdoFields.GetMode(zDO); string text = ColorUtility.ToHtmlStringRGB(mode.GetColor()); List list = new List(); list.Add("\n[PotalMap] " + ModeLabel(mode, flag2) + ""); List list2 = list; if (flag && PotalMapGeneralConfig.AllowNonPublicPortals.Value) { list2.Add("[" + FormatShortcut(PortalModeHotkey.ModifierKey.Value) + "+E] " + (flag2 ? "모드 변경" : "Cycle mode")); } __result += string.Join("\n", list2); } } private static bool IsKorean() { if (Localization.instance != null) { return Localization.instance.GetSelectedLanguage() == "Korean"; } return false; } private static string ModeLabel(PortalMode mode, bool kr) { if (!kr) { return mode.ToString(); } return mode switch { PortalMode.Public => "공개", PortalMode.Private => "개인", PortalMode.Guild => "길드", _ => mode.ToString(), }; } private unsafe static string FormatShortcut(KeyboardShortcut shortcut) { //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) IEnumerable source = ((KeyboardShortcut)(ref shortcut)).Modifiers.Select((KeyCode k) => ((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString()); return string.Join("+", source.Append(((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString())); } } [HarmonyPatch] public static class PortalMapSession { public static bool PendingPortalTrigger; public static bool Active { get; private set; } [HarmonyPatch(typeof(Minimap), "SetMapMode")] [HarmonyPrefix] private static void MarkSession(MapMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 Active = (int)mode == 2 && PendingPortalTrigger; PendingPortalTrigger = false; } } public enum PortalMode { Public, Private, Guild } public static class PortalModeExtensions { private static readonly PortalMode[] Order = new PortalMode[3] { PortalMode.Public, PortalMode.Private, PortalMode.Guild }; public static PortalMode Next(this PortalMode mode) { int num = Array.IndexOf(Order, mode); return Order[(num + 1) % Order.Length]; } public static PortalMode SquashPortalMode(this PortalMode mode) { for (int i = 0; i < Order.Length; i++) { if (mode != PortalMode.Guild || API.IsLoaded()) { return mode; } mode = mode.Next(); } return PortalMode.Public; } public static Color GetColor(this PortalMode mode) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_003f: 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_0056: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) return (Color)(mode switch { PortalMode.Public => new Color(1f, 24f / 85f, 1f), PortalMode.Private => new Color(0.35f, 0.65f, 1f), PortalMode.Guild => new Color(1f, 0.85f, 0.15f), _ => Color.white, }); } } [HarmonyPatch] public static class PortalModeHotkey { public static ConfigEntry ModifierKey; public static void Init(ConfigFile config) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) ModifierKey = PotalMapConfig.Bind(config, "1 - General", "Modifier key for mode toggle", new KeyboardShortcut((KeyCode)304, Array.Empty()), "Modifier key held while interacting with your own portal (E) to cycle its access mode.", synchronized: false); } [HarmonyPatch(typeof(TeleportWorld), "Interact")] [HarmonyPrefix] private static bool OnInteract(TeleportWorld __instance, bool hold, ref bool __result) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (hold) { return true; } ZNetView nview = __instance.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)Player.m_localPlayer == (Object)null) { return true; } if (!PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { return true; } ZDO zDO = nview.GetZDO(); PortalZdoFields.EnsureOwnerInitialized(nview, zDO); bool flag = PortalAccessEvaluator.CanManage(zDO, Player.m_localPlayer.GetPlayerID(), PlayerIdentity.GetMyNormalizedId()); if (!IsModifierHeld()) { return true; } if (!flag) { return true; } if (!PotalMapGeneralConfig.AllowNonPublicPortals.Value) { return true; } PortalMode mode = PortalZdoFields.GetMode(zDO).Next().SquashPortalMode(); PortalModeRpc.Send(zDO.m_uid, mode); __result = true; return false; } private static bool IsModifierHeld() { //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 = ModifierKey.Value; if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return ((KeyboardShortcut)(ref value)).Modifiers.All((Func)Input.GetKey); } return false; } } public static class PortalPinAssets { private static Sprite? _icon; private static bool _loaded; public static Sprite? Icon { get { if (!_loaded) { Load(); } return _icon; } } private static void Load() { _loaded = true; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(".potal", StringComparison.OrdinalIgnoreCase)); if (text == null) { PotalMapPlugin.Log.LogWarning((object)"[PortalPinAssets] embedded 'potal' asset bundle not found."); return; } using Stream stream = executingAssembly.GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); AssetBundle val = AssetBundle.LoadFromMemory(memoryStream.ToArray()); if ((Object)(object)val == (Object)null) { PotalMapPlugin.Log.LogWarning((object)"[PortalPinAssets] AssetBundle.LoadFromMemory returned null."); return; } _icon = ExtractSprite(val); val.Unload(false); if ((Object)(object)_icon == (Object)null) { PotalMapPlugin.Log.LogWarning((object)"[PortalPinAssets] no usable sprite found in 'potal' bundle - falling back to vanilla pin icon."); } } catch (Exception ex) { PotalMapPlugin.Log.LogWarning((object)("[PortalPinAssets] failed to load 'potal' asset bundle: " + ex.Message)); } } private static Sprite? ExtractSprite(AssetBundle bundle) { Sprite[] array = bundle.LoadAllAssets(); if (array.Length != 0) { return array[0]; } Texture2D[] array2 = bundle.LoadAllAssets(); if (array2.Length != 0) { return TextureToSprite(array2[0]); } GameObject[] array3 = bundle.LoadAllAssets(); foreach (GameObject val in array3) { SpriteRenderer componentInChildren = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sprite != (Object)null) { return componentInChildren.sprite; } Image componentInChildren2 = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.sprite != (Object)null) { return componentInChildren2.sprite; } MeshRenderer componentInChildren3 = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren3 != (Object)null && (Object)(object)((Renderer)componentInChildren3).sharedMaterial != (Object)null) { Texture mainTexture = ((Renderer)componentInChildren3).sharedMaterial.mainTexture; Texture2D val2 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null); if (val2 != null) { return TextureToSprite(val2); } } } return null; } private static Sprite TextureToSprite(Texture2D tex) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f)); } } [HarmonyPatch] public static class PortalProximityVfx { public static ConfigEntry Enabled; public static void Init(ConfigFile config) { Enabled = PotalMapConfig.Bind(config, "6 - Portal Proximity VFX", "Enable VFX on proximity without paired target", value: true, "If on, a portal's glow VFX turns on when a teleportable player is nearby, even if the portal has no paired/connected target portal."); } [HarmonyPatch(typeof(TeleportWorld), "UpdatePortal")] [HarmonyPostfix] private static void ForceGlowOnProximity(TeleportWorld __instance) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (Enabled.Value && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && !((Object)(object)__instance.m_proximityRoot == (Object)null) && !((Object)(object)__instance.m_target_found == (Object)null) && PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { Player closestPlayer = Player.GetClosestPlayer(__instance.m_proximityRoot.position, __instance.m_activationRange); if ((Object)(object)closestPlayer != (Object)null && (((Humanoid)closestPlayer).IsTeleportable() || __instance.m_allowAllItems)) { __instance.m_target_found.SetActive(true); } } } } [HarmonyPatch] public static class PortalTagValidation { [HarmonyPatch(typeof(TeleportWorld), "SetText")] [HarmonyPrefix] private static bool OnSetText(TeleportWorld __instance, string text) { ZNetView nview = __instance.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)Player.m_localPlayer == (Object)null) { return true; } if (!PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { return true; } if (string.IsNullOrWhiteSpace(text) || ZDOMan.instance == null) { return true; } ZDO zdo = nview.GetZDO(); if (!ZDOMan.instance.GetPortals().Any((ZDO other) => other.m_uid != zdo.m_uid && PotalMapGeneralConfig.IsEligiblePortal(other) && string.Equals(other.GetString(ZDOVars.s_tag, ""), text, StringComparison.OrdinalIgnoreCase))) { return true; } bool flag = IsKorean(); ((Character)Player.m_localPlayer).Message((MessageType)2, flag ? ("이미 사용 중인 포탈 이름입니다: \"" + text + "\" — 다른 이름을 입력해주세요.") : ("Portal name already in use: \"" + text + "\" — please choose a different name."), 0, (Sprite)null); return false; } private static bool IsKorean() { if (Localization.instance != null) { return Localization.instance.GetSelectedLanguage() == "Korean"; } return false; } } public static class PortalTeleporter { public static bool TryTeleport(ZDOID portalId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0086: 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) ZDO zDO = ZDOMan.instance.GetZDO(portalId); Player localPlayer = Player.m_localPlayer; if (zDO == null || (Object)(object)localPlayer == (Object)null) { return false; } if (!((Humanoid)localPlayer).IsTeleportable()) { ((Character)localPlayer).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null); return false; } if (!PortalAccessEvaluator.HasAccess(zDO)) { ((Character)localPlayer).Message((MessageType)2, "이 포탈은 이용 권한이 없습니다.", 0, (Sprite)null); return false; } if (!PortalFuel.TryConsume(localPlayer)) { return false; } Vector3 position = zDO.GetPosition(); Quaternion rotation = zDO.GetRotation(); Vector3 val = position + rotation * Vector3.forward + Vector3.up; ((Character)localPlayer).TeleportTo(val, rotation, true); return true; } } [HarmonyPatch] public static class PortalTracking { [HarmonyPatch(typeof(Minimap), "Start")] private static class PeriodicPinSync { internal static bool started; [HarmonyPostfix] private static void Postfix(Minimap __instance) { if (!started) { started = true; ((MonoBehaviour)__instance).StartCoroutine(Loop()); } } private static IEnumerator Loop() { yield return null; while (true) { SyncAllPins(); yield return (object)new WaitForSeconds(2f); } } } private static readonly Dictionary Pins = new Dictionary(); private static readonly Dictionary PinToZdoId = new Dictionary(); public static IEnumerable GetVisiblePortalIds() { return Pins.Keys; } public static bool TryGetClosestPortalPin(Vector3 worldPoint, float radius, out ZDOID portalId) { //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_0048: Unknown result type (might be due to invalid IL or missing references) portalId = ZDOID.None; foreach (PinData value in Pins.Values) { value.m_save = true; } PinData closestPin = Minimap.instance.GetClosestPin(worldPoint, radius, true); foreach (PinData value2 in Pins.Values) { value2.m_save = false; } if (closestPin != null) { return PinToZdoId.TryGetValue(closestPin, out portalId); } return false; } public static void RefreshPin(ZDO zdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_006f: Unknown result type (might be due to invalid IL or missing references) if (Pins.TryGetValue(zdo.m_uid, out PinData value)) { Minimap.instance.RemovePin(value); Pins.Remove(zdo.m_uid); PinToZdoId.Remove(value); } if (PortalAccessEvaluator.HasAccess(zdo)) { PinData val = CreatePin(GetDisplayPosition(zdo), PortalZdoFields.GetDisplayName(zdo)); Pins[zdo.m_uid] = val; PinToZdoId[val] = zdo.m_uid; } } private static Vector3 GetDisplayPosition(ZDO zdo) { //IL_0014: 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_0032: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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) Vector3 basePos = zdo.GetPosition(); if (!PotalMapGeneralConfig.DeclutterPortalPins.Value || ZDOMan.instance == null) { return basePos; } float clusterRadius = PotalMapGeneralConfig.PinClusterRadius.Value; HashSet guildMemberIds = PortalAccessEvaluator.SnapshotMyGuildMemberIds(); List list = (from other in ZDOMan.instance.GetPortals() where PotalMapGeneralConfig.IsEligiblePortal(other) && PortalAccessEvaluator.HasAccess(other, guildMemberIds) where Vector3.Distance(other.GetPosition(), basePos) < clusterRadius orderby ((object)Unsafe.As(ref other.m_uid)/*cast due to .constrained prefix*/).ToString() select other).ToList(); if (list.Count <= 1) { return basePos; } float num = (float)list.FindIndex((ZDO other) => other.m_uid == zdo.m_uid) * (360f / (float)list.Count) * ((float)Math.PI / 180f); Vector3 val = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * PotalMapGeneralConfig.PinSpreadRadius.Value; return basePos + val; } private static PinData CreatePin(Vector3 pos, string name) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) PinData val = Minimap.instance.AddPin(pos, (PinType)6, name, false, false, 0L, default(PlatformUserID)); if ((Object)(object)PortalPinAssets.Icon != (Object)null) { val.m_icon = PortalPinAssets.Icon; } return val; } [HarmonyPatch(typeof(Minimap), "UpdatePins")] [HarmonyPostfix] private static void ForcePortalNameColor() { //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) //IL_0057: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair pin in Pins) { PinData value = pin.Value; PinNameData namePinData = value.m_NamePinData; if ((Object)(object)((namePinData != null) ? namePinData.PinNameText : null) == (Object)null) { continue; } ZDO zDO = ZDOMan.instance.GetZDO(pin.Key); if (zDO != null) { Color color = PortalZdoFields.GetMode(zDO).GetColor(); if (((Graphic)value.m_NamePinData.PinNameText).color != color) { ((Graphic)value.m_NamePinData.PinNameText).color = color; } } } } [HarmonyPatch(typeof(TeleportWorld), "RPC_SetTag")] [HarmonyPostfix] private static void OnPortalTagChanged(TeleportWorld __instance) { ZNetView nview = __instance.m_nview; if (!((Object)(object)nview == (Object)null) && nview.IsValid() && PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { RefreshPin(nview.GetZDO()); } } [HarmonyPatch(typeof(TeleportWorld), "Awake")] [HarmonyPostfix] private static void OnPortalAwake(TeleportWorld __instance) { ZNetView nview = __instance.m_nview; if (!((Object)(object)nview == (Object)null) && nview.IsValid() && PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance).gameObject)) { ZDO zDO = nview.GetZDO(); Piece component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.IsCreator() && !PortalZdoFields.IsInitialized(zDO) && (Object)(object)Player.m_localPlayer != (Object)null) { PortalZdoFields.SetMode(zDO, PotalMapGeneralConfig.DefaultPortalMode.Value); PortalZdoFields.SetOwner(zDO, Player.m_localPlayer.GetPlayerID(), Player.m_localPlayer.GetPlayerName(), PlayerIdentity.GetMyNormalizedId()); } RefreshPin(zDO); } } [HarmonyPatch(typeof(ZNetScene), "Destroy")] [HarmonyPrefix] private static void OnPortalDestroyed(GameObject go) { //IL_003f: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) if ((Object)(object)go == (Object)null) { return; } TeleportWorld component = go.GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.m_nview == (Object)null) { return; } ZDOID val = component.m_nview.GetZDO()?.m_uid ?? ZDOID.None; if (!(val == ZDOID.None) && Pins.TryGetValue(val, out PinData value)) { if ((Object)(object)Minimap.instance != (Object)null) { Minimap.instance.RemovePin(value); } Pins.Remove(val); PinToZdoId.Remove(value); } } [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void OnGameStart() { Pins.Clear(); PinToZdoId.Clear(); PeriodicPinSync.started = false; } private static void SyncAllPins() { //IL_0045: 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_00a8: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null || ZDOMan.instance == null) { return; } HashSet myGuildMemberIds = PortalAccessEvaluator.SnapshotMyGuildMemberIds(); HashSet hashSet = new HashSet(); foreach (ZDO portal in ZDOMan.instance.GetPortals()) { if (PotalMapGeneralConfig.IsEligiblePortal(portal)) { hashSet.Add(portal.m_uid); if (Pins.ContainsKey(portal.m_uid) != PortalAccessEvaluator.HasAccess(portal, myGuildMemberIds)) { RefreshPin(portal); } } } foreach (ZDOID item in Pins.Keys.Except(hashSet).ToList()) { if (Pins.TryGetValue(item, out PinData value)) { Minimap.instance.RemovePin(value); Pins.Remove(item); PinToZdoId.Remove(value); } } } } public static class PotalMapConfig { public static readonly ConfigSync ConfigSync = new ConfigSync("PotalMap") { DisplayName = "PotalMap", CurrentVersion = "0.1.55", MinimumRequiredVersion = "0.1.55" }; public static ConfigEntry Bind(ConfigFile config, string group, string name, T value, string description, bool synchronized = true) { ConfigEntry val = config.Bind(group, name, value, description); ((OwnConfigEntryBase)ConfigSync.AddConfigEntry(val)).SynchronizedConfig = synchronized; return val; } } public static class PotalMapGeneralConfig { public static ConfigEntry AllowNonPublicPortals = null; public static ConfigEntry LimitToVanillaPortals = null; public static ConfigEntry DefaultPortalMode = null; public static ConfigEntry DeclutterPortalPins = null; public static ConfigEntry PinClusterRadius = null; public static ConfigEntry PinSpreadRadius = null; private static readonly int PortalWoodHash = StringExtensionMethods.GetStableHashCode("portal_wood"); private static readonly int PortalStoneHash = StringExtensionMethods.GetStableHashCode("portal_stone"); public static void Init(ConfigFile config) { AllowNonPublicPortals = PotalMapConfig.Bind(config, "1 - General", "Allow non public portals", value: true, "If off, the mode-cycle hotkey does nothing and portals stay Public."); LimitToVanillaPortals = PotalMapConfig.Bind(config, "1 - General", "Limit to vanilla portals", value: false, "If on, PotalMap ignores non-vanilla portal pieces entirely (mode/pins do not apply to them)."); DefaultPortalMode = PotalMapConfig.Bind(config, "1 - General", "Default portal mode", PortalMode.Public, "Access mode newly placed portals start in."); DeclutterPortalPins = PotalMapConfig.Bind(config, "1 - General", "Declutter portal pins", value: true, "If on, portal pins that are close together on the map are spread into a small circle so their icons/names don't overlap."); PinClusterRadius = PotalMapConfig.Bind(config, "1 - General", "Pin cluster radius", 15f, "Portals within this many meters of each other are treated as one cluster for pin decluttering."); PinSpreadRadius = PotalMapConfig.Bind(config, "1 - General", "Pin spread radius", 10f, "How far apart (in meters) clustered portal pins are spread on the map."); } public static bool IsEligiblePortal(GameObject go) { bool flag = !LimitToVanillaPortals.Value; if (!flag) { string prefabName = Utils.GetPrefabName(go); bool flag2 = ((prefabName == "portal_wood" || prefabName == "portal_stone") ? true : false); flag = flag2; } return flag; } public static bool IsEligiblePortal(ZDO zdo) { if (LimitToVanillaPortals.Value && zdo.GetPrefab() != PortalWoodHash) { return zdo.GetPrefab() == PortalStoneHash; } return true; } } [BepInPlugin("com.korcaptain.potalmap", "PotalMap", "0.1.55")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PotalMapPlugin : BaseUnityPlugin { public const string ModGuid = "com.korcaptain.potalmap"; public const string ModName = "PotalMap"; public const string ModVersion = "0.1.55"; public static ManualLogSource Log; private void Awake() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ConfigEntry val = PotalMapConfig.Bind(((BaseUnityPlugin)this).Config, "1 - General", "Lock Configuration", value: true, "If on, the configuration is locked and can be changed by server admins only."); PotalMapConfig.ConfigSync.AddLockingConfigEntry(val); PotalMapGeneralConfig.Init(((BaseUnityPlugin)this).Config); PortalModeHotkey.Init(((BaseUnityPlugin)this).Config); PortalBrowserPanel.Init(((BaseUnityPlugin)this).Config); PortalFuel.Init(((BaseUnityPlugin)this).Config); PortalProximityVfx.Init(((BaseUnityPlugin)this).Config); PortalFavorites.Init(((BaseUnityPlugin)this).Config); new Harmony("com.korcaptain.potalmap").PatchAll(); Log.LogInfo((object)"PotalMap 0.1.55 loaded."); } } public static class PortalZdoFields { private const string ModeKey = "PotalMap PortalMode"; private const string OwnerCharIdKey = "PotalMap OwnerCharId"; private const string OwnerNameKey = "PotalMap OwnerName"; private const string OwnerIdNormalizedKey = "PotalMap OwnerIdNormalized"; private const string TagsKey = "PotalMap Tags"; public static bool IsInitialized(ZDO zdo) { return zdo.GetLong("PotalMap OwnerCharId", 0L) != 0; } public static PortalMode GetMode(ZDO zdo) { return (PortalMode)zdo.GetInt("PotalMap PortalMode", 0); } public static void SetMode(ZDO zdo, PortalMode mode) { zdo.Set("PotalMap PortalMode", (int)mode); } public static long GetOwnerCharId(ZDO zdo) { return zdo.GetLong("PotalMap OwnerCharId", 0L); } public static string GetOwnerName(ZDO zdo) { return zdo.GetString("PotalMap OwnerName", ""); } public static string GetOwnerIdNormalized(ZDO zdo) { return zdo.GetString("PotalMap OwnerIdNormalized", ""); } public static void SetOwner(ZDO zdo, long charId, string name, string idNormalized) { zdo.Set("PotalMap OwnerCharId", charId); zdo.Set("PotalMap OwnerName", name); zdo.Set("PotalMap OwnerIdNormalized", idNormalized); } public static void EnsureOwnerInitialized(ZNetView nview, ZDO zdo) { if (!IsInitialized(zdo) && !((Object)(object)Player.m_localPlayer == (Object)null)) { nview.ClaimOwnership(); SetOwner(zdo, Player.m_localPlayer.GetPlayerID(), Player.m_localPlayer.GetPlayerName(), PlayerIdentity.GetMyNormalizedId()); } } public static IReadOnlyList GetTags(ZDO zdo) { return ZdoStringListField.Read(zdo, "PotalMap Tags"); } public static void SetTags(ZDO zdo, IEnumerable tags) { ZdoStringListField.Write(zdo, "PotalMap Tags", tags); } public static string GetDisplayName(ZDO zdo) { string text = zdo.GetString(ZDOVars.s_tag, ""); if (!string.IsNullOrEmpty(text)) { return text; } return "Portal"; } } public static class RpcCooldownGuard { private const float StaleAfterSeconds = 120f; private const float CleanupIntervalSeconds = 60f; private static readonly Dictionary<(long sender, string key), float> LastAccepted = new Dictionary<(long, string), float>(); private static float _lastCleanup; public static bool TryConsume(long sender, string key, float cooldownSeconds) { float time = Time.time; if (time - _lastCleanup > 60f) { CleanupStaleEntries(time); _lastCleanup = time; } (long, string) key2 = (sender, key); if (LastAccepted.TryGetValue(key2, out var value) && time - value < cooldownSeconds) { return false; } LastAccepted[key2] = time; return true; } private static void CleanupStaleEntries(float now) { List<(long, string)> list = null; foreach (KeyValuePair<(long, string), float> item in LastAccepted) { if (!(now - item.Value <= 120f)) { if (list == null) { list = new List<(long, string)>(); } list.Add(item.Key); } } if (list == null) { return; } foreach (var item2 in list) { LastAccepted.Remove(item2); } } } public static class ZdoStringListField { private const char Delimiter = '\u001f'; public static IReadOnlyList Read(ZDO zdo, string key) { return SplitRaw(zdo.GetString(key, "")); } public static void Write(ZDO zdo, string key, IEnumerable values) { zdo.Set(key, JoinRaw(values)); } public static IReadOnlyList SplitRaw(string raw) { if (!string.IsNullOrEmpty(raw)) { return raw.Split(new char[1] { '\u001f' }); } return Array.Empty(); } public static string JoinRaw(IEnumerable values) { return string.Join('\u001f'.ToString(), values); } } [HarmonyPatch] public static class PortalModeRpc { private const string RpcName = "PotalMap ChangePortalMode"; private const float CooldownSeconds = 0.5f; [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void RegisterHandler() { ZRoutedRpc.instance.Register("PotalMap ChangePortalMode", (Action)OnReceive); } public static void Send(ZDOID portalId, PortalMode mode) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "PotalMap ChangePortalMode", new object[2] { portalId, (int)mode }); } private unsafe static void OnReceive(long sender, ZDOID portalId, int mode) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) ZDOID val = portalId; if (!RpcCooldownGuard.TryConsume(sender, "PotalMap ChangePortalMode" + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString(), 0.5f)) { return; } ZDO zDO = ZDOMan.instance.GetZDO(portalId); if (zDO != null && PlayerIdentity.TryGetOnlinePlayerIdentity(sender, out long playerId, out string _)) { PlayerIdentity.TryGetOnlineNormalizedId(sender, out string normalizedId); if (PortalAccessEvaluator.CanManage(zDO, playerId, normalizedId)) { PortalZdoFields.SetMode(zDO, (PortalMode)mode); PortalTracking.RefreshPin(zDO); } } } } [HarmonyPatch] public static class PortalTagsRpc { private const string RpcName = "PotalMap SetTags"; private const float CooldownSeconds = 1f; [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void RegisterHandler() { ZRoutedRpc.instance.Register("PotalMap SetTags", (Action)OnReceive); } public static void Send(ZDOID portalId, string tagsJoined) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "PotalMap SetTags", new object[2] { portalId, tagsJoined }); } private unsafe static void OnReceive(long sender, ZDOID portalId, string tagsJoined) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) ZDOID val = portalId; if (RpcCooldownGuard.TryConsume(sender, "PotalMap SetTags" + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString(), 1f)) { ZDO zDO = ZDOMan.instance.GetZDO(portalId); if (zDO != null && PlayerIdentity.TryGetOnlinePlayerIdentity(sender, out long playerId, out string _) && playerId == PortalZdoFields.GetOwnerCharId(zDO)) { PortalZdoFields.SetTags(zDO, ZdoStringListField.SplitRaw(tagsJoined)); } } } } [HarmonyPatch] public static class MapInteraction { private class PortalTriggerExitWatcher : MonoBehaviour { private void OnTriggerExit(Collider other) { Player component = ((Component)other).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component != (Object)(object)Player.m_localPlayer) && PortalMapSession.Active) { Minimap.instance.SetMapMode((MapMode)1); } } } [HarmonyPatch] private static class BlockOtherMapClicksDuringPortalSession { private static IEnumerable TargetMethods() { return new MethodInfo[3] { AccessTools.DeclaredMethod(typeof(Minimap), "OnMapDblClick", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Minimap), "OnMapRightClick", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Minimap), "OnMapMiddleClick", (Type[])null, (Type[])null) }; } private static bool Prefix() { return !PortalMapSession.Active; } } [HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")] [HarmonyPrefix] private static bool OpenMapOnPortalEnter(TeleportWorldTrigger __instance, Collider colliderIn) { Player component = ((Component)colliderIn).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer) { return true; } if ((Object)(object)__instance.m_teleportWorld != (Object)null && !PotalMapGeneralConfig.IsEligiblePortal(((Component)__instance.m_teleportWorld).gameObject)) { return true; } if (InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } PortalMapSession.PendingPortalTrigger = true; Minimap.instance.SetMapMode((MapMode)2); return false; } [HarmonyPatch(typeof(Player), "Update")] [HarmonyPostfix] private static void OnPlayerUpdate(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && PortalMapSession.Active && Input.GetKeyDown((KeyCode)27)) { if (InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } Minimap.instance.SetMapMode((MapMode)1); } } [HarmonyPatch(typeof(TeleportWorldTrigger), "Awake")] [HarmonyPostfix] private static void AttachExitWatcher(TeleportWorldTrigger __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] [HarmonyPrefix] private static bool TeleportOnPortalPinClick() { //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_0038: Unknown result type (might be due to invalid IL or missing references) if (!PortalMapSession.Active) { return true; } Minimap instance = Minimap.instance; if (!PortalTracking.TryGetClosestPortalPin(instance.ScreenToWorldPoint(ZInput.mousePosition), instance.m_removeRadius * (instance.m_largeZoom * 2f), out var portalId)) { return false; } if (PortalTeleporter.TryTeleport(portalId)) { instance.SetMapMode((MapMode)1); } return false; } } [HarmonyPatch] public static class PortalBrowserPanel { public static ConfigEntry Enabled = null; private static GameObject? _panel; private static Transform? _portalListParent; private static ScrollRect? _scrollRect; private static readonly PortalMode[] GroupOrder = new PortalMode[3] { PortalMode.Guild, PortalMode.Private, PortalMode.Public }; private static readonly Color FavoriteColor = new Color(1f, 0.65f, 0.2f); public static void Init(ConfigFile config) { Enabled = PotalMapConfig.Bind(config, "5 - Portal Browser", "Enable portal browser panel", value: true, "If off, the portal name list on the left side of the large map is not shown."); } [HarmonyPatch(typeof(Minimap), "SetMapMode")] [HarmonyPostfix] private static void OnSetMapMode(MapMode mode) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (Enabled.Value) { if ((int)mode == 2 && PortalMapSession.Active) { EnsurePanel(); _panel.SetActive(true); RefreshPortalList(); } else if ((Object)(object)_panel != (Object)null) { _panel.SetActive(false); } } } private static void EnsurePanel() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_007e: 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_0093: 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_00a8: 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_00e4: 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) //IL_0107: Expected O, but got Unknown if (!((Object)(object)_panel != (Object)null)) { _panel = new GameObject("PotalMapBrowserPanel", new Type[1] { typeof(RectTransform) }); _panel.transform.SetParent(Minimap.instance.m_largeRoot.transform, false); RectTransform val = (RectTransform)_panel.transform; val.anchorMin = new Vector2(0f, 0.5f); val.anchorMax = new Vector2(0f, 0.5f); val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(20f, 0f); val.sizeDelta = new Vector2(190f, 720f); ((Graphic)_panel.AddComponent()).color = new Color(0f, 0f, 0f, 0.75f); VerticalLayoutGroup obj = _panel.AddComponent(); ((LayoutGroup)obj).padding = new RectOffset(8, 8, 8, 8); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; AddHeader(_panel.transform, "Potal_Map"); _portalListParent = (Transform?)(object)BuildPortalListScroll(_panel.transform); } } private static RectTransform BuildPortalListScroll(Transform parent) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0095: 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_00a1: Expected O, but got Unknown //IL_00ac: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Expected O, but got Unknown GameObject val = new GameObject("PortalListScroll", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); val.AddComponent().flexibleHeight = 1f; ((Graphic)val.AddComponent()).color = new Color(1f, 1f, 1f, 0.01f); val.AddComponent(); GameObject val2 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 1f); val3.anchorMax = new Vector2(1f, 1f); val3.pivot = new Vector2(0.5f, 1f); val3.anchoredPosition = Vector2.zero; val3.sizeDelta = Vector2.zero; VerticalLayoutGroup obj = val2.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ContentSizeFitter obj2 = val2.AddComponent(); obj2.horizontalFit = (FitMode)0; obj2.verticalFit = (FitMode)2; GameObject val4 = new GameObject("Scrollbar", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val.transform, false); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = new Vector2(1f, 0f); val5.anchorMax = new Vector2(1f, 1f); val5.pivot = new Vector2(1f, 1f); val5.sizeDelta = new Vector2(6f, 0f); val5.anchoredPosition = Vector2.zero; ((Graphic)val4.AddComponent()).color = new Color(1f, 1f, 1f, 0.08f); Scrollbar val6 = val4.AddComponent(); val6.direction = (Direction)2; GameObject val7 = new GameObject("Handle", new Type[1] { typeof(RectTransform) }); val7.transform.SetParent(val4.transform, false); Image val8 = val7.AddComponent(); ((Graphic)val8).color = new Color(1f, 1f, 1f, 0.25f); RectTransform val9 = (RectTransform)val7.transform; val9.anchorMin = Vector2.zero; val9.anchorMax = Vector2.one; val9.sizeDelta = Vector2.zero; val6.handleRect = val9; ((Selectable)val6).targetGraphic = (Graphic)(object)val8; ScrollRect obj3 = val.AddComponent(); obj3.horizontal = false; obj3.vertical = true; obj3.movementType = (MovementType)2; obj3.viewport = (RectTransform)val.transform; obj3.content = val3; obj3.verticalScrollbar = val6; obj3.verticalScrollbarVisibility = (ScrollbarVisibility)1; obj3.verticalScrollbarSpacing = -3f; _scrollRect = obj3; return val3; } private static void AddHeader(Transform parent, string text) { //IL_0018: 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_002a: 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) GameObject val = new GameObject("Header", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Text obj = val.AddComponent(); obj.font = UiRowFactory.GetFont(); obj.text = text; obj.fontSize = 27; ((Graphic)obj).color = new Color(1f, 0.85f, 0.4f); val.AddComponent().minHeight = 34f; } private static void AddBlankLine(Transform parent) { //IL_0018: 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) GameObject val = new GameObject("BlankLine", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); val.AddComponent().minHeight = 13f; } private static IEnumerable<(ZDOID id, ZDO zdo)> GetVisiblePortals() { foreach (ZDOID visiblePortalId in PortalTracking.GetVisiblePortalIds()) { ZDO zDO = ZDOMan.instance.GetZDO(visiblePortalId); if (zDO != null) { yield return (id: visiblePortalId, zdo: zDO); } } } private static void RefreshPortalList() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_portalListParent == (Object)null) { return; } Transform portalListParent = _portalListParent; foreach (Transform item in portalListParent) { Object.Destroy((Object)(object)((Component)item).gameObject); } List<(ZDOID, string, PortalMode)> list = (from p in GetVisiblePortals() select (id: p.id, name: PortalZdoFields.GetDisplayName(p.zdo), mode: PortalZdoFields.GetMode(p.zdo))).ToList(); list.Sort(((ZDOID id, string name, PortalMode mode) a, (ZDOID id, string name, PortalMode mode) b) => string.Compare(a.name, b.name, StringComparison.CurrentCulture)); bool flag = true; List<(ZDOID, string, PortalMode)> list2 = list.Where<(ZDOID, string, PortalMode)>(((ZDOID id, string name, PortalMode mode) p) => PortalFavorites.IsFavorite(p.id)).ToList(); if (list2.Count > 0) { AddSectionHeader(portalListParent, "즐겨찾기", FavoriteColor); foreach (var (id, text, mode) in list2) { CreatePortalRow(id, GroupLabel(mode) + " - " + text); } flag = false; } PortalMode[] groupOrder = GroupOrder; foreach (PortalMode mode2 in groupOrder) { List<(ZDOID, string, PortalMode)> list3 = list.Where<(ZDOID, string, PortalMode)>(((ZDOID id, string name, PortalMode mode) p) => p.mode == mode2 && !PortalFavorites.IsFavorite(p.id)).ToList(); if (list3.Count == 0) { continue; } if (!flag) { AddBlankLine(portalListParent); } flag = false; AddSectionHeader(portalListParent, GroupLabel(mode2), mode2.GetColor()); foreach (var (id2, label, _) in list3) { CreatePortalRow(id2, label); } } if ((Object)(object)_scrollRect != (Object)null) { _scrollRect.verticalNormalizedPosition = 1f; } } private static string GroupLabel(PortalMode mode) { return mode switch { PortalMode.Public => "공개", PortalMode.Private => "개인", PortalMode.Guild => "길드", _ => mode.ToString(), }; } private static void AddSectionHeader(Transform parent, string text, Color color) { //IL_0018: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Divider", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); ((Graphic)val.AddComponent()).color = new Color(1f, 1f, 1f, 0.15f); val.AddComponent().minHeight = 1f; GameObject val2 = new GameObject("SectionHeader", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(parent, false); Text obj = val2.AddComponent(); obj.font = UiRowFactory.GetFont(); obj.text = text; obj.fontSize = 20; ((Graphic)obj).color = color; val2.AddComponent().minHeight = 24f; } private static void CreatePortalRow(ZDOID id, string label) { //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) GameObject obj = UiRowFactory.CreateRow(_portalListParent, label, delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) TeleportTo(id); }, delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ToggleFavorite(id); }); ((Component)obj.transform.Find("Label")).GetComponent().fontSize = 17; LayoutElement component = obj.GetComponent(); component.minHeight = 20f; component.preferredHeight = 20f; } private static void ToggleFavorite(ZDOID id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) PortalFavorites.Toggle(id); RefreshPortalList(); } private static void TeleportTo(ZDOID portalId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (PortalTeleporter.TryTeleport(portalId)) { Minimap.instance.SetMapMode((MapMode)1); } } } public static class UiRowFactory { private sealed class RightClickRouter : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { public Action? OnRightClick; public void OnPointerClick(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)eventData.button == 1) { OnRightClick?.Invoke(); } } } private static Font? _font; public static Font GetFont() { if ((Object)(object)_font != (Object)null) { return _font; } _font = Font.CreateDynamicFontFromOSFont("Arial", 14); if ((Object)(object)_font == (Object)null) { _font = Resources.GetBuiltinResource("Arial.ttf"); } return _font; } public static GameObject CreateRow(Transform parent, string label, Action? onClick, Action? onRightClick = null) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0054: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_0107: 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_0112: 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_011d: 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_013c: 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_00a4: Expected O, but got Unknown GameObject val = new GameObject("Row", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Image val2 = val.AddComponent(); ((Graphic)val2).color = new Color(1f, 1f, 1f, 0.05f); LayoutElement obj = val.AddComponent(); obj.minHeight = 24f; obj.preferredHeight = 24f; if (onClick != null) { Button obj2 = val.AddComponent