Decompiled source of PeakAntiCheatReborn v1.4.8

plugins/com.github.KinTheInfinite.PeakAntiCheatReborn.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PeakAntiCheat;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.KinTheInfinite.PeakAntiCheatReborn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.8.0")]
[assembly: AssemblyInformationalVersion("1.4.8")]
[assembly: AssemblyProduct("com.github.KinTheInfinite.PeakAntiCheatReborn")]
[assembly: AssemblyTitle("PeakAntiCheatReborn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.8.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PeakAntiCheat
{
	public static class AutokillManager
	{
		public static List<Player> kill_list = new List<Player>();

		public static float delay = 0f;

		public static void KillPlayers()
		{
			//IL_0077: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			delay -= Time.deltaTime;
			if (delay > 0f)
			{
				return;
			}
			delay = 1f;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!allCharacter.data.dead && !((Object)(object)((MonoBehaviourPun)allCharacter).photonView == (Object)null))
				{
					Player owner = ((MonoBehaviourPun)allCharacter).photonView.Owner;
					if (owner != null && kill_list.Contains(owner))
					{
						Vector3 val = allCharacter.Center + Vector3.up * 0.2f + Vector3.forward * 0.1f;
						((MonoBehaviourPun)allCharacter).photonView.RPC("RPCA_Die", (RpcTarget)0, new object[1] { val });
					}
				}
			}
		}
	}
}
namespace AntiCheatMod
{
	public static class InviteLinkGenerator
	{
		[CompilerGenerated]
		private sealed class <GenerateInviteLinkDelayed>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GenerateInviteLinkDelayed>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!PhotonNetwork.InRoom)
					{
						Debug.LogWarning((object)"[PEAK AntiCheat] No longer in room, skipping invite link generation");
						return false;
					}
					if (!PhotonNetwork.IsMasterClient)
					{
						Debug.Log((object)"[PEAK AntiCheat] Not master client, skipping invite link generation");
						return false;
					}
					if (_linkGenerated)
					{
						Debug.Log((object)"[PEAK AntiCheat] Invite link already generated for this room");
						return false;
					}
					try
					{
						if (!SteamManager.Initialized)
						{
							Debug.LogWarning((object)"[PEAK AntiCheat] Steam not initialized, cannot create invite link");
							return false;
						}
						SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
						if (service == null)
						{
							Debug.LogWarning((object)"[PEAK AntiCheat] SteamLobbyHandler not found");
							return false;
						}
						CSteamID val = default(CSteamID);
						if (!service.InSteamLobby(ref val))
						{
							Debug.LogWarning((object)"[PEAK AntiCheat] Not in a Steam lobby");
							return false;
						}
						CSteamID lobbyOwner = SteamMatchmaking.GetLobbyOwner(val);
						if (lobbyOwner == CSteamID.Nil)
						{
							Debug.LogWarning((object)"[PEAK AntiCheat] Could not get lobby owner");
							return false;
						}
						string text2 = (GUIUtility.systemCopyBuffer = $"steam://joinlobby/3527290/{val}/{lobbyOwner}");
						_linkGenerated = true;
						Debug.Log((object)("[PEAK AntiCheat] Invite link copied to clipboard: " + text2));
						AntiCheatPlugin.LogVisually("Invite link copied to clipboard!");
					}
					catch (Exception ex)
					{
						Debug.LogError((object)("[PEAK AntiCheat] Error creating invite link: " + ex.Message));
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static bool _linkGenerated;

		public static void OnJoinedRoom()
		{
			_linkGenerated = false;
			if ((Object)(object)AntiCheatPlugin.Instance != (Object)null)
			{
				((MonoBehaviour)AntiCheatPlugin.Instance).StartCoroutine(GenerateInviteLinkDelayed());
			}
		}

		[IteratorStateMachine(typeof(<GenerateInviteLinkDelayed>d__2))]
		private static IEnumerator GenerateInviteLinkDelayed()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GenerateInviteLinkDelayed>d__2(0);
		}
	}
	public enum AntiCheatNetEvent : byte
	{
		DetectionReport = 100,
		BlockListUpdate,
		DetectionSettingsUpdate,
		WhitelistUpdate,
		SyncRequest,
		SyncResponse,
		CheatModDetected,
		KickPlayer
	}
	public static class AntiCheatEvents
	{
		public static event Action<Player, string, CSteamID, string> OnCheaterDetected;

		public static event Action<DetectionType, Player, string> OnDetectionTriggered;

		public static event Action<Player, bool> OnPlayerBlockStatusChanged;

		public static event Action<Player> OnPlayerKicked;

		public static void NotifyCheaterDetected(Player player, string reason, CSteamID steamID)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			string arg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
			AntiCheatEvents.OnCheaterDetected?.Invoke(player, reason, steamID, arg);
		}

		public static void NotifyDetectionTriggered(DetectionType type, Player player, string reason)
		{
			AntiCheatEvents.OnDetectionTriggered?.Invoke(type, player, reason);
		}

		public static void NotifyPlayerBlockStatusChanged(Player player, bool isBlocked)
		{
			AntiCheatEvents.OnPlayerBlockStatusChanged?.Invoke(player, isBlocked);
		}

		public static void NotifyPlayerKicked(Player player)
		{
			AntiCheatEvents.OnPlayerKicked?.Invoke(player);
		}
	}
	[BepInPlugin("com.hiccup444.anticheat", "PEAK Anticheat Reborn", "1.4.8")]
	public class AntiCheatPlugin : BaseUnityPlugin, IConnectionCallbacks, IMatchmakingCallbacks, IInRoomCallbacks, IOnEventCallback
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass89_0
		{
			public CSteamID steamId;

			public bool receivedUpdate;

			internal void <WaitForPersonaStateChange>b__0(PersonaStateChange_t param)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if (param.m_ulSteamID == steamId.m_SteamID && (param.m_nChangeFlags & 1) != 0)
				{
					receivedUpdate = true;
					Logger.LogInfo((object)$"Received PersonaStateChange for {steamId} - name was updated");
				}
			}
		}

		[CompilerGenerated]
		private sealed class <CheckAllPlayersOnJoin>d__124 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckAllPlayersOnJoin>d__124(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Player[] playerList = PhotonNetwork.PlayerList;
					foreach (Player val in playerList)
					{
						if (val.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
						{
							antiCheatPlugin.CheckPlayerForCheatMods(val);
						}
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <CheckNewPlayerDelayed>d__105 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			public Player player;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckNewPlayerDelayed>d__105(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					antiCheatPlugin.CheckPlayerForCheatMods(player);
					((MonoBehaviour)antiCheatPlugin).StartCoroutine(antiCheatPlugin.SecondaryCheatModCheck(player));
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <CheckPlayersForCheats>d__85 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckPlayersForCheats>d__85(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (PhotonNetwork.InRoom)
					{
						Player[] playerList = PhotonNetwork.PlayerList;
						foreach (Player player in playerList)
						{
							antiCheatPlugin.CheckPlayerForCheatMods(player);
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForSeconds(5f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <CheckPlayersWithoutAnticheat>d__125 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckPlayersWithoutAnticheat>d__125(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && AutoBlockNoAnticheat)
					{
						DateTime now = DateTime.Now;
						List<int> list = new List<int>();
						Player[] playerList = PhotonNetwork.PlayerList;
						foreach (Player val in playerList)
						{
							if (val.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber || val.IsMasterClient)
							{
								continue;
							}
							DateTime value;
							if (!_anticheatUsers.ContainsKey(val.ActorNumber) && !_playersWithoutAnticheat.ContainsKey(val.ActorNumber))
							{
								CSteamID playerSteamID = GetPlayerSteamID(val);
								if (playerSteamID != CSteamID.Nil && BlockingManager.IsWhitelisted(playerSteamID.m_SteamID))
								{
									Logger.LogInfo((object)("[AntiCheat] Player " + val.NickName + " is whitelisted - not tracking for anticheat timeout"));
									BlockingManager.GrantImmunity(val.ActorNumber);
								}
								else if (BlockingManager.IsBlocked(val.ActorNumber))
								{
									Logger.LogInfo((object)("[AntiCheat] Player " + val.NickName + " is already blocked - not tracking for anticheat timeout"));
								}
							}
							else if (!_anticheatUsers.ContainsKey(val.ActorNumber) && _playersWithoutAnticheat.TryGetValue(val.ActorNumber, out value) && (now - value).TotalSeconds >= 10.0 && !BlockingManager.IsBlocked(val.ActorNumber))
							{
								list.Add(val.ActorNumber);
							}
							else if (BlockingManager.IsBlocked(val.ActorNumber) && _playersWithoutAnticheat.ContainsKey(val.ActorNumber))
							{
								Logger.LogInfo((object)("[AntiCheat] Player " + val.NickName + " is already blocked - removing from anticheat timeout tracking"));
								_playersWithoutAnticheat.Remove(val.ActorNumber);
							}
						}
						foreach (int item in list)
						{
							Room currentRoom = PhotonNetwork.CurrentRoom;
							Player val2 = ((currentRoom != null) ? currentRoom.GetPlayer(item, false) : null);
							if (val2 != null)
							{
								if (!BlockingManager.HasImmunity(item))
								{
									Logger.LogWarning((object)("[AUTO BLOCK] Player " + val2.NickName + " has no anticheat - auto-blocking"));
									LogVisually("{userColor}" + val2.NickName + "</color> {leftColor}has no anticheat - auto-blocked</color>", onlySendOnce: false, sfxJoin: false, sfxLeave: true);
									BlockPlayer(val2, "No anticheat installed", DetectionType.SteamIDSpoofing);
								}
								else
								{
									Logger.LogInfo((object)$"[AUTO BLOCK] Skipping auto-block for immune player {val2.NickName} (Actor #{item})");
								}
								_playersWithoutAnticheat.Remove(item);
							}
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RemoveDetectionFromRecent>d__55 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public string detectionKey;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RemoveDetectionFromRecent>d__55(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					_recentDetections.Remove(detectionKey);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SecondaryCheatModCheck>d__108 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SecondaryCheatModCheck>d__108(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (PhotonNetwork.IsMasterClient && player.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
					{
						object[] array = new object[1] { player.ActorNumber };
						RaiseEventOptions val = new RaiseEventOptions();
						val.TargetActors = new int[1] { player.ActorNumber };
						PhotonNetwork.RaiseEvent((byte)70, (object)array, val, SendOptions.SendReliable);
						Logger.LogInfo((object)("[SECONDARY CHECK] Sent secondary cheat mod check to " + player.NickName));
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendAntiCheatPingDelayed>d__122 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendAntiCheatPingDelayed>d__122(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Expected O, but got Unknown
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Logger.LogInfo((object)"[AntiCheat] SendAntiCheatPingDelayed started - waiting 1 second...");
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Logger.LogInfo((object)"[AntiCheat] SendAntiCheatPingDelayed finished waiting - calling SendAntiCheatPing");
					antiCheatPlugin.SendAntiCheatPing();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendAntiCheatPingToAllExistingPlayers>d__107 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendAntiCheatPingToAllExistingPlayers>d__107(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Expected O, but got Unknown
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.LocalPlayer == null)
					{
						return false;
					}
					Player[] array = PhotonNetwork.CurrentRoom.Players.Values.Where((Player p) => p.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber).ToArray();
					if (array.Length == 0)
					{
						return false;
					}
					object[] array2 = new object[3]
					{
						PhotonNetwork.LocalPlayer.NickName,
						PhotonNetwork.LocalPlayer.UserId,
						"1.4.8"
					};
					Player[] array3 = array;
					foreach (Player val in array3)
					{
						RaiseEventOptions val2 = new RaiseEventOptions();
						val2.TargetActors = new int[1] { val.ActorNumber };
						RaiseEventOptions val3 = val2;
						PhotonNetwork.RaiseEvent((byte)69, (object)array2, val3, SendOptions.SendReliable);
						Logger.LogInfo((object)("[AntiCheat] Sent anticheat ping to existing player " + val.NickName));
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendAntiCheatPingToNewPlayer>d__106 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Player newPlayer;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendAntiCheatPingToNewPlayer>d__106(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected O, but got Unknown
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.LocalPlayer == null)
					{
						return false;
					}
					Room currentRoom = PhotonNetwork.CurrentRoom;
					if (((currentRoom != null) ? currentRoom.GetPlayer(newPlayer.ActorNumber, false) : null) == null)
					{
						return false;
					}
					object[] array = new object[3]
					{
						PhotonNetwork.LocalPlayer.NickName,
						PhotonNetwork.LocalPlayer.UserId,
						"1.4.8"
					};
					RaiseEventOptions val = new RaiseEventOptions();
					val.TargetActors = new int[1] { newPlayer.ActorNumber };
					RaiseEventOptions val2 = val;
					PhotonNetwork.RaiseEvent((byte)69, (object)array, val2, SendOptions.SendReliable);
					Logger.LogInfo((object)("[AntiCheat] Sent anticheat ping to new player " + newPlayer.NickName));
					if (AutoBlockNoAnticheat && !_anticheatUsers.ContainsKey(newPlayer.ActorNumber))
					{
						_playersWithoutAnticheat[newPlayer.ActorNumber] = DateTime.Now;
						Logger.LogInfo((object)("[AntiCheat] Started tracking " + newPlayer.NickName + " for anticheat timeout (10s from ping)"));
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendSyncToAllClients>d__91 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendSyncToAllClients>d__91(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Expected O, but got Unknown
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (PhotonNetwork.IsMasterClient)
					{
						Logger.LogInfo((object)"[MASTER CLIENT] Sending sync data to all clients");
						int[] array = (from b in BlockingManager.GetAllBlockedPlayers()
							select b.ActorNumber).ToArray();
						object[] array2 = DetectionManager.SerializeSettings();
						long[] array3 = (from id in BlockingManager.GetWhitelistedSteamIDs()
							select (long)id).ToArray();
						object[] array4 = new object[3] { array, array2, array3 };
						RaiseEventOptions val = new RaiseEventOptions
						{
							Receivers = (ReceiverGroup)0
						};
						PhotonNetwork.RaiseEvent((byte)105, (object)array4, val, SendOptions.SendReliable);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendUnauthorizedBananaSlipToMaster>d__119 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendUnauthorizedBananaSlipToMaster>d__119(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Character val = null;
					Character[] array = Object.FindObjectsOfType<Character>();
					Character[] array2 = array;
					foreach (Character val2 in array2)
					{
						PhotonView component = ((Component)val2).GetComponent<PhotonView>();
						if ((Object)(object)component != (Object)null && component.Owner != null && component.Owner.IsMasterClient)
						{
							val = val2;
							break;
						}
					}
					if ((Object)(object)val == (Object)null)
					{
						Logger.LogWarning((object)"[AntiCheat] Could not find master client's character for cheat mod detection");
						return false;
					}
					PhotonView component2 = ((Component)val).GetComponent<PhotonView>();
					if ((Object)(object)component2 == (Object)null)
					{
						Logger.LogWarning((object)"[AntiCheat] Master client's character has no PhotonView");
						return false;
					}
					BananaPeel val3 = Object.FindFirstObjectByType<BananaPeel>();
					if ((Object)(object)val3 == (Object)null)
					{
						val3 = PhotonNetwork.Instantiate("0_Items/Berrynana Peel Pink Variant", val.Head, Quaternion.identity, (byte)0, (object[])null).GetComponent<BananaPeel>();
						Logger.LogWarning((object)"[AntiCheat] Spawned banana peel for cheat detection");
					}
					Logger.LogWarning((object)$"[AntiCheat] Cheat mod detected - sending unauthorized banana slip RPC to banana peel (ViewID: {((Component)val3).GetComponent<PhotonView>().ViewID})");
					((Component)val3).GetComponent<PhotonView>().RPC("RPCA_TriggerBanana", (RpcTarget)0, new object[1] { component2.ViewID });
					Logger.LogWarning((object)"[AntiCheat] Unauthorized banana slip RPC sent - should trigger detection on master client");
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SendUnauthorizedBananaSlipToMasterDelayed>d__121 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendUnauthorizedBananaSlipToMasterDelayed>d__121(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)antiCheatPlugin).StartCoroutine(antiCheatPlugin.SendUnauthorizedBananaSlipToMaster());
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ShowAnticheatLoadedMessage>d__49 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private float <roomTimeout>5__2;

			private float <roomElapsed>5__3;

			private float <timeout>5__4;

			private float <elapsed>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShowAnticheatLoadedMessage>d__49(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Expected O, but got Unknown
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					_startupMessageShown = true;
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<roomTimeout>5__2 = 10f;
					<roomElapsed>5__3 = 0f;
					goto IL_0096;
				case 2:
					<>1__state = -1;
					<roomElapsed>5__3 += 0.25f;
					goto IL_0096;
				case 3:
					{
						<>1__state = -1;
						<elapsed>5__5 += 0.25f;
						_connectionLog = Object.FindObjectOfType<PlayerConnectionLog>();
						if ((Object)(object)_connectionLog != (Object)null)
						{
							Logger.LogInfo((object)"[PEAKAntiCheat] Found PlayerConnectionLog, initializing reflection cache");
							InitializeReflectionCache();
						}
						break;
					}
					IL_0096:
					if (!PhotonNetwork.InRoom && <roomElapsed>5__3 < <roomTimeout>5__2)
					{
						<>2__current = (object)new WaitForSeconds(0.25f);
						<>1__state = 2;
						return true;
					}
					if (!PhotonNetwork.InRoom)
					{
						Logger.LogWarning((object)"[PEAKAntiCheat] Not in room after timeout, skipping anticheat loaded message");
						return false;
					}
					if (!PhotonNetwork.IsMasterClient)
					{
						Logger.LogInfo((object)"[PEAKAntiCheat] Not master client, skipping anticheat loaded message");
						return false;
					}
					<timeout>5__4 = 5f;
					<elapsed>5__5 = 0f;
					break;
				}
				if ((Object)(object)_connectionLog == (Object)null && <elapsed>5__5 < <timeout>5__4)
				{
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 3;
					return true;
				}
				if ((Object)(object)_connectionLog != (Object)null)
				{
					Logger.LogInfo((object)"[PEAKAntiCheat] Showing anticheat loaded message");
					LogVisually("{joinedColor}Anticheat loaded! Press F2 to open manager.</color>", onlySendOnce: false, sfxJoin: true);
				}
				else
				{
					Logger.LogWarning((object)"[PEAKAntiCheat] PlayerConnectionLog not found after timeout, message will be queued");
					LogVisually("{joinedColor}Anticheat loaded! Press F2 to open manager.</color>", onlySendOnce: false, sfxJoin: true);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TestUIGameObject>d__48 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TestUIGameObject>d__48(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					GameObject val = GameObject.Find("AntiCheatUI");
					if ((Object)(object)val != (Object)null)
					{
						Logger.LogInfo((object)$"[PEAKAntiCheat] Found UI GameObject: {((Object)val).name}, Active: {val.activeInHierarchy}");
						AntiCheatUI component = val.GetComponent<AntiCheatUI>();
						if ((Object)(object)component != (Object)null)
						{
							Logger.LogInfo((object)$"[PEAKAntiCheat] Found UI component: {((Behaviour)component).enabled}");
						}
						else
						{
							Logger.LogWarning((object)"[PEAKAntiCheat] UI component not found!");
						}
					}
					else
					{
						Logger.LogWarning((object)"[PEAKAntiCheat] UI GameObject not found!");
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TrackModListOptOut>d__145 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TrackModListOptOut>d__145(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					foreach (Player value in PhotonNetwork.CurrentRoom.Players.Values)
					{
						if (value.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber && !_playerModLists.ContainsKey(value.ActorNumber))
						{
							_playersOptedOutOfModSharing.Add(value.ActorNumber);
							Logger.LogInfo((object)("[PEAKAntiCheat] Player " + value.NickName + " has opted out of mod sharing"));
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TrackPlayerCoordinates>d__110 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AntiCheatPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TrackPlayerCoordinates>d__110(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				AntiCheatPlugin antiCheatPlugin = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (PhotonNetwork.InRoom)
					{
						Character[] array = Object.FindObjectsOfType<Character>();
						Character[] array2 = array;
						foreach (Character val in array2)
						{
							PhotonView component = ((Component)val).GetComponent<PhotonView>();
							if (!((Object)(object)component == (Object)null) && component.Owner != null && !IsBlocked(component.Owner.ActorNumber))
							{
								Vector3 position = ((Component)val).transform.position;
								_playerLastKnownCoordinates[component.Owner.ActorNumber] = position;
								_playerCoordinateTimestamps[component.Owner.ActorNumber] = DateTime.Now;
								if (PhotonNetwork.IsMasterClient)
								{
									antiCheatPlugin.CheckAndRescuePlayerFromInfinity(val, component.Owner);
								}
							}
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForSeconds(10f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TrackPlayerItems>d__109 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TrackPlayerItems>d__109(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					if (PhotonNetwork.InRoom)
					{
						Character[] array = Object.FindObjectsOfType<Character>();
						Character[] array2 = array;
						foreach (Character val in array2)
						{
							PhotonView component = ((Component)val).GetComponent<PhotonView>();
							if (!((Object)(object)component == (Object)null) && component.Owner != null && !IsBlocked(component.Owner.ActorNumber))
							{
								CharacterData component2 = ((Component)val).GetComponent<CharacterData>();
								if ((Object)(object)component2 != (Object)null && (Object)(object)component2.currentItem != (Object)null)
								{
									bool wasCookable = (Object)(object)component2.currentItem.cooking != (Object)null && component2.currentItem.cooking.canBeCooked;
									UpdatePlayerHeldItem(component.Owner.ActorNumber, ((Object)component2.currentItem).name, wasCookable);
								}
							}
						}
					}
				}
				else
				{
					<>1__state = -1;
				}
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitForPersonaStateChange>d__89 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CSteamID steamId;

			public Player player;

			private <>c__DisplayClass89_0 <>8__1;

			public float timeout;

			public bool blockOnMismatch;

			private float <startTime>5__2;

			private Callback<PersonaStateChange_t> <personaCallback>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForPersonaStateChange>d__89(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<personaCallback>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Expected O, but got Unknown
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_02da: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_020d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0213: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass89_0();
					<>8__1.steamId = steamId;
					<startTime>5__2 = Time.time;
					<>8__1.receivedUpdate = false;
					<personaCallback>5__3 = null;
					<personaCallback>5__3 = Callback<PersonaStateChange_t>.Create((DispatchDelegate<PersonaStateChange_t>)delegate(PersonaStateChange_t param)
					{
						//IL_0000: Unknown result type (might be due to invalid IL or missing references)
						//IL_0013: Unknown result type (might be due to invalid IL or missing references)
						//IL_0014: Unknown result type (might be due to invalid IL or missing references)
						//IL_001a: Unknown result type (might be due to invalid IL or missing references)
						//IL_002f: Unknown result type (might be due to invalid IL or missing references)
						if (param.m_ulSteamID == <>8__1.steamId.m_SteamID && (param.m_nChangeFlags & 1) != 0)
						{
							<>8__1.receivedUpdate = true;
							Logger.LogInfo((object)$"Received PersonaStateChange for {<>8__1.steamId} - name was updated");
						}
					});
					break;
				case 1:
					<>1__state = -1;
					if (PhotonNetwork.CurrentRoom == null || PhotonNetwork.CurrentRoom.GetPlayer(player.ActorNumber, false) == null)
					{
						Logger.LogInfo((object)("Player " + player.NickName + " left before name verification completed"));
						<personaCallback>5__3?.Dispose();
						return false;
					}
					break;
				}
				if (!<>8__1.receivedUpdate && Time.time - <startTime>5__2 < timeout)
				{
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				<personaCallback>5__3?.Dispose();
				string friendPersonaName = SteamFriends.GetFriendPersonaName(<>8__1.steamId);
				if (friendPersonaName.ToLower() != player.NickName.ToLower())
				{
					if (blockOnMismatch)
					{
						Logger.LogWarning((object)("Name mismatch confirmed after PersonaStateChange: Photon='" + player.NickName + "' vs Steam='" + friendPersonaName + "'"));
						LogVisually("{userColor}" + player.NickName + "</color> {leftColor}confirmed spoofing - real Steam name is '" + friendPersonaName + "'!</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
						if (PhotonNetwork.CurrentRoom != null && PhotonNetwork.CurrentRoom.GetPlayer(player.ActorNumber, false) != null)
						{
							DetectionManager.RecordDetection(DetectionType.SteamNameMismatch, player, "Name spoofing confirmed - real name: " + friendPersonaName);
						}
					}
					else
					{
						Logger.LogWarning((object)("Name mismatch on join after refresh: Photon='" + player.NickName + "' vs Steam='" + friendPersonaName + "'"));
						LogVisually("{userColor}" + player.NickName + "</color> {leftColor}has mismatched Steam name: '" + friendPersonaName + "'</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
						DetectionManager.RecordDetection(DetectionType.SteamNameMismatch, player, "Name mismatch: Photon='" + player.NickName + "' vs Steam='" + friendPersonaName + "'");
					}
				}
				else
				{
					Logger.LogInfo((object)("Name verification passed for " + player.NickName + " after fresh data"));
					LogVisually("{userColor}" + player.NickName + "</color> {joinedColor}name verified successfully</color>", onlySendOnce: true);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static ManualLogSource Logger;

		public static ConfigFile Config;

		private static readonly Dictionary<int, (string itemName, DateTime timestamp, bool wasCookable)> _playerLastHeldItems = new Dictionary<int, (string, DateTime, bool)>();

		private static readonly Dictionary<int, Vector3> _playerLastKnownCoordinates = new Dictionary<int, Vector3>();

		private static readonly Dictionary<int, DateTime> _playerCoordinateTimestamps = new Dictionary<int, DateTime>();

		private const float COORDINATE_UPDATE_INTERVAL = 10f;

		private static readonly Dictionary<int, GameObject> _blockedPlayerHeldItems = new Dictionary<int, GameObject>();

		private const string PLUGIN_VERSION = "1.4.8";

		private const byte ANTICHEAT_PING_EVENT = 69;

		private static ConfigEntry<bool> ShowVisualLogs;

		private static ConfigEntry<bool> CheckSteamNames;

		public static ConfigEntry<bool> AutoBlockCheaters;

		public static ConfigEntry<bool> VerboseRPCLogging;

		private static ConfigEntry<string> WhitelistedSteamIDs;

		public static ConfigEntry<KeyboardShortcut> UIToggleKey;

		private static PlayerConnectionLog _connectionLog;

		private static readonly Queue<(string message, bool onlySendOnce, bool sfxJoin, bool sfxLeave)> _queuedLogs = new Queue<(string, bool, bool, bool)>(8);

		private static readonly List<PlayerIdentity> _knownPlayerIdentities = new List<PlayerIdentity>();

		private static MethodInfo _getColorTagMethod;

		private static MethodInfo _addMessageMethod;

		private static FieldInfo _currentLogField;

		private static FieldInfo _joinedColorField;

		private static FieldInfo _leftColorField;

		private static FieldInfo _userColorField;

		private static FieldInfo _sfxJoinField;

		private static FieldInfo _sfxLeaveField;

		private static Func<object, string> _getColorTagDelegate;

		private static Action<object, string> _addMessageDelegate;

		private static FieldInfo _currentLobbyField;

		private static readonly Dictionary<int, DateTime> _recentlySpawnedPlayers = new Dictionary<int, DateTime>();

		private const double SPAWN_GRACE_PERIOD_SECONDS = 5.0;

		private static readonly Dictionary<int, string> _anticheatUsers = new Dictionary<int, string>();

		private static readonly Dictionary<int, string[]> _playerModLists = new Dictionary<int, string[]>();

		private static readonly HashSet<int> _playersOptedOutOfModSharing = new HashSet<int>();

		private static readonly HashSet<string> _recentDetections = new HashSet<string>();

		private static readonly HashSet<int> _detectedCheatModUsers = new HashSet<int>();

		private static bool _startupMessageShown = false;

		private static readonly Dictionary<int, DateTime> _playersWithoutAnticheat = new Dictionary<int, DateTime>();

		private const float ANTICHEAT_TIMEOUT_SECONDS = 10f;

		private static DateTime _lastMasterClientChange = DateTime.MinValue;

		private const float MASTER_CLIENT_CHANGE_COOLDOWN_SECONDS = 30f;

		public static ConfigEntry<bool> ShareModList;

		private const string DEV_STEAM_ID = "STEAM_0:0:143296685";

		public static AntiCheatPlugin Instance { get; private set; }

		public static bool AutoKickBlockedPlayers { get; set; } = false;


		public static bool AutoBlockNoAnticheat { get; set; } = false;


		private void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "com.hiccup444.anticheat.cfg"), true);
			ShowVisualLogs = Config.Bind<bool>("General", "ShowVisualLogs", true, "Show anti-cheat messages in the connection log");
			CheckSteamNames = Config.Bind<bool>("General", "CheckSteamNames", true, "Check if Photon names match Steam names");
			AutoBlockCheaters = Config.Bind<bool>("General", "AutoBlockCheaters", true, "Automatically block all RPCs from detected cheaters");
			VerboseRPCLogging = Config.Bind<bool>("Debug", "VerboseRPCLogging", false, "Log all RPC calls for debugging");
			WhitelistedSteamIDs = Config.Bind<string>("General", "WhitelistedSteamIDs", "", "Comma-separated list of Steam IDs that should never be RPC blocked (e.g. '76561198012345678,76561198087654321')");
			UIToggleKey = Config.Bind<KeyboardShortcut>("General", "UIToggleKey", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Key to toggle the anti-cheat UI (default: F2)");
			ShareModList = Config.Bind<bool>("General", "ShareModList", true, "Share your mod list with the host (enabled by default)");
			ParseWhitelist();
			Config.Save();
			InitializeDetectionManager();
			InitializeEventHandlers();
			Logger.LogInfo((object)"[PEAKAntiCheat] Protection active! (RPC Blocking Mode)");
			Harmony val = new Harmony("com.hiccup444.PEAKanticheat");
			val.PatchAll();
			PhotonNetwork.AddCallbackTarget((object)this);
			((MonoBehaviour)this).StartCoroutine(CheckPlayersForCheats());
			((MonoBehaviour)this).StartCoroutine(TrackPlayerItems());
			((MonoBehaviour)this).StartCoroutine(TrackPlayerCoordinates());
			((MonoBehaviour)this).StartCoroutine(CheckPlayersWithoutAnticheat());
			SceneManager.activeSceneChanged += OnSceneChanged;
		}

		private void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			Logger.LogInfo((object)("[PEAKAntiCheat] Scene changed from " + ((Scene)(ref oldScene)).name + " to " + ((Scene)(ref newScene)).name));
			if (((Scene)(ref newScene)).name.Contains("Airport") || ((Scene)(ref newScene)).name.Contains("Level"))
			{
				Logger.LogInfo((object)("[PEAKAntiCheat] Game scene detected: " + ((Scene)(ref newScene)).name + " - creating UI"));
				CreateUI();
				if (((Scene)(ref newScene)).name.Contains("Airport") && !_startupMessageShown)
				{
					((MonoBehaviour)this).StartCoroutine(ShowAnticheatLoadedMessage());
				}
			}
			if (((Scene)(ref newScene)).name.Contains("Level"))
			{
				Player[] playerList = PhotonNetwork.PlayerList;
				foreach (Player val in playerList)
				{
					OnPlayerSpawned(val.ActorNumber);
				}
				if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null)
				{
					OnPlayerSpawned(PhotonNetwork.LocalPlayer.ActorNumber);
				}
				Logger.LogInfo((object)("Entered game scene '" + ((Scene)(ref newScene)).name + "' - granting spawn grace period to all players including local"));
			}
		}

		private void CreateUI()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			GameObject val = GameObject.Find("AntiCheatUI");
			if ((Object)(object)val != (Object)null)
			{
				Logger.LogInfo((object)"[PEAKAntiCheat] UI already exists, skipping creation");
				return;
			}
			Logger.LogInfo((object)"[PEAKAntiCheat] Creating UI...");
			GameObject val2 = new GameObject("AntiCheatUI");
			Logger.LogInfo((object)$"[PEAKAntiCheat] UI GameObject created: {((Object)val2).name}, Active: {val2.activeInHierarchy}");
			AntiCheatUI antiCheatUI = val2.AddComponent<AntiCheatUI>();
			Logger.LogInfo((object)$"[PEAKAntiCheat] UI component added: {(Object)(object)antiCheatUI != (Object)null}, Component enabled: {((antiCheatUI != null) ? new bool?(((Behaviour)antiCheatUI).enabled) : null)}");
			val2.SetActive(true);
			Logger.LogInfo((object)$"[PEAKAntiCheat] UI GameObject activated: {val2.activeInHierarchy}");
			if ((Object)(object)antiCheatUI != (Object)null)
			{
				Logger.LogInfo((object)"[PEAKAntiCheat] Manually calling Start method on UI component");
				((Component)antiCheatUI).SendMessage("Start", (SendMessageOptions)1);
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			Logger.LogInfo((object)"[PEAKAntiCheat] UI set to persist across scenes");
			Logger.LogInfo((object)"[PEAKAntiCheat] UI creation completed");
			((MonoBehaviour)this).StartCoroutine(TestUIGameObject());
		}

		[IteratorStateMachine(typeof(<TestUIGameObject>d__48))]
		private IEnumerator TestUIGameObject()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TestUIGameObject>d__48(0);
		}

		[IteratorStateMachine(typeof(<ShowAnticheatLoadedMessage>d__49))]
		private IEnumerator ShowAnticheatLoadedMessage()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShowAnticheatLoadedMessage>d__49(0);
		}

		private void InitializeDetectionManager()
		{
			bool flag = false;
			ConfigEntry<string> val = Config.Bind<string>("UI", "GroupSliders", "", "Saved group slider settings");
			ConfigEntry<string> val2 = Config.Bind<string>("UI", "IndividualSliders", "", "Saved individual slider settings");
			if (!string.IsNullOrEmpty(val.Value) || !string.IsNullOrEmpty(val2.Value))
			{
				flag = true;
				Logger.LogInfo((object)"[PEAKAntiCheat] UI settings detected - skipping default detection initialization");
			}
			if (!flag)
			{
				Logger.LogInfo((object)"[PEAKAntiCheat] No UI settings found - initializing with default detection settings");
				DetectionManager.SetDetectionSettings(DetectionType.CherryMod, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.AtlasMod, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.SteamNameMismatch, new DetectionSettings(CheckSteamNames.Value, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.NameImpersonation, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.MidGameNameChange, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.SteamIDSpoofing, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.OwnershipTheft, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedDestroy, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.RateLimitExceeded, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedKill, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedRevive, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedWarp, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedStatusEffect, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedMovement, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedEmote, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedItemDrop, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedCampfireModification, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedFlareLighting, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.UnauthorizedBananaSlip, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.MasterClientTheft, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
				DetectionManager.SetDetectionSettings(DetectionType.InfinityWarp, new DetectionSettings(isEnabled: true, AutoBlockCheaters.Value, ShowVisualLogs.Value));
			}
		}

		private void InitializeEventHandlers()
		{
			DetectionManager.OnDetectionOccurred += OnDetectionOccurred;
			PlayerManager.OnPlayerAdded += OnPlayerAdded;
			PlayerManager.OnPlayerStatusChanged += OnPlayerStatusChanged;
			BlockingManager.OnPlayerBlocked += OnPlayerBlocked;
			BlockingManager.OnPlayerUnblocked += OnPlayerUnblocked;
		}

		private void Update()
		{
			AutokillManager.KillPlayers();
			RPCDetection.ProcessPendingItemChecks();
			if (_queuedLogs.Count > 0)
			{
				var (message, onlySendOnce, sfxJoin, sfxLeave) = _queuedLogs.Dequeue();
				LogVisually(message, onlySendOnce, sfxJoin, sfxLeave, allowNonMaster: true);
			}
		}

		private void OnDestroy()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
			SceneManager.activeSceneChanged -= OnSceneChanged;
			DetectionManager.OnDetectionOccurred -= OnDetectionOccurred;
			PlayerManager.OnPlayerAdded -= OnPlayerAdded;
			PlayerManager.OnPlayerStatusChanged -= OnPlayerStatusChanged;
			BlockingManager.OnPlayerBlocked -= OnPlayerBlocked;
			BlockingManager.OnPlayerUnblocked -= OnPlayerUnblocked;
		}

		private void OnDetectionOccurred(DetectionResult result)
		{
			if (result.Target == null)
			{
				return;
			}
			if (DetectionManager.ShouldLogToConsole(result.Type))
			{
				Logger.LogWarning((object)$"[DETECTION] {result.Target.NickName} ({result.Type}): {result.Reason}");
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				ReportDetectionToMaster(result.Type, result.Target, result.Reason);
				return;
			}
			DetectionSettings detectionSettings = DetectionManager.GetDetectionSettings(result.Type);
			if (detectionSettings.IsEnabled)
			{
				LogVisually("{userColor}" + result.Target.NickName + "</color> {leftColor}" + result.Reason + "</color>", onlySendOnce: false, sfxJoin: false, sfxLeave: true);
				if (detectionSettings.AutoBlock)
				{
					BlockPlayer(result.Target, result.Reason, result.Type);
					LogVisually($"{{userColor}}{result.Target.NickName}</color> {{leftColor}}was auto-blocked for {result.Type}</color>", onlySendOnce: false, sfxJoin: false, sfxLeave: true);
				}
				else if (detectionSettings.ShowVisualWarning)
				{
					string text = $"{result.Target.ActorNumber}_{result.Type}";
					if (!_recentDetections.Contains(text))
					{
						LogVisually($"{{userColor}}{result.Target.NickName}</color> {{leftColor}}detected - {result.Type} - no action taken</color>", onlySendOnce: false, sfxJoin: false, sfxLeave: true);
						_recentDetections.Add(text);
						((MonoBehaviour)this).StartCoroutine(RemoveDetectionFromRecent(text, 30f));
					}
				}
			}
			PlayerManager.AddDetectionReason(result.Target.ActorNumber, result.Reason);
		}

		[IteratorStateMachine(typeof(<RemoveDetectionFromRecent>d__55))]
		private IEnumerator RemoveDetectionFromRecent(string detectionKey, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RemoveDetectionFromRecent>d__55(0)
			{
				detectionKey = detectionKey,
				delay = delay
			};
		}

		private void OnPlayerAdded(PlayerInfo playerInfo)
		{
			Logger.LogInfo((object)$"[PLAYER ADDED] {playerInfo.PhotonName} (Actor #{playerInfo.ActorNumber})");
		}

		private void OnPlayerStatusChanged(PlayerInfo playerInfo)
		{
			Logger.LogInfo((object)$"[STATUS CHANGE] {playerInfo.PhotonName}: {playerInfo.Status}");
		}

		private void OnPlayerBlocked(BlockEntry blockEntry)
		{
			Logger.LogWarning((object)("[PLAYER BLOCKED] " + blockEntry.PlayerName + ": " + blockEntry.SpecificReason));
		}

		private void OnPlayerUnblocked(int actorNumber)
		{
			Logger.LogInfo((object)$"[PLAYER UNBLOCKED] Actor #{actorNumber}");
			_detectedCheatModUsers.Remove(actorNumber);
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Player val = ((currentRoom != null) ? currentRoom.GetPlayer(actorNumber, false) : null);
			if (val != null)
			{
				string item = $"{val.NickName}_{actorNumber}_AtlasMod";
				_recentDetections.Remove(item);
				item = $"{val.NickName}_{actorNumber}_CherryMod";
				_recentDetections.Remove(item);
			}
			RPCDetection.ClearFlagCounts(actorNumber);
			BlockingManager.GrantImmunity(actorNumber);
			Logger.LogInfo((object)$"[PLAYER UNBLOCKED] Granted immunity to Actor #{actorNumber} to prevent re-detection");
		}

		public static void BlockPlayer(Player cheater, string reason, DetectionType? detectionType = null)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			Player cheater2 = cheater;
			if (cheater2.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
				Logger.LogInfo((object)"Not blocking local player");
				return;
			}
			if (cheater2.IsMasterClient)
			{
				Logger.LogWarning((object)("[BLOCK PREVENTED] Attempted to block master client " + cheater2.NickName + " for: " + reason));
				return;
			}
			bool flag = true;
			if (!((!detectionType.HasValue) ? AutoBlockCheaters.Value : DetectionManager.ShouldAutoBlock(detectionType.Value)))
			{
				Logger.LogInfo((object)("Auto-blocking disabled for this detection - only logging cheater: " + cheater2.NickName));
				return;
			}
			Logger.LogWarning((object)("CHEATER DETECTED: " + cheater2.NickName + " - Reason: " + reason));
			CSteamID nil = CSteamID.Nil;
			nil = _knownPlayerIdentities.Find((PlayerIdentity p) => p.ActorNumber == cheater2.ActorNumber)?.SteamID ?? GetPlayerSteamID(cheater2);
			AntiCheatEvents.NotifyCheaterDetected(cheater2, reason, nil);
			BlockingManager.BlockPlayer(cheater2, reason, BlockReason.AutoDetection, nil, detectionType);
			Logger.LogInfo((object)$"All RPCs from {cheater2.NickName} (Actor #{cheater2.ActorNumber}) are now blocked");
		}

		public static bool IsBlocked(int actorNumber)
		{
			return BlockingManager.IsBlocked(actorNumber);
		}

		public static bool HasAnticheat(int actorNumber)
		{
			return _anticheatUsers.ContainsKey(actorNumber);
		}

		public static string GetAnticheatVersion(int actorNumber)
		{
			if (!_anticheatUsers.TryGetValue(actorNumber, out string value))
			{
				return null;
			}
			return value;
		}

		public static bool AreKicksAllowed()
		{
			if (_lastMasterClientChange == DateTime.MinValue)
			{
				return true;
			}
			double totalSeconds = (DateTime.Now - _lastMasterClientChange).TotalSeconds;
			bool flag = totalSeconds >= 30.0;
			if (!flag)
			{
				Logger.LogWarning((object)$"[KICK SECURITY] Kicks disabled - master client changed {totalSeconds:F1} seconds ago (cooldown: {30f}s)");
			}
			return flag;
		}

		public static void UpdatePlayerHeldItem(int actorNumber, string itemName, bool wasCookable = false)
		{
			if (!string.IsNullOrEmpty(itemName))
			{
				_playerLastHeldItems[actorNumber] = (itemName.ToLower(), DateTime.Now, wasCookable);
			}
		}

		public static bool PlayerHadItem(int actorNumber, string itemNamePart, float withinSeconds = 2f, bool checkCookable = false)
		{
			if (_playerLastHeldItems.TryGetValue(actorNumber, out (string, DateTime, bool) value))
			{
				double totalSeconds = (DateTime.Now - value.Item2).TotalSeconds;
				if (totalSeconds <= (double)withinSeconds)
				{
					if (checkCookable)
					{
						return value.Item3;
					}
					return value.Item1.Contains(itemNamePart.ToLower());
				}
			}
			return false;
		}

		public static bool PlayerHadCookableItem(int actorNumber, float withinSeconds = 2f)
		{
			return PlayerHadItem(actorNumber, "", withinSeconds, checkCookable: true);
		}

		private static void InitializeReflectionCache()
		{
			if ((Object)(object)_connectionLog == (Object)null)
			{
				_connectionLog = Object.FindObjectOfType<PlayerConnectionLog>();
				if ((Object)(object)_connectionLog == (Object)null)
				{
					Logger.LogWarning((object)"[PEAKAntiCheat] PlayerConnectionLog not found in scene");
					return;
				}
				Logger.LogInfo((object)"[PEAKAntiCheat] Found PlayerConnectionLog, setting up reflection cache");
			}
			Type type = ((object)_connectionLog).GetType();
			_getColorTagMethod = type.GetMethod("GetColorTag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_addMessageMethod = type.GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_currentLogField = type.GetField("currentLog", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_joinedColorField = type.GetField("joinedColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_leftColorField = type.GetField("leftColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_userColorField = type.GetField("userColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_sfxJoinField = type.GetField("sfxJoin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_sfxLeaveField = type.GetField("sfxLeave", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			try
			{
				if (_getColorTagMethod != null)
				{
					_getColorTagDelegate = (Func<object, string>)Delegate.CreateDelegate(typeof(Func<object, string>), _connectionLog, _getColorTagMethod);
				}
				if (_addMessageMethod != null)
				{
					_addMessageDelegate = (Action<object, string>)Delegate.CreateDelegate(typeof(Action<object, string>), _connectionLog, _addMessageMethod);
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Reflection Cache] Failed to create delegates, falling back to direct reflection: " + ex.Message));
				_getColorTagDelegate = null;
				_addMessageDelegate = null;
			}
		}

		public static bool LogVisually(string message, bool onlySendOnce = false, bool sfxJoin = false, bool sfxLeave = false, bool allowNonMaster = false)
		{
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient && !allowNonMaster && !message.Contains("has anticheat installed"))
			{
				return true;
			}
			if (!ShowVisualLogs.Value)
			{
				return true;
			}
			if ((Object)(object)_connectionLog == (Object)null || _getColorTagMethod == null || _addMessageMethod == null)
			{
				InitializeReflectionCache();
			}
			if (!Object.op_Implicit((Object)(object)_connectionLog) || _getColorTagMethod == null || _addMessageMethod == null)
			{
				Logger.LogWarning((object)$"[PEAKAntiCheat] LogVisually failed - ConnectionLog: {(Object)(object)_connectionLog != (Object)null}, GetColorTagMethod: {_getColorTagMethod != null}, AddMessageMethod: {_addMessageMethod != null}");
				_queuedLogs.Enqueue((message, onlySendOnce, sfxJoin, sfxLeave));
				return false;
			}
			try
			{
				StringBuilder stringBuilder = new StringBuilder(message);
				if (_joinedColorField != null && _leftColorField != null && _userColorField != null)
				{
					object value = _joinedColorField.GetValue(_connectionLog);
					object value2 = _leftColorField.GetValue(_connectionLog);
					object value3 = _userColorField.GetValue(_connectionLog);
					string text = "";
					string text2 = "";
					string text3 = "";
					if (_getColorTagDelegate != null)
					{
						text = _getColorTagDelegate(value);
						text2 = _getColorTagDelegate(value2);
						text3 = _getColorTagDelegate(value3);
					}
					else if (_getColorTagMethod != null)
					{
						text = (string)_getColorTagMethod.Invoke(_connectionLog, new object[1] { value });
						text2 = (string)_getColorTagMethod.Invoke(_connectionLog, new object[1] { value2 });
						text3 = (string)_getColorTagMethod.Invoke(_connectionLog, new object[1] { value3 });
					}
					stringBuilder.Replace("{joinedColor}", text ?? "");
					stringBuilder.Replace("{leftColor}", text2 ?? "");
					stringBuilder.Replace("{userColor}", text3 ?? "");
				}
				message = stringBuilder.ToString();
				if (onlySendOnce && _currentLogField != null)
				{
					string text4 = _currentLogField.GetValue(_connectionLog) as string;
					if (!string.IsNullOrEmpty(text4) && text4.Contains(message))
					{
						return true;
					}
				}
				if (_addMessageDelegate != null)
				{
					_addMessageDelegate(_connectionLog, message);
				}
				else
				{
					_addMessageMethod.Invoke(_connectionLog, new object[1] { message });
				}
				if (sfxJoin && _sfxJoinField != null)
				{
					object value4 = _sfxJoinField.GetValue(_connectionLog);
					value4?.GetType().GetMethod("Play", new Type[1] { typeof(Vector3) })?.Invoke(value4, new object[1] { Vector3.zero });
				}
				if (sfxLeave && _sfxLeaveField != null)
				{
					object value5 = _sfxLeaveField.GetValue(_connectionLog);
					value5?.GetType().GetMethod("Play", new Type[1] { typeof(Vector3) })?.Invoke(value5, new object[1] { Vector3.zero });
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error in LogVisually: " + ex.Message));
				return false;
			}
		}

		public static void OnPlayerSpawned(int actorNumber)
		{
			_recentlySpawnedPlayers[actorNumber] = DateTime.Now;
			Logger.LogInfo((object)$"Tracking spawn for actor #{actorNumber}");
		}

		public static bool IsInSpawnGracePeriod(int actorNumber)
		{
			if (_recentlySpawnedPlayers.ContainsKey(actorNumber))
			{
				if ((DateTime.Now - _recentlySpawnedPlayers[actorNumber]).TotalSeconds <= 5.0)
				{
					return true;
				}
				_recentlySpawnedPlayers.Remove(actorNumber);
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerConnectionLog), "OnPlayerEnteredRoom")]
		[HarmonyPrefix]
		public static bool PreOnPlayerEnteredRoom(PlayerConnectionLog __instance, Player newPlayer)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			if (newPlayer.IsLocal || newPlayer.NickName == "Bing Bong")
			{
				return true;
			}
			bool flag = false;
			try
			{
				CSteamID playerSteamID = GetPlayerSteamID(newPlayer);
				if (playerSteamID != CSteamID.Nil)
				{
					string text = ((object)(CSteamID)(ref playerSteamID)).ToString();
					flag = text == "STEAM_0:0:143296685";
					if (flag)
					{
						Logger.LogInfo((object)("[DEV JOIN] Detected dev joining: " + newPlayer.NickName + " (Steam ID: " + text + ")"));
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[DEV JOIN] Error checking Steam ID for " + newPlayer.NickName + ": " + ex.Message));
			}
			if (flag)
			{
				try
				{
					FieldInfo field = ((object)__instance).GetType().GetField("userColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field2 = ((object)__instance).GetType().GetField("joinedColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field3 = ((object)__instance).GetType().GetField("sfxJoin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					MethodInfo method = ((object)__instance).GetType().GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					MethodInfo method2 = ((object)__instance).GetType().GetMethod("GetColorTag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null && field2 != null && method != null && method2 != null)
					{
						Color val = (Color)field.GetValue(__instance);
						Color val2 = (Color)field2.GetValue(__instance);
						string text2 = (string)method2.Invoke(__instance, new object[1] { val });
						string text3 = (string)method2.Invoke(__instance, new object[1] { val2 });
						string newValue = text2 + " [Anticheat Dev] " + newPlayer.NickName + "</color>";
						string text4 = text3 + LocalizedText.GetText("JOINEDTHEEXPEDITION", true).Replace("#", newValue) + "</color>";
						method.Invoke(__instance, new object[1] { text4 });
						if (field3 != null)
						{
							object value = field3.GetValue(__instance);
							value?.GetType().GetMethod("Play", new Type[1] { typeof(Vector3) })?.Invoke(value, new object[1] { Vector3.zero });
						}
						Logger.LogInfo((object)("[DEV JOIN] Custom dev join message displayed for " + newPlayer.NickName));
						return false;
					}
				}
				catch (Exception ex2)
				{
					Logger.LogError((object)("[DEV JOIN] Error creating custom dev message: " + ex2.Message));
				}
			}
			return true;
		}

		private static CSteamID GetPlayerSteamID(Player player)
		{
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
				if (service == null)
				{
					Logger.LogWarning((object)"[GetPlayerSteamID] SteamLobbyHandler not found.");
					return CSteamID.Nil;
				}
				if (_currentLobbyField == null)
				{
					Type type = ((object)service).GetType();
					_currentLobbyField = type.GetField("m_currentLobby", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				if (_currentLobbyField == null)
				{
					Logger.LogError((object)"[GetPlayerSteamID] Could not find m_currentLobby field via reflection.");
					return CSteamID.Nil;
				}
				CSteamID val = (CSteamID)_currentLobbyField.GetValue(service);
				if (val == CSteamID.Nil)
				{
					Logger.LogWarning((object)"[GetPlayerSteamID] Current Steam lobby is NIL.");
					return CSteamID.Nil;
				}
				int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(val);
				Logger.LogInfo((object)$"[GetPlayerSteamID] Scanning {numLobbyMembers} Steam lobby members for match with Photon name '{player.NickName}'.");
				Dictionary<string, List<CSteamID>> dictionary = new Dictionary<string, List<CSteamID>>();
				List<CSteamID> list = new List<CSteamID>();
				for (int i = 0; i < numLobbyMembers; i++)
				{
					CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(val, i);
					string friendPersonaName = SteamFriends.GetFriendPersonaName(lobbyMemberByIndex);
					if (!dictionary.ContainsKey(friendPersonaName))
					{
						dictionary[friendPersonaName] = new List<CSteamID>();
					}
					dictionary[friendPersonaName].Add(lobbyMemberByIndex);
					list.Add(lobbyMemberByIndex);
				}
				if (dictionary.ContainsKey(player.NickName))
				{
					List<CSteamID> list2 = dictionary[player.NickName];
					Logger.LogInfo((object)string.Format("[GetPlayerSteamID] Found {0} Steam players with name '{1}': {2}", list2.Count, player.NickName, string.Join(", ", list2)));
					List<Player> list3 = new List<Player>();
					Player[] playerList = PhotonNetwork.PlayerList;
					foreach (Player val2 in playerList)
					{
						if (val2.NickName == player.NickName)
						{
							list3.Add(val2);
						}
					}
					if (list2.Count == 1 && list3.Count == 1)
					{
						Logger.LogInfo((object)$"[GetPlayerSteamID] Unique match found: {player.NickName} -> {list2[0]}");
						return list2[0];
					}
					if (list2.Count > 1)
					{
						HashSet<CSteamID> hashSet = new HashSet<CSteamID>();
						Player[] playerList2 = PhotonNetwork.PlayerList;
						foreach (Player val3 in playerList2)
						{
							if (val3.ActorNumber != player.ActorNumber)
							{
								CSteamID playerSteamID = GetPlayerSteamID(val3);
								if (playerSteamID != CSteamID.Nil)
								{
									hashSet.Add(playerSteamID);
								}
							}
						}
						foreach (CSteamID item in list2)
						{
							if (!hashSet.Contains(item))
							{
								Logger.LogInfo((object)$"[GetPlayerSteamID] Found unassigned Steam ID for {player.NickName}: {item}");
								return item;
							}
						}
						Logger.LogWarning((object)("[GetPlayerSteamID] No unassigned Steam IDs found for " + player.NickName));
					}
				}
				int num = PhotonNetwork.PlayerList.Length;
				if (num > numLobbyMembers)
				{
					Logger.LogWarning((object)$"[GetPlayerSteamID] More Photon players ({num}) than Steam lobby members ({numLobbyMembers}). Possible spoofer.");
					return CSteamID.Nil;
				}
				HashSet<CSteamID> hashSet2 = new HashSet<CSteamID>();
				Player[] playerList3 = PhotonNetwork.PlayerList;
				foreach (Player val4 in playerList3)
				{
					if (val4.ActorNumber != player.ActorNumber)
					{
						CSteamID playerSteamID2 = GetPlayerSteamID(val4);
						if (playerSteamID2 != CSteamID.Nil)
						{
							hashSet2.Add(playerSteamID2);
						}
					}
				}
				foreach (CSteamID item2 in list)
				{
					if (!hashSet2.Contains(item2))
					{
						Logger.LogInfo((object)$"[GetPlayerSteamID] Found unassigned Steam ID for {player.NickName}: {item2}");
						return item2;
					}
				}
				Logger.LogWarning((object)$"[GetPlayerSteamID] No unassigned Steam IDs found. All {numLobbyMembers} lobby members are accounted for.");
				return CSteamID.Nil;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("[GetPlayerSteamID] Error getting Steam ID for " + player.NickName + ": " + ex.Message));
				return CSteamID.Nil;
			}
		}

		private static void ParseWhitelist()
		{
			string value = WhitelistedSteamIDs.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return;
			}
			string[] array = value.Split(',');
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Trim();
				if (ulong.TryParse(text2, out var result))
				{
					BlockingManager.AddToWhitelist(result);
					Logger.LogInfo((object)$"[WHITELIST] Added Steam ID to whitelist: {result}");
				}
				else if (!string.IsNullOrEmpty(text2))
				{
					Logger.LogWarning((object)("[WHITELIST] Invalid Steam ID format: " + text2));
				}
			}
		}

		[IteratorStateMachine(typeof(<CheckPlayersForCheats>d__85))]
		private IEnumerator CheckPlayersForCheats()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckPlayersForCheats>d__85(0)
			{
				<>4__this = this
			};
		}

		private void CheckPlayerForCheatMods(Player player)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			Player player2 = player;
			if (player2.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			if (!_knownPlayerIdentities.Exists((PlayerIdentity p) => p.ActorNumber == player2.ActorNumber))
			{
				CSteamID playerSteamID = GetPlayerSteamID(player2);
				Logger.LogInfo((object)$"[Identity Log] Joined: PhotonName={player2.NickName} | ActorNumber={player2.ActorNumber} | SteamName={SteamFriends.GetFriendPersonaName(playerSteamID)} | SteamID={playerSteamID}");
				_knownPlayerIdentities.Add(new PlayerIdentity(player2.NickName, player2.ActorNumber, playerSteamID));
			}
			if (player2.IsMasterClient || _detectedCheatModUsers.Contains(player2.ActorNumber))
			{
				return;
			}
			if (BlockingManager.HasImmunity(player2.ActorNumber))
			{
				Logger.LogInfo((object)("[CHEAT MOD CHECK] Skipping " + player2.NickName + " - player has immunity"));
				return;
			}
			bool flag = false;
			if (((Dictionary<object, object>)(object)player2.CustomProperties).ContainsKey((object)"CherryUser"))
			{
				Logger.LogWarning((object)(player2.NickName + " is using the Cherry cheat mod!"));
				LogVisually("{userColor}" + player2.NickName + "</color> {leftColor}is using the Cherry cheat mod!</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
				DetectionManager.RecordDetection(DetectionType.CherryMod, player2, "Cherry cheat mod user");
				_detectedCheatModUsers.Add(player2.ActorNumber);
			}
			else if (((Dictionary<object, object>)(object)player2.CustomProperties).ContainsKey((object)"CherryOwner"))
			{
				Logger.LogWarning((object)(player2.NickName + " is the Owner of the Cherry cheat mod!"));
				LogVisually("{userColor}" + player2.NickName + "</color> {leftColor}is the Owner of the Cherry cheat mod!</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
				DetectionManager.RecordDetection(DetectionType.CherryMod, player2, "Cherry cheat mod owner");
				_detectedCheatModUsers.Add(player2.ActorNumber);
			}
			else if (((Dictionary<object, object>)(object)player2.CustomProperties).ContainsKey((object)"AtlUser"))
			{
				Logger.LogWarning((object)(player2.NickName + " is using the Atlas cheat mod!"));
				LogVisually("{userColor}" + player2.NickName + "</color> {leftColor}is using the Atlas cheat mod!</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
				DetectionManager.RecordDetection(DetectionType.AtlasMod, player2, "Atlas cheat mod user");
				_detectedCheatModUsers.Add(player2.ActorNumber);
			}
			else if (((Dictionary<object, object>)(object)player2.CustomProperties).ContainsKey((object)"AtlOwner"))
			{
				Logger.LogWarning((object)(player2.NickName + " is the Owner of the Atlas cheat mod!"));
				LogVisually("{userColor}" + player2.NickName + "</color> {leftColor}is the Owner of the Atlas cheat mod!</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
				DetectionManager.RecordDetection(DetectionType.AtlasMod, player2, "Atlas cheat mod owner");
				_detectedCheatModUsers.Add(player2.ActorNumber);
			}
			else if (CheckSteamNames.Value)
			{
				CheckSteamNameMatch(player2);
			}
		}

		private void CheckSteamNameMatch(Player player)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			Player player2 = player;
			PlayerIdentity playerIdentity = _knownPlayerIdentities.Find((PlayerIdentity p) => p.ActorNumber == player2.ActorNumber);
			if (playerIdentity == null || !(playerIdentity.SteamID != CSteamID.Nil))
			{
				return;
			}
			CheckForSteamIDSpoofing(player2, playerIdentity.SteamID);
			if (SteamFriends.RequestUserInformation(playerIdentity.SteamID, true))
			{
				((MonoBehaviour)this).StartCoroutine(WaitForPersonaStateChange(player2, playerIdentity.SteamID, 5f, blockOnMismatch: false));
				return;
			}
			string friendPersonaName = SteamFriends.GetFriendPersonaName(playerIdentity.SteamID);
			if (!(friendPersonaName.ToLower() == player2.NickName.ToLower()))
			{
				Logger.LogWarning((object)("Name mismatch detected on join: Photon='" + player2.NickName + "' vs Steam='" + friendPersonaName + "'"));
				LogVisually("{userColor}" + player2.NickName + "</color> {leftColor}has mismatched Steam name: '" + friendPersonaName + "'</color>", onlySendOnce: true, sfxJoin: false, sfxLeave: true);
				DetectionManager.RecordDetection(DetectionType.SteamNameMismatch, player2, "Name mismatch: Photon='" + player2.NickName + "' vs Steam='" + friendPersonaName + "'");
			}
		}

		private void CheckForSteamIDSpoofing(Player player, CSteamID playerSteamID)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient || player.IsMasterClient)
			{
				return;
			}