Decompiled source of HardAntiCheat v2.5.3

HardAntiCheat.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
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 System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodeTalker;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using Nessie.ATLYSS.EasySettings.UIElements;
using Newtonsoft.Json;
using Steamworks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.HardAntiCheat.sftwre")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.5.3.0")]
[assembly: AssemblyInformationalVersion("2.5.3+331e92aca353ad4f40ff75cc77bdbd3d23df01f4")]
[assembly: AssemblyProduct("HardAntiCheat")]
[assembly: AssemblyTitle("HardAntiCheat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.5.3.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 HardAntiCheat
{
	public class HAC_ModListRequest : BinaryPacketBase
	{
		public override string PacketSignature => "HAC_Request_V6";

		public ulong TargetSteamID { get; set; }

		public override byte[] Serialize()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(TargetSteamID);
			return memoryStream.ToArray();
		}

		public override void Deserialize(byte[] data)
		{
			using MemoryStream input = new MemoryStream(data);
			using BinaryReader binaryReader = new BinaryReader(input);
			TargetSteamID = binaryReader.ReadUInt64();
		}
	}
	public class HAC_ModListResponse : BinaryPacketBase
	{
		public override string PacketSignature => "HAC_Response_V6";

		public List<string> ClientModGUIDs { get; set; }

		public List<string> ClientModNames { get; set; }

		public List<string> ClientModVersions { get; set; }

		public override byte[] Serialize()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			int num = ClientModGUIDs?.Count ?? 0;
			binaryWriter.Write(num);
			for (int i = 0; i < num; i++)
			{
				binaryWriter.Write(ClientModGUIDs[i] ?? string.Empty);
				binaryWriter.Write(ClientModNames[i] ?? string.Empty);
				binaryWriter.Write(ClientModVersions[i] ?? string.Empty);
			}
			return memoryStream.ToArray();
		}

		public override void Deserialize(byte[] data)
		{
			using MemoryStream input = new MemoryStream(data);
			using BinaryReader binaryReader = new BinaryReader(input);
			int num = binaryReader.ReadInt32();
			ClientModGUIDs = new List<string>(num);
			ClientModNames = new List<string>(num);
			ClientModVersions = new List<string>(num);
			for (int i = 0; i < num; i++)
			{
				ClientModGUIDs.Add(binaryReader.ReadString());
				ClientModNames.Add(binaryReader.ReadString());
				ClientModVersions.Add(binaryReader.ReadString());
			}
		}
	}
	public class HAC_KickMessage : BinaryPacketBase
	{
		public override string PacketSignature => "HAC_Kick_V6";

		public string Reason { get; set; }

		public override byte[] Serialize()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(Reason ?? string.Empty);
			return memoryStream.ToArray();
		}

		public override void Deserialize(byte[] data)
		{
			using MemoryStream input = new MemoryStream(data);
			using BinaryReader binaryReader = new BinaryReader(input);
			Reason = binaryReader.ReadString();
		}
	}
	public struct PlayerPositionData
	{
		public Vector3 Position;

		public float Timestamp;
	}
	public struct PlayerStatsData
	{
		public int Level;

		public int Experience;
	}
	public struct PlayerAirborneData
	{
		public float AirTime;

		public Vector3 LastGroundedPosition;

		public int ServerSideJumpCount;

		public float LastVerticalPosition;

		public float VerticalStallTime;
	}
	public struct PlayerMovementStats
	{
		public List<float> RecentSpeeds;

		public float TimeAtMaxSpeed;
	}
	public class ThunderstorePackageV1
	{
		public string uuid4 { get; set; }

		[JsonProperty("namespace")]
		public string namespace_name { get; set; }

		public string name { get; set; }

		public string full_name { get; set; }

		public string owner { get; set; }

		[JsonIgnore]
		public string latest { get; set; }

		public bool is_deprecated { get; set; }

		[JsonProperty("is_flagged")]
		public bool is_flagged { get; set; }

		public string date_created { get; set; }

		public string date_updated { get; set; }

		public int downloads { get; set; }
	}
	public class ThunderstorePackageDetail
	{
		public string uuid4 { get; set; }

		[JsonProperty("namespace")]
		public string namespace_name { get; set; }

		public string name { get; set; }

		public string full_name { get; set; }

		public string owner { get; set; }

		[JsonIgnore]
		public string latest { get; set; }

		public bool is_deprecated { get; set; }

		[JsonProperty("is_flagged")]
		public bool is_flagged { get; set; }

		public List<string> dependencies { get; set; }

		public string date_created { get; set; }

		public string date_updated { get; set; }
	}
	public class ThunderstoreModCache
	{
		public string BepInExGUID { get; set; }

		public string ThunderstoreUUID { get; set; }

		public string Namespace { get; set; }

		public string Name { get; set; }

		public bool IsDeprecated { get; set; }

		public bool IsFlagged { get; set; }

		public DateTime LastVerified { get; set; }

		public DateTime FirstSeen { get; set; }
	}
	public class ThunderstoreSearchResponse
	{
		public string next { get; set; }

		public string previous { get; set; }

		public List<ThunderstorePackageV1> results { get; set; }
	}
	[BepInPlugin("com.HardAntiCheat.sftwre", "HardAntiCheat", "2.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static BinaryPacketListener <0>__OnClientReceivedRequest;

			public static BinaryPacketListener <1>__OnReceivedResponse;

			public static BinaryPacketListener <2>__OnClientReceivedKickMessage;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass104_0
		{
			public List<string> guids;

			internal bool <VerifyClientModsWithThunderstore>b__0(string req)
			{
				return !guids.Contains(req);
			}
		}

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

			private object <>2__current;

			public Main <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					if (EnableThunderstoreWhitelist.Value)
					{
						Log.LogInfo((object)"[HAC] Auto-refreshing Thunderstore database...");
						<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FetchThunderstorePackageList());
						<>1__state = 2;
						return true;
					}
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				<>2__current = (object)new WaitForSeconds(ThunderstoreRefreshInterval.Value * 60f);
				<>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 <BackgroundVerifyModAsync>d__101 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string guid;

			public string name;

			public string version;

			public Main <>4__this;

			private string <lowerGuid>5__1;

			private string <searchTerm>5__2;

			private string <aliasName>5__3;

			private string <searchUrl>5__4;

			private UnityWebRequest <request>5__5;

			private string <json>5__6;

			private List<ThunderstorePackageV1> <results>5__7;

			private ThunderstorePackageV1 <matchedPkg>5__8;

			private ThunderstoreSearchResponse <searchResponse>5__9;

			private List<ThunderstorePackageV1>.Enumerator <>s__10;

			private ThunderstorePackageV1 <pkg>5__11;

			private List<string>.Enumerator <>s__12;

			private string <g>5__13;

			private List<string>.Enumerator <>s__14;

			private string <g>5__15;

			private string <lowerGuidBL>5__16;

			private string <existing>5__17;

			private Exception <ex>5__18;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<lowerGuid>5__1 = null;
				<searchTerm>5__2 = null;
				<aliasName>5__3 = null;
				<searchUrl>5__4 = null;
				<request>5__5 = null;
				<json>5__6 = null;
				<results>5__7 = null;
				<matchedPkg>5__8 = null;
				<searchResponse>5__9 = null;
				<>s__10 = default(List<ThunderstorePackageV1>.Enumerator);
				<pkg>5__11 = null;
				<>s__12 = default(List<string>.Enumerator);
				<g>5__13 = null;
				<>s__14 = default(List<string>.Enumerator);
				<g>5__15 = null;
				<lowerGuidBL>5__16 = null;
				<existing>5__17 = null;
				<ex>5__18 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b6: Invalid comparison between Unknown and I4
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<lowerGuid>5__1 = guid.ToLower();
						if (ThunderstoreKnownPackages.Contains(<lowerGuid>5__1))
						{
							return false;
						}
						<searchTerm>5__2 = ((!string.IsNullOrEmpty(name) && name != "Unknown") ? name : guid);
						if (KnownModAliases.TryGetValue(name, out <aliasName>5__3) || KnownModAliases.TryGetValue(guid, out <aliasName>5__3))
						{
							Log.LogDebug((object)("[HAC] [Background] '" + name + "' (" + guid + ") matched known alias -> searching as '" + <aliasName>5__3 + "'."));
							<searchTerm>5__2 = <aliasName>5__3;
						}
						<searchUrl>5__4 = "https://thunderstore.io/c/" + ThunderstoreCommunity.Value + "/api/v1/package/?search=" + Uri.EscapeDataString(<searchTerm>5__2);
						<request>5__5 = UnityWebRequest.Get(<searchUrl>5__4);
						<>1__state = -3;
						<request>5__5.SetRequestHeader("Accept", "application/json");
						<request>5__5.timeout = 10;
						<>2__current = <request>5__5.SendWebRequest();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -3;
						if ((int)<request>5__5.result == 1)
						{
							try
							{
								<json>5__6 = <request>5__5.downloadHandler.text;
								<results>5__7 = null;
								if (<json>5__6.TrimStart().StartsWith("{"))
								{
									<searchResponse>5__9 = JsonConvert.DeserializeObject<ThunderstoreSearchResponse>(<json>5__6);
									<results>5__7 = <searchResponse>5__9?.results;
									<searchResponse>5__9 = null;
								}
								else
								{
									<results>5__7 = JsonConvert.DeserializeObject<List<ThunderstorePackageV1>>(<json>5__6);
								}
								<matchedPkg>5__8 = null;
								if (<results>5__7 != null)
								{
									<>s__10 = <results>5__7.GetEnumerator();
									try
									{
										while (<>s__10.MoveNext())
										{
											<pkg>5__11 = <>s__10.Current;
											if (PackageMatchesMod(<pkg>5__11, guid, name))
											{
												<matchedPkg>5__8 = <pkg>5__11;
												break;
											}
											<pkg>5__11 = null;
										}
									}
									finally
									{
										((IDisposable)<>s__10).Dispose();
									}
									<>s__10 = default(List<ThunderstorePackageV1>.Enumerator);
								}
								if (<matchedPkg>5__8 != null)
								{
									ThunderstoreKnownPackages.Add(<lowerGuid>5__1);
									<>s__12 = <>4__this.GeneratePossibleGUIDs(<matchedPkg>5__8).GetEnumerator();
									try
									{
										while (<>s__12.MoveNext())
										{
											<g>5__13 = <>s__12.Current;
											ThunderstoreKnownPackages.Add(<g>5__13.ToLower());
											<g>5__13 = null;
										}
									}
									finally
									{
										((IDisposable)<>s__12).Dispose();
									}
									<>s__12 = default(List<string>.Enumerator);
									if (AutoWhitelistNewMods.Value && !<matchedPkg>5__8.is_deprecated && !<matchedPkg>5__8.is_flagged)
									{
										ServerWhitelistedGUIDs.Add(<lowerGuid>5__1);
										<>s__14 = <>4__this.GeneratePossibleGUIDs(<matchedPkg>5__8).GetEnumerator();
										try
										{
											while (<>s__14.MoveNext())
											{
												<g>5__15 = <>s__14.Current;
												ServerWhitelistedGUIDs.Add(<g>5__15.ToLower());
												<g>5__15 = null;
											}
										}
										finally
										{
											((IDisposable)<>s__14).Dispose();
										}
										<>s__14 = default(List<string>.Enumerator);
									}
									Log.LogDebug((object)("[HAC] [Background] Verified and cached " + name + " (" + guid + ") v" + version + " on Thunderstore."));
								}
								else
								{
									Log.LogWarning((object)("[HAC] [Background] '" + name + "' (" + guid + ") v" + version + " was NOT found on Thunderstore. Treating as unknown."));
									if (AutoBlacklistUnknownMods.Value)
									{
										<lowerGuidBL>5__16 = guid.ToLower();
										if (ServerBlacklistedGUIDs.Add(<lowerGuidBL>5__16))
										{
											<existing>5__17 = BlacklistedModGUIDs.Value?.Trim() ?? "";
											BlacklistedModGUIDs.Value = (string.IsNullOrEmpty(<existing>5__17) ? <lowerGuidBL>5__16 : (<existing>5__17 + "," + <lowerGuidBL>5__16));
											Log.LogWarning((object)("[HAC] [Background] '" + name + "' (" + guid + ") auto-blacklisted and saved to config."));
											<existing>5__17 = null;
										}
										<lowerGuidBL>5__16 = null;
									}
								}
								<json>5__6 = null;
								<results>5__7 = null;
								<matchedPkg>5__8 = null;
							}
							catch (Exception ex)
							{
								<ex>5__18 = ex;
								Log.LogWarning((object)("[HAC] [Background] Parse error for '" + guid + "': " + <ex>5__18.Message));
							}
						}
						else
						{
							Log.LogWarning((object)("[HAC] [Background] Failed to verify '" + name + "' (" + guid + ") against Thunderstore: " + <request>5__5.error));
						}
						<>m__Finally1();
						<request>5__5 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__5 != null)
				{
					((IDisposable)<request>5__5).Dispose();
				}
			}

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

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

			private object <>2__current;

			public Player player;

			public string reason;

			public Main <>4__this;

			private NetworkConnectionToClient <conn>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)player != (Object)null)
					{
						CodeTalkerNetwork.SendNetworkPacket(player, (BinaryPacketBase)(object)new HAC_KickMessage
						{
							Reason = reason
						}, (CompressionType)0, CompressionLevel.Fastest);
						<conn>5__1 = ((NetworkBehaviour)player).connectionToClient;
						<>2__current = (object)new WaitForSeconds(0.5f);
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					if (<conn>5__1 != null)
					{
						((NetworkConnection)<conn>5__1).Disconnect();
					}
					<conn>5__1 = null;
					break;
				}
				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 <FetchRemoteDatabaseCoroutine>d__113 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Main <>4__this;

			private UnityWebRequest <webRequest>5__1;

			private string <content>5__2;

			private string[] <lines>5__3;

			private int <added>5__4;

			private string[] <>s__5;

			private int <>s__6;

			private string <line>5__7;

			private string <trimmed>5__8;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<webRequest>5__1 = null;
				<content>5__2 = null;
				<lines>5__3 = null;
				<>s__5 = null;
				<line>5__7 = null;
				<trimmed>5__8 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<webRequest>5__1 = UnityWebRequest.Get(RemoteDatabaseURL.Value);
						<>1__state = -3;
						<>2__current = <webRequest>5__1.SendWebRequest();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -3;
						if (<webRequest>5__1.isNetworkError || <webRequest>5__1.isHttpError)
						{
							Log.LogError((object)("[HAC] Failed to fetch remote database: " + <webRequest>5__1.error));
						}
						else
						{
							<content>5__2 = <webRequest>5__1.downloadHandler.text;
							<lines>5__3 = <content>5__2.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
							<added>5__4 = 0;
							<>s__5 = <lines>5__3;
							for (<>s__6 = 0; <>s__6 < <>s__5.Length; <>s__6++)
							{
								<line>5__7 = <>s__5[<>s__6];
								<trimmed>5__8 = <line>5__7.Trim();
								if (!string.IsNullOrEmpty(<trimmed>5__8) && !<trimmed>5__8.StartsWith("//") && !<trimmed>5__8.StartsWith("#"))
								{
									ServerBlacklistedGUIDs.Add(<trimmed>5__8);
									<added>5__4++;
								}
								<trimmed>5__8 = null;
								<line>5__7 = null;
							}
							<>s__5 = null;
							Log.LogInfo((object)$"[HAC] Remote database loaded. Added {<added>5__4} blacklisted mods.");
							<content>5__2 = null;
							<lines>5__3 = null;
						}
						<>m__Finally1();
						<webRequest>5__1 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<webRequest>5__1 != null)
				{
					((IDisposable)<webRequest>5__1).Dispose();
				}
			}

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

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

			private object <>2__current;

			public Main <>4__this;

			private string <communityUrl>5__1;

			private UnityWebRequest <request>5__2;

			private List<ThunderstorePackageV1> <packages>5__3;

			private int <deprecatedCount>5__4;

			private List<ThunderstorePackageV1>.Enumerator <>s__5;

			private ThunderstorePackageV1 <pkg>5__6;

			private string <fullName>5__7;

			private List<string> <possibleGUIDs>5__8;

			private List<string>.Enumerator <>s__9;

			private string <guid>5__10;

			private List<string>.Enumerator <>s__11;

			private string <guid>5__12;

			private List<string>.Enumerator <>s__13;

			private string <guid>5__14;

			private Exception <ex>5__15;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<communityUrl>5__1 = null;
				<request>5__2 = null;
				<packages>5__3 = null;
				<>s__5 = default(List<ThunderstorePackageV1>.Enumerator);
				<pkg>5__6 = null;
				<fullName>5__7 = null;
				<possibleGUIDs>5__8 = null;
				<>s__9 = default(List<string>.Enumerator);
				<guid>5__10 = null;
				<>s__11 = default(List<string>.Enumerator);
				<guid>5__12 = null;
				<>s__13 = default(List<string>.Enumerator);
				<guid>5__14 = null;
				<ex>5__15 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Invalid comparison between Unknown and I4
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<communityUrl>5__1 = "https://thunderstore.io/c/" + ThunderstoreCommunity.Value + "/api/v1/package/";
						<request>5__2 = UnityWebRequest.Get(<communityUrl>5__1);
						<>1__state = -3;
						<request>5__2.SetRequestHeader("Accept", "application/json");
						<request>5__2.timeout = 15;
						<>2__current = <request>5__2.SendWebRequest();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -3;
						if ((int)<request>5__2.result == 1)
						{
							try
							{
								<packages>5__3 = JsonConvert.DeserializeObject<List<ThunderstorePackageV1>>(<request>5__2.downloadHandler.text);
								if (<packages>5__3 != null)
								{
									ThunderstoreKnownPackages.Clear();
									<deprecatedCount>5__4 = 0;
									<>s__5 = <packages>5__3.GetEnumerator();
									try
									{
										while (<>s__5.MoveNext())
										{
											<pkg>5__6 = <>s__5.Current;
											<fullName>5__7 = <pkg>5__6.full_name ?? (<pkg>5__6.namespace_name + "-" + <pkg>5__6.name);
											ThunderstoreKnownPackages.Add(<fullName>5__7);
											<possibleGUIDs>5__8 = <>4__this.GeneratePossibleGUIDs(<pkg>5__6);
											<>s__9 = <possibleGUIDs>5__8.GetEnumerator();
											try
											{
												while (<>s__9.MoveNext())
												{
													<guid>5__10 = <>s__9.Current;
													ThunderstoreKnownPackages.Add(<guid>5__10.ToLower());
													<guid>5__10 = null;
												}
											}
											finally
											{
												((IDisposable)<>s__9).Dispose();
											}
											<>s__9 = default(List<string>.Enumerator);
											if (<pkg>5__6.is_deprecated && BlockDeprecatedMods.Value)
											{
												<>s__11 = <possibleGUIDs>5__8.GetEnumerator();
												try
												{
													while (<>s__11.MoveNext())
													{
														<guid>5__12 = <>s__11.Current;
														ServerBlacklistedGUIDs.Add(<guid>5__12.ToLower());
														<guid>5__12 = null;
													}
												}
												finally
												{
													((IDisposable)<>s__11).Dispose();
												}
												<>s__11 = default(List<string>.Enumerator);
												ServerBlacklistedGUIDs.Add(<fullName>5__7.ToLower());
												<deprecatedCount>5__4++;
											}
											if (AutoWhitelistNewMods.Value && !<pkg>5__6.is_deprecated && !<pkg>5__6.is_flagged)
											{
												<>s__13 = <possibleGUIDs>5__8.GetEnumerator();
												try
												{
													while (<>s__13.MoveNext())
													{
														<guid>5__14 = <>s__13.Current;
														ServerWhitelistedGUIDs.Add(<guid>5__14.ToLower());
														<guid>5__14 = null;
													}
												}
												finally
												{
													((IDisposable)<>s__13).Dispose();
												}
												<>s__13 = default(List<string>.Enumerator);
											}
											<fullName>5__7 = null;
											<possibleGUIDs>5__8 = null;
											<pkg>5__6 = null;
										}
									}
									finally
									{
										((IDisposable)<>s__5).Dispose();
									}
									<>s__5 = default(List<ThunderstorePackageV1>.Enumerator);
									Log.LogInfo((object)$"[HAC] Thunderstore: {<packages>5__3.Count} packages found, {<deprecatedCount>5__4} deprecated mods auto-blacklisted.");
								}
								<packages>5__3 = null;
							}
							catch (Exception ex)
							{
								<ex>5__15 = ex;
								Log.LogError((object)("[HAC] Failed to parse Thunderstore package list: " + <ex>5__15.Message));
							}
						}
						else
						{
							Log.LogWarning((object)("[HAC] Failed to fetch Thunderstore package list: " + <request>5__2.error + ". Will retry on next refresh."));
						}
						<>m__Finally1();
						<request>5__2 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__2 != null)
				{
					((IDisposable)<request>5__2).Dispose();
				}
			}

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

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

			private object <>2__current;

			public Main <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Log.LogInfo((object)"[HAC] Initializing Thunderstore package database...");
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FetchThunderstorePackageList());
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					isThunderstoreInitialized = true;
					Log.LogInfo((object)$"[HAC] Thunderstore database initialized with {ThunderstoreKnownPackages.Count} known packages.");
					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 <KickClientAfterDelay>d__108 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			public Main <>4__this;

			private ulong <steamId>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)player == (Object)null || !ulong.TryParse(player._steamID, out <steamId>5__1))
					{
						return false;
					}
					<>2__current = (object)new WaitForSeconds(VerificationTimeout.Value);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)player != (Object)null && !VerifiedSteamIDs.Contains(<steamId>5__1) && PendingVerification.ContainsKey(<steamId>5__1))
					{
						if (EnableRequiredMods.Value && ServerRequiredGUIDs.Count > 0)
						{
							PunishVerificationFailure(<steamId>5__1, "Handshake Timeout. Required mods are missing.");
						}
						else
						{
							Log.LogInfo((object)$"[HAC] Client {<steamId>5__1} timed out. Assumed Vanilla. Allowing join.");
							AuthorizePlayer(<steamId>5__1, PendingVerification[<steamId>5__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 <SendRequestWithDelay>d__107 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			public ulong steamId;

			public Main <>4__this;

			private HAC_ModListRequest <req>5__1;

			private Coroutine <kickRoutine>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<req>5__1 = null;
				<kickRoutine>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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;
					if ((Object)(object)player == (Object)null)
					{
						return false;
					}
					<req>5__1 = new HAC_ModListRequest
					{
						TargetSteamID = steamId
					};
					CodeTalkerNetwork.SendNetworkPacket(player, (BinaryPacketBase)(object)<req>5__1, (CompressionType)0, CompressionLevel.Fastest);
					<kickRoutine>5__2 = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.KickClientAfterDelay(player));
					PendingVerification[steamId] = <kickRoutine>5__2;
					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 <StaggeredBackgroundVerify>d__97 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public List<(string guid, string name, string version)> mods;

			public Main <>4__this;

			private List<(string guid, string name, string version)>.Enumerator <>s__1;

			private string <guid>5__2;

			private string <name>5__3;

			private string <version>5__4;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<(string, string, string)>.Enumerator);
				<guid>5__2 = null;
				<name>5__3 = null;
				<version>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = mods.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<>2__current = (object)new WaitForSeconds(0.75f);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -3;
						<guid>5__2 = null;
						<name>5__3 = null;
						<version>5__4 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						(string, string, string) current = <>s__1.Current;
						<guid>5__2 = current.Item1;
						<name>5__3 = current.Item2;
						<version>5__4 = current.Item3;
						<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.BackgroundVerifyModAsync(<guid>5__2, <name>5__3, <version>5__4));
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = default(List<(string, string, string)>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

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

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

			private object <>2__current;

			public ulong steamId;

			public List<string> guids;

			public List<string> names;

			public List<string> versions;

			public Coroutine timeoutCoroutine;

			public Main <>4__this;

			private <>c__DisplayClass104_0 <>8__1;

			private Dictionary<string, (string name, string version)> <modInfoMap>5__2;

			private List<string> <unauthorizedMods>5__3;

			private List<string> <unknownMods>5__4;

			private int <i>5__5;

			private List<string>.Enumerator <>s__6;

			private string <guid>5__7;

			private string <lowerGuid>5__8;

			private string <displayName>5__9;

			private (string name, string version) <info>5__10;

			private List<string> <missingMods>5__11;

			private List<(string guid, string name, string version)> <parsedMods>5__12;

			private List<string>.Enumerator <>s__13;

			private string <unknownDisplay>5__14;

			private string <guid>5__15;

			private string <name>5__16;

			private string <version>5__17;

			private int <start>5__18;

			private int <end>5__19;

			private int <vIdx>5__20;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<modInfoMap>5__2 = null;
				<unauthorizedMods>5__3 = null;
				<unknownMods>5__4 = null;
				<>s__6 = default(List<string>.Enumerator);
				<guid>5__7 = null;
				<lowerGuid>5__8 = null;
				<displayName>5__9 = null;
				<info>5__10 = default((string, string));
				<missingMods>5__11 = null;
				<parsedMods>5__12 = null;
				<>s__13 = default(List<string>.Enumerator);
				<unknownDisplay>5__14 = null;
				<guid>5__15 = null;
				<name>5__16 = null;
				<version>5__17 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass104_0();
				<>8__1.guids = guids;
				if (<>8__1.guids == null || <>8__1.guids.Count == 0)
				{
					Log.LogInfo((object)$"[HAC] Client {steamId} reported 0 mods. Vanilla client authorized.");
					AuthorizePlayer(steamId, timeoutCoroutine);
					return false;
				}
				<modInfoMap>5__2 = new Dictionary<string, (string, string)>();
				<i>5__5 = 0;
				while (<i>5__5 < <>8__1.guids.Count)
				{
					if (!string.IsNullOrEmpty(<>8__1.guids[<i>5__5]))
					{
						<modInfoMap>5__2[<>8__1.guids[<i>5__5].ToLower()] = (names[<i>5__5], versions[<i>5__5]);
					}
					<i>5__5++;
				}
				<unauthorizedMods>5__3 = new List<string>();
				<unknownMods>5__4 = new List<string>();
				<>s__6 = <>8__1.guids.GetEnumerator();
				try
				{
					while (<>s__6.MoveNext())
					{
						<guid>5__7 = <>s__6.Current;
						<lowerGuid>5__8 = <guid>5__7.ToLower();
						if (string.IsNullOrEmpty(<lowerGuid>5__8) || ServerWhitelistedGUIDs.Contains(<lowerGuid>5__8) || ServerRequiredGUIDs.Contains(<guid>5__7))
						{
							continue;
						}
						<displayName>5__9 = (<modInfoMap>5__2.TryGetValue(<lowerGuid>5__8, out <info>5__10) ? (<info>5__10.name + " (" + <guid>5__7 + ") v" + <info>5__10.version) : <guid>5__7);
						if (EnableModBlacklist.Value && ServerBlacklistedGUIDs.Contains(<lowerGuid>5__8))
						{
							<unauthorizedMods>5__3.Add(<displayName>5__9);
							continue;
						}
						if (EnableThunderstoreWhitelist.Value)
						{
							if ((isThunderstoreInitialized && ThunderstoreKnownPackages.Contains(<lowerGuid>5__8)) || !isThunderstoreInitialized)
							{
								continue;
							}
							<unknownMods>5__4.Add(<displayName>5__9);
						}
						else if (EnableModWhitelist.Value && !ServerWhitelistedGUIDs.Contains(<lowerGuid>5__8))
						{
							<unauthorizedMods>5__3.Add(<displayName>5__9);
						}
						<lowerGuid>5__8 = null;
						<displayName>5__9 = null;
						<info>5__10 = default((string, string));
						<guid>5__7 = null;
					}
				}
				finally
				{
					((IDisposable)<>s__6).Dispose();
				}
				<>s__6 = default(List<string>.Enumerator);
				if (<unauthorizedMods>5__3.Any())
				{
					PunishVerificationFailure(steamId, "Unauthorized/Blacklisted Mods Detected: " + string.Join(", ", <unauthorizedMods>5__3.Take(3)));
					return false;
				}
				if (EnableRequiredMods.Value)
				{
					<missingMods>5__11 = ServerRequiredGUIDs.Where((string req) => !<>8__1.guids.Contains(req)).ToList();
					if (<missingMods>5__11.Any())
					{
						PunishVerificationFailure(steamId, "Missing Required Mods: " + string.Join(", ", <missingMods>5__11.Take(3)));
						return false;
					}
					<missingMods>5__11 = null;
				}
				if (<unknownMods>5__4.Any() && isThunderstoreInitialized)
				{
					<parsedMods>5__12 = new List<(string, string, string)>();
					<>s__13 = <unknownMods>5__4.GetEnumerator();
					try
					{
						while (<>s__13.MoveNext())
						{
							<unknownDisplay>5__14 = <>s__13.Current;
							<guid>5__15 = <unknownDisplay>5__14;
							<name>5__16 = "Unknown";
							<version>5__17 = "?";
							<start>5__18 = <unknownDisplay>5__14.IndexOf('(');
							if (<start>5__18 > 0)
							{
								<name>5__16 = <unknownDisplay>5__14.Substring(0, <start>5__18).Trim();
								<end>5__19 = <unknownDisplay>5__14.IndexOf(')', <start>5__18);
								if (<end>5__19 > <start>5__18)
								{
									<guid>5__15 = <unknownDisplay>5__14.Substring(<start>5__18 + 1, <end>5__19 - <start>5__18 - 1);
									<vIdx>5__20 = <unknownDisplay>5__14.IndexOf(" v", <end>5__19);
									if (<vIdx>5__20 > <end>5__19)
									{
										<version>5__17 = <unknownDisplay>5__14.Substring(<vIdx>5__20 + 2).Trim();
									}
								}
							}
							<parsedMods>5__12.Add((<guid>5__15, <name>5__16, <version>5__17));
							<guid>5__15 = null;
							<name>5__16 = null;
							<version>5__17 = null;
							<unknownDisplay>5__14 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__13).Dispose();
					}
					<>s__13 = default(List<string>.Enumerator);
					Log.LogInfo((object)$"[HAC] Player authorized. {<parsedMods>5__12.Count} mods queued for background Thunderstore verification.");
					((MonoBehaviour)Instance).StartCoroutine(<>4__this.StaggeredBackgroundVerify(<parsedMods>5__12));
					<parsedMods>5__12 = null;
				}
				AuthorizePlayer(steamId, timeoutCoroutine);
				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 readonly Harmony harmony = new Harmony("com.HardAntiCheat.sftwre");

		internal static ManualLogSource Log;

		internal static string InfractionLogPath;

		public static ConfigEntry<bool> EnableAntiCheat;

		public static ConfigEntry<bool> DisableForHost;

		public static ConfigEntry<string> TrustedSteamIDs;

		public static ConfigEntry<string> BannedSteamIDs;

		public static ConfigEntry<bool> EnableRequiredMods;

		public static ConfigEntry<string> RequiredModGUIDs;

		public static ConfigEntry<bool> EnableModBlacklist;

		public static ConfigEntry<string> BlacklistedModGUIDs;

		public static ConfigEntry<bool> EnableModWhitelist;

		public static ConfigEntry<string> WhitelistedModGUIDs;

		public static ConfigEntry<bool> EnableRemoteDatabase;

		public static ConfigEntry<string> RemoteDatabaseURL;

		public static ConfigEntry<bool> EnableThunderstoreWhitelist;

		public static ConfigEntry<string> ThunderstoreCommunity;

		public static ConfigEntry<bool> BlockDeprecatedMods;

		public static ConfigEntry<float> ThunderstoreRefreshInterval;

		public static ConfigEntry<float> ThunderstoreCacheTimeout;

		public static ConfigEntry<bool> AutoWhitelistNewMods;

		public static ConfigEntry<bool> AutoBlacklistUnknownMods;

		public static ConfigEntry<float> UnknownModGracePeriod;

		public static ConfigEntry<float> VerificationTimeout;

		public static ConfigEntry<int> MaxLogFileSizeMB;

		public static ConfigEntry<bool> EnableMovementChecks;

		public static ConfigEntry<float> MaxEffectiveSpeed;

		public static ConfigEntry<float> MovementGraceBuffer;

		public static ConfigEntry<float> MovementTimeThreshold;

		public static ConfigEntry<float> TeleportDistanceThreshold;

		public static ConfigEntry<bool> EnableAirborneChecks;

		public static ConfigEntry<bool> EnableSpeedChecks;

		public static ConfigEntry<float> SpeedHackDetectionCooldown;

		public static ConfigEntry<float> JumpHackDetectionCooldown;

		public static ConfigEntry<float> AirborneHackDetectionCooldown;

		public static ConfigEntry<bool> EnableExperienceChecks;

		public static ConfigEntry<int> JumpThreshold;

		public static ConfigEntry<int> MaxPlausibleXPGain;

		public static ConfigEntry<int> MaxXPGainPerWindow;

		public static ConfigEntry<float> XPGainWindowSeconds;

		public static ConfigEntry<bool> EnableCooldownChecks;

		public static ConfigEntry<bool> EnableReviveChecks;

		public static ConfigEntry<bool> EnableSpamChecks;

		public static ConfigEntry<float> MinConsumableInterval;

		public static ConfigEntry<float> MinWeaponSwapInterval;

		public static ConfigEntry<float> MinBlockInterval;

		public static ConfigEntry<bool> EnablePunishmentSystem;

		public static ConfigEntry<int> WarningsUntilAction;

		public static ConfigEntry<string> ActionType;

		public static ConfigEntry<bool> EnableDetailedLogs;

		public static ConfigEntry<bool> LogPlayerName;

		public static ConfigEntry<bool> LogPlayerID;

		public static ConfigEntry<bool> LogInfractionCount;

		public static ConfigEntry<bool> LogInfractionDetails;

		private static readonly HashSet<ulong> WhitelistedUsers = new HashSet<ulong>();

		private static readonly HashSet<ulong> ServerBannedUsers = new HashSet<ulong>();

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

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

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

		private static readonly Dictionary<string, ThunderstoreModCache> ThunderstoreCache = new Dictionary<string, ThunderstoreModCache>();

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

		private static readonly Dictionary<string, DateTime> PendingUnknownMods = new Dictionary<string, DateTime>();

		private static Coroutine thunderstoreRefreshCoroutine;

		private static bool isThunderstoreInitialized = false;

		internal static readonly Dictionary<ulong, Coroutine> PendingVerification = new Dictionary<ulong, Coroutine>();

		internal static readonly HashSet<ulong> VerifiedSteamIDs = new HashSet<ulong>();

		public static readonly Dictionary<uint, Dictionary<string, float>> ServerRemainingCooldowns = new Dictionary<uint, Dictionary<string, float>>();

		public static readonly Dictionary<uint, PlayerPositionData> ServerPlayerPositions = new Dictionary<uint, PlayerPositionData>();

		public static readonly Dictionary<uint, PlayerStatsData> ServerPlayerStats = new Dictionary<uint, PlayerStatsData>();

		public static readonly Dictionary<uint, List<(float Timestamp, int Amount)>> XpGainHistory = new Dictionary<uint, List<(float, int)>>();

		public static readonly Dictionary<uint, int> ServerRunningXpTotal = new Dictionary<uint, int>();

		public static readonly Dictionary<uint, PlayerAirborneData> ServerPlayerAirborneStates = new Dictionary<uint, PlayerAirborneData>();

		public static readonly Dictionary<uint, float> ServerPlayerInitialSpeeds = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, PlayerMovementStats> ServerPlayerMovementStats = new Dictionary<uint, PlayerMovementStats>();

		public static readonly Dictionary<uint, float> ServerPlayerMovementTimers = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, int> ServerPlayerInfractionCount = new Dictionary<uint, int>();

		public static readonly Dictionary<uint, float> ServerPlayerGracePeriod = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> ServerPunishmentCooldown = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> ServerSpeedCheckCooldowns = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> ServerJumpCheckCooldowns = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> ServerAirborneCheckCooldowns = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> AuthorizedSelfRevives = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> LastConsumableTime = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> LastWeaponSwapTime = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> LastBlockTime = new Dictionary<uint, float>();

		public static readonly Dictionary<uint, float> StaminaCheckTimer = new Dictionary<uint, float>();

		private static readonly Dictionary<string, string> KnownModAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "CodeTalker", "CodeYapper" } };

		public static Main Instance { get; private set; }

		private void Awake()
		{
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			string fullName = Directory.GetParent(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)).FullName;
			string text = Path.Combine(fullName, "HardAntiCheat");
			Directory.CreateDirectory(text);
			InfractionLogPath = Path.Combine(text, "HardAntiCheat_InfractionLog.txt");
			EnableAntiCheat = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enable AntiCheat", true, "Master switch.");
			DisableForHost = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Disable Detections for Host", true, "If true, the host is exempt.");
			TrustedSteamIDs = ((BaseUnityPlugin)this).Config.Bind<string>("1. General", "Trusted SteamIDs", "", "Comma-separated list of exempt SteamIDs.");
			BannedSteamIDs = ((BaseUnityPlugin)this).Config.Bind<string>("1. General", "Banned SteamIDs", "", "Comma-separated list of SteamIDs that are banned from joining.");
			MaxLogFileSizeMB = ((BaseUnityPlugin)this).Config.Bind<int>("1. General", "Max Log File Size (MB)", 5, "If the infraction log exceeds this size, it will be archived on startup.");
			EnableRequiredMods = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Mod Lists", "Enable Required Mods", false, "If true, clients MUST have the mods listed in Required Mod GUIDs.");
			RequiredModGUIDs = ((BaseUnityPlugin)this).Config.Bind<string>("2. Mod Lists", "Required Mod GUIDs", "", "Comma-separated list of Mod GUIDs that clients must have.");
			EnableModBlacklist = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Mod Lists", "Enable Mod Blacklist", false, "If true, clients sending a mod GUID found in the Blacklist will be kicked.");
			BlacklistedModGUIDs = ((BaseUnityPlugin)this).Config.Bind<string>("2. Mod Lists", "Blacklisted Mod GUIDs", "com.cheat.menu,another.bad.mod", "Comma-separated list of Mod GUIDs that are strictly forbidden.");
			EnableModWhitelist = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Mod Lists", "Enable Mod Whitelist", false, "If true, ONLY mods in the Whitelist are allowed.");
			WhitelistedModGUIDs = ((BaseUnityPlugin)this).Config.Bind<string>("2. Mod Lists", "Whitelisted Mod GUIDs", "", "Comma-separated list of Mod GUIDs that are permitted.");
			EnableRemoteDatabase = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Remote Database", "Enable Remote Blacklist DB", false, "Fetch a list of blacklisted mods from a URL.");
			RemoteDatabaseURL = ((BaseUnityPlugin)this).Config.Bind<string>("3. Remote Database", "Remote Blacklist DB URL", "", "URL to a raw text file containing blacklisted Mod GUIDs.");
			EnableThunderstoreWhitelist = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thunderstore", "Enable Thunderstore Whitelist", false, "Automatically whitelist all mods published on Thunderstore.");
			ThunderstoreCommunity = ((BaseUnityPlugin)this).Config.Bind<string>("4. Thunderstore", "Community Identifier", "atlyss", "Thunderstore community to fetch packages from.");
			BlockDeprecatedMods = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thunderstore", "Block Deprecated Mods", true, "Automatically block mods that are deprecated on Thunderstore.");
			ThunderstoreRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("4. Thunderstore", "Refresh Interval (Minutes)", 30f, "How often to refresh the Thunderstore package list.");
			ThunderstoreCacheTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("4. Thunderstore", "Cache Timeout (Hours)", 6f, "How long to cache individual package verification results.");
			AutoWhitelistNewMods = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thunderstore", "Auto-Whitelist New Mods", true, "Automatically add newly discovered Thunderstore mods to the whitelist.");
			AutoBlacklistUnknownMods = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thunderstore", "Auto-Blacklist Unknown Mods", true, "Automatically blacklist mods that cannot be verified on Thunderstore. Persists across restarts.");
			UnknownModGracePeriod = ((BaseUnityPlugin)this).Config.Bind<float>("4. Thunderstore", "Unknown Mod Grace Period", 30f, "Seconds to wait before kicking for unknown mods.");
			VerificationTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("5. Handshake", "Verification Timeout", 25f, "Seconds to wait for client mod list before kicking.");
			EnableMovementChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Movement", "Enable Teleport Checks", true, "Checks movement distance.");
			MaxEffectiveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Max Effective Speed", 100f, "Max plausible speed.");
			MovementGraceBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Movement Grace Buffer", 10f, "Distance buffer.");
			MovementTimeThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Movement Time Threshold", 5.5f, "Time between checks.");
			TeleportDistanceThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Teleport Threshold", 50f, "Distance to log as teleport.");
			EnableAirborneChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Movement", "Enable Fly Checks", true, "Checks airtime.");
			EnableSpeedChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Movement", "Enable Speed Stat Checks", true, "Checks base move speed.");
			JumpThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("6. Movement", "Jump Threshold", 8, "Max jumps allowed.");
			SpeedHackDetectionCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Speed Check Cooldown", 2f, "Log cooldown.");
			JumpHackDetectionCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Jump Check Cooldown", 2f, "Log cooldown.");
			AirborneHackDetectionCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("6. Movement", "Airborne Check Cooldown", 10f, "Log cooldown.");
			EnableExperienceChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("7. Stats", "Enable XP Checks", true, "Checks XP gain.");
			MaxPlausibleXPGain = ((BaseUnityPlugin)this).Config.Bind<int>("7. Stats", "Max XP Gain", 1000000, "Max XP in one go.");
			MaxXPGainPerWindow = ((BaseUnityPlugin)this).Config.Bind<int>("7. Stats", "Max XP Rate", 5000000, "Max XP over time.");
			XPGainWindowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("7. Stats", "XP Window", 30f, "Time window for XP rate.");
			EnableCooldownChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("8. Combat", "Enable Cooldown Checks", true, "Enforce skill cooldowns.");
			EnableReviveChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("8. Combat", "Enable Revive Checks", true, "Prevent self-revive.");
			EnableSpamChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("8. Combat", "Enable Spam Checks", true, "Prevents macro-spamming items/swaps/blocking.");
			MinConsumableInterval = ((BaseUnityPlugin)this).Config.Bind<float>("8. Combat", "Min Consumable Interval", 0.4f, "Min seconds between using items.");
			MinWeaponSwapInterval = ((BaseUnityPlugin)this).Config.Bind<float>("8. Combat", "Min Weapon Swap Interval", 0.25f, "Min seconds between switching weapons.");
			MinBlockInterval = ((BaseUnityPlugin)this).Config.Bind<float>("8. Combat", "Min Block Interval", 0.1f, "Min seconds between block inputs.");
			EnablePunishmentSystem = ((BaseUnityPlugin)this).Config.Bind<bool>("9. Punishment", "Enable Auto-Punish", true, "Kick/Ban on infractions.");
			WarningsUntilAction = ((BaseUnityPlugin)this).Config.Bind<int>("9. Punishment", "Infractions Limit", 5, "Warnings before action.");
			ActionType = ((BaseUnityPlugin)this).Config.Bind<string>("9. Punishment", "Action Type", "Kick", new ConfigDescription("Action to take", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Kick", "Ban" }), Array.Empty<object>()));
			EnableDetailedLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("10. Logging", "Enable Detailed Logs", true, "Log details.");
			LogPlayerName = ((BaseUnityPlugin)this).Config.Bind<bool>("10. Logging", "Log Name", true, "");
			LogPlayerID = ((BaseUnityPlugin)this).Config.Bind<bool>("10. Logging", "Log ID", true, "");
			LogInfractionCount = ((BaseUnityPlugin)this).Config.Bind<bool>("10. Logging", "Log Count", true, "");
			LogInfractionDetails = ((BaseUnityPlugin)this).Config.Bind<bool>("10. Logging", "Log Details", true, "");
			CheckAndArchiveLogFile();
			ParseTrustedSteamIDs();
			ParseBannedSteamIDs();
			ParseRequiredMods();
			ParseBlacklistedMods();
			ParseWhitelistedMods();
			if (EnableRemoteDatabase.Value)
			{
				FetchRemoteDatabase();
			}
			TrustedSteamIDs.SettingChanged += delegate
			{
				ParseTrustedSteamIDs();
			};
			BannedSteamIDs.SettingChanged += delegate
			{
				ParseBannedSteamIDs();
			};
			RequiredModGUIDs.SettingChanged += delegate
			{
				ParseRequiredMods();
			};
			BlacklistedModGUIDs.SettingChanged += delegate
			{
				ParseBlacklistedMods();
			};
			WhitelistedModGUIDs.SettingChanged += delegate
			{
				ParseWhitelistedMods();
			};
			RemoteDatabaseURL.SettingChanged += delegate
			{
				if (EnableRemoteDatabase.Value)
				{
					FetchRemoteDatabase();
				}
			};
			EnableThunderstoreWhitelist.SettingChanged += delegate
			{
				if (EnableThunderstoreWhitelist.Value)
				{
					StartThunderstoreIntegration();
				}
			};
			InitEasySettingsSafe();
			harmony.PatchAll();
			Log.LogInfo((object)string.Format("[{0}] loaded. ReqList: {1} | Blacklist: {2} | Whitelist: {3} | Thunderstore: {4}", "HardAntiCheat", EnableRequiredMods.Value, EnableModBlacklist.Value, EnableModWhitelist.Value, EnableThunderstoreWhitelist.Value));
		}

		private void Start()
		{
			//IL_0011: 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_001c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			object obj = <>O.<0>__OnClientReceivedRequest;
			if (obj == null)
			{
				BinaryPacketListener val = OnClientReceivedRequest;
				<>O.<0>__OnClientReceivedRequest = val;
				obj = (object)val;
			}
			CodeTalkerNetwork.RegisterBinaryListener<HAC_ModListRequest>((BinaryPacketListener)obj);
			object obj2 = <>O.<1>__OnReceivedResponse;
			if (obj2 == null)
			{
				BinaryPacketListener val2 = OnReceivedResponse;
				<>O.<1>__OnReceivedResponse = val2;
				obj2 = (object)val2;
			}
			CodeTalkerNetwork.RegisterBinaryListener<HAC_ModListResponse>((BinaryPacketListener)obj2);
			object obj3 = <>O.<2>__OnClientReceivedKickMessage;
			if (obj3 == null)
			{
				BinaryPacketListener val3 = OnClientReceivedKickMessage;
				<>O.<2>__OnClientReceivedKickMessage = val3;
				obj3 = (object)val3;
			}
			CodeTalkerNetwork.RegisterBinaryListener<HAC_KickMessage>((BinaryPacketListener)obj3);
			if (EnableThunderstoreWhitelist.Value && !isThunderstoreInitialized)
			{
				Log.LogInfo((object)"[HAC] Pre-warming Thunderstore cache...");
				StartThunderstoreIntegration();
			}
		}

		private void StartThunderstoreIntegration()
		{
			if (EnableThunderstoreWhitelist.Value)
			{
				if (thunderstoreRefreshCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(thunderstoreRefreshCoroutine);
				}
				thunderstoreRefreshCoroutine = ((MonoBehaviour)this).StartCoroutine(InitializeThunderstoreDatabase());
				((MonoBehaviour)this).StartCoroutine(AutoRefreshThunderstoreDatabase());
			}
		}

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

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

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

		private List<string> GeneratePossibleGUIDs(ThunderstorePackageV1 pkg)
		{
			List<string> list = new List<string>();
			string text = (pkg.namespace_name ?? pkg.owner ?? "").Replace("-", ".").Replace(" ", "");
			string text2 = (pkg.name ?? "").Replace("-", ".").Replace(" ", "");
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2))
			{
				return list;
			}
			list.Add(text + "." + text2);
			list.Add("com." + text + "." + text2);
			list.Add("org." + text + "." + text2);
			list.Add((text + "." + text2).ToLower());
			list.Add(text + "-" + text2);
			if (!string.IsNullOrEmpty(pkg.full_name))
			{
				list.Add(pkg.full_name);
				list.Add(pkg.full_name.Replace("-", "."));
			}
			return list.Distinct().ToList();
		}

		[IteratorStateMachine(typeof(<StaggeredBackgroundVerify>d__97))]
		private IEnumerator StaggeredBackgroundVerify(List<(string guid, string name, string version)> mods)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <StaggeredBackgroundVerify>d__97(0)
			{
				<>4__this = this,
				mods = mods
			};
		}

		private static string NormalizeForMatch(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return "";
			}
			return s.ToLower().Replace(" ", "").Replace("_", "")
				.Replace("-", "")
				.Replace(".", "");
		}

		private static bool PackageMatchesMod(ThunderstorePackageV1 pkg, string guid, string displayName)
		{
			string text = NormalizeForMatch(displayName);
			string text2 = NormalizeForMatch(guid);
			string text3 = NormalizeForMatch(pkg.name ?? "");
			string text4 = NormalizeForMatch(pkg.full_name ?? "");
			string text5 = NormalizeForMatch(pkg.namespace_name ?? pkg.owner ?? "");
			if (!string.IsNullOrEmpty(text) && text == text3)
			{
				return true;
			}
			if (!string.IsNullOrEmpty(text) && text.Length >= 4 && (text4.Contains(text) || (text.Contains(text3) && text3.Length >= 4)))
			{
				return true;
			}
			if (!string.IsNullOrEmpty(text3) && text3.Length >= 4 && text2.Contains(text3))
			{
				return true;
			}
			if (!string.IsNullOrEmpty(text5) && text5.Length >= 4 && text2.Contains(text5))
			{
				return true;
			}
			if ((KnownModAliases.TryGetValue(displayName, out string value) || KnownModAliases.TryGetValue(guid, out value)) && NormalizeForMatch(value) == text3)
			{
				return true;
			}
			return false;
		}

		[IteratorStateMachine(typeof(<BackgroundVerifyModAsync>d__101))]
		private IEnumerator BackgroundVerifyModAsync(string guid, string name, string version)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <BackgroundVerifyModAsync>d__101(0)
			{
				<>4__this = this,
				guid = guid,
				name = name,
				version = version
			};
		}

		public static void OnClientReceivedRequest(PacketHeader header, BinaryPacketBase packet)
		{
			if (!(packet is HAC_ModListRequest hAC_ModListRequest) || !ulong.TryParse(Player._mainPlayer?._steamID, out var result) || hAC_ModListRequest.TargetSteamID != result)
			{
				return;
			}
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				list.Add(pluginInfo.Key);
				list2.Add(pluginInfo.Value.Metadata.Name);
				list3.Add(pluginInfo.Value.Metadata.Version.ToString());
			}
			HAC_ModListResponse hAC_ModListResponse = new HAC_ModListResponse
			{
				ClientModGUIDs = list,
				ClientModNames = list2,
				ClientModVersions = list3
			};
			CodeTalkerNetwork.SendNetworkPacket(header.SenderID, (BinaryPacketBase)(object)hAC_ModListResponse, (CompressionType)0, CompressionLevel.Fastest);
		}

		public static void OnReceivedResponse(PacketHeader header, BinaryPacketBase packet)
		{
			if (!(packet is HAC_ModListResponse hAC_ModListResponse))
			{
				return;
			}
			ulong senderID = header.SenderID;
			if (NetworkServer.active)
			{
				if (PendingVerification.TryGetValue(senderID, out Coroutine value))
				{
					((MonoBehaviour)Instance).StartCoroutine(Instance.VerifyClientModsWithThunderstore(senderID, hAC_ModListResponse.ClientModGUIDs ?? new List<string>(), hAC_ModListResponse.ClientModNames ?? new List<string>(), hAC_ModListResponse.ClientModVersions ?? new List<string>(), value));
				}
			}
			else
			{
				if (!EnableModBlacklist.Value)
				{
					return;
				}
				Player val = ((IEnumerable<Player>)Object.FindObjectsOfType<Player>()).FirstOrDefault((Func<Player, bool>)((Player p) => p._isHostPlayer));
				if (!((Object)(object)val != (Object)null) || !(val._steamID == senderID.ToString()))
				{
					return;
				}
				List<string> source = hAC_ModListResponse.ClientModGUIDs ?? new List<string>();
				List<string> list = source.Where((string m) => ServerBlacklistedGUIDs.Contains(m)).ToList();
				if (list.Any())
				{
					Log.LogWarning((object)("[HAC] Host is using blacklisted mods: " + string.Join(", ", list) + ". Disconnecting for safety."));
					if ((Object)(object)ChatBehaviour._current != (Object)null)
					{
						ChatBehaviour._current.New_ChatMessage("<color=red><b>[HAC] Disconnected:</b> Host is using blacklisted mods!</color>");
					}
					if (NetworkClient.active)
					{
						NetworkClient.Disconnect();
					}
				}
			}
		}

		[IteratorStateMachine(typeof(<VerifyClientModsWithThunderstore>d__104))]
		private IEnumerator VerifyClientModsWithThunderstore(ulong steamId, List<string> guids, List<string> names, List<string> versions, Coroutine timeoutCoroutine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <VerifyClientModsWithThunderstore>d__104(0)
			{
				<>4__this = this,
				steamId = steamId,
				guids = guids,
				names = names,
				versions = versions,
				timeoutCoroutine = timeoutCoroutine
			};
		}

		public static void OnClientReceivedKickMessage(PacketHeader header, BinaryPacketBase packet)
		{
			if (packet is HAC_KickMessage hAC_KickMessage)
			{
				Log.LogWarning((object)("[HAC] Kicked by server. Reason: " + hAC_KickMessage.Reason));
				if ((Object)(object)ChatBehaviour._current != (Object)null)
				{
					ChatBehaviour._current.New_ChatMessage("<color=red><b>[HAC] Kicked by Server:</b> " + hAC_KickMessage.Reason + "</color>");
				}
			}
		}

		private static void AuthorizePlayer(ulong steamId, Coroutine coroutine)
		{
			if ((Object)(object)Instance != (Object)null && coroutine != null)
			{
				((MonoBehaviour)Instance).StopCoroutine(coroutine);
			}
			PendingVerification.Remove(steamId);
			VerifiedSteamIDs.Add(steamId);
		}

		[IteratorStateMachine(typeof(<SendRequestWithDelay>d__107))]
		public IEnumerator SendRequestWithDelay(Player player, ulong steamId)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SendRequestWithDelay>d__107(0)
			{
				<>4__this = this,
				player = player,
				steamId = steamId
			};
		}

		[IteratorStateMachine(typeof(<KickClientAfterDelay>d__108))]
		public IEnumerator KickClientAfterDelay(Player player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <KickClientAfterDelay>d__108(0)
			{
				<>4__this = this,
				player = player
			};
		}

		[IteratorStateMachine(typeof(<DelayedKick>d__109))]
		public IEnumerator DelayedKick(Player player, string reason)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedKick>d__109(0)
			{
				<>4__this = this,
				player = player,
				reason = reason
			};
		}

		public static void BroadcastServerMessage(string message)
		{
			//IL_0052: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				string text = ((message.Length > 120) ? (message.Substring(0, 120) + "...") : message);
				text = text.Replace("<", "").Replace(">", "");
				ServerMessage val = default(ServerMessage);
				val.servMsg = "[HAC] " + text;
				ServerMessage val2 = val;
				NetworkServer.SendToAll<ServerMessage>(val2, 0, false);
			}
		}

		private static void PunishVerificationFailure(ulong steamId, string reason)
		{
			if (PendingVerification.TryGetValue(steamId, out Coroutine value))
			{
				if ((Object)(object)Instance != (Object)null && value != null)
				{
					((MonoBehaviour)Instance).StopCoroutine(value);
				}
				PendingVerification.Remove(steamId);
			}
			VerifiedSteamIDs.Remove(steamId);
			Player playerBySteamID = GetPlayerBySteamID(steamId);
			if ((Object)(object)playerBySteamID != (Object)null && ((NetworkBehaviour)playerBySteamID).connectionToClient != null)
			{
				string text = playerBySteamID._nickname ?? "Unknown";
				Log.LogWarning((object)("[HAC] Kicking " + text + ". Reason: " + reason));
				BroadcastServerMessage(text + " was kicked: " + reason);
				if ((Object)(object)HostConsole._current != (Object)null)
				{
					HostConsole._current.Init_ServerMessage("[HAC]: Kicked " + text + ". " + reason);
				}
				((MonoBehaviour)Instance).StartCoroutine(Instance.DelayedKick(playerBySteamID, reason));
			}
		}

		public void FetchRemoteDatabase()
		{
			if (EnableRemoteDatabase.Value && !string.IsNullOrWhiteSpace(RemoteDatabaseURL.Value))
			{
				((MonoBehaviour)this).StartCoroutine(FetchRemoteDatabaseCoroutine());
			}
		}

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

		private void InitEasySettingsSafe()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			Settings.OnInitialized.AddListener(new UnityAction(AddSettings));
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				((BaseUnityPlugin)this).Config.Reload();
				((BaseUnityPlugin)this).Config.Save();
				ParseTrustedSteamIDs();
				ParseBannedSteamIDs();
				ParseRequiredMods();
				ParseBlacklistedMods();
				ParseWhitelistedMods();
				if (EnableRemoteDatabase.Value)
				{
					FetchRemoteDatabase();
				}
				if (EnableThunderstoreWhitelist.Value)
				{
					StartThunderstoreIntegration();
				}
				Log.LogInfo((object)"[HAC] Settings applied and reloaded successfully.");
			});
		}

		private void AddSettings()
		{
			SettingsTab orAddCustomTab = Settings.GetOrAddCustomTab("HardAntiCheat");
			orAddCustomTab.AddHeader("General");
			orAddCustomTab.AddToggle(EnableAntiCheat);
			orAddCustomTab.AddToggle(DisableForHost);
			orAddCustomTab.AddTextField(TrustedSteamIDs, "Text...");
			orAddCustomTab.AddTextField(BannedSteamIDs, "Text...");
			orAddCustomTab.AddSlider(VerificationTimeout, false);
			orAddCustomTab.AddHeader("Mod Lists");
			orAddCustomTab.AddToggle(EnableRequiredMods);
			orAddCustomTab.AddTextField(RequiredModGUIDs, "Text...");
			orAddCustomTab.AddToggle(EnableModBlacklist);
			orAddCustomTab.AddTextField(BlacklistedModGUIDs, "Text...");
			orAddCustomTab.AddToggle(EnableModWhitelist);
			orAddCustomTab.AddTextField(WhitelistedModGUIDs, "Text...");
			orAddCustomTab.AddHeader("Thunderstore Integration");
			orAddCustomTab.AddToggle(EnableThunderstoreWhitelist);
			orAddCustomTab.AddTextField(ThunderstoreCommunity, "Text...");
			orAddCustomTab.AddToggle(BlockDeprecatedMods);
			orAddCustomTab.AddToggle(AutoWhitelistNewMods);
			orAddCustomTab.AddToggle(AutoBlacklistUnknownMods);
			orAddCustomTab.AddAdvancedSlider(ThunderstoreRefreshInterval, false);
			orAddCustomTab.AddAdvancedSlider(UnknownModGracePeriod, false);
			orAddCustomTab.AddHeader("Remote Database");
			orAddCustomTab.AddToggle(EnableRemoteDatabase);
			orAddCustomTab.AddTextField(RemoteDatabaseURL, "Text...");
			orAddCustomTab.AddHeader("Movement Detection");
			orAddCustomTab.AddToggle(EnableMovementChecks);
			orAddCustomTab.AddSlider(MaxEffectiveSpeed, false);
			orAddCustomTab.AddSlider(TeleportDistanceThreshold, false);
			orAddCustomTab.AddToggle(EnableAirborneChecks);
			orAddCustomTab.AddToggle(EnableSpeedChecks);
			orAddCustomTab.AddAdvancedSlider(JumpThreshold);
			orAddCustomTab.AddHeader("Combat & Stats");
			orAddCustomTab.AddToggle(EnableExperienceChecks);
			orAddCustomTab.AddToggle(EnableCooldownChecks);
			orAddCustomTab.AddToggle(EnableReviveChecks);
			orAddCustomTab.AddToggle(EnableSpamChecks);
			orAddCustomTab.AddSlider(MinBlockInterval, false);
			orAddCustomTab.AddHeader("Punishment");
			orAddCustomTab.AddToggle(EnablePunishmentSystem);
			orAddCustomTab.AddAdvancedSlider(WarningsUntilAction);
			string[] actions = new string[2] { "Kick", "Ban" };
			int num = ((ActionType.Value == "Ban") ? 1 : 0);
			AtlyssDropdown val2 = orAddCustomTab.AddDropdown("Action Type", actions, num);
			val2.OnValueChanged.AddListener((UnityAction<int>)delegate(int val)
			{
				ActionType.Value = actions[val];
			});
			orAddCustomTab.AddHeader("Logging");
			orAddCustomTab.AddToggle(EnableDetailedLogs);
		}

		private static void ParseBlacklistedMods()
		{
			ServerBlacklistedGUIDs.Clear();
			string value = BlacklistedModGUIDs.Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				string[] array = value.Split(',');
				string[] array2 = array;
				foreach (string text in array2)
				{
					string text2 = text.Trim();
					if (!string.IsNullOrEmpty(text2))
					{
						ServerBlacklistedGUIDs.Add(text2.ToLower());
					}
				}
			}
			Log.LogInfo((object)$"[HAC] Blacklist updated. {ServerBlacklistedGUIDs.Count} mods banned.");
		}

		private static void ParseWhitelistedMods()
		{
			ServerWhitelistedGUIDs.Clear();
			string value = WhitelistedModGUIDs.Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				string[] array = value.Split(',');
				string[] array2 = array;
				foreach (string text in array2)
				{
					string text2 = text.Trim();
					if (!string.IsNullOrEmpty(text2))
					{
						ServerWhitelistedGUIDs.Add(text2.ToLower());
					}
				}
			}
			Log.LogInfo((object)$"[HAC] Whitelist updated. {ServerWhitelistedGUIDs.Count} mods permitted.");
		}

		private static void ParseRequiredMods()
		{
			ServerRequiredGUIDs.Clear();
			string value = RequiredModGUIDs.Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				string[] array = value.Split(',');
				string[] array2 = array;
				foreach (string text in array2)
				{
					string text2 = text.Trim();
					if (!string.IsNullOrEmpty(text2))
					{
						ServerRequiredGUIDs.Add(text2.ToLower());
					}
				}
			}
			Log.LogInfo((object)$"[HAC] Required mods updated. {ServerRequiredGUIDs.Count} mods required.");
		}

		private static void ParseTrustedSteamIDs()
		{
			WhitelistedUsers.Clear();
			string[] array = TrustedSteamIDs.Value.Split(',');
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (ulong.TryParse(text.Trim(), out var result))
				{
					WhitelistedUsers.Add(result);
				}
			}
		}

		private static void ParseBannedSteamIDs()
		{
			ServerBannedUsers.Clear();
			string value = BannedSteamIDs.Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				string[] array = value.Split(',');
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (ulong.TryParse(text.Trim(), out var result))
					{
						ServerBannedUsers.Add(result);
					}
				}
			}
			Log.LogInfo((object)$"[HAC] Banned users updated. {ServerBannedUsers.Count} users banned.");
		}

		public static bool IsPlayerExempt(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (DisableForHost.Value && player._isHostPlayer)
			{
				return true;
			}
			if (!string.IsNullOrEmpty(player._steamID) && ulong.TryParse(player._steamID, out var result) && WhitelistedUsers.Contains(result))
			{
				return true;
			}
			return false;
		}

		public static bool IsPlayerBanned(ulong steamId)
		{
			return ServerBannedUsers.Contains(steamId);
		}

		private static Player GetPlayerBySteamID(ulong steamId)
		{
			Player val = default(Player);
			foreach (NetworkConnectionToClient value in NetworkServer.connections.Values)
			{
				if ((Object)(object)((NetworkConnection)value).identity != (Object)null && ((Component)((NetworkConnection)value).identity).TryGetComponent<Player>(ref val) && ulong.TryParse(val._steamID, out var result) && result == steamId)
				{
					return val;
				}
			}
			return null;
		}

		private void CheckAndArchiveLogFile()
		{
			try
			{
				if (File.Exists(InfractionLogPath))
				{
					FileInfo fileInfo = new FileInfo(InfractionLogPath);
					long num = (long)MaxLogFileSizeMB.Value * 1024L * 1024;
					if (fileInfo.Length > num)
					{
						File.Move(InfractionLogPath, Path.Combine(Path.GetDirectoryName(InfractionLogPath), $"{Path.GetFileNameWithoutExtension(InfractionLogPath)}_ARCHIVED_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt"));
					}
				}
			}
			catch
			{
			}
		}

		public static void LogInfraction(NetworkBehaviour instance, string cheatType, string details)
		{
			uint netId = instance.netId;
			if (ServerPunishmentCooldown.TryGetValue(netId, out var value) && Time.time < value)
			{
				return;
			}
			ServerPunishmentCooldown.Remove(netId);
			if (!ServerPlayerInfractionCount.ContainsKey(netId))
			{
				ServerPlayerInfractionCount[netId] = 0;
			}
			ServerPlayerInfractionCount[netId]++;
			int num = ServerPlayerInfractionCount[netId];
			int value2 = WarningsUntilAction.Value;
			Player component = ((Component)instance).GetComponent<Player>();
			string text = component?._nickname ?? "Unknown";
			string text2 = component?._steamID ?? $"netId:{netId}";
			if (EnablePunishmentSystem.Value && !AtlyssNetworkManager._current._soloMode && num >= value2)
			{
				if (!NetworkServer.active || !((Object)(object)component != (Object)null) || ((NetworkBehaviour)component).connectionToClient == null)
				{
					return;
				}
				ServerPunishmentCooldown[netId] = Time.time + 60f;
				string text3 = ActionType.Value.ToLower();
				string text4 = $"Player {text} (ID: {text2}) was automatically {text3.ToUpper()}ed for reaching {num}/{value2} infractions.";
				BroadcastServerMessage($"{text} was {text3}ed for {num} infractions");
				Log.LogWarning((object)text4);
				string capturedPunishment = text4;
				Task.Run(delegate
				{
					try
					{
						File.AppendAllText(InfractionLogPath, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [PUNISHMENT] " + capturedPunishment + Environment.NewLine);
					}
					catch
					{
					}
				});
				if ((Object)(object)HostConsole._current != (Object)null)
				{
					HostConsole._current.Init_ServerMessage("[HAC]: " + text4);
				}
				if (text3 == "kick")
				{
					((MonoBehaviour)Instance).StartCoroutine(Instance.DelayedKick(component, text4));
				}
				else
				{
					HC_PeerListEntry val = null;
					if ((Object)(object)HostConsole._current != (Object)null)
					{
						foreach (HC_PeerListEntry peerListEntry in HostConsole._current._peerListEntries)
						{
							if ((Object)(object)peerListEntry._netId != (Object)null && peerListEntry._netId.netId == netId)
							{
								val = peerListEntry;
								break;
							}
						}
					}
					if ((Object)(object)val != (Object)null)
					{
						CodeTalkerNetwork.SendNetworkPacket(component, (BinaryPacketBase)(object)new HAC_KickMessage
						{
							Reason = text4
						}, (CompressionType)0, CompressionLevel.Fastest);
						HostConsole._current._selectedPeerEntry = val;
						HostConsole._current.Ban_Peer();
					}
					else
					{
						((MonoBehaviour)Instance).StartCoroutine(Instance.DelayedKick(component, text4));
						Log.LogError((object)$"Could not find PeerListEntry for player {text} (netId: {netId}) to BAN, kicked instead.");
					}
				}
				ServerPlayerInfractionCount.Remove(netId);
			}
			else
			{
				if (!EnableDetailedLogs.Value)
				{
					return;
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]");
				List<string> list = new List<string>();
				if (LogPlayerName.Value)
				{
					list.Add("Player: " + text);
				}
				if (LogPlayerID.Value)
				{
					list.Add("ID: " + text2);
				}
				if (list.Any())
				{
					stringBuilder.Append(" " + string.Join(" | ", list));
				}
				stringBuilder.Append(" | Type: " + cheatType);
				if (LogInfractionDetails.Value)
				{
					stringBuilder.Append(" | Details: " + details);
				}
				if (LogInfractionCount.Value)
				{
					stringBuilder.Append($" | Warning {num}/{value2}");
				}
				string logMessage = stringBuilder.ToString();
				Log.LogWarning((object)logMessage);
				Task.Run(delegate
				{
					try
					{
						File.AppendAllText(InfractionLogPath, logMessage + Environment.NewLine);
					}
					catch
					{
					}
				});
			}
		}

		public static void ClearAllPlayerData(uint netId, ulong steamId)
		{
			ServerRemainingCooldowns.Remove(netId);
			ServerPlayerPositions.Remove(netId);
			ServerPlayerStats.Remove(netId);
			XpGainHistory.Remove(netId);
			ServerRunningXpTotal.Remove(netId);
			ServerPlayerAirborneStates.Remove(netId);
			ServerPlayerInitialSpeeds.Remove(netId);
			ServerPlayerMovementStats.Remove(netId);
			ServerPlayerMovementTimers.Remove(netId);
			ServerPlayerInfractionCount.Remove(netId);
			ServerPlayerGracePeriod.Remove(netId);
			ServerPunishmentCooldown.Remove(netId);
			ServerSpeedCheckCooldowns.Remove(netId);
			ServerJumpCheckCooldowns.Remove(netId);
			ServerAirborneCheckCooldowns.Remove(netId);
			LastConsumableTime.Remove(netId);
			LastWeaponSwapTime.Remove(netId);
			LastBlockTime.Remove(netId);
			StaminaCheckTimer.Remove(netId);
			if (PendingVerification.TryGetValue(steamId, out Coroutine value))
			{
				if ((Object)(object)Instance != (Object)null && value != null)
				{
					((MonoBehaviour)Instance).StopCoroutine(value);
				}
				PendingVerification.Remove(steamId);
			}
			VerifiedSteamIDs.Remove(steamId);
		}
	}
	[HarmonyPatch(typeof(PlayerMove), "Start")]
	public static class PlayerSpawnPatch
	{
		private const float GRACE_PERIOD_SECONDS = 3f;

		public static void Postfix(PlayerMove __instance)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			uint netId = ((NetworkBehaviour)__instance).netId;
			Player component = ((Component)__instance).GetComponent<Player>();
			ulong result2;
			if (NetworkServer.active)
			{
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<HoneypotComponent>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<HoneypotComponent>();
				}
				Main.ServerPlayerGracePeriod[netId] = Time.time + 3f;
				if (!Main.ServerPlayerInitialSpeeds.ContainsKey(netId))
				{
					Main.ServerPlayerInitialSpeeds[netId] = __instance.Network_movSpeed;
				}
				Main.ServerPlayerPositions[netId] = new PlayerPositionData
				{
					Position = ((Component)__instance).transform.position,
					Timestamp = Time.time
				};
				Main.ServerPlayerMovementStats[netId] = new PlayerMovementStats
				{
					RecentSpeeds = new List<float>(),
					TimeAtMaxSpeed = 0f
				};
				Main.ServerPlayerMovementTimers[netId] = Time.time;
				if ((Object)(object)component != (Object)null && !((NetworkBehaviour)component).isLocalPlayer && ulong.TryParse(component._steamID, out var result))
				{
					if (Main.IsPlayerBanned(result))
					{
						Main.Log.LogInfo((object)$"Player {component._nickname} ({result}) is on the banned list. Kicking immediately.");
						((MonoBehaviour)Main.Instance).StartCoroutine(Main.Instance.DelayedKick(component, "You are banned from this server."));
					}
					else if (Main.IsPlayerExempt(component))
					{
						Main.Log.LogInfo((object)("Player " + component._nickname + " is exempt. Skipping verification."));
						Main.VerifiedSteamIDs.Add(result);
					}
					else if (!Main.PendingVerification.ContainsKey(result) && !Main.VerifiedSteamIDs.Contains(result) && (Main.EnableModBlacklist.Value || Main.EnableModWhitelist.Value || Main.EnableRequiredMods.Value || Main.EnableThunderstoreWhitelist.Value))
					{
						((MonoBehaviour)Main.Instance).StartCoroutine(Main.Instance.SendRequestWithDelay(component, result));
					}
				}
			}
			else if ((Main.EnableModBlacklist.Value || Main.EnableModWhitelist.Value || Main.EnableRequiredMods.Value || Main.EnableThunderstoreWhitelist.Value) && (Object)(object)component != (Object)null && component._isHostPlayer && !((NetworkBehaviour)component).isLocalPlayer && ulong.TryParse(component._steamID, out result2))
			{
				Main.Log.LogInfo((object)$"[HAC] Requesting Host ({result2}) Mod List... ");
				HAC_ModListRequest hAC_ModListRequest = new HAC_ModListRequest
				{
					TargetSteamID = result2
				};
				CodeTalkerNetwork.SendNetworkPacket(component, (BinaryPacketBase)(object)hAC_ModListRequest, (CompressionType)0, CompressionLevel.Fastest);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerInventory), "Cmd_UseConsumable")]
	public static class PlayerInventory_UseConsumable_Patch
	{
		public static bool Prefix(PlayerInventory __instance)
		{
			if (!NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableSpamChecks.Value)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if (Main.IsPlayerExempt(component))
			{
				return true;
			}
			uint netId = ((NetworkBehaviour)__instance).netId;
			float time = Time.time;
			if (Main.LastConsumableTime.TryGetValue(netId, out var value) && time - value < Main.MinConsumableInterval.Value)
			{
				return false;
			}
			Main.LastConsumableTime[netId] = time;
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerCombat), "Cmd_QuickSwapWeapon")]
	public static class PlayerCombat_QuickSwap_Patch
	{
		public static bool Prefix(PlayerCombat __instance)
		{
			if (!NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableSpamChecks.Value)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if (Main.IsPlayerExempt(component))
			{
				return true;
			}
			uint netId = ((NetworkBehaviour)__instance).netId;
			float time = Time.time;
			if (Main.LastWeaponSwapTime.TryGetValue(netId, out var value) && time - value < Main.MinWeaponSwapInterval.Value)
			{
				return false;
			}
			Main.LastWeaponSwapTime[netId] = time;
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerCombat), "Cmd_ApplyBlockCondition")]
	public static class PlayerCombat_Block_Patch
	{
		public static bool Prefix(PlayerCombat __instance, bool _isTrue)
		{
			if (!_isTrue || !NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableSpamChecks.Value)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if (Main.IsPlayerExempt(component))
			{
				return true;
			}
			uint netId = ((NetworkBehaviour)__instance).netId;
			float time = Time.time;
			if (Main.LastBlockTime.TryGetValue(netId, out var value) && time - value < Main.MinBlockInterval.Value)
			{
				return false;
			}
			Main.LastBlockTime[netId] = time;
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerMove), "Update")]
	public static class MovementAndAirborneValidationPatch
	{
		private const float MAX_ALLOWED_AIR_TIME = 10f;

		private const float MAX_FLIGHT_HEIGHT = 4240f;

		public static void Postfix(PlayerMove __instance)
		{
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)AtlyssNetworkManager._current == (Object)null || !NetworkServer.active || !Main.EnableAntiCheat.Value || AtlyssNetworkManager._current._soloMode || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if ((Object)(object)component == (Object)null || Main.IsPlayerExempt(component))
			{
				return;
			}
			uint netId = ((NetworkBehaviour)__instance).netId;
			if (Main.ServerPlayerGracePeriod.TryGetValue(netId, out var value))
			{
				if (Time.time < value)
				{
					return;
				}
				Main.ServerPlayerGracePeriod.Remove(netId);
			}
			if (Main.EnableSpeedChecks.Value && (!Main.ServerSpeedCheckCooldowns.ContainsKey(netId) || Time.time > Main.ServerSpeedCheckCooldowns[netId]) && Main.ServerPlayerInitialSpeeds.TryGetValue(netId, out var value2) && __instance._movSpeed > value2 * 1.5f)
			{
				Main.LogInfraction((NetworkBehaviour)(object)__instance, "Stat Manipulation (Move Speed)", $"Detected illegal move speed of {__instance._movSpeed}. Reverting.");
				__instance._movSpeed = value2;
				Main.ServerSpeedCheckCooldowns[netId] = Time.time + Main.SpeedHackDetectionCooldown.Value;
			}
			if (Main.EnableExperienceChecks.Value)
			{
				StatusEntity component2 = ((Component)__instance).GetComponent<StatusEntity>();
				PlayerStats component3 = ((Component)__instance).GetComponent<PlayerStats>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null && component2.Network_currentStamina >= component3._statStruct._maxStamina - 1 && __instance.RayGroundCheck() && Main.ServerPlayerInitialSpeeds.TryGetValue(netId, out var value3))
				{
					Rigidbody component4 = ((Component)__instance).GetComponent<Rigidbody>();
					if ((Object)(object)component4 != (Object)null)
					{
						Vector3 velocity = component4.velocity;
						Vector3 val = new Vector3(velocity.x, 0f, velocity.z);
						float magnitude = ((Vector3)(ref val)).magnitude;
						if (magnitude > value3 * 1.2f)
						{
							if (!Main.StaminaCheckTimer.ContainsKey(netId))
							{
								Main.StaminaCheckTimer[netId] = Time.time;
							}
							if (Time.time - Main.StaminaCheckTimer[netId] > 3f)
							{
								Main.LogInfraction((NetworkBehaviour)(object)__instance, "Stat Manipulation (Infinite Stamina)", "Sustained high speed with full stamina.");
								Main.StaminaCheckTimer[netId] = Time.time + 5f;
							}
							else
							{
								Main.StaminaCheckTimer[netId] = Time.time;
							}
						}
					}
				}
				else
				{
					Main.StaminaCheckTimer[netId] = Time.time;
				}
			}
			Vector3 position = ((Component)__instance).transform.position;
			if (Main.EnableMovementChecks.Value && Main.ServerPlayerPositions.TryGetValue(netId, out var value4))
			{
				float num = Time.time - value4.Timestamp;
				float num2 = Vector3.Distance(value4.Position, position);
				if (num > Main.MovementTimeThreshold.Value)
				{
					float value5;
					float num3 = (Main.ServerPlayerInitialSpeeds.TryGetValue(netId, out value5) ? value5 : 50f) * 1.5f * num + Main.MovementGraceBuffer.Value;
					if (num2 > num3)
					{
						string cheatType = ((num2 > Main.TeleportDistanceThreshold.Value) ? "Movement Hack (Teleport)" : "Movement Hack (Speed Mismatch)");
						Main.LogInfraction((NetworkBehaviour)(object)__instance, cheatType, $"Moved {num2:F1} units in {num:F2}s (Expected max: {num3:F1}). Reverting position.");
						((Component)component).transform.position = value4.Position;
					}
				}
				Main.ServerPlayerPositions[netId] = new PlayerPositionData
				{
					Position = position,
					Timestamp = Time.time
				};
			}
			if (!Main.EnableAirborneChecks.Value)
			{
				return;
			}
			PlayerAirborneData playerAirborneData2;
			if (!Main.ServerPlayerAirborneStates.ContainsKey(netId))
			{
				PlayerAirborneData playerAirborneData = default(PlayerAirborneData);
				playerAirborneData.AirTime = 0f;
				playerAirborneData.LastGroundedPosition = position;
				playerAirborneData.ServerSideJumpCount = 0;
				playerAirborneData.LastVerticalPosition = position.y;
				playerAirborneData.VerticalStallTime = 0f;
				playerAirborneData2 = playerAirborneData;
			}
			else
			{
				playerAirborneData2 = Main.ServerPlayerAirborneStates[netId];
			}
			PlayerAirborneData value6 = playerAirborneData2;
			if (__instance.RayGroundCheck())
			{
				value6.AirTime = 0f;
				value6.LastGroundedPosition = position;
			}
			else
			{
				value6.AirTime += Time.deltaTime;
			}
			if (position.y > 4240f)
			{
				Main.LogInfraction((NetworkBehaviour)(object)__instance, "Movement Hack (Fly)", "Exceeded maximum height limit. Reverting.");
				((Component)__instance).transform.position = value6.LastGroundedPosition;
				return;
			}
			if (value6.AirTime > 10f && (!Main.ServerAirborneCheckCooldowns.ContainsKey(netId) || Time.time > Main.ServerAirborneCheckCooldowns[netId]))
			{
				Main.LogInfraction((NetworkBehaviour)(object)__instance, "Movement Hack (Fly)", $"Airborne for {value6.AirTime:F1} seconds. Reverting.");
				Main.ServerAirborneCheckCooldowns[netId] = Time.time + Main.AirborneHackDetectionCooldown.Value;
			}
			if (value6.AirTime > 10f)
			{
				((Component)__instance).transform.position = value6.LastGroundedPosition;
				value6.AirTime = 0f;
			}
			Main.ServerPlayerAirborneStates[netId] = value6;
		}
	}
	[HarmonyPatch]
	public static class ItemUsageValidationPatch
	{
		[HarmonyPatch(typeof(PlayerInventory), "UserCode_Cmd_UseConsumable__ItemData")]
		[HarmonyPrefix]
		public static void GrantTokenOnTearUsage(PlayerInventory __instance, ItemData _itemData)
		{
			if (NetworkServer.active && _itemData != null && _itemData._itemName == "Angela's Tear")
			{
				Main.AuthorizedSelfRevives[((NetworkBehaviour)__instance).netId] = Time.time;
			}
		}
	}
	[HarmonyPatch]
	public static class ServerAuthorityValidationPatch
	{
		[HarmonyPatch(typeof(StatusEntity), "Cmd_RevivePlayer")]
		[HarmonyPrefix]
		public static bool ValidateRevive(StatusEntity __instance, StatusEntity _statusEntity)
		{
			if (!NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableReviveChecks.Value)
			{
				return true;
			}
			Player component = ((Component)_statusEntity).GetComponent<Player>();
			if ((Object)(object)component == (Object)null || Main.IsPlayerExempt(component))
			{
				return true;
			}
			if (((NetworkBehaviour)__instance).netId == ((NetworkBehaviour)_statusEntity).netId)
			{
				Main.LogInfraction((NetworkBehaviour)(object)__instance, "Unauthorized Action (Direct Self-Revive)", "Blocked direct call to self-revive.");
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(StatusEntity), "Cmd_ReplenishAll")]
		[HarmonyPrefix]
		public static bool ValidateReplenish(StatusEntity __instance)
		{
			Player component = ((Component)__instance).GetComponent<Player>();
			if (!NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableReviveChecks.Value || Main.IsPlayerExempt(component))
			{
				return true;
			}
			if (__instance.Network_currentHealth <= 0)
			{
				uint netId = ((NetworkBehaviour)component).netId;
				if (Main.AuthorizedSelfRevives.TryGetValue(netId, out var value) && Time.time - value < 1.5f)
				{
					Main.AuthorizedSelfRevives.Remove(netId);
					return true;
				}
				Main.LogInfraction((NetworkBehaviour)(object)__instance, "Unauthorized Action (Replenish while Dead)", "Blocked replenish call - was not authorized by UI button press.");
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(NetworkTransformBase), "CmdTeleport", new Type[]
	{
		typeof(Vector3),
		typeof(Quaternion)
	})]
	public static class CmdTeleportValidationPatch2
	{
		public static bool Prefix(NetworkBehaviour __instance)
		{
			if (!NetworkServer.active || !Main.EnableAntiCheat.Value || !Main.EnableMovementChecks.Value || Main.IsPlayerExempt(((Component)__instance).GetComponent<Player>()))
			{
				return true;
			}
			Main.LogInfraction(__instance, "Movement Hack (Illegal Teleport Command)", "Player directly called a Teleport command.");
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkTransformBase), "CmdTeleport", new Type[] { typeof(