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<TeleportWorld>();
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<TeleportWorld>();
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<ZNetView>();
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 <EnumerateAllZdos>d__51 : IEnumerable<ZDO>, IEnumerable, IEnumerator<ZDO>, IDisposable, IEnumerator
{
private int <>1__state;
private ZDO <>2__current;
private int <>l__initialThreadId;
private object <zdoMan>5__1;
private Type <zdoManType>5__2;
private BindingFlags <flags>5__3;
private FieldInfo[] <fields>5__4;
private HashSet<ZDOID> <seen>5__5;
private FieldInfo[] <>s__6;
private int <>s__7;
private FieldInfo <field>5__8;
private object <fieldValue>5__9;
private IEnumerator<ZDO> <>s__10;
private ZDO <zdo>5__11;
ZDO IEnumerator<ZDO>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnumerateAllZdos>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();
}
}
<zdoMan>5__1 = null;
<zdoManType>5__2 = null;
<fields>5__4 = null;
<seen>5__5 = null;
<>s__6 = null;
<field>5__8 = null;
<fieldValue>5__9 = null;
<>s__10 = null;
<zdo>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;
<zdo>5__11 = null;
goto IL_014b;
}
<>1__state = -1;
if (ZDOMan.instance == null)
{
return false;
}
<zdoMan>5__1 = ZDOMan.instance;
<zdoManType>5__2 = <zdoMan>5__1.GetType();
<flags>5__3 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
<fields>5__4 = <zdoManType>5__2.GetFields(<flags>5__3);
<seen>5__5 = new HashSet<ZDOID>();
<>s__6 = <fields>5__4;
<>s__7 = 0;
goto IL_0183;
IL_014b:
if (<>s__10.MoveNext())
{
<zdo>5__11 = <>s__10.Current;
<>2__current = <zdo>5__11;
<>1__state = 1;
return true;
}
<>m__Finally1();
<>s__10 = null;
<fieldValue>5__9 = null;
<field>5__8 = null;
goto IL_0175;
IL_0175:
<>s__7++;
goto IL_0183;
IL_0183:
if (<>s__7 < <>s__6.Length)
{
<field>5__8 = <>s__6[<>s__7];
<fieldValue>5__9 = null;
try
{
<fieldValue>5__9 = <field>5__8.GetValue(<zdoMan>5__1);
}
catch
{
goto IL_0175;
}
if (<fieldValue>5__9 == null)
{
goto IL_0175;
}
<>s__10 = EnumerateZdosFromObject(<fieldValue>5__9, <seen>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<ZDO> IEnumerable<ZDO>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <EnumerateAllZdos>d__51(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<ZDO>)this).GetEnumerator();
}
}
[CompilerGenerated]
private sealed class <EnumerateZdosFromObject>d__52 : IEnumerable<ZDO>, IEnumerable, IEnumerator<ZDO>, IDisposable, IEnumerator
{
private int <>1__state;
private ZDO <>2__current;
private int <>l__initialThreadId;
private object obj;
public object <>3__obj;
private HashSet<ZDOID> seen;
public HashSet<ZDOID> <>3__seen;
private ZDO <singleZdo>5__1;
private IDictionary <dictionary>5__2;
private IEnumerable <enumerable>5__3;
private IDictionaryEnumerator <>s__4;
private DictionaryEntry <entry>5__5;
private IEnumerator<ZDO> <>s__6;
private ZDO <zdo>5__7;
private IEnumerator <>s__8;
private object <item>5__9;
private IEnumerator<ZDO> <>s__10;
private ZDO <zdo>5__11;
ZDO IEnumerator<ZDO>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnumerateZdosFromObject>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;
}
<singleZdo>5__1 = null;
<dictionary>5__2 = null;
<enumerable>5__3 = null;
<>s__4 = null;
<entry>5__5 = default(DictionaryEntry);
<>s__6 = null;
<zdo>5__7 = null;
<>s__8 = null;
<item>5__9 = null;
<>s__10 = null;
<zdo>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 <singleZdo>5__1;
object obj = this.obj;
reference = (ZDO)((obj is ZDO) ? obj : null);
if (<singleZdo>5__1 != null)
{
if (seen.Add(<singleZdo>5__1.m_uid))
{
<>2__current = <singleZdo>5__1;
<>1__state = 1;
return true;
}
goto IL_00b2;
}
<dictionary>5__2 = this.obj as IDictionary;
if (<dictionary>5__2 != null)
{
<>s__4 = <dictionary>5__2.GetEnumerator();
<>1__state = -3;
goto IL_01a3;
}
<enumerable>5__3 = this.obj as IEnumerable;
if (<enumerable>5__3 == null || this.obj is string)
{
break;
}
<>s__8 = <enumerable>5__3.GetEnumerator();
<>1__state = -5;
goto IL_02b3;
}
case 1:
<>1__state = -1;
goto IL_00b2;
case 2:
<>1__state = -4;
<zdo>5__7 = null;
goto IL_017b;
case 3:
{
<>1__state = -6;
<zdo>5__11 = null;
goto IL_0290;
}
IL_0290:
if (<>s__10.MoveNext())
{
<zdo>5__11 = <>s__10.Current;
<>2__current = <zdo>5__11;
<>1__state = 3;
return true;
}
<>m__Finally4();
<>s__10 = null;
<item>5__9 = null;
goto IL_02b3;
IL_01a3:
if (<>s__4.MoveNext())
{
<entry>5__5 = (DictionaryEntry)<>s__4.Current;
<>s__6 = EnumerateZdosFromObject(<entry>5__5.Value, seen).GetEnumerator();
<>1__state = -4;
goto IL_017b;
}
<>m__Finally1();
<>s__4 = null;
return false;
IL_017b:
if (<>s__6.MoveNext())
{
<zdo>5__7 = <>s__6.Current;
<>2__current = <zdo>5__7;
<>1__state = 2;
return true;
}
<>m__Finally2();
<>s__6 = null;
<entry>5__5 = default(DictionaryEntry);
goto IL_01a3;
IL_00b2:
return false;
IL_02b3:
if (<>s__8.MoveNext())
{
<item>5__9 = <>s__8.Current;
<>s__10 = EnumerateZdosFromObject(<item>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<ZDO> IEnumerable<ZDO>.GetEnumerator()
{
<EnumerateZdosFromObject>d__52 <EnumerateZdosFromObject>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<EnumerateZdosFromObject>d__ = this;
}
else
{
<EnumerateZdosFromObject>d__ = new <EnumerateZdosFromObject>d__52(0);
}
<EnumerateZdosFromObject>d__.obj = <>3__obj;
<EnumerateZdosFromObject>d__.seen = <>3__seen;
return <EnumerateZdosFromObject>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<ZDO>)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<ZDO> _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<ZNetView>() : 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 "<null portal>";
}
string text = (((Object)(object)((Component)nview).gameObject != (Object)null) ? ((Object)((Component)nview).gameObject).name : "<unknown>");
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(<EnumerateAllZdos>d__51))]
private static IEnumerable<ZDO> EnumerateAllZdos()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnumerateAllZdos>d__51(-2);
}
[IteratorStateMachine(typeof(<EnumerateZdosFromObject>d__52))]
private static IEnumerable<ZDO> EnumerateZdosFromObject(object obj, HashSet<ZDOID> seen)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnumerateZdosFromObject>d__52(-2)
{
<>3__obj = obj,
<>3__seen = seen
};
}
private static List<ZDO> CollectAllTargetPortalZdos()
{
if (_cachedPortalZdos != null && Time.time - _lastZdoCacheTime < 0.5f)
{
return _cachedPortalZdos;
}
List<ZDO> list = new List<ZDO>();
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<ZDO> 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<TeleportWorld>();
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<object> list2 = new List<object>();
foreach (object item in list)
{
if (item != null)
{
list2.Add(item);
}
}
List<ZDO> portalZdos = CollectAllTargetPortalZdos();
List<PinData> list3 = new List<PinData>();
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) : "<null>"));
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 : "<null>") + " valueType=" + ((memberValue2 != null) ? memberValue2.GetType().FullName : "<null>") + " 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<string> hashSet = ParseAllowedRanks(allowedRanksCsv);
if (string.IsNullOrEmpty(text))
{
return false;
}
return hashSet.Contains(text);
}
private static HashSet<string> ParseAllowedRanks(string csv)
{
HashSet<string> hashSet = new HashSet<string>(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<bool> CE_PortalProtection_Enabled;
public static ConfigEntry<bool> CE_TerrainProtection_Enabled;
public static ConfigEntry<float> CE_TerrainProtection_Radius;
public static ConfigEntry<bool> CE_TargetPortalProtection_AdminBypass;
public static ConfigEntry<bool> CE_DebugLogging_Enabled;
public static ConfigEntry<bool> CE_VisibilityProtection_Enabled;
public static ConfigEntry<bool> CE_GuildIntegration_Enabled;
public static ConfigEntry<bool> CE_GuildIntegration_AllowGuildMembersToModifyPortals;
public static ConfigEntry<bool> CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection;
public static ConfigEntry<bool> CE_GuildIntegration_StoreGuildIdOnPortal;
public static ConfigEntry<bool> CE_GuildIntegration_RequireRankForNonOwnerPortalModify;
public static ConfigEntry<string> 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<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_TerrainProtection_Enabled = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
ConfigFile config = ((BaseUnityPlugin)this).Config;
AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f);
CE_TerrainProtection_Radius = ConfigFileExtensions.BindConfig<float>(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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_TargetPortalProtection_AdminBypass = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_VisibilityProtection_Enabled = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_DebugLogging_Enabled = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_Enabled = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_AllowGuildMembersToModifyPortals = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_AllowGuildMembersToBypassTerrainProtection = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_StoreGuildIdOnPortal = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_RequireRankForNonOwnerPortalModify = ConfigFileExtensions.BindConfig<bool>(((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<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
CE_GuildIntegration_AllowedRanksToModifyPortals = ConfigFileExtensions.BindConfig<string>(((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<ConfigEntryBase>)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<string, string>
{
{ "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<string, string>
{
{ "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." }
});
}
}