using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Splatform; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TargetPortalProtectionRewamped")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TargetPortalProtectionRewamped")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("de68470c-68b8-40d0-9a09-eeb9170beaaa")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace TargetPortalProtection; internal static class PortalProtectionLogic { [HarmonyPatch(typeof(ZRoutedRpc), "InvokeRoutedRPC", new Type[] { typeof(long), typeof(string), typeof(object[]) })] internal static class TP_BlockChangeModeRpc { private static bool Prefix(string methodName, object[] parameters) { if (!PortalProtectionEnabled()) { return true; } if (methodName != "TargetPortals ChangePortalMode" || parameters == null || parameters.Length == 0) { return true; } ZNetView val = FindNviewFromZdoid(parameters[0]); if ((Object)(object)val == (Object)null || !val.IsValid() || !IsTargetPortal(val)) { return true; } if (!CanModifyPortal(val, out var reason)) { LogDebug("Blocked portal mode change: " + reason); Center(Player.m_localPlayer, "$tweaks_portal_protected"); return false; } TryStoreGuildIdOnPortal(val, "ChangeMode RPC after permission"); return true; } } [HarmonyPatch(typeof(WearNTear), "Damage")] internal static class TP_Indestructible_NoDamage { private static bool Prefix(WearNTear __instance) { if (!PortalProtectionEnabled()) { return true; } TeleportWorld component = ((Component)__instance).GetComponent(); ZNetView portalNView = GetPortalNView(component); if ((Object)(object)component == (Object)null || (Object)(object)portalNView == (Object)null || !portalNView.IsValid() || !IsTargetPortal(portalNView)) { return true; } TryStoreGuildIdOnPortal(portalNView, "WearNTear.Damage"); if (CanModifyPortal(portalNView, out var _)) { return true; } LogDebug("Blocked portal damage"); return false; } } [HarmonyPatch(typeof(WearNTear), "Remove")] internal static class TP_Indestructible_NoRemove { private static bool Prefix(WearNTear __instance) { if (!PortalProtectionEnabled()) { return true; } TeleportWorld component = ((Component)__instance).GetComponent(); ZNetView portalNView = GetPortalNView(component); if ((Object)(object)component == (Object)null || (Object)(object)portalNView == (Object)null || !portalNView.IsValid() || !IsTargetPortal(portalNView)) { return true; } TryStoreGuildIdOnPortal(portalNView, "WearNTear.Remove"); if (CanModifyPortal(portalNView, out var _)) { return true; } LogDebug("Blocked portal remove"); return false; } } [HarmonyPatch(typeof(TeleportWorld), "Interact")] internal static class TP_CacheGuildIdOnPortalInteract { private static void Prefix(TeleportWorld __instance) { ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } ZDO zDO = component.GetZDO(); if (zDO == null) { return; } string @string = zDO.GetString("TargetPortal PortalOwnerId", ""); if (string.IsNullOrEmpty(@string)) { string text = ""; try { text = ((object)(PlatformUserID)(ref UserInfo.GetLocalUser().UserId)).ToString(); } catch { } if (!string.IsNullOrEmpty(text)) { zDO.Set("TargetPortal PortalOwnerId", text); LogDebug("Owner ID beállítva: " + text); } } TryStoreGuildIdOnPortal(component, "TeleportWorld.Interact"); } } [HarmonyPatch(typeof(PrivateArea), "CheckAccess")] internal static class TP_Terrain_PrivateArea { private static void Postfix(Vector3 point, bool flash, ref bool __result) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (TerrainProtectionEnabled() && __result && IsNearProtectedTargetPortal(point, out var reason)) { LogDebug("Blocked terrain access: " + reason); if (flash && (Object)(object)Player.m_localPlayer != (Object)null) { Center(Player.m_localPlayer, "$tweaks_portal_terrain"); } __result = false; } } } [HarmonyPatch(typeof(Location), "IsInsideNoBuildLocation")] internal static class TP_Terrain_NoBuildLocation { private static void Postfix(Vector3 point, ref bool __result) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (TerrainProtectionEnabled() && !__result && IsNearProtectedTargetPortal(point, out var reason)) { LogDebug("Blocked no-build check bypass: " + reason); __result = true; } } } [HarmonyPatch(typeof(TerrainComp), "ApplyOperation")] internal static class TP_Terrain_BlockTerraform { private static bool Prefix(TerrainOp modifier) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!TerrainProtectionEnabled() || (Object)(object)modifier == (Object)null) { return true; } if (IsNearProtectedTargetPortal(((Component)modifier).transform.position, out var reason)) { LogDebug("Blocked terraform operation: " + reason); Center(Player.m_localPlayer, "$tweaks_portal_terrain"); return false; } return true; } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] internal static class TP_BlockUnauthorizedTargetPortalClick { [HarmonyPriority(800)] private static bool Prefix() { if (!VisibilityProtectionEnabled()) { return true; } if (!IsTargetPortalTeleportActive()) { return true; } if (!TryGetClickedTargetPortalZdo(out var portalZdo)) { return true; } if (CanSeePortal(portalZdo, out var _)) { return true; } Center(Player.m_localPlayer, "$tweaks_portal_protected"); return false; } } [CompilerGenerated] private sealed class d__51 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private ZDO <>2__current; private int <>l__initialThreadId; private object 5__1; private Type 5__2; private BindingFlags 5__3; private FieldInfo[] 5__4; private HashSet 5__5; private FieldInfo[] <>s__6; private int <>s__7; private FieldInfo 5__8; private object 5__9; private IEnumerator <>s__10; private ZDO 5__11; ZDO IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__51(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; 5__4 = null; 5__5 = null; <>s__6 = null; 5__8 = null; 5__9 = null; <>s__10 = null; 5__11 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; 5__11 = null; goto IL_014b; } <>1__state = -1; if (ZDOMan.instance == null) { return false; } 5__1 = ZDOMan.instance; 5__2 = 5__1.GetType(); 5__3 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 5__4 = 5__2.GetFields(5__3); 5__5 = new HashSet(); <>s__6 = 5__4; <>s__7 = 0; goto IL_0183; IL_014b: if (<>s__10.MoveNext()) { 5__11 = <>s__10.Current; <>2__current = 5__11; <>1__state = 1; return true; } <>m__Finally1(); <>s__10 = null; 5__9 = null; 5__8 = null; goto IL_0175; IL_0175: <>s__7++; goto IL_0183; IL_0183: if (<>s__7 < <>s__6.Length) { 5__8 = <>s__6[<>s__7]; 5__9 = null; try { 5__9 = 5__8.GetValue(5__1); } catch { goto IL_0175; } if (5__9 == null) { goto IL_0175; } <>s__10 = EnumerateZdosFromObject(5__9, 5__5).GetEnumerator(); <>1__state = -3; goto IL_014b; } <>s__6 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__10 != null) { <>s__10.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__51(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__52 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private ZDO <>2__current; private int <>l__initialThreadId; private object obj; public object <>3__obj; private HashSet seen; public HashSet <>3__seen; private ZDO 5__1; private IDictionary 5__2; private IEnumerable 5__3; private IDictionaryEnumerator <>s__4; private DictionaryEntry 5__5; private IEnumerator <>s__6; private ZDO 5__7; private IEnumerator <>s__8; private object 5__9; private IEnumerator <>s__10; private ZDO 5__11; ZDO IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__52(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; switch (num) { case -4: case -3: case 2: try { if (num == -4 || num == 2) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } break; case -6: case -5: case 3: try { if (num == -6 || num == 3) { try { } finally { <>m__Finally4(); } } } finally { <>m__Finally3(); } break; } 5__1 = null; 5__2 = null; 5__3 = null; <>s__4 = null; 5__5 = default(DictionaryEntry); <>s__6 = null; 5__7 = null; <>s__8 = null; 5__9 = null; <>s__10 = null; 5__11 = null; <>1__state = -2; } private bool MoveNext() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if (this.obj == null) { return false; } ref ZDO reference = ref 5__1; object obj = this.obj; reference = (ZDO)((obj is ZDO) ? obj : null); if (5__1 != null) { if (seen.Add(5__1.m_uid)) { <>2__current = 5__1; <>1__state = 1; return true; } goto IL_00b2; } 5__2 = this.obj as IDictionary; if (5__2 != null) { <>s__4 = 5__2.GetEnumerator(); <>1__state = -3; goto IL_01a3; } 5__3 = this.obj as IEnumerable; if (5__3 == null || this.obj is string) { break; } <>s__8 = 5__3.GetEnumerator(); <>1__state = -5; goto IL_02b3; } case 1: <>1__state = -1; goto IL_00b2; case 2: <>1__state = -4; 5__7 = null; goto IL_017b; case 3: { <>1__state = -6; 5__11 = null; goto IL_0290; } IL_0290: if (<>s__10.MoveNext()) { 5__11 = <>s__10.Current; <>2__current = 5__11; <>1__state = 3; return true; } <>m__Finally4(); <>s__10 = null; 5__9 = null; goto IL_02b3; IL_01a3: if (<>s__4.MoveNext()) { 5__5 = (DictionaryEntry)<>s__4.Current; <>s__6 = EnumerateZdosFromObject(5__5.Value, seen).GetEnumerator(); <>1__state = -4; goto IL_017b; } <>m__Finally1(); <>s__4 = null; return false; IL_017b: if (<>s__6.MoveNext()) { 5__7 = <>s__6.Current; <>2__current = 5__7; <>1__state = 2; return true; } <>m__Finally2(); <>s__6 = null; 5__5 = default(DictionaryEntry); goto IL_01a3; IL_00b2: return false; IL_02b3: if (<>s__8.MoveNext()) { 5__9 = <>s__8.Current; <>s__10 = EnumerateZdosFromObject(5__9, seen).GetEnumerator(); <>1__state = -6; goto IL_0290; } <>m__Finally3(); <>s__8 = null; return false; } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__4 is IDisposable disposable) { disposable.Dispose(); } } private void <>m__Finally2() { <>1__state = -3; if (<>s__6 != null) { <>s__6.Dispose(); } } private void <>m__Finally3() { <>1__state = -1; if (<>s__8 is IDisposable disposable) { disposable.Dispose(); } } private void <>m__Finally4() { <>1__state = -5; if (<>s__10 != null) { <>s__10.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__52 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__52(0); } d__.obj = <>3__obj; d__.seen = <>3__seen; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private const float DefaultTerrainProtectionRadius = 5f; private const float VisibilityPinMatchMaxDistance = 10f; private const float SearchRadiusPadding = 25f; private const string ZdoOwnerKey = "TargetPortal PortalOwnerId"; private const string ZdoModeKey = "TargetPortal PortalMode"; private const string ZdoGuildIdKey = "TargetPortal GuildId"; private const string RpcChangeMode = "TargetPortals ChangePortalMode"; private const string MsgProtected = "$tweaks_portal_protected"; private const string MsgTerrain = "$tweaks_portal_terrain"; private const int PortalModePublic = 0; private const int PortalModePrivate = 1; private const int PortalModeGroup = 2; private const int PortalModeAdmin = 3; private const int PortalModeGuild = 4; private static List _cachedPortalZdos; private static float _lastZdoCacheTime; private const float ZdoCacheLifetime = 0.5f; internal static void Init() { } private static ZNetView GetPortalNView(TeleportWorld portal) { return ((Object)(object)portal != (Object)null) ? ((Component)portal).GetComponent() : null; } private static bool PortalProtectionEnabled() { try { return TargetPortalProtectionPlugin.CE_PortalProtection_Enabled == null || TargetPortalProtectionPlugin.CE_PortalProtection_Enabled.Value; } catch { return true; } } private static bool TerrainProtectionEnabled() { try { return TargetPortalProtectionPlugin.CE_TerrainProtection_Enabled == null || TargetPortalProtectionPlugin.CE_TerrainProtection_Enabled.Value; } catch { return true; } } internal static bool VisibilityProtectionEnabled() { try { return TargetPortalProtectionPlugin.CE_VisibilityProtection_Enabled == null || TargetPortalProtectionPlugin.CE_VisibilityProtection_Enabled.Value; } catch { return true; } } private static float TerrainProtectionRadius() { try { return Mathf.Max(0f, (TargetPortalProtectionPlugin.CE_TerrainProtection_Radius != null) ? TargetPortalProtectionPlugin.CE_TerrainProtection_Radius.Value : 5f); } catch { return 5f; } } private static float SearchRadius() { return Mathf.Max(TerrainProtectionRadius(), TerrainProtectionRadius() + 25f); } private static bool DebugLoggingEnabled() { try { return TargetPortalProtectionPlugin.CE_DebugLogging_Enabled != null && TargetPortalProtectionPlugin.CE_DebugLogging_Enabled.Value; } catch { return false; } } private static bool AdminBypass() { try { return TargetPortalProtectionPlugin.CE_TargetPortalProtection_AdminBypass == null || TargetPortalProtectionPlugin.CE_TargetPortalProtection_AdminBypass.Value; } catch { return true; } } private static bool GuildIntegrationEnabled() { try { return TargetPortalProtectionPlugin.CE_GuildIntegration_Enabled == null || TargetPortalProtectionPlugin.CE_GuildIntegration_Enabled.Value; } catch { return true; } } private static bool AllowGuildMembersToModifyPortals() { try { return TargetPortalProtectionPlugin.CE_GuildIntegration_AllowGuildMembersToModifyPortals == null || TargetPortalProtectionPlugin.CE_GuildIntegration_AllowGuildMembersToModifyPortals.Value; } catch { return true; } } private static bool AllowGuildMembersToBypassTerrainProtection() { try { return TargetPortalProtectionPlugin.CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection != null && TargetPortalProtectionPlugin.CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection.Value; } catch { return false; } } private static bool StoreGuildIdOnPortal() { try { return TargetPortalProtectionPlugin.CE_GuildIntegration_StoreGuildIdOnPortal == null || TargetPortalProtectionPlugin.CE_GuildIntegration_StoreGuildIdOnPortal.Value; } catch { return true; } } private static bool RequireGuildRankForNonOwners() { try { return TargetPortalProtectionPlugin.CE_GuildIntegration_RequireRankForNonOwnerPortalModify != null && TargetPortalProtectionPlugin.CE_GuildIntegration_RequireRankForNonOwnerPortalModify.Value; } catch { return false; } } private static string AllowedGuildRanksForPortalModify() { try { return (TargetPortalProtectionPlugin.CE_GuildIntegration_AllowedRanksToModifyPortals != null) ? TargetPortalProtectionPlugin.CE_GuildIntegration_AllowedRanksToModifyPortals.Value : "leader,officer,coleader"; } catch { return "leader,officer,coleader"; } } private static void Center(Player player, string tokenOrText) { if ((Object)(object)player == (Object)null) { return; } string text = tokenOrText; try { if (TargetPortalProtectionPlugin.ModLocalization != null) { text = TargetPortalProtectionPlugin.ModLocalization.TryTranslate(tokenOrText); } } catch { text = tokenOrText; } ((Character)player).Message((MessageType)2, text, 0, (Sprite)null); } private static void LogDebug(string message) { if (DebugLoggingEnabled() && TargetPortalProtectionPlugin.Log != null) { TargetPortalProtectionPlugin.Log.LogInfo((object)message); } } private static string NormalizeOwnerId(string value) { return string.IsNullOrEmpty(value) ? string.Empty : value.Replace("Steam_", string.Empty); } private static string GetPortalDebugName(ZNetView nview) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)nview == (Object)null) { return ""; } string text = (((Object)(object)((Component)nview).gameObject != (Object)null) ? ((Object)((Component)nview).gameObject).name : ""); Vector3 val = (((Object)(object)((Component)nview).transform != (Object)null) ? ((Component)nview).transform.position : Vector3.zero); Vector3 val2 = val; return text + " @ " + ((object)(Vector3)(ref val2)).ToString(); } private static bool CanModifyPortal(ZNetView nview, out string reason) { LogDebug("[TPP] CanModifyPortal START: " + GetPortalDebugName(nview)); if (IsOwnerOrAdmin(nview, out reason)) { LogDebug("[TPP] CanModifyPortal -> OWNER/ADMIN TRUE: " + reason); return true; } LogDebug("[TPP] CanModifyPortal -> owner/admin FALSE: " + reason); if (!AllowGuildMembersToModifyPortals()) { reason = "guild portal modification is disabled for " + GetPortalDebugName(nview); LogDebug("[TPP] CanModifyPortal -> guild módosítás tiltva: " + reason); return false; } if (IsSameGuildAsPortal(nview, out var reason2)) { reason = reason2; LogDebug("[TPP] CanModifyPortal -> guild TRUE: " + reason); return true; } reason = reason2; LogDebug("[TPP] CanModifyPortal -> guild FALSE: " + reason); return false; } private static bool CanBypassTerrainProtection(ZNetView nview, out string reason) { if (IsOwnerOrAdmin(nview, out reason)) { return true; } if (!AllowGuildMembersToBypassTerrainProtection()) { reason = "guild terrain bypass is disabled for " + GetPortalDebugName(nview); return false; } if (IsSameGuildAsPortal(nview, out var reason2)) { reason = reason2; return true; } reason = reason2; return false; } private static bool IsOwnerOrAdmin(ZNetView nview, out string reason) { reason = "unknown owner/admin check result"; if ((Object)(object)nview == (Object)null || !nview.IsValid()) { reason = "portal nview is missing or invalid"; LogDebug("[TPP] IsOwnerOrAdmin FALSE: " + reason); return false; } if (AdminBypass() && TargetPortalProtectionPlugin.IsLocalPlayerAdmin()) { reason = "player is admin and AdminBypass is enabled"; LogDebug("[TPP] IsOwnerOrAdmin TRUE: " + reason); return true; } ZDO zDO = nview.GetZDO(); if (zDO == null) { reason = "portal ZDO is null"; LogDebug("[TPP] IsOwnerOrAdmin FALSE: " + reason); return false; } string text = NormalizeOwnerId(zDO.GetString("TargetPortal PortalOwnerId", string.Empty)); if (string.IsNullOrEmpty(text)) { reason = "portal has no owner id: " + GetPortalDebugName(nview); LogDebug("[TPP] IsOwnerOrAdmin FALSE: " + reason); return false; } string text2; try { text2 = NormalizeOwnerId(((object)(PlatformUserID)(ref UserInfo.GetLocalUser().UserId)).ToString()); } catch { text2 = string.Empty; } if (!string.IsNullOrEmpty(text2) && text == text2) { reason = "local platform user matches portal owner id"; LogDebug("[TPP] IsOwnerOrAdmin TRUE: " + reason + " | ownerId=" + text + " | localUserId=" + text2); return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { long @long = zDO.GetLong(ZDOVars.s_creator, 0L); if (@long != 0L && @long == localPlayer.GetPlayerID()) { reason = "local player creator id matches portal creator"; LogDebug("[TPP] IsOwnerOrAdmin TRUE: " + reason + " | creator=" + @long + " | playerId=" + localPlayer.GetPlayerID()); return true; } } reason = "owner/admin mismatch for " + GetPortalDebugName(nview) + " (ownerId=" + text + ", localUserId=" + text2 + ")"; LogDebug("[TPP] IsOwnerOrAdmin FALSE: " + reason); return false; } private static bool IsOwnerOrAdmin(ZDO zdo, out string reason) { reason = "unknown owner/admin check result"; if (zdo == null) { reason = "portal ZDO is null"; return false; } if (AdminBypass() && TargetPortalProtectionPlugin.IsLocalPlayerAdmin()) { reason = "player is admin and AdminBypass is enabled"; return true; } string text = NormalizeOwnerId(zdo.GetString("TargetPortal PortalOwnerId", string.Empty)); if (string.IsNullOrEmpty(text)) { reason = "portal has no owner id"; return false; } string text2; try { text2 = NormalizeOwnerId(((object)(PlatformUserID)(ref UserInfo.GetLocalUser().UserId)).ToString()); } catch { text2 = string.Empty; } if (!string.IsNullOrEmpty(text2) && text == text2) { reason = "local platform user matches portal owner id"; return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { long @long = zdo.GetLong(ZDOVars.s_creator, 0L); if (@long != 0L && @long == localPlayer.GetPlayerID()) { reason = "local player creator id matches portal creator"; return true; } } reason = "owner/admin mismatch (ownerId=" + text + ", localUserId=" + text2 + ")"; return false; } private static bool IsTargetPortal(ZNetView nview) { if ((Object)(object)nview == (Object)null || !nview.IsValid()) { LogDebug("[TPP] IsTargetPortal FALSE: nview null vagy invalid"); return false; } ZDO zDO = nview.GetZDO(); if (zDO == null) { LogDebug("[TPP] IsTargetPortal FALSE: ZDO null"); return false; } int @int = zDO.GetInt("TargetPortal PortalMode", -1); string @string = zDO.GetString("TargetPortal PortalOwnerId", string.Empty); bool result = @int != -1 || !string.IsNullOrEmpty(@string); LogDebug("[TPP] IsTargetPortal: " + GetPortalDebugName(nview) + " | portalMode=" + @int + " | owner=" + @string + " | result=" + result); return result; } private static ZNetView FindNviewFromZdoid(object firstParam) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!(firstParam is ZDOID val)) { return null; } if (ZDOMan.instance == null) { return null; } ZDO zDO = ZDOMan.instance.GetZDO(val); if (zDO == null) { return null; } return ((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zDO) : null; } private static ZNetView FindNviewFromZdo(ZDO zdo) { if (zdo == null || (Object)(object)ZNetScene.instance == (Object)null) { return null; } return ZNetScene.instance.FindInstance(zdo); } private static bool IsTargetPortalZdo(ZDO zdo) { if (zdo == null) { return false; } int @int = zdo.GetInt("TargetPortal PortalMode", -1); string @string = zdo.GetString("TargetPortal PortalOwnerId", string.Empty); return @int != -1 || !string.IsNullOrEmpty(@string); } [IteratorStateMachine(typeof(d__51))] private static IEnumerable EnumerateAllZdos() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__51(-2); } [IteratorStateMachine(typeof(d__52))] private static IEnumerable EnumerateZdosFromObject(object obj, HashSet seen) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__52(-2) { <>3__obj = obj, <>3__seen = seen }; } private static List CollectAllTargetPortalZdos() { if (_cachedPortalZdos != null && Time.time - _lastZdoCacheTime < 0.5f) { return _cachedPortalZdos; } List list = new List(); foreach (ZDO item in EnumerateAllZdos()) { if (item != null && IsTargetPortalZdo(item)) { list.Add(item); } } _cachedPortalZdos = list; _lastZdoCacheTime = Time.time; return list; } private static ZDO FindClosestPortalZdoFromPin(PinData pinData, List portalZdos, out string debugReason) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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) debugReason = "unknown"; if (pinData == null) { debugReason = "pinData is null"; return null; } if (portalZdos == null || portalZdos.Count == 0) { debugReason = "portalZdos list is empty"; return null; } float num = float.MaxValue; ZDO val = null; foreach (ZDO portalZdo in portalZdos) { if (portalZdo != null) { Vector3 position = portalZdo.GetPosition(); float num2 = Vector3.Distance(pinData.m_pos, position); if (num2 < num) { num = num2; val = portalZdo; } } } if (val == null) { debugReason = "no closest portal found"; return null; } if (num > 10f) { debugReason = "nearest portal too far: " + num.ToString("0.00"); return null; } debugReason = "matched portal at distance=" + num.ToString("0.00"); return val; } private static bool IsTargetPortalTeleportActive() { Type type = AccessTools.TypeByName("TargetPortal.Map"); if (type == null) { return false; } FieldInfo fieldInfo = AccessTools.DeclaredField(type, "Teleporting") ?? AccessTools.Field(type, "Teleporting"); if (fieldInfo == null) { return false; } try { object value = fieldInfo.GetValue(null); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static bool TryGetClickedTargetPortalZdo(out ZDO portalZdo) { portalZdo = null; Type type = AccessTools.TypeByName("TargetPortal.Map"); if (type == null) { return false; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "GetClosestPortal", (Type[])null, (Type[])null); if (methodInfo == null) { return false; } object[] array = new object[2]; try { if (!(bool)methodInfo.Invoke(null, array)) { return false; } portalZdo = (ZDO)((array.Length > 1) ? /*isinst with value type is only supported in some contexts*/: null); return portalZdo != null; } catch (Exception ex) { LogDebug("[TPP] TryGetClickedTargetPortalZdo hiba: " + ex); return false; } } private static bool IsNearProtectedTargetPortal(Vector3 point, out string reason) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) float num = TerrainProtectionRadius(); float num2 = SearchRadius(); Collider[] array = Physics.OverlapSphere(point, num2); Collider[] array2 = array; foreach (Collider val in array2) { TeleportWorld componentInParent = ((Component)val).GetComponentInParent(); ZNetView portalNView = GetPortalNView(componentInParent); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)portalNView == (Object)null) && portalNView.IsValid() && IsTargetPortal(portalNView)) { TryStoreGuildIdOnPortal(portalNView, "Terrain proximity check"); float num3 = Vector3.Distance(point, ((Component)componentInParent).transform.position); if (!(num3 > num) && !CanBypassTerrainProtection(portalNView, out var reason2)) { string[] obj = new string[10] { "point ", null, null, null, null, null, null, null, null, null }; Vector3 val2 = point; obj[1] = ((object)(Vector3)(ref val2)).ToString(); obj[2] = " is within "; obj[3] = num3.ToString("0.00"); obj[4] = "m of protected portal "; obj[5] = GetPortalDebugName(portalNView); obj[6] = " (radius "; obj[7] = num.ToString("0.00"); obj[8] = "m). "; obj[9] = reason2; reason = string.Concat(obj); return true; } } } reason = "no protected target portal found in range"; return false; } private static bool IsSameGuildAsPortal(ZNetView nview, out string reason) { reason = "guild integration check failed"; if (!GuildIntegrationEnabled()) { reason = "guild integration is disabled"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } if (!GuildsCompat.IsLoaded()) { reason = "Guilds mod is not loaded"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } ZDO val = (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null); if (val == null) { reason = "portal ZDO is null during guild check"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } int @int = val.GetInt("TargetPortal GuildId", 0); if (@int == 0) { LogDebug("[GUILD CHECK] portalGuildId = 0 -> próbál menteni"); TryStoreGuildIdOnPortal(nview, "Guild comparison fallback"); @int = val.GetInt("TargetPortal GuildId", 0); } int ownGuildId = GuildsCompat.GetOwnGuildId(); string ownGuildRankKey = GuildsCompat.GetOwnGuildRankKey(); LogDebug($"[GUILD CHECK] portalGuild={@int} playerGuild={ownGuildId} playerRank={ownGuildRankKey}"); if (@int == 0) { reason = "portal has no cached guild id: " + GetPortalDebugName(nview); LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } if (ownGuildId == 0) { reason = "local player has no guild id"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } if (ownGuildId != @int) { reason = "guild mismatch for " + GetPortalDebugName(nview) + " (portalGuildId=" + @int + ", ownGuildId=" + ownGuildId + ")"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } if (!RequireGuildRankForNonOwners()) { reason = "guild match succeeded (guildId=" + ownGuildId + ") for " + GetPortalDebugName(nview); LogDebug("IsSameGuildAsPortal: TRUE -> " + reason); return true; } if (GuildsCompat.HasPortalModifyPermission(AllowedGuildRanksForPortalModify())) { reason = "guild match succeeded and rank allows portal modification (guildId=" + ownGuildId + ", rank=" + ownGuildRankKey + ")"; LogDebug("IsSameGuildAsPortal: TRUE -> " + reason); return true; } reason = "guild matches but rank does not allow portal modification (guildId=" + ownGuildId + ", rank=" + ownGuildRankKey + ")"; LogDebug("IsSameGuildAsPortal: FALSE -> " + reason); return false; } private static bool IsSameGuildAsPortalForVisibility(ZDO zdo, out string reason) { reason = "guild visibility check failed"; if (!GuildIntegrationEnabled()) { reason = "guild integration is disabled"; return false; } if (!GuildsCompat.IsLoaded()) { reason = "Guilds mod is not loaded"; return false; } if (zdo == null) { reason = "portal ZDO is null during visibility guild check"; return false; } int @int = zdo.GetInt("TargetPortal GuildId", 0); if (@int == 0) { ZNetView val = FindNviewFromZdo(zdo); if ((Object)(object)val != (Object)null && val.IsValid()) { TryStoreGuildIdOnPortal(val, "Visibility guild fallback"); @int = zdo.GetInt("TargetPortal GuildId", 0); } } int ownGuildId = GuildsCompat.GetOwnGuildId(); if (@int == 0) { reason = "portal has no cached guild id"; return false; } if (ownGuildId == 0) { reason = "local player has no guild id"; return false; } if (ownGuildId != @int) { reason = "guild mismatch (portalGuildId=" + @int + ", ownGuildId=" + ownGuildId + ")"; return false; } reason = "guild visibility match (guildId=" + ownGuildId + ")"; return true; } internal static bool CanSeePortal(ZDO zdo, out string reason) { reason = "unknown visibility result"; if (!VisibilityProtectionEnabled()) { reason = "visibility protection disabled"; return true; } if (zdo == null) { reason = "portal ZDO is null"; return false; } LogDebug("CanSeePortal check: mode=" + zdo.GetInt("TargetPortal PortalMode", 0)); switch (zdo.GetInt("TargetPortal PortalMode", 0)) { case 0: reason = "public portal"; return true; case 1: return IsOwnerOrAdmin(zdo, out reason); case 4: return IsSameGuildAsPortalForVisibility(zdo, out reason); case 3: if (TargetPortalProtectionPlugin.IsLocalPlayerAdmin()) { reason = "admin portal visible to admin"; return true; } reason = "admin portal hidden from non-admin"; return false; case 2: reason = "group portal uses original visibility"; return true; default: reason = "unknown portal mode, leaving visible"; return true; } } internal static void FilterVisiblePortalPins() { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected I4, but got Unknown if (!VisibilityProtectionEnabled()) { return; } Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(Minimap), "m_pins"); if (fieldInfo == null || !(fieldInfo.GetValue(instance) is IList list) || list.Count == 0) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(Minimap), "RemovePin", new Type[1] { typeof(PinData) }, (Type[])null); if (methodInfo == null) { return; } List list2 = new List(); foreach (object item in list) { if (item != null) { list2.Add(item); } } List portalZdos = CollectAllTargetPortalZdos(); List list3 = new List(); foreach (object item2 in list2) { PinData val = (PinData)((item2 is PinData) ? item2 : null); if (val == null) { continue; } int num = (int)val.m_type; if (num == 17) { ZDO val2; string debugReason; try { val2 = FindClosestPortalZdoFromPin(val, portalZdos, out debugReason); } catch (Exception ex) { LogDebug("[VISIBILITY] portal lookup hiba: " + ex); continue; } string reason; if (val2 == null) { LogDebug("[VISIBILITY] nincs ZDO ehhez a pinhez: " + val.m_name + " | " + debugReason); } else if (!CanSeePortal(val2, out reason)) { LogDebug("[VISIBILITY] ELREJTEM: " + val.m_name + " | " + reason); list3.Add(val); } } } foreach (PinData item3 in list3) { try { methodInfo.Invoke(instance, new object[1] { item3 }); } catch (Exception ex2) { LogDebug("[VISIBILITY] pin remove hiba: " + ex2); } } } internal static bool TryPatchVisibility(Harmony harmony) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("TargetPortal.Map"); if (type == null) { LogDebug("TryPatchVisibility: TargetPortal.Map még nincs betöltve"); return false; } MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "AddPortalPins", (Type[])null, (Type[])null); if (methodInfo == null) { LogDebug("TryPatchVisibility: AddPortalPins metódus nem található"); return false; } MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(PortalProtectionLogic), "VisibilityPostfix", (Type[])null, (Type[])null); if (methodInfo2 == null) { LogDebug("TryPatchVisibility: VisibilityPostfix metódus nem található"); return false; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); LogDebug("TryPatchVisibility: AddPortalPins postfix patch sikeresen felment"); return true; } catch (Exception ex) { if (TargetPortalProtectionPlugin.Log != null) { TargetPortalProtectionPlugin.Log.LogError((object)("TryPatchVisibility hiba: " + ex)); } return false; } } private static void VisibilityPostfix() { FilterVisiblePortalPins(); } private static void TryStoreGuildIdOnPortal(ZNetView nview, string context) { LogDebug("[GUILD CACHE ENTER] context=" + context + " portal=" + (((Object)(object)nview != (Object)null) ? GetPortalDebugName(nview) : "")); if (!GuildIntegrationEnabled() || !StoreGuildIdOnPortal() || !GuildsCompat.IsLoaded()) { LogDebug("[GUILD CACHE EXIT] guild integration disabled or Guilds missing"); return; } if ((Object)(object)nview == (Object)null || !nview.IsValid()) { LogDebug("[GUILD CACHE EXIT] invalid nview"); return; } ZDO zDO = nview.GetZDO(); if (zDO == null) { LogDebug("[GUILD CACHE EXIT] zdo null"); return; } if (!nview.IsOwner()) { LogDebug("[GUILD CACHE EXIT] not zdo owner"); return; } int ownGuildId = GuildsCompat.GetOwnGuildId(); int @int = zDO.GetInt("TargetPortal GuildId", 0); LogDebug($"[GUILD CACHE STATE] currentGuildId={@int} ownGuildId={ownGuildId} context={context}"); if (ownGuildId == 0) { LogDebug("[GUILD CACHE EXIT] ownGuildId == 0"); return; } if (@int == ownGuildId) { LogDebug("[GUILD CACHE EXIT] already same guild id"); return; } zDO.Set("TargetPortal GuildId", ownGuildId); LogDebug($"[GUILD CACHE WRITE] portal={GetPortalDebugName(nview)} oldGuildId={@int} newGuildId={ownGuildId} context={context}"); } } internal static class GuildsCompat { private const string GuildsPluginGuid = "org.bepinex.plugins.guilds"; private const string GuildsApiTypeName = "Guilds.API"; private static Type _apiType; private static MethodInfo _isLoadedMethod; private static MethodInfo _getOwnGuildMethod; private static bool _initialized; private static void PortalProtectionLogicLogDebug(string message) { try { if (TargetPortalProtectionPlugin.CE_DebugLogging_Enabled != null && TargetPortalProtectionPlugin.CE_DebugLogging_Enabled.Value && TargetPortalProtectionPlugin.Log != null) { TargetPortalProtectionPlugin.Log.LogInfo((object)message); } } catch { } } internal static bool IsLoaded() { EnsureInitialized(); if (!Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.guilds")) { return false; } if (_apiType == null || _isLoadedMethod == null) { return false; } try { return (bool)_isLoadedMethod.Invoke(null, null); } catch { return false; } } internal static int GetOwnGuildId() { EnsureInitialized(); if (!IsLoaded() || _getOwnGuildMethod == null) { return 0; } try { object obj = _getOwnGuildMethod.Invoke(null, null); if (obj == null) { return 0; } object memberValue = GetMemberValue(obj, "General"); if (memberValue == null) { return 0; } object memberValue2 = GetMemberValue(memberValue, "id"); return (memberValue2 is int) ? ((int)memberValue2) : Convert.ToInt32(memberValue2); } catch { return 0; } } internal static void DebugGuildMembers() { try { if (!IsLoaded()) { return; } object obj = ((_getOwnGuildMethod != null) ? _getOwnGuildMethod.Invoke(null, null) : null); if (obj == null) { return; } object obj2 = GetMemberValue(obj, "Members") ?? GetMemberValue(obj, "members"); if (!(obj2 is IEnumerable enumerable)) { PortalProtectionLogicLogDebug("[GUILD DEBUG] Members nincs vagy nem enumerable"); return; } foreach (object item in enumerable) { if (item != null) { object memberValue = GetMemberValue(item, "Key"); object memberValue2 = GetMemberValue(item, "Value"); string text = ReadStringLike(memberValue, "Name") ?? ReadStringLike(memberValue, "name") ?? ReadStringLike(memberValue, "PlayerName") ?? ReadStringLike(memberValue, "playerName") ?? ReadStringLike(memberValue, "Username") ?? ReadStringLike(memberValue, "username"); string text2 = ReadStringLike(memberValue, "PlayerID") ?? ReadStringLike(memberValue, "playerID") ?? ReadStringLike(memberValue, "PlayerId") ?? ReadStringLike(memberValue, "playerId") ?? ReadStringLike(memberValue, "Id") ?? ReadStringLike(memberValue, "id") ?? ReadStringLike(memberValue, "UserId") ?? ReadStringLike(memberValue, "userId"); string text3 = TryReadRankLikeValue(memberValue2); PortalProtectionLogicLogDebug("[GUILD MEMBER] keyType=" + ((memberValue != null) ? memberValue.GetType().FullName : "") + " valueType=" + ((memberValue2 != null) ? memberValue2.GetType().FullName : "") + " name=" + text + " id=" + text2 + " rank=" + text3); } } } catch (Exception ex) { PortalProtectionLogicLogDebug("[GUILD DEBUG ERROR] " + ex); } } internal static string GetOwnGuildRankKey() { EnsureInitialized(); if (!IsLoaded() || _getOwnGuildMethod == null) { return string.Empty; } try { object obj = _getOwnGuildMethod.Invoke(null, null); if (obj == null) { return string.Empty; } object obj2 = FindOwnMemberObject(obj); if (obj2 == null) { PortalProtectionLogicLogDebug("[GUILD RANK] Nem találtam saját member objektumot."); return string.Empty; } string value = TryReadRankLikeValue(obj2); if (!string.IsNullOrEmpty(value)) { return NormalizeRankKey(value); } object memberValue = GetMemberValue(obj2, "General"); if (memberValue != null) { string value2 = TryReadRankLikeValue(memberValue); if (!string.IsNullOrEmpty(value2)) { return NormalizeRankKey(value2); } } PortalProtectionLogicLogDebug("[GUILD RANK] A member megvan, de rank nem olvasható."); return string.Empty; } catch (Exception ex) { PortalProtectionLogicLogDebug("[GUILD RANK ERROR] " + ex); return string.Empty; } } internal static bool HasPortalModifyPermission(string allowedRanksCsv) { string text = NormalizeRankKey(GetOwnGuildRankKey()); HashSet hashSet = ParseAllowedRanks(allowedRanksCsv); if (string.IsNullOrEmpty(text)) { return false; } return hashSet.Contains(text); } private static HashSet ParseAllowedRanks(string csv) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrWhiteSpace(csv)) { return hashSet; } string[] array = csv.Split(new char[4] { ',', ';', '|', ' ' }, StringSplitOptions.RemoveEmptyEntries); string[] array2 = array; foreach (string value in array2) { string text = NormalizeRankKey(value); if (!string.IsNullOrEmpty(text)) { hashSet.Add(text); } } return hashSet; } private static string NormalizeRankKey(string value) { if (string.IsNullOrWhiteSpace(value)) { return string.Empty; } string text = value.Trim().ToLowerInvariant().Replace("_", "") .Replace("-", "") .Replace(" ", ""); switch (text) { default: if (!(text == "deputyleader")) { if (text == "officer" || text == "elder" || text == "moderator") { return "officer"; } switch (text) { default: if (!(text == "admin")) { if (text == "member" || text == "default") { return "member"; } return text; } goto case "leader"; case "leader": case "owner": case "guildmaster": case "master": return "leader"; } } goto case "coleader"; case "coleader": case "subleader": case "viceleader": return "coleader"; } } private static object FindOwnMemberObject(object guild) { if (guild == null) { return null; } object memberValue = GetMemberValue(guild, "Members"); if (memberValue == null) { memberValue = GetMemberValue(guild, "members"); } if (!(memberValue is IEnumerable enumerable)) { return null; } string localUserId = string.Empty; string localPlayerName = string.Empty; long localPlayerId = 0L; try { localUserId = ((object)(PlatformUserID)(ref UserInfo.GetLocalUser().UserId)).ToString(); } catch { } try { if ((Object)(object)Player.m_localPlayer != (Object)null) { localPlayerName = Player.m_localPlayer.GetPlayerName(); localPlayerId = Player.m_localPlayer.GetPlayerID(); } } catch { } foreach (object item in enumerable) { if (item != null) { object memberValue2 = GetMemberValue(item, "Key"); object memberValue3 = GetMemberValue(item, "Value"); if (memberValue2 != null && memberValue3 != null && MatchesPlayerReference(memberValue2, localUserId, localPlayerName, localPlayerId)) { return memberValue3; } } } return null; } private static bool MatchesPlayerReference(object playerRef, string localUserId, string localPlayerName, long localPlayerId) { if (playerRef == null) { return false; } string[] array = new string[12] { ReadStringLike(playerRef, "PlayerID"), ReadStringLike(playerRef, "playerID"), ReadStringLike(playerRef, "PlayerId"), ReadStringLike(playerRef, "playerId"), ReadStringLike(playerRef, "Id"), ReadStringLike(playerRef, "id"), ReadStringLike(playerRef, "UserId"), ReadStringLike(playerRef, "userId"), ReadStringLike(playerRef, "SteamId"), ReadStringLike(playerRef, "steamId"), ReadStringLike(playerRef, "PlatformId"), ReadStringLike(playerRef, "platformId") }; string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrEmpty(text)) { string text2 = text.Replace("Steam_", string.Empty); string text3 = (string.IsNullOrEmpty(localUserId) ? string.Empty : localUserId.Replace("Steam_", string.Empty)); if (!string.IsNullOrEmpty(text3) && text2 == text3) { return true; } if (localPlayerId != 0L && text2 == localPlayerId.ToString()) { return true; } } } string[] array3 = new string[6] { ReadStringLike(playerRef, "Name"), ReadStringLike(playerRef, "name"), ReadStringLike(playerRef, "PlayerName"), ReadStringLike(playerRef, "playerName"), ReadStringLike(playerRef, "Username"), ReadStringLike(playerRef, "username") }; string[] array4 = array3; foreach (string text4 in array4) { if (!string.IsNullOrEmpty(text4) && !string.IsNullOrEmpty(localPlayerName) && string.Equals(text4, localPlayerName, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static bool MatchesLocalUser(object member, string localUserId) { if (member == null || string.IsNullOrEmpty(localUserId)) { return false; } string[] array = new string[12] { ReadStringLike(member, "UserId"), ReadStringLike(member, "userId"), ReadStringLike(member, "SteamId"), ReadStringLike(member, "steamId"), ReadStringLike(member, "PlatformId"), ReadStringLike(member, "platformId"), ReadStringLike(member, "PlayerId"), ReadStringLike(member, "playerId"), ReadStringLike(member, "playerID"), ReadStringLike(member, "PlayerID"), ReadStringLike(member, "id"), ReadStringLike(member, "Id") }; string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrEmpty(text)) { string text2 = text.Replace("Steam_", string.Empty); string text3 = localUserId.Replace("Steam_", string.Empty); if (text2 == text3) { return true; } } } return false; } private static bool MatchesLocalPlayerName(object member, string localPlayerName) { if (member == null || string.IsNullOrEmpty(localPlayerName)) { return false; } string[] array = new string[6] { ReadStringLike(member, "name"), ReadStringLike(member, "Name"), ReadStringLike(member, "playerName"), ReadStringLike(member, "PlayerName"), ReadStringLike(member, "username"), ReadStringLike(member, "Username") }; string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrEmpty(text) && string.Equals(text, localPlayerName, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static string TryReadRankLikeValue(object instance) { if (instance == null) { return string.Empty; } object[] array = new object[10] { GetMemberValue(instance, "Role"), GetMemberValue(instance, "role"), GetMemberValue(instance, "Rank"), GetMemberValue(instance, "rank"), GetMemberValue(instance, "Permission"), GetMemberValue(instance, "permission"), GetMemberValue(instance, "MemberRole"), GetMemberValue(instance, "memberRole"), GetMemberValue(instance, "MemberRank"), GetMemberValue(instance, "memberRank") }; object[] array2 = array; foreach (object candidate in array2) { string text = ConvertRankCandidate(candidate); if (!string.IsNullOrEmpty(text)) { return text; } } return string.Empty; } private static string ConvertRankCandidate(object candidate) { if (candidate == null) { return string.Empty; } if (candidate is string result) { return result; } Type type = candidate.GetType(); if (type.IsEnum) { return candidate.ToString(); } if (candidate is int || candidate is long || candidate is byte || candidate is short) { int num = Convert.ToInt32(candidate); return num switch { 0 => "leader", 1 => "coleader", 2 => "officer", 3 => "member", _ => num.ToString(), }; } return candidate.ToString(); } private static string ReadStringLike(object instance, string name) { return GetMemberValue(instance, name)?.ToString(); } private static void EnsureInitialized() { if (!_initialized) { _initialized = true; _apiType = AccessTools.TypeByName("Guilds.API"); if (!(_apiType == null)) { _isLoadedMethod = AccessTools.DeclaredMethod(_apiType, "IsLoaded", (Type[])null, (Type[])null); _getOwnGuildMethod = AccessTools.DeclaredMethod(_apiType, "GetOwnGuild", (Type[])null, (Type[])null); } } } private static object GetMemberValue(object instance, string name) { if (instance == null) { return null; } Type type = instance.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(instance, null); } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (field != null) ? field.GetValue(instance) : null; } } [BepInPlugin("hardheim.TargetPortalProtectionReworked", "TargetPortalProtectionReworked", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class TargetPortalProtectionPlugin : BaseUnityPlugin { internal const string ModGuid = "hardheim.TargetPortalProtectionReworked"; internal const string ModName = "TargetPortalProtectionReworked"; internal const string ModVersion = "1.0.1"; private static readonly Harmony HarmonyInstance = new Harmony("hardheim.TargetPortalProtectionReworked"); private static bool _bootstrapped; private bool _visibilityPatchApplied; private float _nextVisibilityPatchRetryTime; private CustomLocalization _localization; internal static ManualLogSource Log; internal static CustomLocalization ModLocalization; public static ConfigEntry CE_PortalProtection_Enabled; public static ConfigEntry CE_TerrainProtection_Enabled; public static ConfigEntry CE_TerrainProtection_Radius; public static ConfigEntry CE_TargetPortalProtection_AdminBypass; public static ConfigEntry CE_DebugLogging_Enabled; public static ConfigEntry CE_VisibilityProtection_Enabled; public static ConfigEntry CE_GuildIntegration_Enabled; public static ConfigEntry CE_GuildIntegration_AllowGuildMembersToModifyPortals; public static ConfigEntry CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection; public static ConfigEntry CE_GuildIntegration_StoreGuildIdOnPortal; public static ConfigEntry CE_GuildIntegration_RequireRankForNonOwnerPortalModify; public static ConfigEntry CE_GuildIntegration_AllowedRanksToModifyPortals; public static bool IsLocalPlayerAdmin() { try { return SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin; } catch { return false; } } private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"TargetPortalProtectionReworked loaded."); Log = ((BaseUnityPlugin)this).Logger; PortalProtectionLogic.Init(); AddLocalizations(); if (_bootstrapped) { return; } _bootstrapped = true; CE_PortalProtection_Enabled = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "PortalProtection", "Enabled", true, "Ha engedélyezve van, más játékosok nem tudják módosítani vagy elpusztítani a védett TargetPortalokat, kivéve ha ők a tulajdonosok, ugyanabban a guildben vannak (ha engedélyezett), vagy adminok.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_TerrainProtection_Enabled = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "TerrainProtection", "Enabled", true, "Ha engedélyezve van, a védett TargetPortalok környezetében nem lehet terepet módosítani.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config = ((BaseUnityPlugin)this).Config; AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f); CE_TerrainProtection_Radius = ConfigFileExtensions.BindConfig(config, "TerrainProtection", "Radius", 5f, "A védelem sugara méterben a TargetPortal körül. Ezen belül tiltott a terep módosítása.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); CE_TargetPortalProtection_AdminBypass = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "PortalProtection", "AdminBypass", true, "Ha engedélyezve van, az adminok figyelmen kívül hagyják a portal védelmet, és módosíthatják a védett TargetPortalokat.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_VisibilityProtection_Enabled = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "VisibilityProtection", "Enabled", true, "Ha engedélyezve van, a TargetPortal selector térképén a private portálok csak a tulajdonosnak, a guild portálok csak ugyanazon guild tagjainak, az admin portálok csak adminoknak látszanak.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_DebugLogging_Enabled = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "Debug", "EnableLogging", false, "Ha engedélyezve van, részletes debug információk kerülnek a BepInEx logba.", false, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_Enabled = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "Enabled", true, "Ha engedélyezve van, a mod együttműködik a Guilds moddal, és figyelembe veszi a guild tagságot.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_AllowGuildMembersToModifyPortals = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "AllowGuildMembersToModifyPortals", true, "Ha engedélyezve van, a portal tulajdonosával azonos guildben lévő játékosok módosíthatják a portált.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "AllowGuildMembersToBypassTerrainProtection", false, "Ha engedélyezve van, a guild tagok figyelmen kívül hagyhatják a terepvédelmet a portal közelében.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_StoreGuildIdOnPortal = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "StoreGuildIdOnPortal", true, "Ha engedélyezve van, a portal eltárolja a tulajdonos guild azonosítóját.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_RequireRankForNonOwnerPortalModify = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "RequireRankForNonOwnerPortalModify", false, "Ha engedélyezve van, a nem tulajdonos guild tagok csak megfelelő guild ranggal módosíthatják a portált.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); CE_GuildIntegration_AllowedRanksToModifyPortals = ConfigFileExtensions.BindConfig(((BaseUnityPlugin)this).Config, "GuildIntegration", "AllowedRanksToModifyPortals", "leader,officer,coleader", "Azok a guild rangok, amelyek nem tulajdonosként módosíthatják a guild portálokat.", true, (int?)null, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); SynchronizationManager.OnConfigurationSynchronized += delegate(object obj, ConfigurationSynchronizationEventArgs args) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[CONFIG SYNC] Lefutott. Initial: {args.InitialSynchronization}"); if (CE_GuildIntegration_AllowGuildMembersToModifyPortals != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[CONFIG SYNC] AllowGuildMembersToModifyPortals = {CE_GuildIntegration_AllowGuildMembersToModifyPortals.Value}"); } if (CE_GuildIntegration_RequireRankForNonOwnerPortalModify != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[CONFIG SYNC] RequireRankForNonOwnerPortalModify = {CE_GuildIntegration_RequireRankForNonOwnerPortalModify.Value}"); } if (CE_GuildIntegration_AllowedRanksToModifyPortals != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[CONFIG SYNC] AllowedRanksToModifyPortals = " + CE_GuildIntegration_AllowedRanksToModifyPortals.Value)); } if (CE_VisibilityProtection_Enabled != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[CONFIG SYNC] VisibilityProtection.Enabled = {CE_VisibilityProtection_Enabled.Value}"); } }; HarmonyInstance.PatchAll(); _visibilityPatchApplied = false; _nextVisibilityPatchRetryTime = Time.time + 2f; } private void Update() { if (!_visibilityPatchApplied && !(Time.time < _nextVisibilityPatchRetryTime)) { _nextVisibilityPatchRetryTime = Time.time + 2f; if (PortalProtectionLogic.TryPatchVisibility(HarmonyInstance)) { _visibilityPatchApplied = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VISIBILITY] AddPortalPins patch applied successfully."); } else if (CE_DebugLogging_Enabled != null && CE_DebugLogging_Enabled.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VISIBILITY] AddPortalPins patch még nem rakható fel, újrapróbálom..."); } } } private void AddLocalizations() { _localization = LocalizationManager.Instance.GetLocalization(); ModLocalization = _localization; CustomLocalization localization = _localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary { { "tweaks_portal_protected", "You are not allowed to modify this protected TargetPortal." }, { "tweaks_portal_terrain", "You cannot modify terrain near this protected TargetPortal." } }); CustomLocalization localization2 = _localization; text = "Hungarian"; localization2.AddTranslation(ref text, new Dictionary { { "tweaks_portal_protected", "Ehhez a védett portálhoz nincs módosítási jogosultságod." }, { "tweaks_portal_terrain", "A védett portál közelében nem módosíthatod a terepet." } }); } }