Decompiled source of FusionGuard v8.4.9

Mods/FusionGuard.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using FusionGuard;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.VFX;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VRMK;
using Il2CppSystem.Collections.Generic;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Marrow.Extenders;
using LabFusion.Marrow.Messages;
using LabFusion.Marrow.Serialization;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.Preferences;
using LabFusion.Preferences.Server;
using LabFusion.Representation;
using LabFusion.SDK.Gamemodes;
using LabFusion.SDK.Metadata;
using LabFusion.Senders;
using LabFusion.Utilities;
using LabFusion.Voice;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "FusionGuard", "8.4.9", "DragonBird", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "LabFusion" })]
[assembly: AssemblyMetadata("AIGenerated", "Code written with the help of Claude (Anthropic)")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 FusionGuard
{
	internal class PendingSpawn
	{
		public object Handler;

		public MethodInfo Method;

		public ReceivedMessage Message;

		public byte Owner;

		public int EntityID = -1;

		public bool Particle;
	}
	internal class FxEntry
	{
		public Poolee Poolee;

		public GameObject Go;

		public byte Owner;

		public float Time;
	}
	internal static class FusionCompat
	{
		private const BindingFlags PubStatic = BindingFlags.Static | BindingFlags.Public;

		private const BindingFlags PubInst = BindingFlags.Instance | BindingFlags.Public;

		private static PropertyInfo _playerIdPlat;

		private static PropertyInfo _playerInfoPlat;

		private static MethodInfo _fetchPerm;

		private static MethodInfo _setPerm;

		private static MethodInfo _pardon;

		private static bool _init;

		private static MethodInfo _deny;

		private static MethodInfo _disconnectUser;

		internal static bool StringIds { get; private set; }

		internal static string Mode => StringIds ? "Fusion EOS (Epic/Quest)" : "Official Fusion (SteamVR)";

		internal static bool PermsOk
		{
			get
			{
				Init();
				return _fetchPerm != null;
			}
		}

		internal static void Init()
		{
			if (!_init)
			{
				_init = true;
				_playerIdPlat = typeof(PlayerID).GetProperty("PlatformID", BindingFlags.Instance | BindingFlags.Public);
				_playerInfoPlat = typeof(PlayerInfo).GetProperty("PlatformID", BindingFlags.Instance | BindingFlags.Public);
				StringIds = _playerIdPlat != null && _playerIdPlat.PropertyType == typeof(string);
				Type typeFromHandle = typeof(FusionPermissions);
				_fetchPerm = typeFromHandle.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "FetchPermissionLevel" && m.GetParameters().Length == 3);
				_setPerm = typeFromHandle.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "TrySetPermission" && m.GetParameters().Length == 3);
				_pardon = typeof(NetworkHelper).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "PardonUser" && m.GetParameters().Length == 1);
			}
		}

		internal static string Plat(PlayerID player)
		{
			if (player == null)
			{
				return string.Empty;
			}
			Init();
			return Normalize(_playerIdPlat?.GetValue(player));
		}

		internal static string BanPlat(PlayerInfo info)
		{
			if (info == null)
			{
				return string.Empty;
			}
			Init();
			return Normalize(_playerInfoPlat?.GetValue(info));
		}

		internal static bool Has(string plat)
		{
			return !string.IsNullOrEmpty(plat);
		}

		private static string Normalize(object value)
		{
			if (value == null)
			{
				return string.Empty;
			}
			if (value is ulong num)
			{
				return (num == 0L) ? string.Empty : num.ToString();
			}
			return value.ToString() ?? string.Empty;
		}

		private static bool TryArg(string plat, Type target, out object arg)
		{
			arg = null;
			if (!Has(plat))
			{
				return false;
			}
			if (target == typeof(string))
			{
				arg = plat;
				return true;
			}
			if (target == typeof(ulong) && ulong.TryParse(plat, out var result))
			{
				arg = result;
				return true;
			}
			return false;
		}

		internal static PermissionLevel FetchPermission(string plat)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Init();
			if (_fetchPerm == null || !TryArg(plat, _fetchPerm.GetParameters()[0].ParameterType, out var arg))
			{
				return (PermissionLevel)0;
			}
			object[] array = new object[3] { arg, null, null };
			_fetchPerm.Invoke(null, array);
			return (PermissionLevel)((array[1] is PermissionLevel val) ? ((int)val) : 0);
		}

		internal static void SetPermission(string plat, string username, PermissionLevel level)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Init();
			if (!(_setPerm == null) && TryArg(plat, _setPerm.GetParameters()[0].ParameterType, out var arg))
			{
				_setPerm.Invoke(null, new object[3] { arg, username, level });
			}
		}

		internal static void Deny(string plat, string reason)
		{
			try
			{
				if (_deny == null)
				{
					_deny = typeof(ConnectionSender).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "SendConnectionDeny" && m.GetParameters().Length == 2);
				}
				if (!(_deny == null) && TryArg(plat, _deny.GetParameters()[0].ParameterType, out var arg))
				{
					_deny.Invoke(null, new object[2] { arg, reason });
				}
			}
			catch
			{
			}
		}

		internal static void Pardon(string plat)
		{
			Init();
			if (!(_pardon == null) && TryArg(plat, _pardon.GetParameters()[0].ParameterType, out var arg))
			{
				_pardon.Invoke(null, new object[1] { arg });
			}
		}

		internal static void CloseConnection(string plat)
		{
			try
			{
				if (_disconnectUser == null)
				{
					_disconnectUser = typeof(NetworkConnectionManager).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "DisconnectUser" && m.GetParameters().Length == 1);
				}
				if (!(_disconnectUser == null) && TryArg(plat, _disconnectUser.GetParameters()[0].ParameterType, out var arg))
				{
					_disconnectUser.Invoke(null, new object[1] { arg });
				}
			}
			catch
			{
			}
		}
	}
	internal static class PlatformDetect
	{
		private const BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static bool _init;

		private static bool _ok;

		private static PropertyInfo _connectProp;

		private static FieldInfo _runtimeField;

		private static FieldInfo _connIface;

		private static FieldInfo _localUser;

		private static MethodInfo _fromString;

		private static MethodInfo _copyInfo;

		private static MethodInfo _query;

		private static ConstructorInfo _utfCtor;

		private static Type _copyOptT;

		private static Type _queryOptT;

		private static Type _puidT;

		private static Delegate _callback;

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

		private static readonly Dictionary<string, float> asked = new Dictionary<string, float>();

		private static void Init()
		{
			if (_init)
			{
				return;
			}
			_init = true;
			try
			{
				Assembly assembly = typeof(PlayerID).Assembly;
				Type type = assembly.GetType("LabFusion.Network.EOSRuntime");
				Type type2 = assembly.GetType("LabFusion.Network.EpicGamesNetworkLayer");
				if (type2 != null)
				{
					_runtimeField = type2.GetField("Runtime", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				Type type3 = assembly.GetType("LabFusion.Network.EOSConnect");
				_puidT = assembly.GetType("Epic.OnlineServices.ProductUserId");
				Type type4 = assembly.GetType("Epic.OnlineServices.Utf8String");
				Type type5 = assembly.GetType("Epic.OnlineServices.Connect.ConnectInterface");
				_copyOptT = assembly.GetType("Epic.OnlineServices.Connect.CopyProductUserInfoOptions");
				_queryOptT = assembly.GetType("Epic.OnlineServices.Connect.QueryProductUserIdMappingsOptions");
				Type type6 = assembly.GetType("Epic.OnlineServices.Connect.OnQueryProductUserIdMappingsCallback");
				if (!(type == null) && !(type3 == null) && !(_puidT == null) && !(type4 == null) && !(type5 == null) && !(_copyOptT == null) && !(_queryOptT == null) && !(type6 == null))
				{
					_connectProp = type.GetProperty("Connect", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					_connIface = type3.GetField("ConnectInterface", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					_localUser = type3.GetField("LocalUserId", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					_fromString = _puidT.GetMethod("FromString", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { type4 }, null);
					_utfCtor = type4.GetConstructor(new Type[1] { typeof(string) });
					_copyInfo = type5.GetMethod("CopyProductUserInfo", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					_query = type5.GetMethod("QueryProductUserIdMappings", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					Type parameterType = type6.GetMethod("Invoke").GetParameters()[0].ParameterType;
					ParameterExpression parameterExpression = Expression.Parameter(parameterType, "data");
					_callback = Expression.Lambda(type6, Expression.Empty(), parameterExpression).Compile();
					_ok = _connectProp != null && _runtimeField != null && _connIface != null && _localUser != null && _fromString != null && _utfCtor != null && _copyInfo != null && _query != null;
				}
			}
			catch (Exception ex)
			{
				_ok = false;
				MelonLogger.Warning("[Platform] init : " + ex.Message);
			}
		}

		internal static void Clear()
		{
			asked.Clear();
		}

		internal static string Get(string plat)
		{
			if (!FusionCompat.Has(plat))
			{
				return "?";
			}
			if (!FusionCompat.StringIds)
			{
				return "PC";
			}
			if (cache.TryGetValue(plat, out var value))
			{
				return value;
			}
			Init();
			if (!_ok)
			{
				return "?";
			}
			try
			{
				object layer = NetworkLayerManager.Layer;
				if (layer == null || !_runtimeField.DeclaringType.IsInstanceOfType(layer))
				{
					return "?";
				}
				object value2 = _runtimeField.GetValue(layer);
				object obj = ((value2 != null) ? _connectProp.GetValue(value2) : null);
				if (obj == null)
				{
					return "?";
				}
				object value3 = _connIface.GetValue(obj);
				object value4 = _localUser.GetValue(obj);
				object obj2 = _fromString.Invoke(null, new object[1] { _utfCtor.Invoke(new object[1] { plat }) });
				if (value3 == null || obj2 == null)
				{
					return "?";
				}
				object obj3 = Activator.CreateInstance(_copyOptT);
				_copyOptT.GetProperty("TargetUserId").SetValue(obj3, obj2);
				object[] array = new object[2] { obj3, null };
				object obj4 = _copyInfo.Invoke(value3, array);
				if (obj4 != null && obj4.ToString() == "Success" && array[1] != null)
				{
					object obj5 = array[1];
					string text = obj5.GetType().GetProperty("AccountIdType")?.GetValue(obj5)?.ToString() ?? "";
					string text2 = text switch
					{
						"Epic" => "PC (Epic)", 
						"Oculus" => "QUEST", 
						"Steam" => "PC", 
						_ => text.ToUpperInvariant(), 
					};
					if (!string.IsNullOrEmpty(text2))
					{
						cache[plat] = text2;
						return text2;
					}
				}
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (value4 != null && (!asked.TryGetValue(plat, out var value5) || realtimeSinceStartup - value5 > 20f))
				{
					asked[plat] = realtimeSinceStartup;
					object obj6 = Activator.CreateInstance(_queryOptT);
					_queryOptT.GetProperty("LocalUserId").SetValue(obj6, value4);
					Array array2 = Array.CreateInstance(_puidT, 1);
					array2.SetValue(obj2, 0);
					_queryOptT.GetProperty("ProductUserIds").SetValue(obj6, array2);
					_query.Invoke(value3, new object[3] { obj6, null, _callback });
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[Platform] " + (ex.InnerException?.Message ?? ex.Message));
			}
			return "?";
		}
	}
	internal class SecAlert
	{
		public string Kind;

		public byte Small;

		public string PlatformID;

		public string Name;

		public string Reason;

		public int Count;

		public float Last;

		public byte? Target;

		public string TargetName;

		public bool Ban;

		public bool Kicked;

		public float KickedAt;

		public bool Allowed;
	}
	internal class PlayerHold
	{
		public byte SmallID;

		public string PlatformID;

		public string Name;

		public int Total;

		public int Particles;

		public int Dropped;

		public bool ByParticles;

		public bool Quarantine;

		public int ScoreAtStart;

		public readonly Dictionary<string, int> Counts = new Dictionary<string, int>();

		public readonly Dictionary<string, string> Titles = new Dictionary<string, string>();

		public readonly List<PendingSpawn> Queue = new List<PendingSpawn>();

		public readonly List<PendingSpawn> FxQueue = new List<PendingSpawn>();
	}
	public class Core : MelonMod
	{
		private delegate void PlatSetter(ref ReadableMessage message, string plat);

		private class GuardBan
		{
			public string Plat;

			public string Name;

			public string Reason;

			public string Date;
		}

		private class GodTrack
		{
			public float Start = -1f;

			public int Hits;

			public float MinRatio = 1f;

			public float LastH;

			public float LastM;

			public float LastDrop = -1f;

			public readonly List<float> RegenHits = new List<float>();

			public int BadHealth;

			public int AvatarId;
		}

		private class MsgCounter
		{
			public float Since;

			public int Count;

			public int Over;

			public long Bytes;

			public int OverBytes;
		}

		private sealed class LobbyPlayerRow
		{
			public string Name;

			public string User;

			public string Id;

			public string Fg;

			public string Watch;

			public bool HasFg;
		}

		private sealed class LobbyRow
		{
			public string Key;

			public string Name;

			public string Host;

			public string Code;

			public string Level;

			public string Mode;

			public string Privacy;

			public string FgHostVer;

			public string FgHostPlat;

			public int Count;

			public int Max;

			public int FgCount;

			public bool FgHost;

			public bool Open;

			public List<LobbyPlayerRow> Players = new List<LobbyPlayerRow>();

			public Action Join;
		}

		private struct RecentSpawn
		{
			public ushort Id;

			public byte Owner;

			public float Time;
		}

		private class NetStat
		{
			public int Msgs;

			public int Spawns;

			public int Despawns;

			public int Owners;

			public int Damage;

			public int Kicks;

			public long Bytes;

			public readonly Dictionary<string, int> Types = new Dictionary<string, int>();
		}

		private class GunTrack
		{
			public int LastAmmo = -1;

			public float LastShot;

			public int NoDrop;

			public readonly Queue<float> Times = new Queue<float>();

			public Gun Gun;

			public float GunAt;

			public readonly List<KeyValuePair<float, Vector3>> Aim = new List<KeyValuePair<float, Vector3>>();
		}

		private class LastShotInfo
		{
			public float Time;

			public ushort GunId;

			public Gun Gun;
		}

		private class RecentShot
		{
			public float Time;

			public Vector3 Muzzle;

			public Vector3 Forward;

			public float Spread;

			public float TurnSpeed;
		}

		private class GrabOnMe
		{
			public byte Sender;

			public Handedness Hand;

			public float Since;

			public float BadSince = -1f;
		}

		private class DmgSample
		{
			public byte Shooter;

			public float K;

			public string Gun;
		}

		private class FreezeState
		{
			public Vector3 Pos;

			public float LastTp;

			public string Name;
		}

		private class AimEval
		{
			public float Time;

			public bool Sus;

			public float Angle;
		}

		private class AimShot
		{
			public float Time;

			public byte Target = byte.MaxValue;

			public float Dist;

			public bool Snap;

			public float Peak;

			public bool Hit;

			public bool Head;

			public bool Moving;
		}

		private class BlockedWord
		{
			public string Word;

			public bool On = true;

			public bool Everywhere;
		}

		private class ApprovalHold
		{
			public byte SmallID;

			public string PlatformID;

			public string Name;

			public float Since;

			public readonly List<PendingSpawn> Queue = new List<PendingSpawn>();

			public readonly Dictionary<string, int> Counts = new Dictionary<string, int>();
		}

		private enum ItemKind
		{
			Toggle,
			Slider,
			Cycle,
			Page,
			Action,
			Info,
			Header
		}

		private class MenuItem
		{
			public string Label;

			public ItemKind Kind;

			public Func<bool> GetBool;

			public Action<bool> SetBool;

			public Func<float> GetFloat;

			public Action<float> SetFloat;

			public float Min;

			public float Max;

			public float Step;

			public string Suffix = "";

			public Func<string> GetText;

			public Action Click;

			public MenuPage Target;

			public bool HasTint;

			public Color Tint;

			public string Key;

			public string ConfirmKey;
		}

		private class MenuPage
		{
			public string Title;

			public MenuPage Parent;

			public int Scroll;

			public bool NoSave;

			public object Tag;

			public Func<int> Badge;

			public string Desc;

			public List<MenuItem> Items = new List<MenuItem>();
		}

		private class UiButton
		{
			public Renderer Rend;

			public Vector2 Center;

			public Vector2 Half;

			public Color Base;

			public Action Press;

			public string Key;
		}

		private class TpBack
		{
			public Vector3 Pos;

			public Vector3 SentTo;

			public string Plat;
		}

		private static class PcOverlay
		{
			private static bool cursorSaved;

			private static bool oldVisible;

			private static CursorLockMode oldLock;

			private static float styleScale = -1f;

			private static GUIStyle sLabel;

			private static GUIStyle sLabelR;

			private static GUIStyle sLabelC;

			private static GUIStyle sTitle;

			private static GUIStyle sTitle2;

			private static GUIStyle sSmall;

			private static GUIStyle sSmallL;

			private static GUIStyle sWrap;

			private static readonly Dictionary<MenuPage, float> scroll = new Dictionary<MenuPage, float>();

			private static float lastToggle = -10f;

			private static bool loggedInputSystem;

			internal static void ShowCursor()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				if (!cursorSaved)
				{
					oldVisible = Cursor.visible;
					oldLock = Cursor.lockState;
					cursorSaved = true;
				}
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}

			internal static void RestoreCursor()
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (cursorSaved)
				{
					cursorSaved = false;
					Cursor.visible = oldVisible;
					Cursor.lockState = oldLock;
				}
			}

			private static bool KeyDown(Core c)
			{
				Keyboard current = Keyboard.current;
				if (current == null)
				{
					return false;
				}
				KeyControl val = null;
				switch (c.overlayKey)
				{
				case 0:
					val = current.f6Key;
					break;
				case 1:
					val = current.f7Key;
					break;
				case 2:
					val = current.f8Key;
					break;
				case 3:
					val = current.f9Key;
					break;
				case 4:
					val = current.f10Key;
					break;
				case 5:
					val = current.f11Key;
					break;
				case 6:
					val = current.insertKey;
					break;
				}
				return val != null && ((ButtonControl)val).wasPressedThisFrame;
			}

			internal static void Poll(Core c)
			{
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Invalid comparison between Unknown and I4
				bool flag = false;
				try
				{
					flag = KeyDown(c);
				}
				catch (Exception ex)
				{
					if (!loggedInputSystem)
					{
						loggedInputSystem = true;
						((MelonBase)c).LoggerInstance.Warning("[Overlay] Unity Input System keyboard unavailable: " + ex.Message);
					}
				}
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (flag && realtimeSinceStartup - lastToggle > 0.3f)
				{
					lastToggle = realtimeSinceStartup;
					c.SetOverlayOpen(!c.overlayOpen);
				}
				if (!c.overlayOpen)
				{
					return;
				}
				bool flag2 = false;
				try
				{
					Keyboard current = Keyboard.current;
					if (current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame)
					{
						flag2 = true;
					}
				}
				catch
				{
				}
				if (flag2 && realtimeSinceStartup - lastToggle > 0.3f)
				{
					lastToggle = realtimeSinceStartup;
					c.SetOverlayOpen(open: false);
					return;
				}
				try
				{
					if (!Cursor.visible || (int)Cursor.lockState > 0)
					{
						ShowCursor();
					}
				}
				catch
				{
				}
			}

			private static GUIStyle Make(GUIStyle from, int size, TextAnchor anchor, bool bold, bool wrap)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				GUIStyle val = new GUIStyle(from);
				val.fontSize = size;
				val.alignment = anchor;
				val.fontStyle = (FontStyle)(bold ? 1 : 0);
				val.wordWrap = wrap;
				val.richText = false;
				val.clipping = (TextClipping)1;
				val.normal.textColor = Color.white;
				val.normal.background = null;
				val.hover.background = null;
				val.active.background = null;
				return val;
			}

			private static void Styles(float k)
			{
				if (!(Mathf.Abs(k - styleScale) < 0.001f) || sLabel == null)
				{
					styleScale = k;
					GUIStyle label = GUI.skin.label;
					sLabel = Make(label, Mathf.RoundToInt(15f * k), (TextAnchor)3, bold: false, wrap: false);
					sLabelR = Make(label, Mathf.RoundToInt(15f * k), (TextAnchor)5, bold: true, wrap: false);
					sLabelC = Make(label, Mathf.RoundToInt(15f * k), (TextAnchor)4, bold: true, wrap: false);
					sTitle = Make(label, Mathf.RoundToInt(19f * k), (TextAnchor)3, bold: true, wrap: false);
					sSmall = Make(label, Mathf.RoundToInt(12f * k), (TextAnchor)4, bold: false, wrap: false);
					sSmallL = Make(label, Mathf.RoundToInt(12f * k), (TextAnchor)3, bold: false, wrap: false);
					sTitle2 = Make(label, Mathf.RoundToInt(24f * k), (TextAnchor)4, bold: true, wrap: false);
					sWrap = Make(label, Mathf.RoundToInt(13f * k), (TextAnchor)4, bold: false, wrap: true);
				}
			}

			private static void Fill(Rect r, Color col)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				Color color = GUI.color;
				GUI.color = col;
				GUI.DrawTexture(r, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color;
			}

			private static void Text(Rect r, string s, GUIStyle st, Color col)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				Color contentColor = GUI.contentColor;
				GUI.contentColor = col;
				GUI.Label(r, s ?? "", st);
				GUI.contentColor = contentColor;
			}

			private static void Btn(Core c, Rect r, Color bg, Action click)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				bool flag = ((Rect)(ref r)).Contains(Event.current.mousePosition);
				Fill(r, flag ? Color.Lerp(bg, c.Accent(), 0.3f) : bg);
				if (GUI.Button(r, "", sSmall) && click != null)
				{
					c.overlayActions.Add(click);
				}
			}

			internal static void Draw(Core c)
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0169: Unknown result type (might be due to invalid IL or missing references)
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				//IL_0220: Unknown result type (might be due to invalid IL or missing references)
				//IL_025d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0262: Unknown result type (might be due to invalid IL or missing references)
				//IL_029e: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0409: Unknown result type (might be due to invalid IL or missing references)
				//IL_040e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0468: Unknown result type (might be due to invalid IL or missing references)
				//IL_0702: Unknown result type (might be due to invalid IL or missing references)
				//IL_0707: Unknown result type (might be due to invalid IL or missing references)
				//IL_0475: Unknown result type (might be due to invalid IL or missing references)
				//IL_047a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0481: Unknown result type (might be due to invalid IL or missing references)
				//IL_046e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0776: Unknown result type (might be due to invalid IL or missing references)
				//IL_0514: Unknown result type (might be due to invalid IL or missing references)
				//IL_0519: Unknown result type (might be due to invalid IL or missing references)
				//IL_054d: Unknown result type (might be due to invalid IL or missing references)
				//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_077b: Unknown result type (might be due to invalid IL or missing references)
				//IL_076f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0768: Unknown result type (might be due to invalid IL or missing references)
				//IL_1060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0fef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ff4: Unknown result type (might be due to invalid IL or missing references)
				//IL_1026: Unknown result type (might be due to invalid IL or missing references)
				//IL_1035: Unknown result type (might be due to invalid IL or missing references)
				//IL_058f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0588: Unknown result type (might be due to invalid IL or missing references)
				//IL_1091: Unknown result type (might be due to invalid IL or missing references)
				//IL_10b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_10c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_10e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_10ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_110f: Unknown result type (might be due to invalid IL or missing references)
				//IL_1114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0807: Unknown result type (might be due to invalid IL or missing references)
				//IL_0809: Unknown result type (might be due to invalid IL or missing references)
				//IL_0840: Unknown result type (might be due to invalid IL or missing references)
				//IL_0845: Unknown result type (might be due to invalid IL or missing references)
				//IL_0879: Unknown result type (might be due to invalid IL or missing references)
				//IL_087e: Unknown result type (might be due to invalid IL or missing references)
				//IL_08b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_08e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_091d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0929: Unknown result type (might be due to invalid IL or missing references)
				//IL_0963: Unknown result type (might be due to invalid IL or missing references)
				//IL_096f: Unknown result type (might be due to invalid IL or missing references)
				//IL_064d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0663: Unknown result type (might be due to invalid IL or missing references)
				//IL_066e: Unknown result type (might be due to invalid IL or missing references)
				//IL_118f: Unknown result type (might be due to invalid IL or missing references)
				//IL_1195: Invalid comparison between Unknown and I4
				//IL_0a60: Unknown result type (might be due to invalid IL or missing references)
				//IL_09bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_09bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_09fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a21: Unknown result type (might be due to invalid IL or missing references)
				//IL_119a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a6d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a66: Unknown result type (might be due to invalid IL or missing references)
				//IL_0689: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ab0: Unknown result type (might be due to invalid IL or missing references)
				//IL_11b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ae8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b1f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b2f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b60: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b62: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ba0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0bcd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0c04: Unknown result type (might be due to invalid IL or missing references)
				//IL_0c14: Unknown result type (might be due to invalid IL or missing references)
				//IL_12ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_12ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0d7d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0d7f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0dbb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e74: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e83: Unknown result type (might be due to invalid IL or missing references)
				//IL_1261: Unknown result type (might be due to invalid IL or missing references)
				//IL_1266: Unknown result type (might be due to invalid IL or missing references)
				//IL_1333: Unknown result type (might be due to invalid IL or missing references)
				//IL_1349: Unknown result type (might be due to invalid IL or missing references)
				//IL_0df5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ddb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ed7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0ee6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e24: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e33: Unknown result type (might be due to invalid IL or missing references)
				//IL_0f32: Unknown result type (might be due to invalid IL or missing references)
				//IL_0f3e: Unknown result type (might be due to invalid IL or missing references)
				Event current = Event.current;
				float num = Mathf.Clamp(c.overlayScale, 0.6f, 2f) * Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2f);
				Styles(num);
				Color val = c.Accent();
				float num2 = 640f * num;
				float num3 = 12f * num;
				num2 = Mathf.Min(num2, (float)Screen.width - 36f * num);
				float num4 = (float)Screen.width - num2 - 18f * num;
				float num5 = 18f * num;
				float num6 = Mathf.Min((float)Screen.height - 36f * num, 600f * num);
				Rect r = default(Rect);
				((Rect)(ref r))..ctor(num4, num5, num2, num6);
				Fill(new Rect(num4 - 2f * num, num5 - 2f * num, num2 + 4f * num, num6 + 4f * num), val);
				Fill(r, CBg);
				MenuPage menuPage = c.currentPage ?? c.homePage;
				float num7 = 46f * num;
				Fill(new Rect(num4, num5, num2, num7), CTop);
				Fill(new Rect(num4 + num3, num5 + 10f * num, 26f * num, 26f * num), val);
				Text(new Rect(num4 + num3, num5 + 10f * num, 26f * num, 26f * num), "FG", sLabelC, CBg);
				Text(new Rect(num4 + num3 + 34f * num, num5, num2 * 0.5f, num7), "FUSION GUARD", sTitle, CText);
				Text(new Rect(num4 + num2 * 0.45f, num5, num2 * 0.55f - 48f * num, num7), c.OverlayStatus(), sLabelR, c.protection ? CSub : CAlert);
				Btn(c, new Rect(num4 + num2 - 38f * num, num5 + 8f * num, 30f * num, 30f * num), CDanger, delegate
				{
					c.SetOverlayOpen(open: false);
				});
				Text(new Rect(num4 + num2 - 38f * num, num5 + 8f * num, 30f * num, 30f * num), "X", sLabelC, CText);
				float num8 = 150f * num;
				float num9 = num5 + num7 + 8f * num;
				float num10 = num6 - num7 - 16f * num;
				Fill(new Rect(num4 + num3 * 0.5f, num9, num8, num10), CSide);
				List<MenuPage> list = new List<MenuPage> { c.homePage };
				foreach (MenuItem item in c.homePage.Items)
				{
					if (item.Kind == ItemKind.Page && item.Target != null)
					{
						list.Add(item.Target);
					}
				}
				float num11 = Mathf.Min(44f * num, (num10 - 8f * num) / (float)list.Count);
				MenuPage menuPage2 = ((menuPage == c.homePage) ? c.homePage : c.RootOf(menuPage));
				Rect r2 = default(Rect);
				Rect r3 = default(Rect);
				for (int num12 = 0; num12 < list.Count; num12++)
				{
					MenuPage cat = list[num12];
					Color val2 = c.CatColor(cat);
					((Rect)(ref r2))..ctor(num4 + num3 * 0.5f + 5f * num, num9 + 4f * num + (float)num12 * num11, num8 - 10f * num, num11 - 6f * num);
					bool flag = cat == menuPage2;
					Btn(c, r2, flag ? Color.Lerp(CSide, val2, 0.32f) : CSide, delegate
					{
						c.currentPage = cat;
					});
					if (flag)
					{
						Fill(new Rect(((Rect)(ref r2)).x, ((Rect)(ref r2)).y + 6f * num, 3f * num, ((Rect)(ref r2)).height - 12f * num), val2);
					}
					Fill(new Rect(((Rect)(ref r2)).x + 10f * num, ((Rect)(ref r2)).y + ((Rect)(ref r2)).height / 2f - 4f * num, 8f * num, 8f * num), val2);
					Text(new Rect(((Rect)(ref r2)).x + 24f * num, ((Rect)(ref r2)).y, ((Rect)(ref r2)).width - 50f * num, ((Rect)(ref r2)).height), (cat == c.homePage) ? "Home" : cat.Title, sLabel, flag ? CText : CTextDim);
					int num13 = ((cat == c.pendingPage) ? (c.holds.Count + c.alerts.Count + c.approvals.Count) : 0);
					if (num13 > 0)
					{
						((Rect)(ref r3))..ctor(((Rect)(ref r2)).xMax - 30f * num, ((Rect)(ref r2)).y + ((Rect)(ref r2)).height / 2f - 9f * num, 24f * num, 18f * num);
						Fill(r3, new Color(0.85f, 0.22f, 0.2f, 1f));
						Text(r3, (num13 > 99) ? "99" : num13.ToString(), sSmall, Color.white);
					}
				}
				float num14 = num4 + num3 * 0.5f + num8 + 10f * num;
				float num15 = num4 + num2 - num3 - num14;
				float num16 = num9;
				float num17 = num5 + num6 - 26f * num;
				float rowH = 34f * num;
				float num18 = 6f * num;
				Color col = c.CatColor(menuPage2);
				if (menuPage == c.homePage)
				{
					int num19 = c.alerts.Count + c.approvals.Count + c.holds.Count;
					Color col2 = ((!c.protection) ? CAlert : ((num19 > 0) ? CWarn : COn));
					string s = ((!c.protection) ? "Protection OFF" : ((num19 > 0) ? "Needs your attention" : "Protected"));
					string s2 = ((!c.protection) ? "FusionGuard is not checking anything" : ((num19 > 0) ? (num19 + " thing(s) waiting in Alerts") : ((!NetworkInfo.HasServer) ? "Not in a server" : (NetworkInfo.IsHost ? "Host: the whole server is protected" : "Client: you are protected"))));
					Rect r4 = default(Rect);
					((Rect)(ref r4))..ctor(num14, num16, num15, 78f * num);
					Fill(r4, CCard);
					Fill(new Rect(((Rect)(ref r4)).x + 12f * num, ((Rect)(ref r4)).y + 14f * num, 50f * num, 50f * num), col2);
					Fill(new Rect(((Rect)(ref r4)).x + 17f * num, ((Rect)(ref r4)).y + 19f * num, 40f * num, 40f * num), CCard);
					Text(new Rect(((Rect)(ref r4)).x + 12f * num, ((Rect)(ref r4)).y + 14f * num, 50f * num, 50f * num), (!c.protection) ? "OFF" : ((num19 > 0) ? num19.ToString() : "ON"), sLabelC, col2);
					Text(new Rect(((Rect)(ref r4)).x + 76f * num, ((Rect)(ref r4)).y + 12f * num, num15 - 86f * num, 28f * num), s, sTitle, CText);
					Text(new Rect(((Rect)(ref r4)).x + 76f * num, ((Rect)(ref r4)).y + 40f * num, num15 - 86f * num, 24f * num), s2, sLabel, CSub);
					num16 += 78f * num + 8f * num;
					if (c.updAvailable)
					{
						Rect r5 = default(Rect);
						((Rect)(ref r5))..ctor(num14, num16, num15, 28f * num);
						Btn(c, r5, CCard, delegate
						{
							if (c.updPage != null)
							{
								c.currentPage = c.updPage;
							}
						});
						Text(new Rect(((Rect)(ref r5)).x + 12f * num, ((Rect)(ref r5)).y, num15 - 24f * num, ((Rect)(ref r5)).height), "Update available: v" + c.updLatest + "  |  update it with r2modman", sLabel, CWarn);
						num16 += 34f * num;
					}
					bool flag2 = c.ProtectionArmed();
					Rect r6 = default(Rect);
					((Rect)(ref r6))..ctor(num14, num16, num15, 40f * num);
					Btn(c, r6, flag2 ? CArmed : CCard, c.PressProtection);
					Text(new Rect(((Rect)(ref r6)).x + 12f * num, ((Rect)(ref r6)).y, num15 - 80f * num, ((Rect)(ref r6)).height), flag2 ? "Protection: click again = OFF" : ("Protection" + (c.protection ? "  (click twice to turn off)" : "")), sLabel, CText);
					Pill(new Rect(((Rect)(ref r6)).xMax - 62f * num, ((Rect)(ref r6)).y + 10f * num, 50f * num, 20f * num), c.protection, COn);
					num16 += 46f * num;
					Rect r7 = default(Rect);
					((Rect)(ref r7))..ctor(num14, num16, num15, 40f * num);
					Btn(c, r7, CCard, delegate
					{
						c.SetAntiSpawn(!c.antiSpawn);
					});
					Text(new Rect(((Rect)(ref r7)).x + 12f * num, ((Rect)(ref r7)).y, num15 - 80f * num, ((Rect)(ref r7)).height), "Anti-Spawn" + (c.antiSpawn ? "  (nobody else can spawn)" : ""), sLabel, CText);
					Pill(new Rect(((Rect)(ref r7)).xMax - 62f * num, ((Rect)(ref r7)).y + 10f * num, 50f * num, 20f * num), c.antiSpawn, KSpawns);
					num16 += 50f * num;
					int num20 = c.combatBlocked + c.kicksBlocked + c.netBlocked + c.floodDropped + c.badPoses + c.spoofBlocked + c.godAlerts + c.aimAlerts + c.aimLockAlerts + c.multAlerts;
					int[] array = new int[3]
					{
						num19,
						Mathf.Max(0, PlayerIDManager.PlayerCount - 1),
						num20
					};
					string[] array2 = new string[3] { "ALERTS", "PLAYERS", "BLOCKED" };
					MenuPage[] array3 = new MenuPage[3] { c.pendingPage, c.playersPage, c.securityPage };
					float num21 = (num15 - 12f * num) / 3f;
					Rect r8 = default(Rect);
					for (int num22 = 0; num22 < 3; num22++)
					{
						MenuPage t = array3[num22];
						((Rect)(ref r8))..ctor(num14 + (float)num22 * (num21 + 6f * num), num16, num21, 58f * num);
						Btn(c, r8, CCard, delegate
						{
							c.currentPage = t;
						});
						Text(new Rect(((Rect)(ref r8)).x, ((Rect)(ref r8)).y + 4f * num, ((Rect)(ref r8)).width, 32f * num), array[num22].ToString(), sTitle2, (array[num22] > 0) ? c.CatColor(t) : CSub);
						Text(new Rect(((Rect)(ref r8)).x, ((Rect)(ref r8)).y + 36f * num, ((Rect)(ref r8)).width, 18f * num), array2[num22], sSmall, CSub);
					}
					num16 += 66f * num;
					Text(new Rect(num14 + 2f * num, num16, num15, 18f * num), "RECENT", sSmallL, CSub);
					num16 += 20f * num;
					List<string> list2 = c.spawnLog.Take(4).ToList();
					if (list2.Count == 0)
					{
						Text(new Rect(num14 + 2f * num, num16, num15, 18f * num), "Nothing happened yet", sSmallL, CTextDim);
					}
					foreach (string item2 in list2)
					{
						if (num16 + 18f * num > num17)
						{
							break;
						}
						Text(new Rect(num14 + 2f * num, num16, num15, 18f * num), item2, sSmallL, CTextDim);
						num16 += 19f * num;
					}
				}
				else
				{
					bool flag3 = menuPage.Parent != null && menuPage.Parent != c.homePage;
					float num23 = num14;
					if (flag3)
					{
						MenuPage parent = menuPage.Parent;
						Btn(c, new Rect(num14, num16 + 4f * num, 34f * num, 34f * num), CChip, delegate
						{
							c.currentPage = parent;
						});
						Text(new Rect(num14, num16 + 4f * num, 34f * num, 34f * num), "<", sLabelC, CText);
						num23 = num14 + 44f * num;
					}
					Text(new Rect(num23, num16, num15 - (num23 - num14), 16f * num), flag3 ? PagePath(menuPage.Parent) : (menuPage.Desc ?? "").ToUpperInvariant(), sSmallL, col);
					Text(new Rect(num23, num16 + 14f * num, num15 - (num23 - num14), 28f * num), menuPage.Title, sTitle, CText);
					Fill(new Rect(num14, num16 + 46f * num, num15, 1f * num), CChip);
					Fill(new Rect(num14, num16 + 45f * num, 40f * num, 2f * num), col);
					float num24 = num16 + 54f * num;
					List<MenuItem> items = menuPage.Items;
					float num25 = 0f;
					foreach (MenuItem item3 in items)
					{
						num25 += RowHeight(item3, rowH) + num18;
					}
					float num26 = num17 - num24;
					scroll.TryGetValue(menuPage, out var value);
					if ((int)current.type == 6 && ((Rect)(ref r)).Contains(current.mousePosition))
					{
						value += current.delta.y * 22f * num;
						current.Use();
					}
					value = Mathf.Clamp(value, 0f, Mathf.Max(0f, num25 - num26));
					scroll[menuPage] = value;
					float num27 = num24 - value;
					foreach (MenuItem item4 in items)
					{
						float num28 = RowHeight(item4, rowH);
						if (num27 >= num24 - 1f && num27 + num28 <= num17 + 1f)
						{
							DrawRow(c, item4, new Rect(num14, num27, num15 - 8f * num, num28), val);
						}
						num27 += num28 + num18;
					}
					if (num25 > num26)
					{
						float num29 = Mathf.Max(20f * num, num26 * num26 / num25);
						float num30 = num24 + (num26 - num29) * (value / Mathf.Max(1f, num25 - num26));
						Fill(new Rect(num14 + num15 - 4f * num, num30, 3f * num, num29), col);
					}
				}
				string text = OverlayKeyNames[Mathf.Clamp(c.overlayKey, 0, OverlayKeyNames.Length - 1)];
				Text(new Rect(num14, num5 + num6 - 24f * num, num15, 22f * num), text + " / Esc: close   |   mouse wheel: scroll   |   v8.4.9", sSmall, CSub);
			}

			private static void Pill(Rect r, bool on, Color onCol)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				Fill(r, on ? onCol : CTrack);
				float num = ((Rect)(ref r)).height - 4f;
				Fill(new Rect(on ? (((Rect)(ref r)).xMax - num - 2f) : (((Rect)(ref r)).x + 2f), ((Rect)(ref r)).y + 2f, num, num), Color.white);
			}

			private static float RowHeight(MenuItem it, float rowH)
			{
				if (it.Kind == ItemKind.Header)
				{
					return rowH * 0.75f;
				}
				if (it.Kind == ItemKind.Info)
				{
					return rowH * 1.25f;
				}
				return rowH;
			}

			private static void DrawRow(Core c, MenuItem it, Rect r, Color acc)
			{
				//IL_0446: Unknown result type (might be due to invalid IL or missing references)
				//IL_0551: Unknown result type (might be due to invalid IL or missing references)
				//IL_065f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0660: Unknown result type (might be due to invalid IL or missing references)
				//IL_0697: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_0198: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: 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_020b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0232: Unknown result type (might be due to invalid IL or missing references)
				//IL_0237: Unknown result type (might be due to invalid IL or missing references)
				//IL_0268: Unknown result type (might be due to invalid IL or missing references)
				//IL_0277: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02da: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_034b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0350: Unknown result type (might be due to invalid IL or missing references)
				//IL_0382: Unknown result type (might be due to invalid IL or missing references)
				//IL_0387: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0406: Unknown result type (might be due to invalid IL or missing references)
				//IL_046d: Unknown result type (might be due to invalid IL or missing references)
				//IL_045a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0586: Unknown result type (might be due to invalid IL or missing references)
				//IL_060d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0638: Unknown result type (might be due to invalid IL or missing references)
				//IL_0651: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: 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_04b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_059c: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_057f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0572: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0505: Unknown result type (might be due to invalid IL or missing references)
				//IL_053a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0537: Unknown result type (might be due to invalid IL or missing references)
				float num = styleScale;
				Rect r2 = default(Rect);
				((Rect)(ref r2))..ctor(((Rect)(ref r)).x + 10f * num, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 20f * num, ((Rect)(ref r)).height);
				switch (it.Kind)
				{
				case ItemKind.Toggle:
				{
					bool flag = false;
					try
					{
						flag = it.GetBool();
					}
					catch
					{
					}
					Btn(c, r, CRow, delegate
					{
						it.SetBool(!it.GetBool());
					});
					if (flag)
					{
						Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 4f * num, 4f * num, ((Rect)(ref r)).height - 8f * num), COn);
					}
					Text(r2, it.Label, sLabel, flag ? CText : CTextDim);
					Pill(new Rect(((Rect)(ref r)).xMax - 58f * num, ((Rect)(ref r)).y + 8f * num, 46f * num, ((Rect)(ref r)).height - 16f * num), flag, acc);
					break;
				}
				case ItemKind.Slider:
				{
					float num3 = 0f;
					try
					{
						num3 = it.GetFloat();
					}
					catch
					{
					}
					Fill(r, CRowSoft);
					float num4 = 40f * num;
					Btn(c, new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, num4, ((Rect)(ref r)).height), CRow, delegate
					{
						it.SetFloat(Mathf.Clamp(Snap(it.GetFloat() - it.Step, it.Step), it.Min, it.Max));
					});
					Text(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, num4, ((Rect)(ref r)).height), "-", sLabelC, acc);
					Btn(c, new Rect(((Rect)(ref r)).xMax - num4, ((Rect)(ref r)).y, num4, ((Rect)(ref r)).height), CRow, delegate
					{
						it.SetFloat(Mathf.Clamp(Snap(it.GetFloat() + it.Step, it.Step), it.Min, it.Max));
					});
					Text(new Rect(((Rect)(ref r)).xMax - num4, ((Rect)(ref r)).y, num4, ((Rect)(ref r)).height), "+", sLabelC, acc);
					Rect r3 = default(Rect);
					((Rect)(ref r3))..ctor(((Rect)(ref r)).x + num4 + 8f * num, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 2f * num4 - 16f * num, ((Rect)(ref r)).height);
					Text(r3, it.Label, sLabel, CTextDim);
					Text(r3, FormatValue(num3) + it.Suffix, sLabelR, CText);
					float num5 = Mathf.Clamp01(Mathf.InverseLerp(it.Min, it.Max, num3));
					Fill(new Rect(((Rect)(ref r3)).x, ((Rect)(ref r)).yMax - 4f * num, ((Rect)(ref r3)).width, 2f * num), COff);
					Fill(new Rect(((Rect)(ref r3)).x, ((Rect)(ref r)).yMax - 4f * num, ((Rect)(ref r3)).width * num5, 2f * num), acc);
					break;
				}
				case ItemKind.Cycle:
				{
					string text = "";
					try
					{
						text = it.GetText();
					}
					catch
					{
					}
					Btn(c, r, CRow, it.Click);
					Text(r2, it.Label, sLabel, CText);
					Text(r2, "< " + text + " >", sLabelR, acc);
					break;
				}
				case ItemKind.Page:
				{
					MenuPage target = it.Target;
					Btn(c, r, it.HasTint ? it.Tint : CRow, delegate
					{
						if (target != null)
						{
							c.currentPage = target;
						}
					});
					Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 4f * num, 4f * num, ((Rect)(ref r)).height - 8f * num), acc);
					int num2 = ((target != null) ? c.CountActive(target) : 0);
					Text(r2, it.Label, sLabel, CText);
					Text(r2, ((num2 > 0) ? (num2 + "   ") : "") + ">", sLabelR, (num2 > 0) ? CWarn : acc);
					break;
				}
				case ItemKind.Action:
					Btn(c, r, c.IsArmed(it) ? CArmed : (it.HasTint ? it.Tint : CDanger), it.Click);
					Text(r, ActionLabel(it), sLabelC, CText);
					break;
				case ItemKind.Header:
					Text(new Rect(((Rect)(ref r)).x + 2f * num, ((Rect)(ref r)).y, ((Rect)(ref r)).width, ((Rect)(ref r)).height - 4f * num), (it.Label ?? "").ToUpperInvariant(), sLabel, acc);
					Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 2f * num, ((Rect)(ref r)).width, 1f * num), new Color(1f, 1f, 1f, 0.15f));
					break;
				case ItemKind.Info:
					Fill(r, CRowSoft);
					Text(new Rect(((Rect)(ref r)).x + 6f * num, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 12f * num, ((Rect)(ref r)).height), ActionLabel(it), sWrap, CSub);
					break;
				}
			}
		}

		private class StateSlot
		{
			public MenuItem It;

			public MelonPreferences_Entry<bool> B;

			public MelonPreferences_Entry<float> F;

			public MelonPreferences_Entry<string> S;
		}

		internal static Core Instance;

		private static int _isQuest = -1;

		internal static bool Replaying;

		private static MethodInfo handleMethod;

		private static MethodInfo requestMethod;

		private bool protection = true;

		private bool antiSpawn = false;

		private bool allowPerms = true;

		private int preset = 1;

		private float threshold = 15f;

		private float window = 3f;

		private float loadSpeed = 4f;

		private float maxQueue = 1500f;

		private bool trustHost = true;

		private bool autoOpen = true;

		private bool autoClose = true;

		private bool notifications = true;

		private bool hostFilter = true;

		private bool clientFilter = true;

		private bool warnHold = true;

		private bool warnBlocked = true;

		private bool logAll = false;

		private bool blockItems = true;

		private bool askExplosives = true;

		private bool fxFilter = true;

		private float fxThreshold = 10f;

		private float fxWindow = 3f;

		private float maxActiveFx = 40f;

		private bool blockAllFx = false;

		private bool limitSpawnFx = true;

		private float spawnFxPerSec = 10f;

		private bool antiCheatDamage = true;

		private bool autoKick = true;

		private float kickStrikes = 3f;

		private float meleeRange = 3f;

		private bool antiKickServer = true;

		private bool antiFakeKick = true;

		private bool kickNotifs = true;

		private bool secPopup = true;

		private bool godDetect = true;

		private bool confirmOpKicks = false;

		private bool antiFakePerms = true;

		private bool antiHijack = true;

		private bool antiForeignDespawn = true;

		private bool limitAvatarSpam = true;

		private bool antiHealthHack = true;

		private float godHits = 10f;

		private bool antiBadPose = true;

		private bool antiFlood = true;

		private float floodLimit = 3000f;

		private float floodKB = 512f;

		private bool antiGamemodeTriggers = true;

		private bool antiFakeTp = true;

		private bool limitTeleports = true;

		private int triggersBlocked;

		private int tpBlocked;

		private int ghostDropped;

		private bool operatorMode = true;

		private bool autoBanCrashSpam = true;

		private bool hostCrashDespawn = true;

		private bool kickNukeSpam = true;

		private float nukeKickAt = 2f;

		private float explosiveKickAt = 6f;

		private int spawnKicks;

		private float crashSpamSecs = 5f;

		private bool shieldMode = false;

		private int shieldDropped;

		private int autoBans;

		private bool antiGodGuns = true;

		private bool antiSilentAim = true;

		private bool detectAimLock = true;

		private bool antiInfiniteAmmo = true;

		private bool antiWallbang = true;

		private bool antiNoShotDamage = true;

		private bool antiRemoteGrab = true;

		private bool antiFling = true;

		private float flingSpeed = 60f;

		private int combatBlocked;

		private int grabsBlocked;

		private int flingsStopped;

		private int ammoAlerts;

		private bool warnBannedJoin = true;

		private bool watchScanLobbies = true;

		private bool detectDmgMult = true;

		private bool antiKillAir = true;

		private int multAlerts;

		private int godScanHits;

		private const int MaxMessageBytes = 262144;

		private const int MaxMetadataChars = 1024;

		private bool antiRemoteFire = true;

		private bool antiSlowMo = true;

		private bool antiLinks = true;

		private float avatarMax = 6f;

		private static readonly string[] PresetNames = new string[5] { "Low", "Normal", "High", "Max", "Custom" };

		private static readonly string[] SpawnPermNames = new string[3] { "Normal", "Trusted", "Blocked" };

		private static readonly string[] PermNames = new string[4] { "Guest", "Default", "Operator", "Owner" };

		private static readonly float[] PresetThreshold = new float[4] { 40f, 15f, 8f, 4f };

		private static readonly float[] PresetWindow = new float[4] { 3f, 3f, 3f, 2f };

		private bool applyingPreset = false;

		private const int BindCount = 5;

		private int menuBind = 1;

		private int menuHand = 0;

		private int menuAccent = 0;

		private float menuSize = 1f;

		private float textSize = 1f;

		private bool haptics = true;

		private int touchSafety = 0;

		private static readonly string[] TouchNames = new string[2] { "Normal", "Strict" };

		private MelonPreferences_Entry<bool> tutorialPref;

		private GameObject hintRoot;

		private TextMesh hintLine2;

		private string hintBind;

		private readonly List<Material> hintMats = new List<Material>();

		private bool hintNotified;

		private const string TsNamespace = "FusionGuardTeam";

		private bool checkUpdates = true;

		private volatile bool updBusy;

		private bool updAvailable;

		private bool updNotifyPending;

		private string updLatest;

		private string updStatus = "Not checked yet";

		private MenuPage updPage;

		private static readonly string[] AccentNames = new string[6] { "Cyan", "Purple", "Green", "Orange", "Pink", "Rainbow" };

		private static readonly Color[] AccentColors = (Color[])(object)new Color[5]
		{
			new Color(0.2f, 0.85f, 1f, 1f),
			new Color(0.66f, 0.45f, 1f, 1f),
			new Color(0.25f, 0.9f, 0.5f, 1f),
			new Color(1f, 0.6f, 0.2f, 1f),
			new Color(1f, 0.4f, 0.75f, 1f)
		};

		private float aimHeadshots = 5f;

		private float aimDistance = 15f;

		private float silentShots = 4f;

		private float fireRateMargin = 50f;

		private float killAirPct = 50f;

		private float graceUntil;

		private const float GraceSeconds = 12f;

		private readonly Dictionary<byte, Queue<float>> recent = new Dictionary<byte, Queue<float>>();

		private readonly Dictionary<byte, PlayerHold> holds = new Dictionary<byte, PlayerHold>();

		private readonly Dictionary<string, string> blocked = new Dictionary<string, string>();

		private readonly Dictionary<string, string> trusted = new Dictionary<string, string>();

		private readonly Dictionary<string, string> fxBlocked = new Dictionary<string, string>();

		private readonly Dictionary<byte, Queue<float>> recentFx = new Dictionary<byte, Queue<float>>();

		private readonly Dictionary<byte, Queue<float>> recentAmmo = new Dictionary<byte, Queue<float>>();

		private int fxDropped;

		private readonly Dictionary<string, bool> fxCache = new Dictionary<string, bool>();

		private readonly Dictionary<string, bool> fxGuess = new Dictionary<string, bool>();

		private readonly Dictionary<int, FxEntry> activeFx = new Dictionary<int, FxEntry>();

		private readonly Queue<float> spawnFxTimes = new Queue<float>();

		private int fxCapped;

		private readonly List<SecAlert> alerts = new List<SecAlert>();

		private readonly Dictionary<byte, float> lastHeld = new Dictionary<byte, float>();

		private readonly Dictionary<byte, List<float>> strikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<string, string> damageAllow = new Dictionary<string, string>();

		private readonly Dictionary<string, float> lastSecNotify = new Dictionary<string, float>();

		private int dmgBlocked;

		private int kicksBlocked;

		private float heldTimer;

		private SecAlert autoOpenAlert;

		private readonly Dictionary<byte, GodTrack> godTrack = new Dictionary<byte, GodTrack>();

		private readonly Dictionary<byte, Queue<float>> dmgRate = new Dictionary<byte, Queue<float>>();

		private float godTimer;

		private float permTimer;

		private readonly Dictionary<byte, float> poseQuarantine = new Dictionary<byte, float>();

		private readonly Dictionary<byte, float> downUntil = new Dictionary<byte, float>();

		private readonly Dictionary<byte, List<float>> badPoseStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> bigMsgStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> gunStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> slowMoStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, MsgCounter> msgCount = new Dictionary<byte, MsgCounter>();

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

		private int badPoses;

		private int floodDropped;

		private int remoteFireBlocked;

		private readonly Dictionary<byte, List<float>> hijackStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> despawnStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, Queue<float>> avatarSwaps = new Dictionary<byte, Queue<float>>();

		private int netBlocked;

		private int foreignDespawns;

		private readonly Dictionary<byte, float> lastDeath = new Dictionary<byte, float>();

		private readonly Dictionary<byte, float> godFlagged = new Dictionary<byte, float>();

		private readonly Dictionary<byte, float> hpFlagged = new Dictionary<byte, float>();

		private int godAlerts;

		private const float HoldGrace = 6f;

		private int spawnFxSkipped;

		private float fxTimer;

		private static readonly string[] GunFxWords = new string[7] { "muzzle", "tracer", "tracers", "casing", "casings", "shellcasing", "brass" };

		private static readonly string[] FxWords = new string[19]
		{
			"vfx", "fx", "particle", "particles", "smoke", "explosion", "explosions", "spark", "sparks", "effect",
			"effects", "firework", "fireworks", "confetti", "fog", "nuke", "blood", "splash", "flash"
		};

		private readonly Queue<PendingSpawn> replayQueue = new Queue<PendingSpawn>();

		private int blockedDropped;

		private bool holdsDirty;

		private float holdsRefreshTimer;

		private bool menuAutoOpened;

		private bool pendingAutoOpen;

		private PlayerHold autoOpenTarget;

		private readonly Dictionary<byte, List<ushort>> spawnedBy = new Dictionary<byte, List<ushort>>();

		private readonly Dictionary<byte, int> spawnCount = new Dictionary<byte, int>();

		private readonly List<string> spawnLog = new List<string>();

		private readonly Dictionary<byte, float> lastWarn = new Dictionary<byte, float>();

		private bool adminDirty = true;

		private float adminTimer;

		private string boneAdminSig = "";

		private readonly List<GameObject> hiddenProps = new List<GameObject>();

		private string confirmKey;

		private float confirmUntil;

		private string lastActiveScene;

		private static FieldInfo _discPlatF;

		private static FieldInfo _discReasonF;

		[ThreadStatic]
		private static string _eosPeer;

		[ThreadStatic]
		private static bool _eosFresh;

		[ThreadStatic]
		private static bool _eosNetDisconnect;

		[ThreadStatic]
		private static bool _eosServerHandled;

		[ThreadStatic]
		private static bool _eosNativeCheck;

		private static bool eosPatched;

		private static bool eosNativeOn;

		private bool antiSpoof = true;

		private int spoofBlocked;

		private readonly Dictionary<string, List<float>> spoofStrikes = new Dictionary<string, List<float>>();

		private static FieldInfo _backupIdField;

		private readonly Dictionary<string, float> blockedPeers = new Dictionary<string, float>();

		private readonly Dictionary<string, float> joinGrace = new Dictionary<string, float>();

		private readonly Dictionary<string, float> peerCloseAt = new Dictionary<string, float>();

		private readonly Dictionary<string, float> ghostLogAt = new Dictionary<string, float>();

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

		private static bool eosIdsMatch;

		private static FieldInfo _rcvP2P;

		private static FieldInfo _p2pPool;

		private static MethodInfo _poolReturn;

		private static bool _poolInit;

		private static FieldInfo _p2pLocalId;

		private static long _selfPackets;

		private static bool _selfLogged;

		private static PlatSetter _setPlat;

		private bool lockdown = false;

		private bool quarantineOn = true;

		private float quarantineSecs = 45f;

		private bool autoSanctions = true;

		private float sanctionBlockAt = 2f;

		private float sanctionKickAt = 3f;

		private float sanctionBanAt = 5f;

		private bool antiRejoin = true;

		private bool epicAccountCheck = true;

		private bool securityLogFile = true;

		private bool strongHaptics = true;

		private readonly Dictionary<byte, float> firstSeen = new Dictionary<byte, float>();

		private float serverSeenAt = -1f;

		private readonly Dictionary<string, List<float>> kickHistory = new Dictionary<string, List<float>>();

		private readonly Dictionary<string, float> tempBans = new Dictionary<string, float>();

		private readonly Dictionary<string, List<float>> joinAttempts = new Dictionary<string, List<float>>();

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

		private readonly HashSet<string> epicKicked = new HashSet<string>();

		private readonly Dictionary<string, float> banKickAt = new Dictionary<string, float>();

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

		private int joinsDenied;

		private bool hapticPending;

		private float lastDenyNotify;

		private static readonly HashSet<string> SevereKinds = new HashSet<string> { "kickcheat", "spoof", "badpose", "flood", "hijack", "fakekick", "fakeperm", "remotefire", "damage", "faketp" };

		private static readonly HashSet<string> ScoreKinds = new HashSet<string> { "kickcheat", "spoof", "fakekick", "fakeperm", "flood", "badpose", "remotefire", "nukespam" };

		private readonly Dictionary<string, GuardBan> guardBans = new Dictionary<string, GuardBan>();

		private string trustedSig = "";

		private readonly Dictionary<byte, string> slotOwner = new Dictionary<byte, string>();

		private static PropertyInfo _recvPlatProp;

		private bool muteAllNonStaff;

		private readonly Dictionary<byte, KeyValuePair<float, bool>> staffCache = new Dictionary<byte, KeyValuePair<float, bool>>();

		private readonly Dictionary<string, float> lastNetCheat = new Dictionary<string, float>();

		private readonly Dictionary<byte, float> cullSeen = new Dictionary<byte, float>();

		private const float CullGrace = 3f;

		private readonly Dictionary<byte, float> disarmAt = new Dictionary<byte, float>();

		private static bool shotWatchPatched;

		private int disarms;

		private const float PoseLimit = 100000f;

		private static FieldInfo _bodiesField;

		private static PropertyInfo _bodiesProp;

		private static bool _bodiesInit;

		private static FieldInfo _gunIdF;

		private static FieldInfo _gunF;

		private static FieldInfo _entF;

		private static FieldInfo _idF;

		private static bool _gunInit;

		private const string GuardKey = "FusionGuard";

		private float guardTimer;

		private int guardTries;

		private readonly HashSet<byte> guardSeen = new HashSet<byte>();

		internal const bool AdminBuild = false;

		private const string LobbyGuardKey = "FusionGuard";

		private bool shareLobbyFg = true;

		private bool lobbyFgPatched;

		private string lobbyFgSig;

		private float nextLobbyFgWrite;

		private readonly List<LobbyRow> lobbyRows = new List<LobbyRow>();

		private MenuPage lobbyPage;

		private bool lobbyBusy;

		private float lobbyReqAt;

		private float lobbyLoadedAt = -1f;

		private string lobbyStatus = "Open this page to load the lobby list";

		private const string MegaKey = "FusionGuard.Mega";

		private bool megaphone;

		private readonly Dictionary<byte, KeyValuePair<float, bool>> megaCache = new Dictionary<byte, KeyValuePair<float, bool>>();

		private readonly HashSet<int> megaApplied = new HashSet<int>();

		private static readonly Vector3 VanishSpot = new Vector3(0f, -4000f, 0f);

		private bool vanish;

		private bool vanishPatched;

		private readonly Dictionary<string, List<float>> crashSeconds = new Dictionary<string, List<float>>();

		private readonly Dictionary<string, float> crashKickAt = new Dictionary<string, float>();

		private readonly Dictionary<string, List<float>> nukeTries = new Dictionary<string, List<float>>();

		private readonly Dictionary<string, List<float>> explosiveTries = new Dictionary<string, List<float>>();

		private readonly Dictionary<string, float> spawnKickAt = new Dictionary<string, float>();

		private readonly Dictionary<byte, float> shieldDrop = new Dictionary<byte, float>();

		private readonly List<RecentSpawn> recentSpawns = new List<RecentSpawn>();

		private bool netDebug = true;

		private float netSummarySecs = 10f;

		private readonly Dictionary<byte, NetStat> netStats = new Dictionary<byte, NetStat>();

		private readonly Dictionary<byte, string> netRoster = new Dictionary<byte, string>();

		private readonly Dictionary<string, float> netLineAt = new Dictionary<string, float>();

		private readonly Dictionary<string, string> netMetaLast = new Dictionary<string, string>();

		private float netSummaryTimer;

		private float netStatusTimer;

		private float netRosterTimer;

		[ThreadStatic]
		private static bool _fgDropped;

		private const byte NetNoSender = byte.MaxValue;

		private static readonly FieldInfo _discPlatF2 = typeof(DisconnectMessageData).GetField("PlatformID", BindingFlags.Instance | BindingFlags.Public);

		private static readonly FieldInfo _discReasonF2 = typeof(DisconnectMessageData).GetField("Reason", BindingFlags.Instance | BindingFlags.Public);

		private readonly Dictionary<byte, List<RecentShot>> recentShots = new Dictionary<byte, List<RecentShot>>();

		private readonly Dictionary<ushort, GunTrack> gunTracks = new Dictionary<ushort, GunTrack>();

		private readonly Dictionary<byte, LastShotInfo> lastShotBy = new Dictionary<byte, LastShotInfo>();

		private readonly HashSet<byte> infAmmoPopped = new HashSet<byte>();

		private readonly Dictionary<string, float> combatNotifyAt = new Dictionary<string, float>();

		private readonly Dictionary<string, List<float>> combatStrikes = new Dictionary<string, List<float>>();

		[ThreadStatic]
		private static bool _dmgCertain;

		private static FieldInfo _ammoF;

		private static bool _ammoInit;

		private static FieldInfo _gunIdxF;

		private static FieldInfo _gunIdxInner;

		private static bool _gunIdxInit;

		private static FieldInfo _magGunF;

		private static FieldInfo _magEjGunF;

		private static readonly Dictionary<int, bool> solidLayerCache = new Dictionary<int, bool>();

		private static readonly string[] SoftLayerWords = new string[18]
		{
			"ignore", "nocollide", "trigger", "player", "ui", "water", "block", "clip", "nav", "invisible",
			"socket", "deciverse", "feet", "hand", "interactable", "ragdoll", "effect", "fx"
		};

		private static readonly Handedness HandLeft = (Handedness)1;

		private readonly List<GrabOnMe> grabsOnMe = new List<GrabOnMe>();

		private float flingWatchUntil;

		private float flingNotifyAt;

		private Rigidbody[] myRbs;

		private float myRbsAt;

		private readonly Dictionary<string, float> bannedJoinAt = new Dictionary<string, float>();

		private const string DefaultWatchlist = "nyro,nyro.dll";

		private const int WatchlistVersion = 2;

		private MelonPreferences_Entry<string> watchPref;

		private MelonPreferences_Entry<int> watchVer;

		private readonly Dictionary<byte, string> watchSeen = new Dictionary<byte, string>();

		private readonly Dictionary<string, float> watchLobbyAt = new Dictionary<string, float>();

		private readonly HashSet<string> knownAmmo = new HashSet<string>();

		private readonly List<DmgSample>[] dmgSamples = new List<DmgSample>[2]
		{
			new List<DmgSample>(),
			new List<DmgSample>()
		};

		private readonly Dictionary<byte, List<float>> shooterRatios = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, float> multFlagged = new Dictionary<byte, float>();

		private readonly Dictionary<byte, FreezeState> frozen = new Dictionary<byte, FreezeState>();

		[ThreadStatic]
		private static bool _freezeTp;

		private readonly Dictionary<byte, List<AimEval>> aimEvals = new Dictionary<byte, List<AimEval>>();

		private int aimAlerts;

		private readonly Dictionary<byte, List<AimShot>> aimShots = new Dictionary<byte, List<AimShot>>();

		private readonly Dictionary<byte, List<KeyValuePair<float, Vector3>>> holdAim = new Dictionary<byte, List<KeyValuePair<float, Vector3>>>();

		private readonly Dictionary<byte, KeyValuePair<float, Vector3>> pelvisLast = new Dictionary<byte, KeyValuePair<float, Vector3>>();

		private readonly Dictionary<byte, float> pelvisSpeed = new Dictionary<byte, float>();

		private int aimLockAlerts;

		private readonly Dictionary<byte, List<float>> triggerTimes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> triggerStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> tpTimes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> tpStrikes = new Dictionary<byte, List<float>>();

		private readonly Dictionary<byte, List<float>> fakeTpStrikes = new Dictionary<byte, List<float>>();

		private static readonly Regex LinkRegex = new Regex("(https?://|www\\.|discord\\.gg|discord\\.com/invite|\\b[a-z0-9-]{2,}\\.(com|net|org|gg|fun|xyz|io|ru|tk|ly|me|tv|site|online|shop)\\b)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private static bool vfxBroken;

		private static readonly string[] AmmoWords = new string[12]
		{
			"magazine", "magazines", "mag", "mags", "ammo", "clip", "clips", "shell", "shells", "cartridge",
			"battery", "cell"
		};

		private readonly Dictionary<string, bool> ammoCache = new Dictionary<string, bool>();

		private static readonly string[] DefaultBlockedItems = new string[8] { "!nuke", "missile", "explosion", "explosive", "bomb", "c4", "!void spawn", "!void orb" };

		private static readonly string[] AllowedItemWords = new string[3] { "rpg", "launcher", "bazooka" };

		private const int BlockedItemsVersion = 3;

		private readonly List<BlockedWord> blockedItems = new List<BlockedWord>();

		private MelonPreferences_Entry<string> blockedItemsPref;

		private MelonPreferences_Entry<int> blockedItemsVer;

		private readonly Dictionary<string, string> crateText = new Dictionary<string, string>();

		private readonly Dictionary<string, BlockedWord> itemMatch = new Dictionary<string, BlockedWord>();

		private int itemsBlocked;

		private MenuPage itemsPage;

		private static readonly string[] ExplosiveWords = new string[17]
		{
			"explosive", "explosion", "grenade", "bomb", "c4", "missile", "rocket", "nuke", "mine", "landmine",
			"dynamite", "tnt", "claymore", "detonator", "frag", "molotov", "warhead"
		};

		private readonly Dictionary<byte, ApprovalHold> approvals = new Dictionary<byte, ApprovalHold>();

		private readonly Dictionary<string, string> explosiveTrusted = new Dictionary<string, string>();

		private readonly Dictionary<string, string> explosiveBlocked = new Dictionary<string, string>();

		private readonly Dictionary<string, bool> explosiveCache = new Dictionary<string, bool>();

		private ApprovalHold autoOpenApproval;

		private int explosivesRefused;

		private const int MaxApprovalQueue = 30;

		private const float ApprovalTimeout = 90f;

		private static int mainThreadId = -1;

		private static readonly ConcurrentQueue<Action> mainQueue = new ConcurrentQueue<Action>();

		private float nextMenuErr;

		private bool menuOpen = false;

		private bool lastCombo = false;

		private float menuAnim = 0f;

		private GameObject menuRoot;

		private GameObject pointerBall;

		private Renderer pointerRend;

		private MenuPage homePage;

		private MenuPage currentPage;

		private MenuPage pendingPage;

		private MenuPage playersPage;

		private MenuPage filterPage;

		private MenuPage fxPage;

		private MenuPage securityPage;

		private MenuPage netPage;

		private MenuPage toolsPage;

		private MenuPage settingsPage;

		private MenuPage watchPage;

		private readonly List<UiButton> uiButtons = new List<UiButton>();

		private readonly List<Material> menuMats = new List<Material>();

		private readonly List<Renderer> accentRends = new List<Renderer>();

		private readonly List<TextMesh> accentTexts = new List<TextMesh>();

		private Animator fingerAnim;

		private float nextFingerSearch;

		private Font menuFont;

		private Material textMat;

		private bool fontSearched = false;

		private bool pressLock = false;

		private UiButton armedBtn;

		private UiButton approachBtn;

		private float armedSince;

		private float approachTime;

		private float settleUntil;

		private const int HiddenLayer = 0;

		private static readonly Color CBg = new Color(0.05f, 0.055f, 0.07f, 1f);

		private static readonly Color CTop = new Color(0.075f, 0.082f, 0.104f, 1f);

		private static readonly Color CSide = new Color(0.068f, 0.075f, 0.096f, 1f);

		private static readonly Color CCard = new Color(0.108f, 0.118f, 0.15f, 1f);

		private static readonly Color CInfo = new Color(0.08f, 0.088f, 0.112f, 1f);

		private static readonly Color CChip = new Color(0.155f, 0.168f, 0.212f, 1f);

		private static readonly Color CTrack = new Color(0.215f, 0.228f, 0.275f, 1f);

		private static readonly Color COn = new Color(0.2f, 0.8f, 0.45f, 1f);

		private static readonly Color COff = new Color(0.3f, 0.32f, 0.38f, 1f);

		private static readonly Color CText = new Color(0.95f, 0.96f, 1f, 1f);

		private static readonly Color CTextDim = new Color(0.76f, 0.79f, 0.87f, 1f);

		private static readonly Color CSub = new Color(0.55f, 0.6f, 0.7f, 1f);

		private static readonly Color CGood = new Color(0.11f, 0.42f, 0.25f, 1f);

		private static readonly Color CDanger = new Color(0.5f, 0.12f, 0.15f, 1f);

		private static readonly Color CArmed = new Color(0.9f, 0.15f, 0.12f, 1f);

		private static readonly Color CWarn = new Color(1f, 0.78f, 0.3f, 1f);

		private static readonly Color CAlert = new Color(1f, 0.45f, 0.45f, 1f);

		private static readonly Color CHeader = CTop;

		private static readonly Color CRow = CCard;

		private static readonly Color CRowSoft = CInfo;

		private static readonly Color CTile = CCard;

		private static readonly Color CNav = CChip;

		private static readonly Color TLoad = new Color(0.13f, 0.5f, 0.3f, 1f);

		private static readonly Color TTrust = new Color(0.12f, 0.36f, 0.55f, 1f);

		private static readonly Color TRefuse = new Color(0.45f, 0.1f, 0.12f, 1f);

		private static readonly Color TBlock = new Color(0.3f, 0.05f, 0.06f, 1f);

		private static readonly Color TFrozen = new Color(0.1f, 0.32f, 0.72f, 1f);

		private static readonly Color KAlerts = new Color(1f, 0.56f, 0.26f, 1f);

		private static readonly Color KPlayers = new Color(0.38f, 0.66f, 1f, 1f);

		private static readonly Color KServer = new Color(0.68f, 0.52f, 1f, 1f);

		private static readonly Color KSpawns = new Color(1f, 0.8f, 0.3f, 1f);

		private static readonly Color KParticles = new Color(1f, 0.46f, 0.76f, 1f);

		private static readonly Color KCheat = new Color(1f, 0.36f, 0.4f, 1f);

		private static readonly Color KNetwork = new Color(0.3f, 0.86f, 0.76f, 1f);

		private static readonly Color KSettings = new Color(0.66f, 0.7f, 0.78f, 1f);

		private const float PW = 0.37f;

		private const float PH = 0.36f;

		private const float MW = 0.37f;

		private const float MH = 0.36f;

		private const float SideW = 0.082f;

		private const float CL = -0.087f;

		private const float CR = 0.175f;

		private const float CW = 0.262f;

		private const float CX = 0.044f;

		private const float RW = 0.262f;

		private const float RowH = 0.031f;

		private const float RowStep = 0.038f;

		private const int RowsPerPage = 6;

		private const float HitInset = 0.002f;

		private MenuPage serverPage;

		private readonly Dictionary<byte, TpBack> tpBack = new Dictionary<byte, TpBack>();

		private MenuPage resumePage;

		private bool tutorialSessionDone;

		private float nextHintErr;

		private MenuPage lastDrawnPage;

		private bool lastArmedState;

		private Color drawCat;

		private static Shader menuShader;

		private static bool shaderSearched;

		private static readonly string[] ShaderNames = new string[5] { "Hidden/Internal-Colored", "Universal Render Pipeline/Unlit", "Unlit/Color", "Sprites/Default", "UI/Default" };

		private Page bonePending;

		private Page bonePlayers;

		private Page boneTools;

		private static readonly string[] OverlayKeyNames = new string[8] { "F6", "F7", "F8", "F9", "F10", "F11", "Insert", "Off" };

		private int overlayKey = 2;

		private float overlayScale = 1f;

		private bool overlayOpen;

		private bool overlayBroken;

		private readonly List<Action> overlayActions = new List<Action>();

		private float overlayOpenedAt;

		private bool overlayDrawn;

		private bool overlayNoGuiWarned;

		private bool overlayLoggedDraw;

		private float nextOverlayErr;

		private MelonPreferences_Category stateCat;

		private readonly List<StateSlot> stateSlots = new List<StateSlot>();

		private bool loadingState = false;

		private bool saveQueued;

		private float saveTimer;

		internal static bool IsQuest
		{
			get
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Invalid comparison between Unknown and I4
				if (_isQuest < 0)
				{
					try
					{
						_isQuest = (((int)Application.platform == 11) ? 1 : 0);
					}
					catch
					{
						_isQuest = ((Environment.OSVersion.Platform == PlatformID.Unix) ? 1 : 0);
					}
				}
				return _isQuest == 1;
			}
		}

		private static bool GuardOn => Instance != null && Instance.protection;

		private bool TutorialDone
		{
			get
			{
				try
				{
					return tutorialPref != null && tutorialPref.Value;
				}
				catch
				{
					return true;
				}
			}
		}

		private static string TsPackage => IsQuest ? "FusionGuard_Quest" : "FusionGuard";

		private string BansPath => Path.Combine(GuardDir(), "bans.txt");

		private string ImportPath => Path.Combine(GuardDir(), "import_bans.txt");

		private string TrustedPath => Path.Combine(GuardDir(), "trusted.txt");

		private bool ShieldActive => shieldMode && NetworkInfo.HasServer && !NetworkInfo.IsHost;

		private static bool OnMainThread => Thread.CurrentThread.ManagedThreadId == mainThreadId;

		private bool IsGunFx(string barcode)
		{
			string text = CrateWords(barcode);
			string[] gunFxWords = GunFxWords;
			foreach (string text2 in gunFxWords)
			{
				if (text.Contains(" " + text2 + " "))
				{
					return true;
				}
			}
			return false;
		}

		public override void OnInitializeMelon()
		{
			Instance = this;
			mainThreadId = Thread.CurrentThread.ManagedThreadId;
			bool flag = true;
			try
			{
				if (MelonBase.RegisteredMelons.Any((MelonBase m) => m != null && (object)m != this && m.Info != null && m.Info.Name == "FusionGuard Admin"))
				{
					((MelonBase)this).LoggerInstance.Error("FusionGuard Admin is also installed: this FusionGuard disables itself. Keep only one of the DLLs.");
					Instance = null;
					try
					{
						((MelonBase)this).Unregister("FusionGuard Admin already installed", false);
						return;
					}
					catch
					{
						return;
					}
				}
			}
			catch
			{
			}
			FusionCompat.Init();
			((MelonBase)this).LoggerInstance.Msg("Fusion version detected: " + FusionCompat.Mode);
			((MelonBase)this).LoggerInstance.Msg("Platform: " + (IsQuest ? "Quest standalone (Android / LemonLoader)" : "PC"));
			if (IsQuest)
			{
				maxActiveFx = 25f;
				spawnFxPerSec = 6f;
			}
			PatchFusion();
			BuildPages();
			LoadState();
			LoadTrusted();
			SetupBoneMenu();
			try
			{
				MelonPreferences_Category val = MelonPreferences.CreateCategory("FusionGuard");
				tutorialPref = val.CreateEntry<bool>("TutorialDone", false, (string)null, "true once the hand menu has been opened (hides the \"how to open\" hint)", false, false, (ValueValidator)null, (string)null);
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("[Tutorial] " + ex.Message);
			}
			if (!IsQuest && checkUpdates)
			{
				CheckForUpdates(manual: false);
			}
			((MelonBase)this).LoggerInstance.Msg("FusionGuard 8.4.9 loaded. Hand menu: " + BindName() + " on the " + ((menuHand == 0) ? "left" : "right") + " hand");
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			menuRoot = null;
			pointerBall = null;
			menuOpen = false;
			menuAnim = 0f;
			uiButtons.Clear();
			menuMats.Clear();
			DestroyHint();
			hintRoot = null;
			fingerAnim = null;
			armedBtn = null;
			approachBtn = null;
			lastDrawnPage = null;
			accentRends.Clear();
			accentTexts.Clear();
			graceUntil = Time.realtimeSinceStartup + 12f;
			string text = sceneName ?? "";
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				text = ((Scene)(ref activeScene)).name ?? text;
			}
			catch
			{
			}
			if (text != lastActiveScene)
			{
				lastActiveScene = text;
				try
				{
					ClearPending();
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Warning("[Map] " + ex.Message);
				}
			}
		}

		public override void OnApplicationQuit()
		{
			try
			{
				SaveTrustedIfChanged();
			}
			catch
			{
			}
			SaveState();
		}

		private void PatchFusion()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			try
			{
				handleMethod = typeof(SpawnResponseMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (handleMethod == null)
				{
					((MelonBase)this).LoggerInstance.Error("SpawnResponseMessage.OnHandleMessage not found (different Fusion version?)");
					return;
				}
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)handleMethod, new HarmonyMethod(typeof(Core).GetMethod("SpawnPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Guard] patch spawn Fusion OK");
				requestMethod = typeof(SpawnRequestMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (requestMethod != null)
				{
					((MelonBase)this).HarmonyInstance.Patch((MethodBase)requestMethod, new HarmonyMethod(typeof(Core).GetMethod("ServerSpawnPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((MelonBase)this).LoggerInstance.Msg("[Guard] anti-spawn host OK");
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("[Guard] SpawnRequestMessage.OnHandleMessage not found, host anti-spawn disabled");
				}
				MethodInfo method = typeof(SpawnResponseMessage).GetMethod("OnSpawnFinished", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					((MelonBase)this).HarmonyInstance.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(Core).GetMethod("SpawnFinishedPostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((MelonBase)this).LoggerInstance.Msg("[Guard] particle tracking OK");
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("[Guard] SpawnResponseMessage.OnSpawnFinished not found, active particle limit disabled");
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("[Guard] Fusion patch failed: " + ex);
			}
			try
			{
				MethodInfo method2 = typeof(SpawnEffects).GetMethod("CallSpawnEffect", BindingFlags.Static | BindingFlags.Public);
				if (method2 != null)
				{
					((MelonBase)this).HarmonyInstance.Patch((MethodBase)method2, new HarmonyMethod(typeof(Core).GetMethod("SpawnEffectPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((MelonBase)this).LoggerInstance.Msg("[Guard] spawn effect limit OK");
				}
			}
			catch (Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Error("[Guard] Fusion patch failed: " + ex2);
			}
			PatchSecurity();
		}

		private void PatchSecurity()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Expected O, but got Unknown
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Expected O, but got Unknown
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Expected O, but got Unknown
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Expected O, but got Unknown
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Expected O, but got Unknown
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Expected O, but got Unknown
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Expected O, but got Unknown
			//IL_0741: Unknown result type (might be due to invalid IL or missing references)
			//IL_074e: Expected O, but got Unknown
			//IL_0782: Unknown result type (might be due to invalid IL or missing references)
			//IL_078f: Expected O, but got Unknown
			//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b1: Expected O, but got Unknown
			//IL_091d: Unknown result type (might be due to invalid IL or missing references)
			//IL_092b: Expected O, but got Unknown
			//IL_099b: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a9: Expected O, but got Unknown
			//IL_0a19: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a27: Expected O, but got Unknown
			//IL_060b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Expected O, but got Unknown
			//IL_06b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Expected O, but got Unknown
			//IL_080e: Unknown result type (might be due to invalid IL or missing references)
			//IL_081c: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			try
			{
				MethodInfo method = typeof(PlayerRepDamageMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)method, new HarmonyMethod(typeof(Core).GetMethod("DamagePrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Security] cheat damage guard OK");
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("[Security] damage patch failed: " + ex.Message);
			}
			try
			{
				MethodInfo method2 = typeof(MessageHandler).GetMethod("OnPreRelayMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)method2, new HarmonyMethod(typeof(Core).GetMethod("RelayPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Security] host damage guard (relay) OK");
			}
			catch (Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Warning("[Security] relay patch failed: " + ex2.Message);
			}
			try
			{
				MethodInfo method3 = typeof(DisconnectMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)method3, new HarmonyMethod(typeof(Core).GetMethod("DisconnectPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Security] fake kick guard OK");
			}
			catch (Exception ex3)
			{
				((MelonBase)this).LoggerInstance.Warning("[Security] disconnect patch failed: " + ex3.Message);
			}
			try
			{
				MethodInfo methodInfo = typeof(PlayerSender).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo x) => x.Name == "SendPlayerDamage" && x.GetParameters().Length == 3);
				if (methodInfo != null)
				{
					((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Core).GetMethod("SendDamagePrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo method4 = typeof(PlayerRepActionMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)method4, new HarmonyMethod(typeof(Core).GetMethod("ActionPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Security] god mode detector OK");
			}
			catch (Exception ex4)
			{
				((MelonBase)this).LoggerInstance.Warning("[Security] god mode patch failed: " + ex4.Message);
			}
			try
			{
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(EntityOwnershipRequestMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), new HarmonyMethod(typeof(Core).GetMethod("OwnershipPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(DespawnRequestMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), new HarmonyMethod(typeof(Core).GetMethod("DespawnRequestPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(PlayerRepAvatarMessage).GetMethod("OnHandleMessage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), new HarmonyMethod(typeof(Core).GetMethod("AvatarPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("[Security] hijack / despawn / avatar spam guard OK");
			}
			catch (Exception ex5)
			{
				((MelonBase)this).LoggerIn