using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace PortalLimit.Client; [BepInPlugin("keith.valheim.portallimit.client", "Portal Limit and Discovery Client", "0.1.4")] public class PortalLimitClientPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Chat), "InputText")] private static class ChatInputPatch { private static bool Prefix(Chat __instance) { string a = (((Object)(object)((Terminal)__instance).m_input != (Object)null) ? ((TMP_InputField)((Terminal)__instance).m_input).text : string.Empty); if (string.Equals(a, "/portals", StringComparison.OrdinalIgnoreCase)) { if ((Object)(object)Instance != (Object)null) { Instance.RequestCountForChat(); } if ((Object)(object)((Terminal)__instance).m_input != (Object)null) { ((TMP_InputField)((Terminal)__instance).m_input).text = string.Empty; } __instance.Hide(); return false; } if (!string.Equals(a, "/portallimit", StringComparison.OrdinalIgnoreCase)) { return true; } if ((Object)(object)Instance != (Object)null) { Instance.ToggleAdminWindow(); } if ((Object)(object)((Terminal)__instance).m_input != (Object)null) { ((TMP_InputField)((Terminal)__instance).m_input).text = string.Empty; } __instance.Hide(); return false; } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static class PlacePiecePatch { private static bool Prefix(Piece piece, ref bool __result) { if (!WouldExceedPortalLimit(piece)) { return true; } __result = false; Instance.ShowMessage("Portal limit reached: " + Instance.maxPortalsPerPlayer + " portal(s) per player."); Instance.RequestCount(); return false; } private static void Postfix(Piece piece, bool __result) { if (__result && (Object)(object)Instance != (Object)null && (Object)(object)piece != (Object)null && Instance.IsLimitedPortal(piece)) { Instance.ReportPortalMetadata(piece, "placed"); Instance.RequestPlacementCountSoon(); } } } [HarmonyPatch(typeof(Piece), "CanBeRemoved")] private static class PieceCanBeRemovedPatch { private static void Postfix(Piece __instance, ref bool __result) { if (__result && !((Object)(object)Instance == (Object)null) && !((Object)(object)__instance == (Object)null) && Instance.IsLimitedPortal(__instance)) { long creator = __instance.GetCreator(); long localPlayerId = GetLocalPlayerId(); if (!Instance.isAdmin && creator != 0 && creator != localPlayerId) { __result = false; Instance.ShowMessage("Only the builder or an admin can remove this portal."); } } } } [HarmonyPatch(typeof(TeleportWorld), "Interact")] private static class TeleportWorldInteractPatch { private static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, ref bool __result) { if ((Object)(object)Instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)human != (Object)(object)Player.m_localPlayer) { return true; } if (Instance.replayingVanillaPortalInteract) { return true; } if (Instance.isAdmin && Instance.adminHoldEToEdit && !hold) { Instance.BeginDelayedPortalInteract(__instance); __result = false; return false; } if (hold && Instance.isAdmin && Instance.adminHoldEToEdit) { Instance.OpenAdminWindowForPortal(__instance); Instance.ResetHoldInteract(); __result = false; return false; } if (!hold && ShouldBlockPortalUse(__instance)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] private static class TeleportWorldTeleportPatch { private static bool Prefix(TeleportWorld __instance, Player player) { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return true; } bool flag = !ShouldBlockBlankPortalUse(__instance) && !ShouldBlockPortalUse(__instance); if (flag && (Object)(object)Instance != (Object)null) { Instance.ReportPortalMetadata(__instance, "used"); } return flag; } } [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] private static class TeleportWorldHoverTextPatch { private static void Postfix(TeleportWorld __instance, ref string __result) { if ((Object)(object)Instance == (Object)null) { return; } if (string.IsNullOrWhiteSpace(GetPortalTag(__instance)) && !string.IsNullOrEmpty(__result)) { __result = __result.Replace(" [CONNECTED]", string.Empty).Replace("[CONNECTED]", string.Empty); } if (Instance.isAdmin) { if (Instance.adminHoldEToEdit) { __result += "\nHold E: Portal Limit settings"; } string portalCreatorName = GetPortalCreatorName(__instance); if (!string.IsNullOrWhiteSpace(portalCreatorName)) { __result = __result + "\nBuilt by: " + portalCreatorName + ""; } } if (!Instance.discoveryEnabled || (!Instance.showDiscoveryHoverText && !Instance.isAdmin)) { return; } int discoveryRole = GetDiscoveryRole(__instance); if (discoveryRole == 0) { return; } string discoveryLink = GetDiscoveryLink(__instance); if (string.IsNullOrWhiteSpace(discoveryLink)) { return; } string text = string.Empty; if (Instance.IsDiscoveryUnlocked(discoveryLink)) { text = GetDiscoveryHoverOverride(__instance, "PortalLimit_DiscoveryUnlockedHoverText"); if (string.IsNullOrWhiteSpace(text)) { text = Instance.discoveryUnlockedHoverText; } } else { switch (discoveryRole) { case 1: text = GetDiscoveryHoverOverride(__instance, "PortalLimit_DiscoveryLockedHoverText"); if (string.IsNullOrWhiteSpace(text)) { text = Instance.discoveryLockedHoverText; } break; case 2: text = GetDiscoveryHoverOverride(__instance, "PortalLimit_DiscoveryRemoteHoverText"); if (string.IsNullOrWhiteSpace(text)) { text = Instance.discoveryRemoteHoverText; } break; } } if (!string.IsNullOrWhiteSpace(text)) { __result = __result + "\n" + text + ""; } } } [HarmonyPatch(typeof(TeleportWorld), "TargetFound")] private static class TeleportWorldTargetFoundPatch { private static void Postfix(TeleportWorld __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && string.IsNullOrWhiteSpace(GetPortalTag(__instance))) { __result = false; SetTargetFound(__instance, value: false); } } } [HarmonyPatch(typeof(TeleportWorld), "HaveTarget")] private static class TeleportWorldHaveTargetPatch { private static void Postfix(TeleportWorld __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && string.IsNullOrWhiteSpace(GetPortalTag(__instance))) { __result = false; } } } [HarmonyPatch(typeof(TeleportWorld), "Update")] private static class TeleportWorldVisualPatch { private static void Postfix(TeleportWorld __instance) { if (!((Object)(object)__instance == (Object)null)) { PortalLimitDiscoveryVisual portalLimitDiscoveryVisual = ((Component)__instance).GetComponent(); if ((Object)(object)portalLimitDiscoveryVisual == (Object)null) { portalLimitDiscoveryVisual = ((Component)__instance).gameObject.AddComponent(); } portalLimitDiscoveryVisual.Refresh(__instance); } } } private class PortalLimitDiscoveryVisual : MonoBehaviour { private GameObject markerRoot; private TextMesh markerText; private Renderer[] portalRenderers; private ParticleSystem[] portalParticles; private Light[] portalLights; private readonly Dictionary originalColors = new Dictionary(); private readonly Dictionary originalParticleStates = new Dictionary(); private readonly Dictionary originalLightStates = new Dictionary(); internal void Refresh(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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance == (Object)null) && !((Object)(object)portal == (Object)null)) { bool flag = Instance.ShouldShowDiscoveryWorldMarker(portal); bool enabled = Instance.ShouldTintDiscoveryPortal(portal); bool suppress = Instance.ShouldSuppressLockedPortalGlow(portal); Color discoveryVisualColor = Instance.GetDiscoveryVisualColor(portal); EnsureMarker(); markerRoot.SetActive(flag); if (flag) { SetMarkerWorldPose(portal); SetMarkerText(Instance.GetDiscoveryMarkerDisplayText(portal)); SetMarkerColor(discoveryVisualColor); } UpdatePortalTint(enabled, discoveryVisualColor); UpdatePortalEffects(suppress); } } private void EnsureMarker() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)markerRoot != (Object)null)) { markerRoot = new GameObject("PortalLimit_DiscoveryMarker"); markerRoot.transform.SetParent(((Component)this).transform, false); markerRoot.transform.localPosition = new Vector3(0f, 1.55f, 0f); markerRoot.transform.localRotation = Quaternion.identity; markerRoot.transform.localScale = Vector3.one; markerText = markerRoot.AddComponent(); markerText.text = "UNLOCK ON OTHER SIDE"; markerText.anchor = (TextAnchor)4; markerText.alignment = (TextAlignment)1; markerText.fontSize = 96; markerText.characterSize = 0.01f; markerText.richText = false; SetMarkerColor(LockedOrange); markerRoot.SetActive(false); } } private void SetMarkerText(string text) { if (!((Object)(object)markerText == (Object)null)) { markerText.text = text; if (string.Equals(text, "X", StringComparison.Ordinal)) { markerText.fontSize = 128; markerText.characterSize = 0.03f; } else if (string.Equals(text, "LOCKED", StringComparison.Ordinal)) { markerText.fontSize = 96; markerText.characterSize = 0.018f; } else { markerText.fontSize = 96; markerText.characterSize = 0.01f; } } } private void SetMarkerColor(Color color) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)markerText != (Object)null) { markerText.color = color; } } private void SetMarkerWorldPose(TeleportWorld portal) { //IL_002d: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)markerRoot == (Object)null || (Object)(object)portal == (Object)null) { return; } Vector3 val = ((Component)portal).transform.position + Vector3.up * 1.55f; if ((Object)(object)Camera.main != (Object)null) { Vector3 val2 = ((Component)Camera.main).transform.position - val; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { markerRoot.transform.position = val + ((Vector3)(ref val2)).normalized * 0.45f; markerRoot.transform.rotation = Quaternion.LookRotation(-((Vector3)(ref val2)).normalized, Vector3.up); return; } } markerRoot.transform.position = val; markerRoot.transform.rotation = ((Component)portal).transform.rotation; } private void UpdatePortalTint(bool enabled, Color color) { //IL_009b: 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_00de: 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_00e9: 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 (portalRenderers == null) { portalRenderers = ((Component)this).GetComponentsInChildren(true); } Renderer[] array = portalRenderers; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && !((Component)val).transform.IsChildOf(markerRoot.transform)) { if (!originalColors.ContainsKey(val)) { originalColors[val] = (val.material.HasProperty("_Color") ? val.material.color : Color.white); } if (val.material.HasProperty("_Color")) { val.material.color = (enabled ? Color.Lerp(originalColors[val], color, 0.45f) : originalColors[val]); } } } } private void UpdatePortalEffects(bool suppress) { ParticleSystem[] array; if (portalParticles == null) { portalParticles = ((Component)this).GetComponentsInChildren(true); array = portalParticles; foreach (ParticleSystem val in array) { if ((Object)(object)val != (Object)null) { originalParticleStates[val] = ((Component)val).gameObject.activeSelf; } } } Light[] array2; if (portalLights == null) { portalLights = ((Component)this).GetComponentsInChildren(true); array2 = portalLights; foreach (Light val2 in array2) { if ((Object)(object)val2 != (Object)null) { originalLightStates[val2] = ((Behaviour)val2).enabled; } } } array = portalParticles; foreach (ParticleSystem val in array) { if (!((Object)(object)val == (Object)null) && !((Component)val).transform.IsChildOf(markerRoot.transform)) { if (!originalParticleStates.TryGetValue(val, out var value)) { value = true; } ((Component)val).gameObject.SetActive(!suppress && value); if (!suppress && value && !val.isPlaying) { val.Play(true); } } } array2 = portalLights; foreach (Light val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !((Component)val2).transform.IsChildOf(markerRoot.transform)) { if (!originalLightStates.TryGetValue(val2, out var value2)) { value2 = true; } ((Behaviour)val2).enabled = !suppress && value2; } } } } public const string PluginGuid = "keith.valheim.portallimit.client"; public const string PluginName = "Portal Limit and Discovery Client"; public const string PluginVersion = "0.1.4"; private const string RpcConfigRequest = "keith.valheim.portallimit.config_request"; private const string RpcConfigResponse = "keith.valheim.portallimit.config_response"; private const string RpcConfigUpdate = "keith.valheim.portallimit.config_update"; private const string RpcCountRequest = "keith.valheim.portallimit.count_request"; private const string RpcCountResponse = "keith.valheim.portallimit.count_response"; private const string RpcNotice = "keith.valheim.portallimit.notice"; private const string RpcDiscoveryMarkRequest = "keith.valheim.portallimit.discovery_mark_request"; private const string RpcDiscoveryUnlockRequest = "keith.valheim.portallimit.discovery_unlock_request"; private const string RpcDiscoveryRelockRequest = "keith.valheim.portallimit.discovery_relock_request"; private const string RpcDiscoveryUnlockListRequest = "keith.valheim.portallimit.discovery_unlock_list_request"; private const string RpcDiscoveryUnlockListResponse = "keith.valheim.portallimit.discovery_unlock_list_response"; private const string RpcAdminReportRequest = "keith.valheim.portallimit.admin_report_request"; private const string RpcAdminReportResponse = "keith.valheim.portallimit.admin_report_response"; private const string RpcPortalMetadataUpdate = "keith.valheim.portallimit.portal_metadata_update"; private const string DiscoveryRoleKey = "PortalLimit_DiscoveryRole"; private const string DiscoveryLinkKey = "PortalLimit_DiscoveryLink"; private const string DiscoveryColorKey = "PortalLimit_DiscoveryColor"; private const string DiscoveryMarkerTextKey = "PortalLimit_DiscoveryMarkerText"; private const string DiscoveryShowMarkerKey = "PortalLimit_DiscoveryShowMarker"; private const string DiscoverySuppressGlowKey = "PortalLimit_DiscoverySuppressGlow"; private const string DiscoveryLockedHoverTextKey = "PortalLimit_DiscoveryLockedHoverText"; private const string DiscoveryRemoteHoverTextKey = "PortalLimit_DiscoveryRemoteHoverText"; private const string DiscoveryUnlockedHoverTextKey = "PortalLimit_DiscoveryUnlockedHoverText"; private const string PortalBuiltUtcKey = "PortalLimit_BuiltUtc"; private const int DiscoveryRoleNone = 0; private const int DiscoveryRoleLocked = 1; private const int DiscoveryRoleRemote = 2; internal static PortalLimitClientPlugin Instance; internal static ManualLogSource Log; private static readonly FieldInfo AllPiecesField = AccessTools.Field(typeof(Piece), "s_allPieces"); private static readonly FieldInfo TeleportWorldTargetFoundField = AccessTools.Field(typeof(TeleportWorld), "m_target_found"); private static readonly MethodInfo GetPlayerIdMethod = AccessTools.Method(typeof(Player), "GetPlayerID", (Type[])null, (Type[])null); private static readonly MethodInfo GetPrefabNameMethod = AccessTools.Method(typeof(ZNetView), "GetPrefabName", (Type[])null, (Type[])null); private static readonly Color LockedOrange = new Color(1f, 0.6235294f, 0.1019608f, 1f); private static readonly string[] MarkerColorLabels = new string[8] { "RED", "ORANGE", "YELLOW", "GREEN", "BLUE", "PURPLE", "WHITE", "BLACK" }; private static readonly string[] MarkerColorValues = new string[8] { "#ff3030", "#ff9f1a", "#ffd84a", "#42ff68", "#38a6ff", "#b05cff", "#ffffff", "#000000" }; private static readonly string[] PortalRoleChoiceLabels = new string[3] { "NORMAL PORTAL", "LOCKED ENTRANCE", "UNLOCKED ENTRANCE" }; private static readonly string[] MarkerTextLabels = new string[3] { "UNLOCK ON OTHER SIDE", "LOCKED", "X" }; private static readonly string[] MarkerTextValues = new string[3] { "UnlockOnOtherSide", "Locked", "X" }; private Harmony harmony; private bool rpcRegistered; private bool configRequested; private bool showCountMessageOnNextResponse; private bool showPlacementCountOnNextResponse; private bool openAdminUiAfterPermissionCheck; private bool adminStatusKnown; private bool isAdmin; private bool adminBypass = true; private bool enforceOnServer = true; private int maxPortalsPerPlayer = 10; private string portalPrefabNames = "portal_wood,portal_stone"; private bool discoveryEnabled = true; private bool discoveryAdminBypass = true; private bool adminHoldEToEdit = true; private bool showDiscoveryHoverText = true; private string discoveryLockedHoverText = "Locked: find the other end first."; private string discoveryRemoteHoverText = "Discovery portal: use this side to unlock the route."; private string discoveryUnlockedHoverText = "Discovery route unlocked."; private string discoveryLockedMessage = "This portal is locked. Find and enter the other end first."; private string discoveryUnlockMessage = "Discovery portal unlocked."; private bool discoveryShowWorldMarker = true; private bool discoveryTintPortalModel; private bool discoverySuppressLockedGlow; private string discoveryLockedColor = "#ff9f1a"; private string discoveryRemoteColor = "#38a6ff"; private string discoveryUnlockedColor = "#42ff68"; private readonly HashSet unlockedDiscoveryLinks = new HashSet(StringComparer.OrdinalIgnoreCase); private int serverPortalCount; private Rect adminWindow = new Rect(120f, 60f, 700f, 720f); private Vector2 adminScroll; private Vector2 portalInfoThisScroll; private Vector2 portalInfoWorldScroll; private bool showAdminWindow; private int adminTab; private string openDropdown = string.Empty; private bool portalInfoShowThis; private bool portalInfoShowWorld; private string portalInfoThisText = "Open this tab while editing a portal."; private string portalInfoWorldText = "Click Refresh to load world portal information."; private string portalInfoRequestedPortalKey = string.Empty; private int selectedPortalRole; private string loadedPortalKey = string.Empty; private TeleportWorld selectedPortal; private string maxText = "10"; private string portalNamesText = "portal_wood,portal_stone"; private string discoveryLinkText = string.Empty; private string selectedPortalColorText = "#ff9f1a"; private int selectedPortalColorIndex; private string selectedPortalMarkerText = "UNLOCK ON OTHER SIDE"; private bool selectedPortalShowMarker = true; private bool selectedPortalSuppressGlow; private string selectedLockedHoverText = string.Empty; private string selectedRemoteHoverText = string.Empty; private string selectedUnlockedHoverText = string.Empty; private string discoveryLockedHoverTextField = "Locked: find the other end first."; private string discoveryRemoteHoverTextField = "Discovery portal: use this side to unlock the route."; private string discoveryUnlockedHoverTextField = "Discovery route unlocked."; private string discoveryLockedMessageField = "This portal is locked. Find and enter the other end first."; private string discoveryUnlockMessageField = "Discovery portal unlocked."; private int selectedPortalMarkerTextIndex; private TeleportWorld holdInteractPortal; private float holdInteractStartedAt; private bool holdInteractOpened; private bool replayingVanillaPortalInteract; private string discoveryLockedColorField = "#ff9f1a"; private string discoveryRemoteColorField = "#38a6ff"; private string discoveryUnlockedColorField = "#42ff68"; private string statusMessage = "Use /portallimit to load server settings."; private bool adminStylesReady; private Texture2D adminWindowTexture; private Texture2D adminHeaderTexture; private Texture2D adminSectionTexture; private Texture2D adminInputTexture; private Texture2D adminButtonTexture; private Texture2D adminButtonHoverTexture; private Texture2D adminTabTexture; private Texture2D adminTabSelectedTexture; private GUIStyle adminWindowStyle; private GUIStyle adminTitleStyle; private GUIStyle adminLabelStyle; private GUIStyle adminHelpStyle; private GUIStyle adminSectionStyle; private GUIStyle adminButtonStyle; private GUIStyle adminTabStyle; private GUIStyle adminTabSelectedStyle; private GUIStyle adminTextFieldStyle; private GUIStyle adminBoxStyle; private ConfigEntry toggleAdminUiKey; private void Awake() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown if (IsDedicatedServerProcess()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Portal Limit Client disabled on the dedicated server process."); ((Behaviour)this).enabled = false; return; } Instance = this; Log = ((BaseUnityPlugin)this).Logger; toggleAdminUiKey = ((BaseUnityPlugin)this).Config.Bind("Input", "ToggleAdminUIKey", (KeyCode)291, "Key used to open the portal limit admin UI."); harmony = new Harmony("keith.valheim.portallimit.client"); harmony.PatchAll(); RegisterConsoleCommands(); ((MonoBehaviour)this).InvokeRepeating("TryRegisterRpcs", 1f, 1f); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } DestroyAdminTexture(adminWindowTexture); DestroyAdminTexture(adminHeaderTexture); DestroyAdminTexture(adminSectionTexture); DestroyAdminTexture(adminInputTexture); DestroyAdminTexture(adminButtonTexture); DestroyAdminTexture(adminButtonHoverTexture); DestroyAdminTexture(adminTabTexture); DestroyAdminTexture(adminTabSelectedTexture); } private static bool IsDedicatedServerProcess() { string processName = Process.GetCurrentProcess().ProcessName; return processName.StartsWith("valheim_server", StringComparison.OrdinalIgnoreCase); } private void TryRegisterRpcs() { if (!rpcRegistered && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register("keith.valheim.portallimit.config_response", (Action)OnConfigResponse); ZRoutedRpc.instance.Register("keith.valheim.portallimit.count_response", (Method)OnCountResponse); ZRoutedRpc.instance.Register("keith.valheim.portallimit.notice", (Action)OnNotice); ZRoutedRpc.instance.Register("keith.valheim.portallimit.discovery_unlock_list_response", (Action)OnDiscoveryUnlockListResponse); ZRoutedRpc.instance.Register("keith.valheim.portallimit.admin_report_response", (Action)OnAdminReportResponse); rpcRegistered = true; ((MonoBehaviour)this).CancelInvoke("TryRegisterRpcs"); } } private static void RegisterConsoleCommands() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("portallimit", "Portal Limit commands. Use: portallimit, portallimit count, portallimit counts, portallimit portals, portallimit export", new ConsoleEvent(OnConsolePortalLimit), false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void OnConsolePortalLimit(ConsoleEventArgs args) { if ((Object)(object)Instance == (Object)null) { Terminal.Log((object)"Portal Limit client is not ready."); return; } string text = ((args.Length > 1) ? args[1].ToLowerInvariant() : "help"); if (text == "help") { Terminal.Log((object)"Portal Limit F5 commands:"); Terminal.Log((object)" portallimit count - show your portal count"); Terminal.Log((object)" portallimit counts - admin: show counts for all players"); Terminal.Log((object)" portallimit portals - admin: list known portals with names and coordinates"); Terminal.Log((object)" portallimit export - admin: rewrite report files on the server"); Terminal.Log((object)"Regular players can also type /portals in normal chat."); } else if (text == "count") { Instance.showCountMessageOnNextResponse = true; Instance.RequestCount(); Terminal.Log((object)"Portal Limit: checking your portal count..."); } else if (text != "counts" && text != "portals" && text != "export") { Terminal.Log((object)"Unknown Portal Limit command. Use: portallimit"); } else if (ZRoutedRpc.instance == null) { Terminal.Log((object)"Portal Limit server RPC is not ready yet."); } else { ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.admin_report_request", new object[1] { text }); Terminal.Log((object)("Portal Limit: requesting " + text + " report...")); } } private void Update() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (rpcRegistered && !((Object)(object)ZNet.instance == (Object)null)) { if (!configRequested && (Object)(object)Player.m_localPlayer != (Object)null) { RequestConfig(openUi: false); } if (Input.GetKeyDown(toggleAdminUiKey.Value)) { ToggleAdminWindow(); } UpdateHoldInteractAdminOpen(); } } private void UpdateHoldInteractAdminOpen() { if (!isAdmin || !adminHoldEToEdit || showAdminWindow || (Object)(object)Player.m_localPlayer == (Object)null) { ResetHoldInteract(); } else if ((Object)(object)holdInteractPortal == (Object)null) { TeleportWorld hoveredPortal = GetHoveredPortal(); if ((Object)(object)hoveredPortal != (Object)null && Input.GetKey((KeyCode)101)) { BeginDelayedPortalInteract(hoveredPortal); } } else if (!Input.GetKey((KeyCode)101)) { TeleportWorld val = holdInteractPortal; bool flag = !holdInteractOpened && Time.unscaledTime - holdInteractStartedAt < 0.45f; ResetHoldInteract(); if (flag && (Object)(object)val != (Object)null) { ReplayVanillaPortalInteract(val); } } else if (!holdInteractOpened && Time.unscaledTime - holdInteractStartedAt >= 0.45f) { holdInteractOpened = true; OpenAdminWindowForPortal(holdInteractPortal); } } private void BeginDelayedPortalInteract(TeleportWorld portal) { holdInteractPortal = portal; holdInteractStartedAt = Time.unscaledTime; holdInteractOpened = false; } private void ResetHoldInteract() { holdInteractPortal = null; holdInteractStartedAt = 0f; holdInteractOpened = false; } private void ReplayVanillaPortalInteract(TeleportWorld portal) { if ((Object)(object)portal == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } replayingVanillaPortalInteract = true; try { portal.Interact((Humanoid)(object)Player.m_localPlayer, false, false); } finally { replayingVanillaPortalInteract = false; } } private void OnGUI() { //IL_0025: 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_0045: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (showAdminWindow) { EnsureAdminStyles(); CenterAdminWindowIfNeeded(); adminWindow = GUI.Window(((Object)this).GetInstanceID(), adminWindow, new WindowFunction(DrawAdminWindow), GUIContent.none, GUIStyle.none); } } private void CenterAdminWindowIfNeeded() { //IL_008c: 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) float num = Mathf.Min(760f, (float)Screen.width - 40f); float num2 = Mathf.Min(680f, (float)Screen.height - 40f); if (Math.Abs(((Rect)(ref adminWindow)).width - num) > 0.1f || Math.Abs(((Rect)(ref adminWindow)).height - num2) > 0.1f) { adminWindow = new Rect(((float)Screen.width - num) * 0.5f, ((float)Screen.height - num2) * 0.5f, num, num2); } } private void DrawAdminWindow(int id) { //IL_0028: 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_008e: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_026d: Unknown result type (might be due to invalid IL or missing references) EnsureAdminStyles(); GUI.Box(new Rect(0f, 0f, ((Rect)(ref adminWindow)).width, ((Rect)(ref adminWindow)).height), GUIContent.none, adminWindowStyle); GUI.Box(new Rect(0f, 0f, ((Rect)(ref adminWindow)).width, 42f), GUIContent.none, adminSectionStyle); GUI.Label(new Rect(18f, 9f, ((Rect)(ref adminWindow)).width - 36f, 28f), "Portal Limit Admin", adminTitleStyle); if (GUI.Button(new Rect(((Rect)(ref adminWindow)).width - 38f, 8f, 28f, 26f), "X", adminButtonStyle)) { showAdminWindow = false; return; } GUILayout.BeginArea(new Rect(16f, 48f, ((Rect)(ref adminWindow)).width - 32f, ((Rect)(ref adminWindow)).height - 62f)); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label(statusMessage, adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); if (isAdmin) { DrawAdminTabs(); adminScroll = GUILayout.BeginScrollView(adminScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Math.Max(220f, ((Rect)(ref adminWindow)).height - 145f)) }); if (adminTab == 0) { DrawServerSettingsTab(); } else if (adminTab == 1) { DrawPortalSettingsTab(); } else { DrawPortalInformationTab(); } GUILayout.EndScrollView(); if (adminTab == 2) { DrawInformationFooter(); } else { DrawAdminFooter(); } } else { GUILayout.Label("You need to be on the Valheim admin list to edit this.", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); if (GUILayout.Button("Close", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { showAdminWindow = false; } } GUILayout.EndVertical(); GUILayout.EndArea(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref adminWindow)).width, 42f)); } private void EnsureAdminStyles() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_011a: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: 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_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Expected O, but got Unknown //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Expected O, but got Unknown //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Expected O, but got Unknown //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Expected O, but got Unknown //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Expected O, but got Unknown //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Expected O, but got Unknown //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Expected O, but got Unknown //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Expected O, but got Unknown //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Expected O, but got Unknown //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Expected O, but got Unknown //IL_060a: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Expected O, but got Unknown if (!adminStylesReady) { adminWindowTexture = MakeAdminTexture(new Color(0.03f, 0.026f, 0.022f, 0.98f)); adminHeaderTexture = MakeAdminTexture(new Color(0.18f, 0.115f, 0.065f, 0.98f)); adminSectionTexture = MakeAdminTexture(new Color(0.13f, 0.085f, 0.052f, 0.96f)); adminInputTexture = MakeAdminBorderTexture(new Color(0.12f, 0.105f, 0.08f, 1f), new Color(1f, 0.78f, 0.26f, 1f)); adminButtonTexture = MakeAdminTexture(new Color(0.25f, 0.24f, 0.21f, 0.98f)); adminButtonHoverTexture = MakeAdminTexture(new Color(0.36f, 0.31f, 0.23f, 0.98f)); adminTabTexture = MakeAdminTexture(new Color(0.16f, 0.14f, 0.12f, 0.98f)); adminTabSelectedTexture = MakeAdminTexture(new Color(0.45f, 0.31f, 0.14f, 0.98f)); adminWindowStyle = new GUIStyle(GUI.skin.box); adminWindowStyle.normal.background = adminWindowTexture; adminWindowStyle.border = new RectOffset(8, 8, 8, 8); adminWindowStyle.padding = new RectOffset(14, 14, 14, 14); adminTitleStyle = new GUIStyle(GUI.skin.label); adminTitleStyle.fontSize = 18; adminTitleStyle.fontStyle = (FontStyle)1; adminTitleStyle.alignment = (TextAnchor)4; adminTitleStyle.normal.textColor = new Color(0.95f, 0.83f, 0.55f, 1f); adminLabelStyle = new GUIStyle(GUI.skin.label); adminLabelStyle.fontSize = 14; adminLabelStyle.wordWrap = true; adminLabelStyle.normal.textColor = new Color(0.88f, 0.84f, 0.74f, 1f); adminHelpStyle = new GUIStyle(adminLabelStyle); adminHelpStyle.fontSize = 13; adminHelpStyle.normal.textColor = new Color(0.67f, 0.64f, 0.56f, 1f); adminSectionStyle = new GUIStyle(GUI.skin.box); adminSectionStyle.normal.background = adminSectionTexture; adminSectionStyle.border = new RectOffset(4, 4, 4, 4); adminSectionStyle.padding = new RectOffset(8, 8, 4, 4); adminSectionStyle.normal.textColor = new Color(0.98f, 0.82f, 0.43f, 1f); adminSectionStyle.alignment = (TextAnchor)3; adminSectionStyle.fontStyle = (FontStyle)1; adminSectionStyle.fontSize = 15; adminButtonStyle = new GUIStyle(GUI.skin.button); adminButtonStyle.normal.background = adminButtonTexture; adminButtonStyle.hover.background = adminButtonHoverTexture; adminButtonStyle.active.background = adminTabSelectedTexture; adminButtonStyle.normal.textColor = new Color(0.9f, 0.86f, 0.76f, 1f); adminButtonStyle.hover.textColor = new Color(1f, 0.9f, 0.58f, 1f); adminButtonStyle.active.textColor = Color.white; adminButtonStyle.fontSize = 13; adminButtonStyle.padding = new RectOffset(8, 8, 5, 5); adminButtonStyle.margin = new RectOffset(3, 3, 3, 3); adminTabStyle = new GUIStyle(adminButtonStyle); adminTabStyle.normal.background = adminTabTexture; adminTabStyle.fontStyle = (FontStyle)1; adminTabSelectedStyle = new GUIStyle(adminButtonStyle); adminTabSelectedStyle.normal.background = adminTabSelectedTexture; adminTabSelectedStyle.normal.textColor = Color.white; adminTabSelectedStyle.fontStyle = (FontStyle)1; adminTextFieldStyle = new GUIStyle(GUI.skin.textField); adminTextFieldStyle.normal.background = adminInputTexture; adminTextFieldStyle.focused.background = adminInputTexture; adminTextFieldStyle.hover.background = adminInputTexture; adminTextFieldStyle.border = new RectOffset(4, 4, 4, 4); adminTextFieldStyle.normal.textColor = new Color(1f, 0.98f, 0.86f, 1f); adminTextFieldStyle.focused.textColor = Color.white; adminTextFieldStyle.fontSize = 15; adminTextFieldStyle.padding = new RectOffset(12, 12, 8, 8); adminTextFieldStyle.margin = new RectOffset(3, 3, 5, 10); adminBoxStyle = new GUIStyle(GUI.skin.box); adminBoxStyle.normal.background = adminHeaderTexture; adminBoxStyle.padding = new RectOffset(6, 6, 6, 6); adminBoxStyle.margin = new RectOffset(0, 0, 2, 8); adminStylesReady = true; } } private static Texture2D MakeAdminTexture(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); val.SetPixel(0, 0, color); val.Apply(); return val; } private static Texture2D MakeAdminBorderTexture(Color fill, Color border) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0037: 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) Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false); for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { bool flag = j < 2 || i < 2 || j > 13 || i > 13; val.SetPixel(j, i, flag ? border : fill); } } val.Apply(); return val; } private static void DestroyAdminTexture(Texture2D texture) { if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } } private void DrawAdminTabs() { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); if (GUILayout.Button("Server Settings", (adminTab == 0) ? adminTabSelectedStyle : adminTabStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { adminTab = 0; openDropdown = string.Empty; } if (GUILayout.Button("This Portal", (adminTab == 1) ? adminTabSelectedStyle : adminTabStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { adminTab = 1; openDropdown = string.Empty; } if (GUILayout.Button("Portal Information", (adminTab == 2) ? adminTabSelectedStyle : adminTabStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { adminTab = 2; openDropdown = string.Empty; RequestPortalInformation(showStatus: false); } GUILayout.EndHorizontal(); } private void DrawSectionHeader(string text) { GUILayout.Box(text, adminSectionStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(30f) }); } private void DrawServerSettingsTab() { GUILayout.Space(8f); DrawSectionHeader("Portal Limit"); GUILayout.Label("How many counted portals may each non-admin player own? Use 0 for no limit.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); maxText = GUILayout.TextField(maxText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); adminBypass = DrawBoolDropdown("adminBypass", "Admin portal limit bypass", adminBypass, "Allowed", "Not allowed"); enforceOnServer = DrawBoolDropdown("enforceOnServer", "Server removes extra portals over the limit", enforceOnServer, "Enabled", "Disabled"); GUILayout.Label("Which portal types count toward the limit?", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Default covers normal wood and stone portals. Empty means every portal-like object.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); portalNamesText = GUILayout.TextField(portalNamesText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Your current portal count: " + serverPortalCount + " / " + maxPortalsPerPlayer, adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Space(12f); DrawSectionHeader("Discovery Portals"); GUILayout.Label("These settings apply to every locked discovery portal pair.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); discoveryEnabled = DrawBoolDropdown("discoveryEnabled", "Locked discovery portals", discoveryEnabled, "Enabled", "Disabled"); discoveryAdminBypass = DrawBoolDropdown("discoveryAdminBypass", "Admin bypass for locked discovery portals", discoveryAdminBypass, "Allowed", "Not allowed"); adminHoldEToEdit = DrawBoolDropdown("adminHoldEToEdit", "Admin hold E portal editor", adminHoldEToEdit, "Enabled", "Disabled"); GUILayout.Label("When enabled, admins can hold E on a portal to edit that portal. Tap E still opens Valheim's normal Set Tag box.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); showDiscoveryHoverText = DrawBoolDropdown("showDiscoveryHoverText", "Lock/unlock hover text", showDiscoveryHoverText, "Shown", "Hidden"); GUILayout.Space(12f); DrawSectionHeader("Default Player-Facing Hover Text"); GUILayout.Label("These are the server defaults. A locked portal can override them on its own This Portal tab.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Locked entrance text", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); discoveryLockedHoverTextField = GUILayout.TextField(discoveryLockedHoverTextField, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Unlocked entrance text", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); discoveryRemoteHoverTextField = GUILayout.TextField(discoveryRemoteHoverTextField, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("After unlocked text", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); discoveryUnlockedHoverTextField = GUILayout.TextField(discoveryUnlockedHoverTextField, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); } private void DrawPortalSettingsTab() { GUILayout.Space(8f); TeleportWorld val = GetSelectedPortal(); if ((Object)(object)val == (Object)null) { DrawSectionHeader("This Portal"); GUILayout.Label("No portal was opened.", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Look at a portal and hold E to open settings for that exact portal.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); return; } int discoveryRole = GetDiscoveryRole(val); string portalTagForUi = GetPortalTagForUi(val); GUILayout.Label("Portal tag", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Use the same tag on both portals, for example: Bog Witch.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); if (CanEditPortalTag(val)) { discoveryLinkText = GUILayout.TextField(discoveryLinkText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); } else { GUILayout.Label(discoveryLinkText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("This portal was built by another player. Admins can edit Portal Limit settings, but the portal tag stays protected.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); } GUILayout.Space(8f); DrawSectionHeader("This portal"); GUILayout.Label("Current: " + GetPortalRoleLabel(discoveryRole).ToUpperInvariant() + " | Tag: " + (string.IsNullOrWhiteSpace(portalTagForUi) ? "(NONE)" : portalTagForUi), adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); selectedPortalRole = DrawInlineChoice("selectedPortalRole", selectedPortalRole, PortalRoleChoiceLabels); int selectedPortalRoleValue = GetSelectedPortalRoleValue(); if (selectedPortalRoleValue != 0) { GUILayout.Space(10f); DrawSectionHeader("Relock Portal Tag"); GUILayout.Label("For this portal tag, make every player discover the unlocked entrance again.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); bool flag2 = (GUI.enabled = !string.IsNullOrWhiteSpace(discoveryLinkText)); if (GUILayout.Button("Relock this portal tag for players", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { RelockSelectedDiscoveryPortal(); } GUI.enabled = true; if (!flag2) { GUILayout.Label("Enter a portal tag before relocking players.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); } } switch (selectedPortalRoleValue) { case 1: { GUILayout.Space(10f); DrawSectionHeader("Locked Entrance Options"); selectedPortalShowMarker = DrawBoolInline("Unlock message marker", selectedPortalShowMarker, "SHOWN", "HIDDEN"); selectedPortalSuppressGlow = !DrawBoolInline("Orange glow while locked", !selectedPortalSuppressGlow, "SHOWN", "HIDDEN"); GUILayout.Space(8f); GUILayout.Label("Marker color", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); int num = selectedPortalColorIndex; selectedPortalColorIndex = DrawInlineChoice("selectedPortalColor", selectedPortalColorIndex, MarkerColorLabels); if (num != selectedPortalColorIndex) { selectedPortalColorText = MarkerColorValues[Mathf.Clamp(selectedPortalColorIndex, 0, MarkerColorValues.Length - 1)]; } selectedPortalColorText = GUILayout.TextField(selectedPortalColorText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Space(8f); GUILayout.Label("Marker text", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); int num2 = selectedPortalMarkerTextIndex; selectedPortalMarkerTextIndex = DrawInlineChoice("selectedPortalMarkerText", selectedPortalMarkerTextIndex, MarkerTextLabels); if (num2 != selectedPortalMarkerTextIndex) { selectedPortalMarkerText = MarkerTextLabels[Mathf.Clamp(selectedPortalMarkerTextIndex, 0, MarkerTextLabels.Length - 1)]; } selectedPortalMarkerText = GUILayout.TextField(selectedPortalMarkerText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Space(8f); GUILayout.Label("Player-facing hover text for this portal", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Leave blank to use the server default.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); selectedLockedHoverText = GUILayout.TextField(selectedLockedHoverText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); break; } case 2: GUILayout.Space(10f); DrawSectionHeader("Unlocked Entrance Options"); GUILayout.Label("Player-facing hover text for this portal", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Leave blank to use the server default.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); selectedRemoteHoverText = GUILayout.TextField(selectedRemoteHoverText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); break; } if (selectedPortalRoleValue != 0) { GUILayout.Space(10f); DrawSectionHeader("Unlocked Message"); GUILayout.Label("Text players see after they have unlocked this portal tag. Leave blank to use the server default.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); selectedUnlockedHoverText = GUILayout.TextField(selectedUnlockedHoverText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); } } private void DrawPortalInformationTab() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(8f); TeleportWorld val = GetSelectedPortal(); if ((Object)(object)val == (Object)null) { DrawSectionHeader("Portal Information"); GUILayout.Label("No portal was opened.", adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label("Look at a portal and hold E to open settings for that exact portal.", adminHelpStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); return; } if (GUILayout.Button("Refresh portal information", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { RequestPortalInformation(showStatus: true); } portalInfoShowThis = DrawCollapseHeader(portalInfoShowThis, "THIS PORTAL"); if (portalInfoShowThis) { portalInfoThisScroll = GUILayout.BeginScrollView(portalInfoThisScroll, adminBoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(220f) }); GUILayout.TextArea(portalInfoThisText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(GetTextAreaHeight(portalInfoThisText, 170f)) }); GUILayout.EndScrollView(); } portalInfoShowWorld = DrawCollapseHeader(portalInfoShowWorld, "WORLD PORTALS"); if (portalInfoShowWorld) { portalInfoWorldScroll = GUILayout.BeginScrollView(portalInfoWorldScroll, adminBoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(260f) }); GUILayout.TextArea(portalInfoWorldText, adminTextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(GetTextAreaHeight(portalInfoWorldText, 220f)) }); GUILayout.EndScrollView(); } } private static float GetTextAreaHeight(string text, float minimum) { int num = 1; if (!string.IsNullOrEmpty(text)) { num = text.Split(new char[1] { '\n' }).Length; } return Math.Max(minimum, 22f + (float)num * 20f); } private bool DrawCollapseHeader(bool expanded, string label) { GUILayout.Space(8f); if (GUILayout.Button((expanded ? "v " : "> ") + label, adminTabSelectedStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { expanded = !expanded; } return expanded; } private bool DrawBoolInline(string label, bool value, string trueLabel, string falseLabel) { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); GUILayout.Label(label, adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (GUILayout.Button((value ? "> " : string.Empty) + trueLabel, value ? adminTabSelectedStyle : adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { value = true; } if (GUILayout.Button(((!value) ? "> " : string.Empty) + falseLabel, (!value) ? adminTabSelectedStyle : adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { value = false; } GUILayout.EndHorizontal(); return value; } private int DrawInlineChoice(string id, int selected, string[] labels) { if (labels == null || labels.Length == 0) { return selected; } selected = Mathf.Clamp(selected, 0, labels.Length - 1); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); for (int i = 0; i < labels.Length; i++) { if (GUILayout.Button(((i == selected) ? "> " : string.Empty) + labels[i], (i == selected) ? adminTabSelectedStyle : adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { selected = i; openDropdown = string.Empty; } } GUILayout.EndHorizontal(); return selected; } private bool DrawBoolDropdown(string id, string label, bool value, string trueLabel, string falseLabel) { int selected = ((!value) ? 1 : 0); selected = DrawChoiceDropdown(id, label, selected, new string[2] { trueLabel, falseLabel }); return selected == 0; } private int DrawChoiceDropdown(string id, int selected, string[] labels) { return DrawChoiceDropdown(id, string.Empty, selected, labels); } private int DrawChoiceDropdown(string id, string label, int selected, string[] labels) { if (labels == null || labels.Length == 0) { return selected; } selected = Mathf.Clamp(selected, 0, labels.Length - 1); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); if (!string.IsNullOrWhiteSpace(label)) { GUILayout.Label(label, adminLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(330f) }); } string text = labels[selected] + " v"; if (GUILayout.Button(text, adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(190f) })) { openDropdown = ((openDropdown == id) ? string.Empty : id); } GUILayout.EndHorizontal(); if (openDropdown == id) { GUILayout.BeginVertical(adminBoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); for (int i = 0; i < labels.Length; i++) { string text2 = ((i == selected) ? "> " : " "); if (GUILayout.Button(text2 + labels[i], adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { selected = i; openDropdown = string.Empty; } } GUILayout.EndVertical(); } return selected; } private int DrawChoiceList(string id, int selected, string[] labels) { if (labels == null || labels.Length == 0) { return selected; } selected = Mathf.Clamp(selected, 0, labels.Length - 1); GUILayout.BeginVertical(adminBoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]); for (int i = 0; i < labels.Length; i++) { string text = ((i == selected) ? "> " : " "); if (GUILayout.Button(text + labels[i], adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { selected = i; openDropdown = string.Empty; } } GUILayout.EndVertical(); return selected; } private void DrawAdminFooter() { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); if (GUILayout.Button("Apply", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { ApplyActiveTab(closeAfterApply: false); } if (GUILayout.Button("Apply & Close", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { ApplyActiveTab(closeAfterApply: true); } if (GUILayout.Button("Close Without Applying", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { showAdminWindow = false; } GUILayout.EndHorizontal(); } private void DrawInformationFooter() { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]); if (GUILayout.Button("Refresh", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { RequestPortalInformation(showStatus: true); } if (GUILayout.Button("Close", adminButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[0])) { showAdminWindow = false; } GUILayout.EndHorizontal(); } private void ApplyActiveTab(bool closeAfterApply) { if (adminTab == 0) { SaveConfigFromUi(); } else { MarkSelectedDiscoveryPortal(GetSelectedPortalRoleValue()); } if (closeAfterApply) { showAdminWindow = false; } } private void ToggleAdminWindow() { if (!adminStatusKnown) { openAdminUiAfterPermissionCheck = true; RequestConfig(openUi: false); ShowMessage("Checking portal limit permissions..."); return; } if (!isAdmin) { showAdminWindow = false; RequestCountForChat(); return; } showAdminWindow = !showAdminWindow; openDropdown = string.Empty; if (showAdminWindow) { RequestConfig(openUi: true); RequestCount(); CenterAdminWindowIfNeeded(); } } private void OpenAdminWindowForPortal(TeleportWorld portal) { SelectPortalForEditing(portal, showStatus: false); showAdminWindow = true; openDropdown = string.Empty; adminTab = 1; statusMessage = "Portal selected. Choose what this portal should do, then Apply or Apply & Close."; CenterAdminWindowIfNeeded(); RequestConfig(openUi: true); RequestCount(); } private void SaveConfigFromUi() { if (!int.TryParse(maxText, out var result)) { statusMessage = "Max portals must be a whole number."; return; } string text = "max=" + Math.Max(0, result) + "\nadminBypass=" + adminBypass + "\nenforceOnServer=" + enforceOnServer + "\nportalPrefabNames=" + Escape(portalNamesText) + "\ndiscoveryEnabled=" + discoveryEnabled + "\ndiscoveryAdminBypass=" + discoveryAdminBypass + "\nadminHoldEToEdit=" + adminHoldEToEdit + "\nshowDiscoveryHoverText=" + showDiscoveryHoverText + "\ndiscoveryLockedHoverText=" + Escape(discoveryLockedHoverTextField) + "\ndiscoveryRemoteHoverText=" + Escape(discoveryRemoteHoverTextField) + "\ndiscoveryUnlockedHoverText=" + Escape(discoveryUnlockedHoverTextField) + "\ndiscoveryLockedMessage=" + Escape(discoveryLockedMessageField) + "\ndiscoveryUnlockMessage=" + Escape(discoveryUnlockMessageField) + "\ndiscoveryShowWorldMarker=" + discoveryShowWorldMarker + "\ndiscoveryTintPortalModel=" + discoveryTintPortalModel + "\ndiscoverySuppressLockedGlow=" + discoverySuppressLockedGlow + "\ndiscoveryLockedColor=" + Escape(discoveryLockedColorField) + "\ndiscoveryRemoteColor=" + Escape(discoveryRemoteColorField) + "\ndiscoveryUnlockedColor=" + Escape(discoveryUnlockedColorField); ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.config_update", new object[1] { text }); statusMessage = "Saving portal limit settings..."; } private void RequestConfig(bool openUi) { configRequested = true; if (openUi) { statusMessage = "Loading portal limit settings..."; } ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.config_request", new object[1] { (openUi ? string.Empty : "[silent]") + GetPlayerName() }); RequestUnlockList(); } private void RequestCount() { long localPlayerId = GetLocalPlayerId(); if (localPlayerId != 0) { ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.count_request", new object[1] { localPlayerId }); } } private void RequestCountForChat() { showCountMessageOnNextResponse = true; RequestCount(); ShowMessage("Checking portal count..."); } private void RequestPlacementCountSoon() { ((MonoBehaviour)this).StartCoroutine(RequestPlacementCountNextFrame()); } private IEnumerator RequestPlacementCountNextFrame() { yield return (object)new WaitForSeconds(0.35f); long playerId = GetLocalPlayerId(); int count = CountPortals(playerId); string maxText = ((maxPortalsPerPlayer > 0) ? maxPortalsPerPlayer.ToString() : "unlimited"); serverPortalCount = count; ShowMessage("Portals placed: " + count + " / " + maxText); RequestCount(); } private void RequestUnlockList() { long localPlayerId = GetLocalPlayerId(); if (localPlayerId != 0) { ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.discovery_unlock_list_request", new object[1] { localPlayerId }); } } private void RequestPortalInformation(bool showStatus) { TeleportWorld val = GetSelectedPortal(); if ((Object)(object)val == (Object)null) { portalInfoThisText = "No portal was opened."; portalInfoWorldText = "Open this tab while editing a portal."; return; } ZNetView component = ((Component)val).GetComponent(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); portalInfoRequestedPortalKey = ((val2 != null) ? ((object)(ZDOID)(ref val2.m_uid)).ToString() : GetPortalKey(val)); portalInfoThisText = "Loading authoritative portal information from the server..."; string portalTagForUi = GetPortalTagForUi(val); if (ZRoutedRpc.instance == null) { portalInfoWorldText = "Portal Limit server RPC is not ready yet."; return; } if (showStatus) { statusMessage = "Loading portal information..."; } ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.admin_report_request", new object[1] { "portalinfo|" + Escape(portalTagForUi) + "|" + Escape(portalInfoRequestedPortalKey) }); } private static void OnConfigResponse(long sender, string payload) { Instance.ApplyConfigPayload(payload); } private static void OnCountResponse(long sender, int count, int max, bool limitReached, string payload) { Instance.serverPortalCount = count; Instance.maxPortalsPerPlayer = max; Instance.ApplyConfigPayload(payload); if (Instance.showPlacementCountOnNextResponse) { Instance.showPlacementCountOnNextResponse = false; string text = ((max > 0) ? max.ToString() : "unlimited"); Instance.ShowMessage("Portals placed: " + count + " / " + text); } else if (Instance.showCountMessageOnNextResponse) { Instance.showCountMessageOnNextResponse = false; string text = ((max > 0) ? max.ToString() : "unlimited"); Instance.ShowMessage("Portals: " + count + " / " + text); } } private static void OnNotice(long sender, string message) { Instance.ShowMessage(message); } private static void OnDiscoveryUnlockListResponse(long sender, string payload) { Instance.ApplyUnlockPayload(payload); } private static void OnAdminReportResponse(long sender, string payload) { if (string.IsNullOrWhiteSpace(payload)) { Terminal.Log((object)"Portal Limit: empty report."); return; } if ((Object)(object)Instance != (Object)null && payload.StartsWith("PortalInfoResponse\n", StringComparison.Ordinal)) { Instance.ApplyPortalInformationPayload(payload); return; } string[] array = payload.Split(new char[1] { '\n' }); foreach (string text in array) { Terminal.Log((object)text); } if ((Object)(object)Instance != (Object)null) { Instance.ShowMessage("Portal Limit report written to F5 console."); } } private void ApplyPortalInformationPayload(string payload) { string text = payload.Substring("PortalInfoResponse\n".Length); string[] array = text.Split(new string[1] { "\n---WORLD---\n" }, StringSplitOptions.None); if (array.Length > 0 && !string.IsNullOrWhiteSpace(array[0])) { portalInfoThisText = array[0].Trim(); } portalInfoWorldText = ((array.Length > 1) ? array[1].Trim() : text.Trim()); statusMessage = "Portal information loaded."; } private void ApplyConfigPayload(string payload) { Dictionary dictionary = ParsePayload(payload); if (dictionary.TryGetValue("isAdmin", out var value) && bool.TryParse(value, out var result)) { isAdmin = result; adminStatusKnown = true; if (!isAdmin) { showAdminWindow = false; } if (openAdminUiAfterPermissionCheck) { openAdminUiAfterPermissionCheck = false; if (isAdmin) { showAdminWindow = true; openDropdown = string.Empty; CenterAdminWindowIfNeeded(); RequestConfig(openUi: true); RequestCount(); } else { RequestCountForChat(); } } } if (dictionary.TryGetValue("max", out value) && int.TryParse(value, out var result2)) { maxPortalsPerPlayer = result2; maxText = result2.ToString(); } if (dictionary.TryGetValue("adminBypass", out value) && bool.TryParse(value, out result)) { adminBypass = result; } if (dictionary.TryGetValue("enforceOnServer", out value) && bool.TryParse(value, out result)) { enforceOnServer = result; } if (dictionary.TryGetValue("portalPrefabNames", out value)) { portalPrefabNames = value; portalNamesText = value; } if (dictionary.TryGetValue("discoveryEnabled", out value) && bool.TryParse(value, out result)) { discoveryEnabled = result; } if (dictionary.TryGetValue("discoveryAdminBypass", out value) && bool.TryParse(value, out result)) { discoveryAdminBypass = result; } if (dictionary.TryGetValue("adminHoldEToEdit", out value) && bool.TryParse(value, out result)) { adminHoldEToEdit = result; } if (dictionary.TryGetValue("showDiscoveryHoverText", out value) && bool.TryParse(value, out result)) { showDiscoveryHoverText = result; } if (dictionary.TryGetValue("discoveryLockedHoverText", out value)) { discoveryLockedHoverText = value; discoveryLockedHoverTextField = value; } if (dictionary.TryGetValue("discoveryRemoteHoverText", out value)) { discoveryRemoteHoverText = value; discoveryRemoteHoverTextField = value; } if (dictionary.TryGetValue("discoveryUnlockedHoverText", out value)) { discoveryUnlockedHoverText = value; discoveryUnlockedHoverTextField = value; } if (dictionary.TryGetValue("discoveryLockedMessage", out value)) { discoveryLockedMessage = value; discoveryLockedMessageField = value; } if (dictionary.TryGetValue("discoveryUnlockMessage", out value)) { discoveryUnlockMessage = value; discoveryUnlockMessageField = value; } if (dictionary.TryGetValue("discoveryShowWorldMarker", out value) && bool.TryParse(value, out result)) { discoveryShowWorldMarker = result; } if (dictionary.TryGetValue("discoveryTintPortalModel", out value) && bool.TryParse(value, out result)) { discoveryTintPortalModel = result; } if (dictionary.TryGetValue("discoverySuppressLockedGlow", out value) && bool.TryParse(value, out result)) { discoverySuppressLockedGlow = result; } if (dictionary.TryGetValue("discoveryLockedColor", out value)) { discoveryLockedColor = value; discoveryLockedColorField = value; } if (dictionary.TryGetValue("discoveryRemoteColor", out value)) { discoveryRemoteColor = value; discoveryRemoteColorField = value; } if (dictionary.TryGetValue("discoveryUnlockedColor", out value)) { discoveryUnlockedColor = value; discoveryUnlockedColorField = value; } if (dictionary.TryGetValue("message", out value) && !string.IsNullOrWhiteSpace(value)) { statusMessage = value; ShowMessage(value); } } private void ApplyUnlockPayload(string payload) { Dictionary dictionary = ParsePayload(payload); unlockedDiscoveryLinks.Clear(); if (dictionary.TryGetValue("links", out var value)) { string[] array = value.Split(new char[1] { ';' }); foreach (string text in array) { string text2 = text.Trim(); if (!string.IsNullOrWhiteSpace(text2)) { unlockedDiscoveryLinks.Add(text2); } } } if (dictionary.TryGetValue("message", out var value2) && !string.IsNullOrWhiteSpace(value2)) { ShowMessage(value2); } } private void MarkSelectedDiscoveryPortal(int role) { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) TeleportWorld val = GetSelectedPortal(); if ((Object)(object)val == (Object)null) { statusMessage = "No portal selected. Look at a portal and click Select first."; return; } ZNetView component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { statusMessage = "That portal has no valid network view."; return; } string text = discoveryLinkText.Trim(); bool flag = CanEditPortalTag(val); if (!flag) { text = GetPortalTagForUi(val).Trim(); } if (role != 0 && string.IsNullOrWhiteSpace(text)) { statusMessage = "Enter a portal tag first."; return; } discoveryLinkText = text; if (flag) { SetPortalTag(val, text); } string text2 = ((role == 0) ? string.Empty : text); string normalized = string.Empty; string text3 = string.Empty; if (role != 0) { if (!TryNormalizeHexColor(selectedPortalColorText, out normalized)) { statusMessage = "Enter a color like #ff3030."; return; } selectedPortalColorText = normalized; text3 = NormalizeMarkerTextValue(selectedPortalMarkerText); } string text4 = "role=" + role + "\nlink=" + Escape(text2) + "\nmarkerColor=" + Escape(normalized) + "\nmarkerText=" + Escape(text3) + "\nshowMarker=" + selectedPortalShowMarker + "\nsuppressGlow=" + selectedPortalSuppressGlow + "\nlockedHoverText=" + Escape(selectedLockedHoverText) + "\nremoteHoverText=" + Escape(selectedRemoteHoverText) + "\nunlockedHoverText=" + Escape(selectedUnlockedHoverText); ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.discovery_mark_request", new object[2] { component.GetZDO().m_uid, text4 }); ApplyLocalPortalMarker(val, role, text2, normalized, text3, selectedPortalShowMarker, selectedPortalSuppressGlow, selectedLockedHoverText, selectedRemoteHoverText, selectedUnlockedHoverText); statusMessage = "Portal settings saved."; Log.LogInfo((object)("Sent discovery portal marker request role=" + role + " tag='" + text + "' portal=" + component.GetZDO().m_uid)); } private void RelockSelectedDiscoveryPortal() { RelockDiscoveryPortalTag(discoveryLinkText); } private void RelockDiscoveryPortalTag(string portalTagText) { string text = (portalTagText ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(text)) { statusMessage = "Enter a portal tag first."; return; } ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.discovery_relock_request", new object[1] { text }); unlockedDiscoveryLinks.Remove(text); statusMessage = "Relock request sent for portal tag '" + text + "'."; } private void ReadSelectedPortalSettings() { TeleportWorld val = GetSelectedPortal(); if ((Object)(object)val == (Object)null) { statusMessage = "No portal selected. Look at a portal and click Select first."; } else { LoadPortalSettings(val, showStatus: true); } } private string BuildLocalPortalInformation(TeleportWorld portal) { if ((Object)(object)portal == (Object)null) { return "THIS PORTAL\nNo portal selected."; } ZNetView component = ((Component)portal).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString("PortalLimit_BuiltUtc", string.Empty) : string.Empty); string text2 = GetPortalCreatorName(portal); if (string.IsNullOrWhiteSpace(text2)) { text2 = "unknown"; } string text3 = GetPortalTagForUi(portal); if (string.IsNullOrWhiteSpace(text3)) { text3 = "(none)"; } string text4 = (string.IsNullOrWhiteSpace(text) ? "unknown for older portals" : text); return "THIS PORTAL\nPortal Tag: " + text3 + "\nPlayer Who Built the Portal: " + text2 + "\nDate the portal was built: " + text4 + "\nPortal role: " + GetPortalRoleLabel(GetDiscoveryRole(portal)) + "\nPortal id: " + ((val != null) ? ((object)(ZDOID)(ref val.m_uid)).ToString() : "unknown"); } private void SelectPortalForEditing(TeleportWorld portal, bool showStatus) { if ((Object)(object)portal == (Object)null) { if (showStatus) { statusMessage = "Look directly at a portal first."; } } else { selectedPortal = portal; LoadPortalSettings(portal, showStatus); } } private TeleportWorld GetSelectedPortal() { if ((Object)(object)selectedPortal != (Object)null) { ZNetView component = ((Component)selectedPortal).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { return selectedPortal; } } selectedPortal = null; loadedPortalKey = string.Empty; return null; } private void LoadPortalSettings(TeleportWorld portal, bool showStatus) { selectedPortalRole = GetDiscoveryRole(portal) switch { 2 => 2, 1 => 1, _ => 0, }; string discoveryLink = GetDiscoveryLink(portal); if (!string.IsNullOrWhiteSpace(discoveryLink)) { discoveryLinkText = discoveryLink; } else { string portalTag = GetPortalTag(portal); if (!string.IsNullOrWhiteSpace(portalTag)) { discoveryLinkText = portalTag; } } loadedPortalKey = GetPortalKey(portal); selectedPortalColorText = GetDiscoveryColor(portal); if (string.IsNullOrWhiteSpace(selectedPortalColorText)) { selectedPortalColorText = MarkerColorValues[0]; } selectedPortalColorIndex = GetMarkerColorIndex(selectedPortalColorText); selectedPortalMarkerText = GetDiscoveryMarkerText(portal); selectedPortalMarkerTextIndex = GetMarkerTextIndex(selectedPortalMarkerText); selectedPortalShowMarker = GetDiscoveryShowMarker(portal); selectedPortalSuppressGlow = GetDiscoverySuppressGlow(portal); selectedLockedHoverText = GetDiscoveryHoverOverride(portal, "PortalLimit_DiscoveryLockedHoverText"); selectedRemoteHoverText = GetDiscoveryHoverOverride(portal, "PortalLimit_DiscoveryRemoteHoverText"); selectedUnlockedHoverText = GetDiscoveryHoverOverride(portal, "PortalLimit_DiscoveryUnlockedHoverText"); if (showStatus) { statusMessage = "Selected portal loaded. Choose what this portal does, then Apply."; } } private static void ApplyLocalPortalMarker(TeleportWorld portal, int role, string link, string markerColor, string markerText, bool showMarker, bool suppressGlow, string lockedHoverText, string remoteHoverText, string unlockedHoverText) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 != null) { val2.Set("PortalLimit_DiscoveryRole", role); val2.Set("PortalLimit_DiscoveryLink", (role == 0) ? string.Empty : link); val2.Set("PortalLimit_DiscoveryColor", (role == 0) ? string.Empty : markerColor); val2.Set("PortalLimit_DiscoveryMarkerText", (role == 0) ? string.Empty : NormalizeMarkerTextValue(markerText)); val2.Set("PortalLimit_DiscoveryShowMarker", (role != 0) ? (showMarker ? 1 : 0) : 0); val2.Set("PortalLimit_DiscoverySuppressGlow", (role != 0) ? (suppressGlow ? 1 : 0) : 0); val2.Set("PortalLimit_DiscoveryLockedHoverText", (role == 0) ? string.Empty : (lockedHoverText ?? string.Empty).Trim()); val2.Set("PortalLimit_DiscoveryRemoteHoverText", (role == 0) ? string.Empty : (remoteHoverText ?? string.Empty).Trim()); val2.Set("PortalLimit_DiscoveryUnlockedHoverText", (role == 0) ? string.Empty : (unlockedHoverText ?? string.Empty).Trim()); } } private int GetSelectedPortalRoleValue() { if (selectedPortalRole == 1) { return 1; } if (selectedPortalRole == 2) { return 2; } return 0; } private static string GetPortalRoleLabel(int role) { return role switch { 1 => "Locked entrance", 2 => "Unlocked entrance", _ => "Normal portal", }; } private static TeleportWorld GetHoveredPortal() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return null; } GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return null; } TeleportWorld val = hoverObject.GetComponent(); if ((Object)(object)val == (Object)null) { val = hoverObject.GetComponentInParent(); } return val; } private static string GetPortalKey(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? ((object)(ZDOID)(ref val2.m_uid)).ToString() : string.Empty; } private static string GetPortalCreatorName(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 == null) { return string.Empty; } string @string = val2.GetString(ZDOVars.s_creatorName, string.Empty); return @string ?? string.Empty; } private static bool CanEditPortalTag(TeleportWorld portal) { if ((Object)(object)Instance == (Object)null || (Object)(object)portal == (Object)null) { return false; } Piece val = ((Component)portal).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)portal).GetComponentInParent(); } if ((Object)(object)val == (Object)null) { return true; } long creator = val.GetCreator(); long localPlayerId = GetLocalPlayerId(); return creator == 0 || creator == localPlayerId; } private static string GetPortalTag(TeleportWorld portal) { MethodInfo methodInfo = AccessTools.Method(typeof(TeleportWorld), "GetText", (Type[])null, (Type[])null); if ((Object)(object)portal != (Object)null && methodInfo != null) { object obj = methodInfo.Invoke(portal, null); if (obj != null) { return obj.ToString(); } } return string.Empty; } private static string GetPortalTagForUi(TeleportWorld portal) { string discoveryLink = GetDiscoveryLink(portal); if (!string.IsNullOrWhiteSpace(discoveryLink)) { return discoveryLink; } return GetPortalTag(portal); } private static void SetPortalTag(TeleportWorld portal, string tag) { if ((Object)(object)portal == (Object)null) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(TeleportWorld), "SetText", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(portal, new object[1] { tag ?? string.Empty }); return; } ZNetView component = ((Component)portal).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null) { val.Set("tag", tag ?? string.Empty); } } private static void SetTargetFound(TeleportWorld portal, bool value) { if ((Object)(object)portal != (Object)null && TeleportWorldTargetFoundField != null) { TeleportWorldTargetFoundField.SetValue(portal, value); } } private static int GetDiscoveryRole(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? val2.GetInt("PortalLimit_DiscoveryRole", 0) : 0; } private static string GetDiscoveryLink(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? val2.GetString("PortalLimit_DiscoveryLink", string.Empty) : string.Empty; } private static string GetDiscoveryColor(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? val2.GetString("PortalLimit_DiscoveryColor", string.Empty) : string.Empty; } private static string GetDiscoveryMarkerText(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? NormalizeMarkerTextValue(val2.GetString("PortalLimit_DiscoveryMarkerText", string.Empty)) : MarkerTextValues[0]; } private bool GetDiscoveryShowMarker(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? (val2.GetInt("PortalLimit_DiscoveryShowMarker", discoveryShowWorldMarker ? 1 : 0) != 0) : discoveryShowWorldMarker; } private bool GetDiscoverySuppressGlow(TeleportWorld portal) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? (val2.GetInt("PortalLimit_DiscoverySuppressGlow", discoverySuppressLockedGlow ? 1 : 0) != 0) : discoverySuppressLockedGlow; } private static string GetDiscoveryHoverOverride(TeleportWorld portal, string key) { ZNetView val = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); return (val2 != null) ? val2.GetString(key, string.Empty) : string.Empty; } private Color GetDiscoveryVisualColor(TeleportWorld portal) { //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_0020: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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) string discoveryColor = GetDiscoveryColor(portal); if (!string.IsNullOrWhiteSpace(discoveryColor)) { return ParseHexColor(discoveryColor, LockedOrange); } int discoveryRole = GetDiscoveryRole(portal); string discoveryLink = GetDiscoveryLink(portal); if (discoveryRole != 0 && !string.IsNullOrWhiteSpace(discoveryLink) && IsDiscoveryUnlocked(discoveryLink)) { return ParseHexColor(discoveryUnlockedColor, Color.green); } if (discoveryRole == 2) { return ParseHexColor(discoveryRemoteColor, Color.cyan); } return ParseHexColor(discoveryLockedColor, LockedOrange); } private bool ShouldShowDiscoveryWorldMarker(TeleportWorld portal) { return discoveryEnabled && GetDiscoveryShowMarker(portal) && ShouldShowLockedEntranceX(portal); } private string GetDiscoveryMarkerDisplayText(TeleportWorld portal) { string discoveryMarkerText = GetDiscoveryMarkerText(portal); if (string.Equals(discoveryMarkerText, "Locked", StringComparison.OrdinalIgnoreCase)) { return "LOCKED"; } if (string.Equals(discoveryMarkerText, "X", StringComparison.OrdinalIgnoreCase)) { return "X"; } if (string.Equals(discoveryMarkerText, "UnlockOnOtherSide", StringComparison.OrdinalIgnoreCase)) { return "UNLOCK ON OTHER SIDE"; } return string.IsNullOrWhiteSpace(discoveryMarkerText) ? "UNLOCK ON OTHER SIDE" : discoveryMarkerText; } private bool ShouldShowLockedEntranceX(TeleportWorld portal) { if (GetDiscoveryRole(portal) != 1) { return false; } string discoveryLink = GetDiscoveryLink(portal); return !string.IsNullOrWhiteSpace(discoveryLink) && !IsDiscoveryUnlocked(discoveryLink); } private bool ShouldTintDiscoveryPortal(TeleportWorld portal) { return false; } private bool ShouldSuppressLockedPortalGlow(TeleportWorld portal) { if (!discoveryEnabled || !GetDiscoverySuppressGlow(portal) || GetDiscoveryRole(portal) != 1) { return false; } string discoveryLink = GetDiscoveryLink(portal); return !string.IsNullOrWhiteSpace(discoveryLink) && !IsDiscoveryUnlocked(discoveryLink); } private static Color ParseHexColor(string text, Color fallback) { //IL_0011: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(text)) { return fallback; } string text2 = text.Trim(); if (text2.StartsWith("#", StringComparison.Ordinal)) { text2 = text2.Substring(1); } if (text2.Length == 6 && int.TryParse(text2.Substring(0, 2), NumberStyles.HexNumber, null, out var result) && int.TryParse(text2.Substring(2, 2), NumberStyles.HexNumber, null, out var result2) && int.TryParse(text2.Substring(4, 2), NumberStyles.HexNumber, null, out var result3)) { return new Color((float)result / 255f, (float)result2 / 255f, (float)result3 / 255f, 1f); } return fallback; } private static string NormalizeHexColor(string text, string fallback) { string text2 = (text ?? string.Empty).Trim(); if (!text2.StartsWith("#", StringComparison.Ordinal)) { text2 = "#" + text2; } Color val = default(Color); return ColorUtility.TryParseHtmlString(text2, ref val) ? text2 : fallback; } private static bool TryNormalizeHexColor(string text, out string normalized) { normalized = (text ?? string.Empty).Trim(); if (!normalized.StartsWith("#", StringComparison.Ordinal)) { normalized = "#" + normalized; } Color val = default(Color); if (normalized.Length == 7 && ColorUtility.TryParseHtmlString(normalized, ref val)) { return true; } normalized = string.Empty; return false; } private static int GetMarkerColorIndex(string color) { string a = NormalizeHexColor(color, MarkerColorValues[0]); for (int i = 0; i < MarkerColorValues.Length; i++) { if (string.Equals(a, MarkerColorValues[i], StringComparison.OrdinalIgnoreCase)) { return i; } } return 0; } private static string NormalizeMarkerTextValue(string value) { string text = (value ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(text)) { return MarkerTextLabels[0]; } for (int i = 0; i < MarkerTextValues.Length; i++) { if (string.Equals(text, MarkerTextValues[i], StringComparison.OrdinalIgnoreCase) || string.Equals(text, MarkerTextLabels[i], StringComparison.OrdinalIgnoreCase)) { return MarkerTextLabels[i]; } } return text; } private static int GetMarkerTextIndex(string value) { string a = NormalizeMarkerTextValue(value); for (int i = 0; i < MarkerTextValues.Length; i++) { if (string.Equals(a, MarkerTextValues[i], StringComparison.OrdinalIgnoreCase) || string.Equals(a, MarkerTextLabels[i], StringComparison.OrdinalIgnoreCase)) { return i; } } return 0; } private bool IsDiscoveryUnlocked(string link) { if (string.IsNullOrWhiteSpace(link)) { return false; } return unlockedDiscoveryLinks.Contains(link); } private void UnlockDiscoveryLink(string link, TeleportWorld portal) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0099: 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) if (!string.IsNullOrWhiteSpace(link)) { unlockedDiscoveryLinks.Add(link); long localPlayerId = GetLocalPlayerId(); if (localPlayerId != 0 && ZRoutedRpc.instance != null) { Vector3 val = (((Object)(object)portal != (Object)null) ? ((Component)portal).transform.position : Vector3.zero); ZNetView val2 = (((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null); ZDOID val3 = (((Object)(object)val2 != (Object)null && val2.IsValid()) ? val2.GetZDO().m_uid : ZDOID.None); string text = "link=" + Escape(link.Trim()) + "\nplayerName=" + Escape(GetPlayerName()) + "\nportalId=" + Escape(((object)(ZDOID)(ref val3)).ToString()) + "\nx=" + val.x.ToString("F1") + "\ny=" + val.y.ToString("F1") + "\nz=" + val.z.ToString("F1"); ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.discovery_unlock_request", new object[2] { localPlayerId, text }); } } } private static bool ShouldBlockPortalUse(TeleportWorld portal) { if ((Object)(object)Instance == (Object)null || !Instance.discoveryEnabled || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } int discoveryRole = GetDiscoveryRole(portal); if (discoveryRole == 0) { return false; } string discoveryLink = GetDiscoveryLink(portal); if (string.IsNullOrWhiteSpace(discoveryLink)) { return false; } if (Instance.discoveryAdminBypass && Instance.isAdmin) { return false; } switch (discoveryRole) { case 2: if (!Instance.IsDiscoveryUnlocked(discoveryLink)) { Instance.UnlockDiscoveryLink(discoveryLink, portal); Instance.ShowMessage(Instance.discoveryUnlockMessage); } return false; case 1: if (!Instance.IsDiscoveryUnlocked(discoveryLink)) { Instance.ShowMessage(Instance.discoveryLockedMessage); Instance.RequestUnlockList(); return true; } break; } return false; } private static bool ShouldBlockBlankPortalUse(TeleportWorld portal) { if ((Object)(object)Instance == (Object)null || (Object)(object)portal == (Object)null) { return false; } if (string.IsNullOrWhiteSpace(GetPortalTag(portal))) { Instance.ShowMessage("Set a portal tag first."); return true; } return false; } internal static bool WouldExceedPortalLimit(Piece piece) { PortalLimitClientPlugin instance = Instance; if ((Object)(object)instance == (Object)null || (Object)(object)piece == (Object)null || !instance.IsLimitedPortal(piece)) { return false; } if (instance.maxPortalsPerPlayer <= 0) { return false; } if (instance.adminBypass && instance.isAdmin) { return false; } long localPlayerId = GetLocalPlayerId(); int num = instance.CountPortals(localPlayerId); return num >= instance.maxPortalsPerPlayer; } private bool IsLimitedPortal(Piece piece) { if ((Object)(object)piece == (Object)null || (Object)(object)((Component)piece).GetComponent() == (Object)null) { return false; } HashSet portalPrefabNameSet = GetPortalPrefabNameSet(); if (portalPrefabNameSet.Count == 0) { return true; } ZNetView component = ((Component)piece).GetComponent(); string prefabName = GetPrefabName(component, piece); return portalPrefabNameSet.Contains(prefabName); } private void ReportPortalMetadata(Piece piece, string action) { //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) if (!((Object)(object)piece == (Object)null) && IsLimitedPortal(piece) && ZRoutedRpc.instance != null) { ZNetView component = ((Component)piece).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null) { Vector3 position = ((Component)piece).transform.position; string text = "action=" + Escape(action) + "\nportalId=" + Escape(((object)(ZDOID)(ref val.m_uid)).ToString()) + "\nplayerId=" + GetLocalPlayerId() + "\nplayerName=" + Escape(GetPlayerName()) + "\nx=" + position.x.ToString("F1") + "\ny=" + position.y.ToString("F1") + "\nz=" + position.z.ToString("F1"); ZRoutedRpc.instance.InvokeRoutedRPC("keith.valheim.portallimit.portal_metadata_update", new object[1] { text }); } } } private void ReportPortalMetadata(TeleportWorld portal, string action) { if (!((Object)(object)portal == (Object)null)) { Piece val = ((Component)portal).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)portal).GetComponentInParent(); } ReportPortalMetadata(val, action); } } private static string GetPrefabName(ZNetView nview, Piece piece) { if ((Object)(object)nview != (Object)null && GetPrefabNameMethod != null) { object obj = GetPrefabNameMethod.Invoke(nview, null); if (obj != null) { return obj.ToString(); } } return ((Object)(object)piece != (Object)null) ? ((Object)piece).name.Replace("(Clone)", string.Empty) : string.Empty; } private int CountPortals(long creatorId) { if (creatorId == 0 || AllPiecesField == null) { return serverPortalCount; } int num = 0; if (!(AllPiecesField.GetValue(null) is IEnumerable enumerable)) { return serverPortalCount; } foreach (object item in enumerable) { Piece val = (Piece)((item is Piece) ? item : null); if ((Object)(object)val != (Object)null && val.GetCreator() == creatorId && IsLimitedPortal(val)) { num++; } } return num; } private HashSet GetPortalPrefabNameSet() { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = portalPrefabNames.Split(new char[1] { ',' }); foreach (string text in array) { string text2 = text.Trim(); if (!string.IsNullOrWhiteSpace(text2)) { hashSet.Add(text2); } } return hashSet; } private static long GetLocalPlayerId() { try { if ((Object)(object)Player.m_localPlayer != (Object)null && GetPlayerIdMethod != null) { object obj = GetPlayerIdMethod.Invoke(Player.m_localPlayer, null); if (obj != null && obj.GetType() == typeof(long)) { return (long)obj; } } } catch (Exception ex) { Log.LogWarning((object)("Could not read local player ID: " + ex.Message)); } return 0L; } private static string GetPlayerName() { return ((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerName() : "unknown-player"; } internal void ShowMessage(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false); } else { Log.LogMessage((object)message); } } private static Dictionary ParsePayload(string payload) { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrEmpty(payload)) { return dictionary; } string[] array = payload.Split(new char[1] { '\n' }); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0) { dictionary[text.Substring(0, num)] = Unescape(text.Substring(num + 1)); } } return dictionary; } private static string Escape(string value) { return (value ?? string.Empty).Replace("\\", "\\\\").Replace("\n", "\\n").Replace("=", "\\e"); } private static string Unescape(string value) { return (value ?? string.Empty).Replace("\\e", "=").Replace("\\n", "\n").Replace("\\\\", "\\"); } }