Decompiled source of FusionGod v1.1.0

FusionGod.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using FusionGod;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(FusionGodMod), "FusionGod", "1.2.0", "JoshSievers24", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FusionGod
{
	internal static class FusionHooks
	{
		internal static void Init(Harmony harmony)
		{
			HookJoinLeave();
			PatchAvatar(harmony);
		}

		private static void HookJoinLeave()
		{
			try
			{
				Type type = Type.GetType("LabFusion.Utilities.MultiplayerHooking, LabFusion") ?? Type.GetType("LabFusion.Network.MultiplayerHooking, LabFusion");
				if (!(type == null))
				{
					Bind(type, "OnPlayerJoined", new Action<object>(OnJoined));
					Bind(type, "OnPlayerJoin", new Action<object>(OnJoined));
					Bind(type, "OnPlayerLeft", new Action<object>(OnLeft));
					Bind(type, "OnDisconnected", new Action(OnDisconnected));
					Bind(type, "OnDisconnect", new Action(OnDisconnected));
					Bind(type, "OnStartedServer", new Action(OnHostStart));
					Bind(type, "OnStartServer", new Action(OnHostStart));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] join/leave hooks: " + ex.Message);
			}
		}

		private static void Bind(Type type, string eventName, Delegate handler)
		{
			EventInfo eventInfo = type.GetEvent(eventName, BindingFlags.Static | BindingFlags.Public);
			if (eventInfo == null)
			{
				return;
			}
			try
			{
				eventInfo.AddEventHandler(null, Delegate.CreateDelegate(eventInfo.EventHandlerType, handler.Target, handler.Method));
			}
			catch
			{
				try
				{
					eventInfo.GetAddMethod()?.Invoke(null, new object[1] { handler });
				}
				catch
				{
				}
			}
		}

		private static void OnJoined(object playerId)
		{
			string text = FusionApi.DisplayName(playerId);
			ViolationLog.Add("join", text + " joined");
			if (FusionApi.IsHost())
			{
				NetSend.HostCommand(GodCommand.EnforcePolicy, byte.MaxValue, Prefs.GodProtect.Value ? 1f : 0f, Prefs.HealthProtect.Value ? 1f : 0f, Prefs.MaxVitality.Value);
			}
			NetSend.ClientToHost(GodCommand.Presence, "hello");
		}

		private static void OnLeft(object playerId)
		{
			try
			{
				PlayerID val = (PlayerID)((playerId is PlayerID) ? playerId : null);
				if (val != null)
				{
					Presence.Forget(val.SmallID);
				}
			}
			catch
			{
			}
			ViolationLog.Add("leave", FusionApi.DisplayName(playerId) + " left");
		}

		private static void OnDisconnected()
		{
			Presence.Clear();
			LocalEffects.Clear();
			GodMenu.Rebuild();
		}

		private static void OnHostStart()
		{
			ViolationLog.Add("server", "You are hosting. Fusion God admin unlocked.");
			GodMenu.Rebuild();
		}

		private static void PatchAvatar(Harmony harmony)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("LabFusion.Network.PlayerRepAvatarMessage");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "OnHandleMessage", (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				MelonLogger.Warning("[FusionGod] Could not patch PlayerRepAvatarMessage.");
			}
			else
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(FusionHooks), "AvatarPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void AvatarPostfix(object __instance, object received)
		{
			if (!FusionApi.IsHost() || !Prefs.AvatarValidate.Value)
			{
				return;
			}
			try
			{
				MethodInfo method = received.GetType().GetMethod("ReadData");
				if (method == null)
				{
					return;
				}
				MethodInfo methodInfo = method.MakeGenericMethod(AccessTools.TypeByName("LabFusion.Network.PlayerRepAvatarData") ?? received.GetType());
				object obj;
				try
				{
					obj = methodInfo.Invoke(received, null);
				}
				catch
				{
					return;
				}
				if (obj == null)
				{
					return;
				}
				string text = (obj.GetType().GetField("Barcode")?.GetValue(obj) as string) ?? (obj.GetType().GetProperty("Barcode")?.GetValue(obj) as string) ?? "";
				object obj3 = obj.GetType().GetField("Stats")?.GetValue(obj) ?? obj.GetType().GetProperty("Stats")?.GetValue(obj);
				float num = ReadFloat(obj3, "vitality", "_vitality", "Vitality");
				float num2 = ReadFloat(obj3, "speed", "_speed", "Speed");
				float num3 = ReadFloat(obj3, "agility", "_agility", "Agility");
				float num4 = ReadFloat(obj3, "strengthUpper", "_strengthUpper", "StrengthUpper", "strength");
				object obj4 = received.GetType().GetProperty("Sender")?.GetValue(received);
				byte b = 0;
				if (obj4 is byte b2)
				{
					b = b2;
				}
				else if (obj4?.GetType().GetProperty("Value")?.GetValue(obj4) is byte b3)
				{
					b = b3;
				}
				string text2 = b.ToString();
				if (FusionApi.TryGetPlayerBySmall(b, out var player))
				{
					text2 = player.Name;
				}
				bool flag = false;
				string text3 = "";
				if (Prefs.IsBarcodeBlocked(text))
				{
					flag = true;
					text3 = "blacklisted barcode " + text;
				}
				if (num > Prefs.MaxVitality.Value)
				{
					flag = true;
					text3 = $"vitality {num:0.00} > {Prefs.MaxVitality.Value:0.00}";
				}
				if (num2 > Prefs.MaxSpeed.Value)
				{
					flag = true;
					text3 = $"speed {num2:0.00} > {Prefs.MaxSpeed.Value:0.00}";
				}
				if (num3 > Prefs.MaxAgility.Value)
				{
					flag = true;
					text3 = $"agility {num3:0.00} > {Prefs.MaxAgility.Value:0.00}";
				}
				if (num4 > Prefs.MaxStrength.Value)
				{
					flag = true;
					text3 = $"strength {num4:0.00} > {Prefs.MaxStrength.Value:0.00}";
				}
				if (flag)
				{
					ViolationLog.Add("avatar", text2 + " — " + text3);
					NetSend.HostCommand(GodCommand.ClampAvatar, b, Prefs.MaxVitality.Value);
					if (Prefs.WarnPlayers.Value)
					{
						NetSend.HostCommand(GodCommand.Announce, b, 0f, 0f, 0f, "Avatar stats rejected: " + text3);
					}
					if ((Prefs.AvatarAction.Value == ViolationAction.Kick || Prefs.KickOnViolation.Value) && FusionApi.TryGetPlayerBySmall(b, out var player2))
					{
						FusionApi.Kick(player2.RawId);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] avatar inspect: " + ex.Message);
			}
		}

		private static float ReadFloat(object obj, params string[] names)
		{
			if (obj == null)
			{
				return 0f;
			}
			Type type = obj.GetType();
			foreach (string name in names)
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object value = field.GetValue(obj);
					if (value is float)
					{
						return (float)value;
					}
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					object value = property.GetValue(obj);
					if (value is float)
					{
						return (float)value;
					}
				}
			}
			return 0f;
		}
	}
	internal static class HealthGuard
	{
		private static bool _enforceGod;

		private static bool _enforceHealth;

		private static float _maxVitality = 3f;

		private static float _nextTick;

		private static int _strikes;

		internal static void ApplyPolicyFromHost(bool godProtect, bool healthProtect, float maxVit)
		{
			_enforceGod = godProtect;
			_enforceHealth = healthProtect;
			if (maxVit > 0f)
			{
				_maxVitality = maxVit;
			}
		}

		internal static void Tick()
		{
			if (!FusionApi.HasServer() || Time.unscaledTime < _nextTick)
			{
				return;
			}
			_nextTick = Time.unscaledTime + 1.25f;
			if (!_enforceGod && !Prefs.GodProtect.Value && !FusionApi.IsHost())
			{
				return;
			}
			bool flag = (FusionApi.IsHost() ? Prefs.GodProtect.Value : _enforceGod);
			bool flag2 = (FusionApi.IsHost() ? Prefs.HealthProtect.Value : _enforceHealth);
			if (!flag && !flag2)
			{
				return;
			}
			try
			{
				RigManager rigManager = Player.RigManager;
				Health val = ((rigManager != null) ? rigManager.health : null);
				if (!((Object)(object)val == (Object)null))
				{
					if (flag)
					{
						ForceMortalSilent(val);
					}
					if (flag2)
					{
						ClampVitality(rigManager, FusionApi.IsHost() ? Prefs.MaxVitality.Value : _maxVitality);
					}
				}
			}
			catch
			{
			}
		}

		internal static void ForceResetHealth()
		{
			try
			{
				Type.GetType("LabFusion.Player.LocalHealth, LabFusion")?.GetMethod("SetFullHealth", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
			}
			catch
			{
			}
		}

		internal static void ForceMortal()
		{
			_enforceGod = true;
			try
			{
				PropertyInfo propertyInfo = Type.GetType("LabFusion.Player.LocalHealth, LabFusion")?.GetProperty("MortalityOverride", BindingFlags.Static | BindingFlags.Public);
				if (propertyInfo != null && propertyInfo.CanWrite)
				{
					propertyInfo.SetValue(null, true);
				}
			}
			catch
			{
			}
			try
			{
				RigManager rigManager = Player.RigManager;
				ForceMortalSilent((rigManager != null) ? rigManager.health : null);
			}
			catch
			{
			}
		}

		internal static void ClampLocalAvatar(float maxVit)
		{
			try
			{
				ClampVitality(Player.RigManager, (maxVit > 0f) ? maxVit : Prefs.MaxVitality.Value);
			}
			catch
			{
			}
		}

		internal static void ReportLocal(string reason)
		{
			_strikes++;
			if (Prefs.LogViolations.Value)
			{
				MelonLogger.Msg("[FusionGod] Local violation: " + reason);
			}
			if (Prefs.WarnPlayers.Value)
			{
				CommandRouter.Notify("Fusion God", reason);
			}
			NetSend.ClientToHost(GodCommand.ViolationReport, reason, _strikes);
		}

		private static void ForceMortalSilent(object healthComp)
		{
			if (healthComp == null)
			{
				return;
			}
			try
			{
				PropertyInfo property = healthComp.GetType().GetProperty("healthMode");
				if (property == null)
				{
					return;
				}
				object value = property.GetValue(healthComp);
				object obj = Enum.Parse(property.PropertyType, "Mortal");
				if (value != null && !value.Equals(obj))
				{
					property.SetValue(healthComp, obj);
					if (!FusionApi.IsHost())
					{
						ReportLocal("healthMode was " + value?.ToString() + " (forced Mortal)");
					}
				}
			}
			catch
			{
			}
		}

		private static void ClampVitality(RigManager rig, float max)
		{
			if ((Object)(object)((rig != null) ? rig.avatar : null) == (Object)null)
			{
				return;
			}
			try
			{
				FieldInfo field = ((object)rig.avatar).GetType().GetField("_vitality", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null) && field.GetValue(rig.avatar) is float num && num > max)
				{
					field.SetValue(rig.avatar, max);
					Health health = rig.health;
					if (health != null)
					{
						health.SetAvatar(rig.avatar);
					}
					if (!FusionApi.IsHost())
					{
						ReportLocal($"vitality {num:0.00} > {max:0.00}");
					}
				}
			}
			catch
			{
			}
		}
	}
	internal static class KillWatch
	{
		private class Pending
		{
			public byte SmallId;

			public ulong PlatformId;

			public string Name;

			public object RawId;

			public float Due;
		}

		private static readonly List<Pending> _pending = new List<Pending>();

		internal static void Watch(LobbyPlayer player)
		{
			if (!player.IsMe)
			{
				_pending.Add(new Pending
				{
					SmallId = player.SmallId,
					PlatformId = player.PlatformId,
					Name = player.Name,
					RawId = player.RawId,
					Due = Time.unscaledTime + 2.4f
				});
			}
		}

		internal static void Tick()
		{
			if (_pending.Count == 0)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			for (int num = _pending.Count - 1; num >= 0; num--)
			{
				Pending pending = _pending[num];
				if (!(unscaledTime < pending.Due))
				{
					_pending.RemoveAt(num);
					bool flag = false;
					foreach (LobbyPlayer item in FusionApi.Players())
					{
						if (item.SmallId == pending.SmallId || item.PlatformId == pending.PlatformId)
						{
							flag = true;
							pending.RawId = item.RawId;
							pending.Name = item.Name;
							break;
						}
					}
					if (flag)
					{
						ViolationLog.Add("godmode?", pending.Name + " ignored a host kill (likely god mode / no FusionGod).");
						CommandRouter.Notify("Fusion God", pending.Name + " ignored kill — likely god mode.");
						if (Prefs.KickOnViolation.Value)
						{
							FusionApi.Kick(pending.RawId);
							ViolationLog.Add("kick", "Auto-kicked " + pending.Name + " for ignored kill.");
							CommandRouter.Notify("Fusion God", "Kicked " + pending.Name);
						}
					}
				}
			}
		}
	}
	internal static class ViolationLog
	{
		internal static readonly List<string> Lines = new List<string>();

		internal static void Load()
		{
		}

		internal static void Add(string kind, string message)
		{
			string text = $"[{DateTime.Now:HH:mm:ss}] {kind}: {message}";
			Lines.Insert(0, text);
			if (Lines.Count > 40)
			{
				Lines.RemoveAt(Lines.Count - 1);
			}
			if (Prefs.LogViolations.Value)
			{
				MelonLogger.Msg("[FusionGod] " + text);
			}
		}

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

		internal static List<string> Latest(int count)
		{
			if (count >= Lines.Count)
			{
				return new List<string>(Lines);
			}
			return Lines.GetRange(0, count);
		}
	}
	internal static class CommandRouter
	{
		internal static void HandleHostIncoming(GodCommandData data)
		{
			GodCommand command = (GodCommand)data.Command;
			string text = "id " + data.SenderSmallId;
			if (FusionApi.TryGetPlayerBySmall(data.SenderSmallId, out var player))
			{
				text = player.Name;
			}
			switch (command)
			{
			case GodCommand.Presence:
				Presence.Mark(data.SenderSmallId);
				ViolationLog.Add("presence", text + " is running FusionGod");
				break;
			case GodCommand.ViolationReport:
			{
				ViolationLog.Add("client-report", text + ": " + data.Text);
				if (Prefs.KickOnViolation.Value && FusionApi.TryGetPlayerBySmall(data.SenderSmallId, out var player2))
				{
					FusionApi.Kick(player2.RawId);
				}
				break;
			}
			}
		}

		internal static void HandleClientIncoming(GodCommandData data)
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			GodCommand command = (GodCommand)data.Command;
			byte b = FusionApi.LocalSmallId();
			if (data.TargetSmallId == byte.MaxValue || data.TargetSmallId == b || command == GodCommand.EnforcePolicy || command == GodCommand.Announce || command == GodCommand.Jumpscare)
			{
				switch (command)
				{
				case GodCommand.EnforcePolicy:
					HealthGuard.ApplyPolicyFromHost(data.A > 0.5f, data.B > 0.5f, data.C);
					break;
				case GodCommand.ResetHealth:
					HealthGuard.ForceResetHealth();
					Notify("Fusion God", "Host reset your health.");
					break;
				case GodCommand.ForceMortal:
					HealthGuard.ForceMortal();
					Notify("Fusion God", "Host forced mortal health.");
					break;
				case GodCommand.Kill:
					LocalEffects.KillLocal();
					break;
				case GodCommand.Respawn:
					LocalEffects.RespawnLocal();
					break;
				case GodCommand.Freeze:
					LocalEffects.Frozen = true;
					Notify("Fusion God", "Frozen by host.");
					break;
				case GodCommand.Unfreeze:
					LocalEffects.Frozen = false;
					Notify("Fusion God", "Unfrozen.");
					break;
				case GodCommand.TeleportTo:
					LocalEffects.TeleportTo(new Vector3(data.A, data.B, data.C));
					break;
				case GodCommand.Launch:
					LocalEffects.Launch((data.A <= 0f) ? 12f : data.A);
					break;
				case GodCommand.Scale:
					LocalEffects.SetScale((data.A <= 0f) ? 1f : data.A, Prefs.EffectSeconds.Value);
					break;
				case GodCommand.Gravity:
					LocalEffects.SetGravity(new Vector3(0f, data.A, 0f), Prefs.EffectSeconds.Value);
					break;
				case GodCommand.Spin:
					LocalEffects.Spin(Prefs.EffectSeconds.Value);
					break;
				case GodCommand.SlowMo:
					LocalEffects.SlowMo((data.A <= 0f) ? 0.35f : data.A, Prefs.EffectSeconds.Value);
					break;
				case GodCommand.Slippery:
					LocalEffects.Slippery(Prefs.EffectSeconds.Value);
					break;
				case GodCommand.Jumpscare:
					LocalEffects.Jumpscare(string.IsNullOrEmpty(data.Text) ? "BEHIND YOU" : data.Text);
					break;
				case GodCommand.Announce:
					Notify("SERVER", string.IsNullOrEmpty(data.Text) ? "Host announcement" : data.Text);
					break;
				case GodCommand.RandomTeleport:
					LocalEffects.RandomTeleport((data.A <= 0f) ? 8f : data.A);
					break;
				case GodCommand.ClearEffects:
					LocalEffects.Clear();
					Notify("Fusion God", "Effects cleared.");
					break;
				case GodCommand.ClampAvatar:
					HealthGuard.ClampLocalAvatar(data.A);
					break;
				}
			}
		}

		internal static void Notify(string title, string message)
		{
			MelonLogger.Msg("[FusionGod] " + title + ": " + message);
			try
			{
				Type type = Type.GetType("BoneLib.Notifications.Notification, BoneLib");
				Type type2 = Type.GetType("BoneLib.Notifications.Notifier, BoneLib");
				if (!(type == null) && !(type2 == null))
				{
					object obj = Activator.CreateInstance(type);
					type.GetProperty("Title")?.SetValue(obj, title);
					type.GetProperty("Message")?.SetValue(obj, message);
					type.GetProperty("ShowPopup")?.SetValue(obj, true);
					type2.GetMethod("Send", new Type[1] { type })?.Invoke(null, new object[1] { obj });
				}
			}
			catch
			{
			}
		}
	}
	internal static class LocalEffects
	{
		internal static bool Frozen;

		private static float _scaleUntil;

		private static float _gravUntil;

		private static float _spinUntil;

		private static float _slowUntil;

		private static float _slipUntil;

		private static float _targetScale = 1f;

		private static Vector3 _savedGravity;

		private static bool _gravSaved;

		private static float _savedTimeScale = 1f;

		internal static void Tick()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!FusionApi.HasServer())
			{
				if (Frozen || _scaleUntil > 0f)
				{
					Clear();
				}
				return;
			}
			float unscaledTime = Time.unscaledTime;
			RigManager rig = GetRig();
			if (Frozen && (Object)(object)rig != (Object)null)
			{
				try
				{
					PhysicsRig physicsRig = rig.physicsRig;
					if ((Object)(object)physicsRig != (Object)null)
					{
						ZeroRb(((Component)physicsRig).gameObject);
					}
				}
				catch
				{
				}
			}
			if (_scaleUntil > 0f && unscaledTime > _scaleUntil)
			{
				ApplyScale(1f);
				_scaleUntil = 0f;
				_targetScale = 1f;
			}
			else if (_scaleUntil > 0f)
			{
				ApplyScale(_targetScale);
			}
			if (_gravUntil > 0f && unscaledTime > _gravUntil)
			{
				if (_gravSaved)
				{
					Physics.gravity = _savedGravity;
				}
				_gravUntil = 0f;
			}
			if (_spinUntil > 0f)
			{
				if (unscaledTime > _spinUntil)
				{
					_spinUntil = 0f;
				}
				else if ((Object)(object)rig != (Object)null)
				{
					try
					{
						((Component)rig.physicsRig).transform.Rotate(0f, 720f * Time.deltaTime, 0f, (Space)0);
					}
					catch
					{
					}
				}
			}
			if (_slowUntil > 0f && unscaledTime > _slowUntil)
			{
				Time.timeScale = ((_savedTimeScale <= 0f) ? 1f : _savedTimeScale);
				_slowUntil = 0f;
			}
			if (_slipUntil > 0f && unscaledTime > _slipUntil)
			{
				_slipUntil = 0f;
			}
		}

		internal static void Clear()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Frozen = false;
			_scaleUntil = 0f;
			_spinUntil = 0f;
			_slipUntil = 0f;
			ApplyScale(1f);
			if (_gravUntil > 0f && _gravSaved)
			{
				Physics.gravity = _savedGravity;
			}
			_gravUntil = 0f;
			if (_slowUntil > 0f)
			{
				Time.timeScale = ((_savedTimeScale <= 0f) ? 1f : _savedTimeScale);
			}
			_slowUntil = 0f;
		}

		internal static void KillLocal()
		{
			try
			{
				RigManager rigManager = Player.RigManager;
				Health val = ((rigManager != null) ? rigManager.health : null);
				if (!((Object)(object)val == (Object)null))
				{
					((object)val).GetType().GetMethod("ApplyKillDamage", BindingFlags.Instance | BindingFlags.Public)?.Invoke(val, null);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] KillLocal: " + ex.Message);
			}
		}

		internal static void RespawnLocal()
		{
			try
			{
				Type? type = Type.GetType("LabFusion.Player.LocalHealth, LabFusion");
				type?.GetMethod("InvokeRespawn", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(null, null);
				type?.GetMethod("SetFullHealth", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
			}
			catch
			{
			}
			try
			{
				Type.GetType("LabFusion.Player.LocalPlayer, LabFusion")?.GetMethod("TeleportToCheckpoint", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
			}
			catch
			{
			}
		}

		internal static void TeleportTo(Vector3 pos)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RigManager rig = GetRig();
				if (!((Object)(object)((rig != null) ? rig.physicsRig : null) == (Object)null))
				{
					((Component)rig.physicsRig).transform.position = pos;
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Teleport: " + ex.Message);
			}
		}

		internal static void Launch(float force)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RigManager rig = GetRig();
				if ((Object)(object)((rig != null) ? rig.physicsRig : null) == (Object)null)
				{
					return;
				}
				foreach (Rigidbody componentsInChild in ((Component)rig.physicsRig).GetComponentsInChildren<Rigidbody>())
				{
					if (!((Object)(object)componentsInChild == (Object)null))
					{
						componentsInChild.velocity = new Vector3(componentsInChild.velocity.x, force, componentsInChild.velocity.z);
					}
				}
			}
			catch
			{
			}
		}

		internal static void SetScale(float scale, float seconds)
		{
			_targetScale = Mathf.Clamp(scale, 0.15f, 8f);
			_scaleUntil = Time.unscaledTime + seconds;
			ApplyScale(_targetScale);
		}

		internal static void SetGravity(Vector3 g, float seconds)
		{
			//IL_0017: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!_gravSaved)
			{
				_savedGravity = Physics.gravity;
				_gravSaved = true;
			}
			Physics.gravity = g;
			_gravUntil = Time.unscaledTime + seconds;
		}

		internal static void Spin(float seconds)
		{
			_spinUntil = Time.unscaledTime + seconds;
		}

		internal static void SlowMo(float scale, float seconds)
		{
			if (_slowUntil <= 0f)
			{
				_savedTimeScale = Time.timeScale;
			}
			Time.timeScale = Mathf.Clamp(scale, 0.05f, 1f);
			_slowUntil = Time.unscaledTime + seconds;
		}

		internal static void Slippery(float seconds)
		{
			_slipUntil = Time.unscaledTime + seconds;
		}

		internal static void RandomTeleport(float radius)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			RigManager rig = GetRig();
			if (!((Object)(object)((rig != null) ? rig.physicsRig : null) == (Object)null))
			{
				Vector3 position = ((Component)rig.physicsRig).transform.position;
				Vector3 val = Random.insideUnitSphere * radius;
				val.y = Mathf.Abs(val.y) + 0.5f;
				TeleportTo(position + val);
			}
		}

		internal static void Jumpscare(string text)
		{
			CommandRouter.Notify("⚠ " + text, "FUSION GOD");
			SlowMo(0.2f, Prefs.JumpscareSeconds.Value);
		}

		private static void ApplyScale(float scale)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RigManager rig = GetRig();
				if (!((Object)(object)rig == (Object)null))
				{
					((Component)rig).transform.localScale = new Vector3(scale, scale, scale);
				}
			}
			catch
			{
			}
		}

		private static void ZeroRb(GameObject go)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			foreach (Rigidbody componentsInChild in go.GetComponentsInChildren<Rigidbody>())
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					componentsInChild.velocity = Vector3.zero;
					componentsInChild.angularVelocity = Vector3.zero;
				}
			}
		}

		private static RigManager GetRig()
		{
			try
			{
				return Player.RigManager;
			}
			catch
			{
				return null;
			}
		}
	}
	internal static class PuppetFx
	{
		internal static void Apply(byte smallId, GodCommand cmd, float a, float b, float c)
		{
			//IL_0059: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform val = FindRig(smallId);
				if (!((Object)(object)val == (Object)null))
				{
					switch (cmd)
					{
					case GodCommand.Launch:
						Yeet(val, (a <= 0f) ? 14f : a);
						break;
					case GodCommand.Scale:
						val.localScale = Vector3.one * Mathf.Clamp((a <= 0f) ? 1f : a, 0.15f, 8f);
						break;
					case GodCommand.Spin:
						val.Rotate(0f, 180f, 0f, (Space)0);
						break;
					case GodCommand.Freeze:
						Zero(val);
						break;
					case GodCommand.ClearEffects:
						val.localScale = Vector3.one;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] PuppetFx: " + ex.Message);
			}
		}

		internal static bool TryGetPosition(byte smallId, out Vector3 pos)
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			pos = Vector3.zero;
			Transform val = FindRig(smallId);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			pos = val.position;
			return true;
		}

		private static Transform FindRig(byte smallId)
		{
			object obj = (Type.GetType("LabFusion.Entities.NetworkPlayerManager, LabFusion")?.GetProperty("Players", BindingFlags.Static | BindingFlags.Public))?.GetValue(null);
			if (obj == null)
			{
				return null;
			}
			foreach (object item in (IEnumerable)obj)
			{
				if (item == null)
				{
					continue;
				}
				object obj2 = item.GetType().GetProperty("PlayerID")?.GetValue(item) ?? item.GetType().GetField("PlayerID")?.GetValue(item);
				byte b = 0;
				if (obj2 != null && obj2.GetType().GetProperty("SmallID")?.GetValue(obj2) is byte b2)
				{
					b = b2;
				}
				if (b == smallId)
				{
					object obj3 = item.GetType().GetProperty("RigRefs")?.GetValue(item) ?? item.GetType().GetField("RigRefs")?.GetValue(item);
					object? obj4 = obj3?.GetType().GetProperty("RigManager")?.GetValue(obj3) ?? item.GetType().GetProperty("RigManager")?.GetValue(item);
					Component val = (Component)((obj4 is Component) ? obj4 : null);
					if (val != null)
					{
						return val.transform;
					}
				}
			}
			return null;
		}

		private static void Yeet(Transform t, float force)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			foreach (Rigidbody componentsInChild in ((Component)t).GetComponentsInChildren<Rigidbody>())
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					componentsInChild.velocity = new Vector3(componentsInChild.velocity.x, force, componentsInChild.velocity.z);
				}
			}
		}

		private static void Zero(Transform t)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			foreach (Rigidbody componentsInChild in ((Component)t).GetComponentsInChildren<Rigidbody>())
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					componentsInChild.velocity = Vector3.zero;
					componentsInChild.angularVelocity = Vector3.zero;
				}
			}
		}
	}
	internal struct LobbyPlayer
	{
		public ulong PlatformId;

		public byte SmallId;

		public string Name;

		public bool IsMe;

		public bool IsHost;

		public object RawId;
	}
	internal static class FusionApi
	{
		internal static bool HasServer()
		{
			try
			{
				return NetworkInfo.HasServer;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsHost()
		{
			try
			{
				return NetworkInfo.IsHost;
			}
			catch
			{
				return false;
			}
		}

		internal static byte LocalSmallId()
		{
			try
			{
				Type type = Type.GetType("LabFusion.Player.PlayerIDManager, LabFusion");
				object obj = (type?.GetProperty("LocalSmallID", BindingFlags.Static | BindingFlags.Public) ?? type?.GetProperty("LocalSmallId", BindingFlags.Static | BindingFlags.Public))?.GetValue(null);
				if (obj is byte)
				{
					return (byte)obj;
				}
			}
			catch
			{
			}
			return 0;
		}

		internal static IEnumerable<LobbyPlayer> Players()
		{
			List<LobbyPlayer> list = new List<LobbyPlayer>();
			if (!HasServer())
			{
				return list;
			}
			try
			{
				foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
				{
					if (playerID != null && playerID.IsValid)
					{
						list.Add(new LobbyPlayer
						{
							PlatformId = playerID.PlatformID,
							SmallId = playerID.SmallID,
							Name = DisplayName(playerID),
							IsMe = playerID.IsMe,
							IsHost = playerID.IsHost,
							RawId = playerID
						});
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] player list: " + ex.Message);
			}
			return list;
		}

		internal static string DisplayName(object playerId)
		{
			if (playerId == null)
			{
				return "Unknown";
			}
			try
			{
				MethodInfo method = playerId.GetType().GetMethod("TryGetDisplayName");
				if (method != null)
				{
					object[] array = new object[1];
					object obj = method.Invoke(playerId, array);
					bool flag = default(bool);
					int num;
					if (obj is bool)
					{
						flag = (bool)obj;
						num = 1;
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0 && array[0] is string text && !string.IsNullOrWhiteSpace(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			try
			{
				PlayerID val = (PlayerID)((playerId is PlayerID) ? playerId : null);
				if (val != null)
				{
					return val.PlatformID.ToString();
				}
			}
			catch
			{
			}
			return "Unknown";
		}

		internal static void Kick(object playerId)
		{
			if (playerId == null || !IsHost())
			{
				return;
			}
			try
			{
				PlayerID val = (PlayerID)((playerId is PlayerID) ? playerId : null);
				if (val != null)
				{
					NetworkHelper.KickUser(val);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Kick failed: " + ex.Message);
			}
		}

		internal static Vector3 HostHeadPosition()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager != (Object)null && (Object)(object)rigManager.physicsRig != (Object)null)
				{
					return ((Rig)rigManager.physicsRig).m_head.position + Vector3.up * 0.2f;
				}
			}
			catch
			{
			}
			return Vector3.zero;
		}

		internal static bool TryGetPlayerBySmall(byte small, out LobbyPlayer player)
		{
			foreach (LobbyPlayer item in Players())
			{
				if (item.SmallId == small)
				{
					player = item;
					return true;
				}
			}
			player = default(LobbyPlayer);
			return false;
		}
	}
	public class FusionGodMod : MelonMod
	{
		internal static FusionGodMod Instance { get; private set; }

		internal static bool FusionPresent { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			FusionPresent = HelperMethods.CheckIfAssemblyLoaded("LabFusion");
			Prefs.Load();
			ViolationLog.Load();
			GodMenu.Create();
			if (!FusionPresent)
			{
				((MelonBase)this).LoggerInstance.Warning("[FusionGod] LabFusion not found. Menu will stay locked until Fusion loads.");
				return;
			}
			try
			{
				FusionHooks.Init(((MelonBase)this).HarmonyInstance);
				GodModule.Register();
				((MelonBase)this).LoggerInstance.Msg("[FusionGod] Fusion hooks ready. Module registered=" + GodModule.Registered);
			}
			catch (Exception value)
			{
				((MelonBase)this).LoggerInstance.Error($"[FusionGod] Init failed: {value}");
			}
		}

		public override void OnUpdate()
		{
			if (FusionPresent)
			{
				LocalEffects.Tick();
				HealthGuard.Tick();
				KillWatch.Tick();
				GodOverlay.Tick();
			}
		}

		public override void OnDeinitializeMelon()
		{
			Prefs.Save();
		}
	}
	public static class ModInfo
	{
		public const string Name = "FusionGod";

		public const string Author = "JoshSievers24";

		public const string Version = "1.2.0";
	}
	public enum ViolationAction
	{
		LogOnly,
		Warn,
		Reset,
		Kick
	}
	internal static class Prefs
	{
		private static MelonPreferences_Category _cat;

		internal static MelonPreferences_Entry<bool> HealthProtect;

		internal static MelonPreferences_Entry<bool> GodProtect;

		internal static MelonPreferences_Entry<bool> AvatarValidate;

		internal static MelonPreferences_Entry<bool> KickOnViolation;

		internal static MelonPreferences_Entry<bool> WarnPlayers;

		internal static MelonPreferences_Entry<bool> LogViolations;

		internal static MelonPreferences_Entry<ViolationAction> HealthAction;

		internal static MelonPreferences_Entry<ViolationAction> AvatarAction;

		internal static MelonPreferences_Entry<float> MaxVitality;

		internal static MelonPreferences_Entry<float> MaxSpeed;

		internal static MelonPreferences_Entry<float> MaxAgility;

		internal static MelonPreferences_Entry<float> MaxStrength;

		internal static MelonPreferences_Entry<float> CommandCooldown;

		internal static MelonPreferences_Entry<bool> FunEnabled;

		internal static MelonPreferences_Entry<float> JumpscareSeconds;

		internal static MelonPreferences_Entry<float> EffectSeconds;

		internal static MelonPreferences_Entry<string> AvatarBarcodeBlacklist;

		internal static void Load()
		{
			_cat = MelonPreferences.CreateCategory("FusionGod", "Fusion God");
			HealthProtect = _cat.CreateEntry<bool>("HealthProtect", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			GodProtect = _cat.CreateEntry<bool>("GodProtect", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			AvatarValidate = _cat.CreateEntry<bool>("AvatarValidate", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			KickOnViolation = _cat.CreateEntry<bool>("KickOnViolation", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			WarnPlayers = _cat.CreateEntry<bool>("WarnPlayers", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			LogViolations = _cat.CreateEntry<bool>("LogViolations", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			HealthAction = _cat.CreateEntry<ViolationAction>("HealthAction", ViolationAction.Reset, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			AvatarAction = _cat.CreateEntry<ViolationAction>("AvatarAction", ViolationAction.Warn, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MaxVitality = _cat.CreateEntry<float>("MaxVitality", 3f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MaxSpeed = _cat.CreateEntry<float>("MaxSpeed", 4f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MaxAgility = _cat.CreateEntry<float>("MaxAgility", 4f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MaxStrength = _cat.CreateEntry<float>("MaxStrength", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			CommandCooldown = _cat.CreateEntry<float>("CommandCooldown", 1.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			FunEnabled = _cat.CreateEntry<bool>("FunEnabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			JumpscareSeconds = _cat.CreateEntry<float>("JumpscareSeconds", 2.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			EffectSeconds = _cat.CreateEntry<float>("EffectSeconds", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			AvatarBarcodeBlacklist = _cat.CreateEntry<string>("AvatarBarcodeBlacklist", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MelonPreferences.Save();
		}

		internal static void Save()
		{
			MelonPreferences.Save();
		}

		internal static bool IsBarcodeBlocked(string barcode)
		{
			if (string.IsNullOrWhiteSpace(barcode) || string.IsNullOrWhiteSpace(AvatarBarcodeBlacklist.Value))
			{
				return false;
			}
			string[] array = AvatarBarcodeBlacklist.Value.Split(new char[3] { ',', ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				if (barcode.IndexOf(text.Trim(), StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal enum GodCommand : byte
	{
		Presence = 1,
		EnforcePolicy,
		ResetHealth,
		ForceMortal,
		Kill,
		Respawn,
		Freeze,
		Unfreeze,
		TeleportTo,
		Launch,
		Scale,
		Gravity,
		Spin,
		SlowMo,
		Slippery,
		Jumpscare,
		Announce,
		RandomTeleport,
		ClearEffects,
		ClampAvatar,
		ViolationReport
	}
	public class GodCommandData : INetSerializable
	{
		public byte Command;

		public byte TargetSmallId;

		public byte SenderSmallId;

		public float A;

		public float B;

		public float C;

		public string Text;

		public int? GetSize()
		{
			return 19 + ((Text != null) ? (Text.Length * 2 + 4) : 4);
		}

		public void Serialize(INetSerializer serializer)
		{
			serializer.SerializeValue(ref Command);
			serializer.SerializeValue(ref TargetSmallId);
			serializer.SerializeValue(ref SenderSmallId);
			serializer.SerializeValue(ref A);
			serializer.SerializeValue(ref B);
			serializer.SerializeValue(ref C);
			serializer.SerializeValue(ref Text);
		}
	}
	public class GodCommandMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			GodCommandData godCommandData;
			try
			{
				godCommandData = ((ReceivedMessage)(ref received)).ReadData<GodCommandData>();
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Bad packet: " + ex.Message);
				return;
			}
			if (godCommandData == null)
			{
				return;
			}
			GodCommand command = (GodCommand)godCommandData.Command;
			bool flag;
			try
			{
				flag = IsHostSender(((ReceivedMessage)(ref received)).Sender, godCommandData.SenderSmallId);
			}
			catch
			{
				flag = FusionApi.IsHost();
			}
			if (command == GodCommand.Presence || command == GodCommand.ViolationReport)
			{
				if (FusionApi.IsHost())
				{
					CommandRouter.HandleHostIncoming(godCommandData);
				}
			}
			else if (!flag)
			{
				MelonLogger.Warning("[FusionGod] Dropped non-host admin packet: " + command);
			}
			else
			{
				CommandRouter.HandleClientIncoming(godCommandData);
			}
		}

		private static bool IsHostSender(object sender, byte claimed)
		{
			try
			{
				if (FusionApi.IsHost() && claimed == FusionApi.LocalSmallId())
				{
					return true;
				}
				byte? b = null;
				if (sender is byte value)
				{
					b = value;
				}
				else if (sender != null)
				{
					PropertyInfo property = sender.GetType().GetProperty("HasValue");
					bool flag = default(bool);
					int num;
					if (property != null)
					{
						object value2 = property.GetValue(sender);
						if (value2 is bool)
						{
							flag = (bool)value2;
							num = 1;
						}
						else
						{
							num = 0;
						}
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0 && sender.GetType().GetProperty("Value")?.GetValue(sender) is byte value3)
					{
						b = value3;
					}
					if (sender.GetType().GetProperty("SmallID")?.GetValue(sender) is byte value4)
					{
						b = value4;
					}
				}
				if (!b.HasValue)
				{
					return claimed == 0;
				}
				if (FusionApi.TryGetPlayerBySmall(b.Value, out var player))
				{
					return player.IsHost;
				}
				return b.Value == 0;
			}
			catch
			{
				return false;
			}
		}
	}
	public class GodModule : Module
	{
		internal static bool Registered;

		public override string Name => "FusionGod";

		public override string Author => "JoshSievers24";

		public override Version Version => new Version(1, 1, 0);

		public override ConsoleColor Color => ConsoleColor.Magenta;

		protected override void OnModuleRegistered()
		{
			try
			{
				ModuleMessageManager.RegisterHandler<GodCommandMessage>();
				Registered = true;
				MelonLogger.Msg("[FusionGod] Module registered. Other FusionGod clients can receive commands.");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[FusionGod] RegisterHandler failed: " + ex);
			}
		}

		internal static void Register()
		{
			try
			{
				ModuleManager.RegisterModule<GodModule>();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[FusionGod] ModuleManager.RegisterModule failed: " + ex);
			}
		}
	}
	internal static class NativeBridge
	{
		internal static bool TryTeleport(byte targetSmallId, Vector3 worldPos)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type type = Type.GetType("LabFusion.Network.PlayerRepTeleportData, LabFusion");
				Type type2 = Type.GetType("LabFusion.Network.NativeMessageTag, LabFusion");
				Type type3 = Type.GetType("LabFusion.Network.MessageRelay, LabFusion");
				if (type == null || type2 == null || type3 == null)
				{
					return false;
				}
				object obj = Activator.CreateInstance(type);
				if ((object)type.GetField("Position") == null)
				{
					type.GetProperty("Position");
				}
				SetMember(obj, "Position", worldPos);
				object tag = GetTag(type2, "PlayerRepTeleport");
				if (tag == null)
				{
					return false;
				}
				MessageRoute val = default(MessageRoute);
				((MessageRoute)(ref val))..ctor(targetSmallId, (NetworkChannel)0);
				if (type3.GetMethod("RelayNative", BindingFlags.Static | BindingFlags.Public) == null)
				{
					return false;
				}
				MethodInfo[] methods = type3.GetMethods(BindingFlags.Static | BindingFlags.Public);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name != "RelayNative" || methodInfo.GetParameters().Length < 3)
					{
						continue;
					}
					try
					{
						if (methodInfo.IsGenericMethodDefinition)
						{
							methodInfo.MakeGenericMethod(type).Invoke(null, new object[3] { obj, tag, val });
						}
						else
						{
							methodInfo.Invoke(null, new object[3] { obj, tag, val });
						}
						return true;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Native teleport: " + ex.Message);
			}
			return false;
		}

		internal static bool TryKill(byte targetSmallId)
		{
			return (byte)(0u | (TryRelayNative("LabFusion.Network.PlayerRepDamageData, LabFusion", "PlayerRepDamage", targetSmallId, delegate(object data)
			{
				TrySetDamage(data, 9999f);
			}) ? 1u : 0u) | (TryRelayNative("LabFusion.Network.PlayerRepActionData, LabFusion", "PlayerRepAction", targetSmallId, delegate(object data)
			{
				SetMember(data, "Type", FindEnum("LabFusion.Senders.PlayerActionType, LabFusion", "DEATH"));
				SetMember(data, "OtherPlayer", targetSmallId);
			}) ? 1u : 0u)) != 0;
		}

		private static void TrySetDamage(object data, float amount)
		{
			Type type = data.GetType();
			string[] array = new string[3] { "Damage", "damage", "Amount" };
			foreach (string name in array)
			{
				FieldInfo field = type.GetField(name);
				if (field != null && (field.FieldType == typeof(float) || field.FieldType == typeof(int)))
				{
					field.SetValue(data, amount);
					return;
				}
			}
			FieldInfo fieldInfo = type.GetField("Attack") ?? type.GetField("attack");
			if (fieldInfo == null)
			{
				return;
			}
			object obj = fieldInfo.GetValue(data);
			if (obj == null)
			{
				try
				{
					obj = Activator.CreateInstance(fieldInfo.FieldType);
				}
				catch
				{
					return;
				}
				fieldInfo.SetValue(data, obj);
			}
			array = new string[4] { "damage", "Damage", "attackDamage", "AttackDamage" };
			foreach (string name2 in array)
			{
				FieldInfo field2 = obj.GetType().GetField(name2);
				if (field2 != null)
				{
					try
					{
						field2.SetValue(obj, Convert.ChangeType(amount, field2.FieldType));
					}
					catch
					{
					}
				}
				PropertyInfo property = obj.GetType().GetProperty(name2);
				if (property != null && property.CanWrite)
				{
					try
					{
						property.SetValue(obj, Convert.ChangeType(amount, property.PropertyType));
					}
					catch
					{
					}
				}
			}
			if ((object)obj.GetType().GetProperty("Attack") == null)
			{
				obj.GetType().GetField("Attack");
			}
		}

		private static object FindEnum(string typeName, string value)
		{
			Type type = Type.GetType(typeName);
			if (type == null || !type.IsEnum)
			{
				return 3;
			}
			try
			{
				return Enum.Parse(type, value);
			}
			catch
			{
				return 3;
			}
		}

		private static bool TryRelayNative(string dataTypeName, string tagName, byte targetSmallId, Action<object> fill)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type type = Type.GetType(dataTypeName);
				Type type2 = Type.GetType("LabFusion.Network.NativeMessageTag, LabFusion");
				Type type3 = Type.GetType("LabFusion.Network.MessageRelay, LabFusion");
				if (type == null || type2 == null || type3 == null)
				{
					return false;
				}
				object obj = Activator.CreateInstance(type);
				fill?.Invoke(obj);
				object tag = GetTag(type2, tagName);
				if (tag == null)
				{
					return false;
				}
				MessageRoute val = default(MessageRoute);
				((MessageRoute)(ref val))..ctor(targetSmallId, (NetworkChannel)0);
				MethodInfo[] methods = type3.GetMethods(BindingFlags.Static | BindingFlags.Public);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name != "RelayNative")
					{
						continue;
					}
					try
					{
						if (methodInfo.IsGenericMethodDefinition)
						{
							methodInfo.MakeGenericMethod(type).Invoke(null, new object[3] { obj, tag, val });
						}
						else
						{
							methodInfo.Invoke(null, new object[3] { obj, tag, val });
						}
						return true;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Native " + tagName + ": " + ex.Message);
			}
			return false;
		}

		internal static bool TryRagdollVisual(byte ownerSmallId, bool enabled)
		{
			return false;
		}

		private static object GetTag(Type tagType, string name)
		{
			return tagType.GetField(name, BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
		}

		private static void SetMember(object obj, string name, object value)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(name);
			if (field != null)
			{
				field.SetValue(obj, value);
				return;
			}
			PropertyInfo property = type.GetProperty(name);
			if (property != null && property.CanWrite)
			{
				property.SetValue(obj, value);
			}
		}
	}
	internal static class NetSend
	{
		internal const byte AllPlayers = byte.MaxValue;

		internal static void HostCommand(GodCommand cmd, byte target, float a = 0f, float b = 0f, float c = 0f, string text = "")
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!FusionApi.IsHost())
			{
				CommandRouter.Notify("Fusion God", "Only the host can do that.");
				return;
			}
			GodCommandData godCommandData = new GodCommandData
			{
				Command = (byte)cmd,
				TargetSmallId = target,
				SenderSmallId = FusionApi.LocalSmallId(),
				A = a,
				B = b,
				C = c,
				Text = (text ?? "")
			};
			byte b2 = FusionApi.LocalSmallId();
			bool flag = target == byte.MaxValue || target == b2;
			SendNativeHelpers(cmd, target, a, b, c);
			try
			{
				if (target == byte.MaxValue)
				{
					MessageRelay.RelayModule<GodCommandMessage, GodCommandData>(godCommandData, new MessageRoute((RelayType)3, (NetworkChannel)0));
				}
				else if (target != b2)
				{
					MessageRelay.RelayModule<GodCommandMessage, GodCommandData>(godCommandData, new MessageRoute(target, (NetworkChannel)0));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[FusionGod] Module relay failed: " + ex.Message);
			}
			if (flag)
			{
				CommandRouter.HandleClientIncoming(godCommandData);
			}
			ApplyPuppets(cmd, target, a, b, c, b2);
		}

		private static void SendNativeHelpers(GodCommand cmd, byte target, float a, float b, float c)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			switch (cmd)
			{
			case GodCommand.TeleportTo:
			{
				Vector3 pos = new Vector3(a, b, c);
				ForTargets(target, delegate(LobbyPlayer p)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					NativeBridge.TryTeleport(p.SmallId, pos);
				});
				break;
			}
			case GodCommand.Kill:
				ForTargets(target, delegate(LobbyPlayer p)
				{
					NativeBridge.TryKill(p.SmallId);
					KillWatch.Watch(p);
				});
				break;
			}
		}

		private static void ForTargets(byte target, Action<LobbyPlayer> fn)
		{
			foreach (LobbyPlayer item in FusionApi.Players())
			{
				if (!item.IsMe && (target == byte.MaxValue || item.SmallId == target))
				{
					fn(item);
				}
			}
		}

		private static void ApplyPuppets(GodCommand cmd, byte target, float a, float b, float c, byte me)
		{
			if (target == byte.MaxValue)
			{
				foreach (LobbyPlayer item in FusionApi.Players())
				{
					if (!item.IsMe)
					{
						PuppetFx.Apply(item.SmallId, cmd, a, b, c);
					}
				}
				return;
			}
			if (target != me)
			{
				PuppetFx.Apply(target, cmd, a, b, c);
			}
		}

		internal static void ClientToHost(GodCommand cmd, string text = "", float a = 0f)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!FusionApi.HasServer())
			{
				return;
			}
			GodCommandData godCommandData = new GodCommandData
			{
				Command = (byte)cmd,
				TargetSmallId = 0,
				SenderSmallId = FusionApi.LocalSmallId(),
				A = a,
				Text = (text ?? "")
			};
			try
			{
				MessageRelay.RelayModule<GodCommandMessage, GodCommandData>(godCommandData, new MessageRoute((RelayType)1, (NetworkChannel)0));
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[FusionGod] Report failed: " + ex.Message);
			}
		}
	}
	internal static class Presence
	{
		private static readonly HashSet<byte> _clients = new HashSet<byte>();

		internal static int Count => _clients.Count;

		internal static void Mark(byte smallId)
		{
			_clients.Add(smallId);
		}

		internal static void Forget(byte smallId)
		{
			_clients.Remove(smallId);
		}

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

		internal static bool HasMod(byte smallId)
		{
			if (smallId == FusionApi.LocalSmallId())
			{
				return true;
			}
			return _clients.Contains(smallId);
		}
	}
	internal static class GodMenu
	{
		private static Page _root;

		private static Page _players;

		private static Page _anticheat;

		private static Page _avatars;

		private static Page _server;

		private static Page _fun;

		private static Page _settings;

		private static Page _logs;

		private static StringElement _announce;

		private static StringElement _blacklist;

		internal static void Create()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			_root = Page.Root.CreatePage("Fusion God", new Color(0.35f, 0.2f, 0.85f), 0, true);
			_root.CreateFunction("OPEN PANEL", new Color(0.45f, 0.35f, 1f), (Action)GodOverlay.Toggle);
			_root.CreateFunction("Refresh / rebuild menu", Color.white, (Action)Rebuild);
			Rebuild();
		}

		internal static void Rebuild()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			if (_root == null)
			{
				return;
			}
			_root.RemoveAll();
			bool flag = FusionApi.HasServer();
			bool flag2 = FusionApi.IsHost();
			Color val = default(Color);
			((Color)(ref val))..ctor(0.25f, 0.35f, 0.85f);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.55f, 0.25f, 0.9f);
			_root.CreateFunction((!flag) ? "DASHBOARD  •  NO LOBBY" : (flag2 ? "DASHBOARD  •  HOST UNLOCKED" : "DASHBOARD  •  CLIENT LOCKED"), flag2 ? Color.cyan : Color.yellow, (Action)null);
			_root.CreateFunction("Module: " + (GodModule.Registered ? "REGISTERED" : "NOT REGISTERED"), GodModule.Registered ? Color.green : Color.red, (Action)null);
			if (!flag || !flag2)
			{
				_root.CreateFunction("Host a Fusion lobby to open admin pages.", Color.gray, (Action)null);
				_root.CreateFunction("Give other players FusionGod.dll or only Kick/Teleport work.", Color.gray, (Action)null);
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (LobbyPlayer item in FusionApi.Players())
			{
				num++;
				if (Presence.HasMod(item.SmallId) || item.IsMe)
				{
					num2++;
				}
			}
			_root.CreateFunction("Players " + num + "   |   FusionGod clients " + num2, val, (Action)null);
			if (num2 < num)
			{
				_root.CreateFunction("VANILLA PLAYERS: only Kick / Teleport / Kill+autokick work", Color.yellow, (Action)null);
			}
			_root.CreateFunction("Health guard " + (Prefs.HealthProtect.Value ? "ON" : "OFF") + "   God guard " + (Prefs.GodProtect.Value ? "ON" : "OFF"), val2, (Action)null);
			_players = _root.CreatePage("Players", val, 0, true);
			_anticheat = _root.CreatePage("Anti-Cheat", new Color(0.7f, 0.3f, 0.9f), 0, true);
			_avatars = _root.CreatePage("Avatars", val2, 0, true);
			_server = _root.CreatePage("Server", new Color(0.45f, 0.2f, 0.85f), 0, true);
			_fun = _root.CreatePage("Troll", new Color(0.85f, 0.3f, 0.95f), 0, true);
			_settings = _root.CreatePage("Settings", Color.white, 0, true);
			_logs = _root.CreatePage("Logs", Color.gray, 0, true);
			FillPlayers();
			FillAntiCheat();
			FillAvatars();
			FillServer();
			FillFun();
			FillSettings();
			FillLogs();
		}

		private static void FillPlayers()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			_players.RemoveAll();
			_players.CreateFunction("Refresh players", Color.green, (Action)delegate
			{
				FillPlayers();
				FillLogs();
			});
			foreach (LobbyPlayer item in from p in FusionApi.Players()
				orderby p.Name
				select p)
			{
				LobbyPlayer captured = item;
				bool flag = Presence.HasMod(captured.SmallId) || captured.IsMe;
				Page val = _players.CreatePage(captured.Name + (captured.IsMe ? " (you)" : "") + (captured.IsHost ? " [host]" : "") + (flag ? "  • FG" : "  • vanilla"), (Color)(captured.IsMe ? Color.cyan : (flag ? new Color(0.6f, 0.4f, 1f) : Color.white)), 0, true);
				val.CreateFunction("Platform " + captured.PlatformId, Color.gray, (Action)null);
				val.CreateFunction("SmallID " + captured.SmallId, Color.gray, (Action)null);
				val.CreateFunction(flag ? "Status: FusionGod client" : "Status: vanilla — Kick + Bring work, trolls need the mod", flag ? Color.green : Color.yellow, (Action)null);
				if (captured.IsMe)
				{
					continue;
				}
				val.CreateFunction("Kick", Color.red, (Action)delegate
				{
					Menu.DisplayDialog("Kick " + captured.Name + "?", "Remove this player from the lobby?", (Texture2D)null, (Action)delegate
					{
						HostActions.Kick(captured);
					}, (Action)null);
				});
				val.CreateFunction("Kill", Color.red, (Action)delegate
				{
					HostActions.Do(GodCommand.Kill, captured.SmallId);
				});
				val.CreateFunction("Respawn", Color.green, (Action)delegate
				{
					HostActions.Do(GodCommand.Respawn, captured.SmallId);
				});
				val.CreateFunction("Freeze", Color.yellow, (Action)delegate
				{
					HostActions.Do(GodCommand.Freeze, captured.SmallId);
				});
				val.CreateFunction("Unfreeze", Color.yellow, (Action)delegate
				{
					HostActions.Do(GodCommand.Unfreeze, captured.SmallId);
				});
				val.CreateFunction("Bring to me", Color.cyan, (Action)delegate
				{
					//IL_0000: 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_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0019: Unknown result type (might be due to invalid IL or missing references)
					//IL_001f: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val2 = HostActions.HostPos();
					HostActions.Do(GodCommand.TeleportTo, captured.SmallId, val2.x, val2.y, val2.z);
				});
				val.CreateFunction("Teleport to them", Color.cyan, (Action)delegate
				{
					HostActions.Goto(captured);
				});
				val.CreateFunction("Reset health", Color.white, (Action)delegate
				{
					HostActions.Do(GodCommand.ResetHealth, captured.SmallId);
				});
				val.CreateFunction("Force mortal", Color.white, (Action)delegate
				{
					HostActions.Do(GodCommand.ForceMortal, captured.SmallId);
				});
				val.CreateFunction("Launch", Color.magenta, (Action)delegate
				{
					HostActions.Do(GodCommand.Launch, captured.SmallId, 14f);
				});
				val.CreateFunction("Tiny", Color.magenta, (Action)delegate
				{
					HostActions.Do(GodCommand.Scale, captured.SmallId, 0.35f);
				});
				val.CreateFunction("Giant", Color.magenta, (Action)delegate
				{
					HostActions.Do(GodCommand.Scale, captured.SmallId, 2.4f);
				});
			}
		}

		private static void FillAntiCheat()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			_anticheat.RemoveAll();
			_anticheat.CreateBool("Health protection", Color.white, Prefs.HealthProtect.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.HealthProtect.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateBool("God-mode protection", Color.white, Prefs.GodProtect.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.GodProtect.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateBool("Avatar validation", Color.white, Prefs.AvatarValidate.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.AvatarValidate.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateBool("Kick on violation", Color.red, Prefs.KickOnViolation.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.KickOnViolation.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateBool("Warn players", Color.yellow, Prefs.WarnPlayers.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.WarnPlayers.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateEnum("Health action", Color.cyan, (Enum)Prefs.HealthAction.Value, (Action<Enum>)delegate(Enum v)
			{
				Prefs.HealthAction.Value = (ViolationAction)(object)v;
				Prefs.Save();
			});
			_anticheat.CreateFloat("Max vitality", Color.white, Prefs.MaxVitality.Value, 0.25f, 0.25f, 20f, (Action<float>)delegate(float v)
			{
				Prefs.MaxVitality.Value = v;
				Prefs.Save();
			});
			_anticheat.CreateFunction("Push policy to clients", Color.green, (Action)HostActions.EnforceNow);
			_anticheat.CreateFunction("Reset all suspicious health", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.ResetHealth);
			});
			_anticheat.CreateFunction("Force everyone mortal", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.ForceMortal);
			});
		}

		private static void FillAvatars()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			_avatars.RemoveAll();
			_avatars.CreateFloat("Max speed", Color.white, Prefs.MaxSpeed.Value, 0.25f, 0.25f, 20f, (Action<float>)delegate(float v)
			{
				Prefs.MaxSpeed.Value = v;
				Prefs.Save();
			});
			_avatars.CreateFloat("Max agility", Color.white, Prefs.MaxAgility.Value, 0.25f, 0.25f, 20f, (Action<float>)delegate(float v)
			{
				Prefs.MaxAgility.Value = v;
				Prefs.Save();
			});
			_avatars.CreateFloat("Max strength", Color.white, Prefs.MaxStrength.Value, 0.25f, 0.25f, 40f, (Action<float>)delegate(float v)
			{
				Prefs.MaxStrength.Value = v;
				Prefs.Save();
			});
			_avatars.CreateEnum("Avatar action", Color.cyan, (Enum)Prefs.AvatarAction.Value, (Action<Enum>)delegate(Enum v)
			{
				Prefs.AvatarAction.Value = (ViolationAction)(object)v;
				Prefs.Save();
			});
			_blacklist = _avatars.CreateString("Barcode blacklist (comma)", Color.white, Prefs.AvatarBarcodeBlacklist.Value, (Action<string>)delegate(string v)
			{
				Prefs.AvatarBarcodeBlacklist.Value = v;
				Prefs.Save();
			});
			_avatars.CreateFunction("Clamp all avatars now", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.ClampAvatar, byte.MaxValue, Prefs.MaxVitality.Value);
			});
		}

		private static void FillServer()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			_server.RemoveAll();
			_server.CreateFunction("Kill all", Color.red, (Action)delegate
			{
				Menu.DisplayDialog("Kill all players?", "Sends a kill command to every FusionGod client.", (Texture2D)null, (Action)delegate
				{
					HostActions.Do(GodCommand.Kill);
				}, (Action)null);
			});
			_server.CreateFunction("Respawn all", Color.green, (Action)delegate
			{
				HostActions.Do(GodCommand.Respawn);
			});
			_server.CreateFunction("Freeze all", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.Freeze);
			});
			_server.CreateFunction("Unfreeze all", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.Unfreeze);
			});
			_server.CreateFunction("Teleport everyone to host", Color.cyan, (Action)delegate
			{
				//IL_0000: 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_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = HostActions.HostPos();
				HostActions.Do(GodCommand.TeleportTo, byte.MaxValue, val.x, val.y, val.z);
			});
			_server.CreateFunction("Clear all effects", Color.white, (Action)delegate
			{
				HostActions.Do(GodCommand.ClearEffects);
			});
		}

		private static void FillFun()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			_fun.RemoveAll();
			_fun.CreateBool("Fun commands enabled", Color.white, Prefs.FunEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.FunEnabled.Value = v;
				Prefs.Save();
			});
			_fun.CreateFunction("Gravity/scale/jumpscare need FusionGod on THEIR PC", Color.yellow, (Action)null);
			_fun.CreateFunction("Jumpscare all", Color.red, (Action)delegate
			{
				HostActions.Do(GodCommand.Jumpscare, byte.MaxValue, 0f, 0f, 0f, "BEHIND YOU");
			});
			_fun.CreateFunction("Low gravity", Color.cyan, (Action)delegate
			{
				HostActions.Do(GodCommand.Gravity, byte.MaxValue, -2.2f);
			});
			_fun.CreateFunction("High gravity", Color.cyan, (Action)delegate
			{
				HostActions.Do(GodCommand.Gravity, byte.MaxValue, -24f);
			});
			_fun.CreateFunction("Tiny players", Color.magenta, (Action)delegate
			{
				HostActions.Do(GodCommand.Scale, byte.MaxValue, 0.35f);
			});
			_fun.CreateFunction("Giant players", Color.magenta, (Action)delegate
			{
				HostActions.Do(GodCommand.Scale, byte.MaxValue, 2.5f);
			});
			_fun.CreateFunction("Launch all", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.Launch, byte.MaxValue, 16f);
			});
			_fun.CreateFunction("Slippery mode", Color.yellow, (Action)delegate
			{
				HostActions.Do(GodCommand.Slippery);
			});
			_fun.CreateFunction("Random teleport", Color.green, (Action)delegate
			{
				HostActions.Do(GodCommand.RandomTeleport, byte.MaxValue, 10f);
			});
			_fun.CreateFunction("Spin players", Color.green, (Action)delegate
			{
				HostActions.Do(GodCommand.Spin);
			});
			_fun.CreateFunction("Slow motion", Color.white, (Action)delegate
			{
				HostActions.Do(GodCommand.SlowMo, byte.MaxValue, 0.3f);
			});
			_fun.CreateFunction("Super jump (launch)", Color.white, (Action)delegate
			{
				HostActions.Do(GodCommand.Launch, byte.MaxValue, 22f);
			});
			_announce = _fun.CreateString("Fake emergency text", Color.white, "EMERGENCY: void crab breach in sector 7", (Action<string>)delegate
			{
			});
			_fun.CreateFunction("Fake emergency", Color.red, (Action)delegate
			{
				HostActions.Do(GodCommand.Announce, byte.MaxValue, 0f, 0f, 0f, (_announce != null) ? _announce.Value : "EMERGENCY");
			});
			_fun.CreateFunction("Random player event", Color.cyan, (Action)RandomPlayerEvent);
		}

		private static void RandomPlayerEvent()
		{
			List<LobbyPlayer> list = (from p in FusionApi.Players()
				where !p.IsMe
				select p).ToList();
			if (list.Count == 0)
			{
				CommandRouter.Notify("Fusion God", "No other players.");
				return;
			}
			LobbyPlayer lobbyPlayer = list[Random.Range(0, list.Count)];
			GodCommand[] array = new GodCommand[5]
			{
				GodCommand.Launch,
				GodCommand.Spin,
				GodCommand.Scale,
				GodCommand.Jumpscare,
				GodCommand.RandomTeleport
			};
			GodCommand godCommand = array[Random.Range(0, array.Length)];
			float a = godCommand switch
			{
				GodCommand.Launch => 18f, 
				GodCommand.Scale => 0.4f, 
				_ => 8f, 
			};
			HostActions.Do(godCommand, lobbyPlayer.SmallId, a, 0f, 0f, "gotcha");
			CommandRouter.Notify("Fusion God", "Hit " + lobbyPlayer.Name + " with " + godCommand);
		}

		private static void FillSettings()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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)
			_settings.RemoveAll();
			_settings.CreateFloat("Command cooldown (s)", Color.white, Prefs.CommandCooldown.Value, 0.25f, 0f, 10f, (Action<float>)delegate(float v)
			{
				Prefs.CommandCooldown.Value = v;
				Prefs.Save();
			});
			_settings.CreateFloat("Effect duration (s)", Color.white, Prefs.EffectSeconds.Value, 1f, 1f, 60f, (Action<float>)delegate(float v)
			{
				Prefs.EffectSeconds.Value = v;
				Prefs.Save();
			});
			_settings.CreateFloat("Jumpscare duration (s)", Color.white, Prefs.JumpscareSeconds.Value, 0.5f, 0.5f, 8f, (Action<float>)delegate(float v)
			{
				Prefs.JumpscareSeconds.Value = v;
				Prefs.Save();
			});
			_settings.CreateBool("Log violations", Color.white, Prefs.LogViolations.Value, (Action<bool>)delegate(bool v)
			{
				Prefs.LogViolations.Value = v;
				Prefs.Save();
			});
		}

		private static void FillLogs()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			_logs.RemoveAll();
			_logs.CreateFunction("Clear logs", Color.red, (Action)delegate
			{
				ViolationLog.Clear();
				FillLogs();
			});
			if (ViolationLog.Lines.Count == 0)
			{
				_logs.CreateFunction("No events yet.", Color.gray, (Action)null);
			}
			foreach (string item in ViolationLog.Lines.Take(12))
			{
				_logs.CreateFunction((item.Length > 48) ? (item.Substring(0, 48) + "…") : item, Color.white, (Action)null);
			}
		}
	}
	internal static class GodOverlay
	{
		private static GameObject _root;

		private static Transform _board;

		private static string _page = "dash";

		private static byte _selected;

		private static string _status = "Ready";

		private static float _lastClick;

		private static readonly List<OverlayHit> _hits = new List<OverlayHit>();

		private static readonly Color Navy = new Color(0.07f, 0.09f, 0.18f, 0.96f);

		private static readonly Color Panel = new Color(0.1f, 0.12f, 0.24f, 0.96f);

		private static readonly Color Purple = new Color(0.45f, 0.28f, 0.85f, 1f);

		private static readonly Color Accent = new Color(0.35f, 0.55f, 1f, 1f);

		private static readonly Color Card = new Color(0.14f, 0.16f, 0.32f, 1f);

		private static readonly Color CardHot = new Color(0.28f, 0.22f, 0.55f, 1f);

		private static readonly Color Danger = new Color(0.85f, 0.25f, 0.35f, 1f);

		private static readonly Color Ok = new Color(0.25f, 0.85f, 0.55f, 1f);

		internal static bool IsOpen
		{
			get
			{
				if ((Object)(object)_root != (Object)null)
				{
					return _root.activeSelf;
				}
				return false;
			}
		}

		internal static void Toggle()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		internal static void Open()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Close();
			_root = new GameObject("FusionGodOverlay");
			Object.DontDestroyOnLoad((Object)(object)_root);
			_board = new GameObject("Board").transform;
			_board.SetParent(_root.transform, false);
			Rebuild();
			PlaceInFront();
			_status = (FusionApi.IsHost() ? "Host panel open" : "Client view — admin locked");
		}

		internal static void Close()
		{
			_hits.Clear();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_board = null;
		}

		internal static void Tick()
		{
			if (IsOpen)
			{
				PlaceInFront();
				PollHands();
			}
		}

		private static void PlaceInFront()
		{
			//IL_0015: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform head = Player.Head;
				if (!((Object)(object)head == (Object)null))
				{
					Vector3 forward = head.forward;
					forward.y = 0f;
					if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
					{
						forward = head.forward;
					}
					((Vector3)(ref forward)).Normalize();
					Vector3 val = head.position + forward * 1.15f + Vector3.up * 0.05f;
					_root.transform.position = val;
					_root.transform.rotation = Quaternion.LookRotation(val - head.position, Vector3.up);
				}
			}
			catch
			{
			}
		}

		private static void PollHands()
		{
			TryHand((Component)(object)Player.RightHand, Player.RightController);
			TryHand((Component)(object)Player.LeftHand, Player.LeftController);
		}

		private static void TryHand(Component hand, object ctrl)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand == (Object)null)
			{
				return;
			}
			Transform transform = hand.transform;
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val, 2.4f, -1, (QueryTriggerInteraction)2))
			{
				return;
			}
			OverlayHit component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<OverlayHit>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			component.LastHover = Time.unscaledTime;
			bool flag = false;
			try
			{
				MethodInfo methodInfo = ctrl?.GetType().GetMethod("GetTrigger");
				if (methodInfo != null && methodInfo.Invoke(ctrl, null) is float num && num > 0.72f)
				{
					flag = true;
				}
			}
			catch
			{
			}
			if (flag && Time.unscaledTime - _lastClick > 0.25f)
			{
				_lastClick = Time.unscaledTime;
				component.Click();
			}
		}

		internal static void Rebuild()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_board == (Object)null)
			{
				return;
			}
			_hits.Clear();
			for (int num = _board.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_board.GetChild(num)).gameObject);
			}
			Quad(_board, new Vector3(0f, 0f, 0.02f), new Vector3(1.28f, 0.82f, 1f), Navy, null);
			Quad(_board, new Vector3(0f, 0.36f, 0.01f), new Vector3(1.24f, 0.1f, 1f), Purple, null);
			Label(_board, new Vector3(-0.46f, 0.36f, 0f), "FUSION GOD", 0.045f, Color.white);
			Label(_board, new Vector3(0.38f, 0.36f, 0f), _status, 0.022f, new Color(0.85f, 0.9f, 1f));
			string[] tabs = new string[8] { "dash", "players", "cheat", "avatars", "server", "troll", "settings", "logs" };
			string[] array = new string[8] { "Dashboard", "Players", "Anti-Cheat", "Avatars", "Server", "Troll", "Settings", "Logs" };
			for (int i = 0; i < tabs.Length; i++)
			{
				int idx = i;
				float num2 = 0.24f - (float)i * 0.075f;
				bool flag = _page == tabs[i];
				Button(new Vector3(-0.46f, num2, 0f), new Vector3(0.28f, 0.065f, 0.02f), array[i], flag ? Accent : Card, delegate
				{
					_page = tabs[idx];
					Rebuild();
				});
			}
			Button(new Vector3(-0.46f, -0.36f, 0f), new Vector3(0.28f, 0.06f, 0.02f), "Close", Danger, Close);
			Transform transform = new GameObject("Content").transform;
			transform.SetParent(_board, false);
			transform.localPosition = new Vector3(0.18f, 0.02f, 0f);
			bool host = FusionApi.IsHost() && FusionApi.HasServer();
			string page = _page;
			if (page == null)
			{
				return;
			}
			switch (page.Length)
			{
			case 4:
				switch (page[0])
				{
				case 'd':
					if (page == "dash")
					{
						FillDash(transform, host);
					}
					break;
				case 'l':
					if (page == "logs")
					{
						FillLogs(transform);
					}
					break;
				}
				break;
			case 7:
				switch (page[0])
				{
				case 'p':
					if (page == "players")
					{
						FillPlayers(transform, host);
					}
					break;
				case 'a':
					if (page == "avatars")
					{
						FillAvatars(transform, host);
					}
					break;
				}
				break;
			case 5:
				switch (page[0])
				{
				case 'c':
					if (page == "cheat")
					{
						FillCheat(transform, host);
					}
					break;
				case 't':
					if (page == "troll")
					{
						FillTroll(transform, host);
					}
					break;
				}
				break;
			case 6:
				if (page == "server")
				{
					FillServer(transform, host);
				}
				break;
			case 8:
				if (page == "settings")
				{
					FillSettings(transform, host);
				}
				break;
			}
		}

		private static void FillDash(Transform parent, bool host)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			foreach (LobbyPlayer item in FusionApi.Players())
			{
				num++;
				if (item.IsMe || Presence.HasMod(item.SmallId))
				{
					num2++;
				}
			}
			Label(parent, new Vector3(0f, 0.26f, 0f), host ? "SERVER ADMIN" : "LOCKED — host a Fusion lobby", 0.032f, host ? Ok : Color.yellow);
			Label(parent, new Vector3(0f, 0.18f, 0f), "Players " + num + "   FusionGod clients " + num2, 0.024f, Color.white);
			Label(parent, new Vector3(0f, 0.12f, 0f), "Module " + (GodModule.Registered ? "REGISTERED" : "NOT REGISTERED"), 0.022f, GodModule.Registered ? Ok : Danger);
			Label(parent, new Vector3(0f, 0.05f, 0f), "Health " + OnOff(Prefs.HealthProtect.Value) + "   God " + OnOff(Prefs.GodProtect.Value), 0.022f, Accent);
			Label(parent, new Vector3(0f, -0.02f, 0f), "Point a hand at a card and pull trigger", 0.018f, new Color(0.7f, 0.75f, 0.9f));
			if (host)
			{
				Button(parent, new Vector3(-0.18f, -0.16f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Push policy", Purple, delegate
				{
					HostActions.EnforceNow();
					Toast("Policy sent");
				});
				Button(parent, new Vector3(0.16f, -0.16f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Clear effects", Card, delegate
				{
					HostActions.Do(GodCommand.ClearEffects);
					Toast("Cleared");
				});
			}
		}

		private static void FillPlayers(Transform parent, bool host)
		{
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			float num = 0.26f;
			foreach (LobbyPlayer item in FusionApi.Players())
			{
				LobbyPlayer cap = item;
				bool flag = cap.IsMe || Presence.HasMod(cap.SmallId);
				bool flag2 = _selected == cap.SmallId;
				string text = cap.Name + (cap.IsMe ? " (you)" : "") + (flag ? "  FG" : "  vanilla");
				Button(parent, new Vector3(0f, num, 0f), new Vector3(0.62f, 0.055f, 0.02f), text, flag2 ? Accent : Card, delegate
				{
					_selected = cap.SmallId;
					Rebuild();
				});
				num -= 0.062f;
				if (num < -0.12f)
				{
					break;
				}
			}
			if (!host)
			{
				Label(parent, new Vector3(0f, -0.22f, 0f), "Host only", 0.02f, Color.yellow);
				return;
			}
			Button(parent, new Vector3(-0.22f, -0.22f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Kill", Danger, delegate
			{
				HostActions.Do(GodCommand.Kill, _selected);
			});
			Button(parent, new Vector3(0.02f, -0.22f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Freeze", Purple, delegate
			{
				HostActions.Do(GodCommand.Freeze, _selected);
			});
			Button(parent, new Vector3(0.26f, -0.22f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Bring", Accent, delegate
			{
				//IL_0000: 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_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = HostActions.HostPos();
				HostActions.Do(GodCommand.TeleportTo, _selected, val.x, val.y, val.z);
			});
			Button(parent, new Vector3(-0.22f, -0.29f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Kick", Danger, delegate
			{
				if (FusionApi.TryGetPlayerBySmall(_selected, out var player) && !player.IsMe)
				{
					HostActions.Kick(player);
				}
			});
			Button(parent, new Vector3(0.02f, -0.29f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Launch", CardHot, delegate
			{
				HostActions.Do(GodCommand.Launch, _selected, 16f);
			});
			Button(parent, new Vector3(0.26f, -0.29f, 0f), new Vector3(0.2f, 0.055f, 0.02f), "Go to", Card, delegate
			{
				if (FusionApi.TryGetPlayerBySmall(_selected, out var player))
				{
					HostActions.Goto(player);
				}
			});
		}

		private static void FillCheat(Transform parent, bool host)
		{
			//IL_001a: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			if (!host)
			{
				Locked(parent);
				return;
			}
			ToggleCard(parent, new Vector3(-0.16f, 0.22f, 0f), "Block god mode", Prefs.GodProtect, delegate
			{
				Prefs.GodProtect.Value = !Prefs.GodProtect.Value;
			});
			ToggleCard(parent, new Vector3(0.18f, 0.22f, 0f), "Block health mods", Prefs.HealthProtect, delegate
			{
				Prefs.HealthProtect.Value = !Prefs.HealthProtect.Value;
			});
			ToggleCard(parent, new Vector3(-0.16f, 0.1f, 0f), "Kick violators", Prefs.KickOnViolation, delegate
			{
				Prefs.KickOnViolation.Value = !Prefs.KickOnViolation.Value;
			});
			ToggleCard(parent, new Vector3(0.18f, 0.1f, 0f), "Warn players", Prefs.WarnPlayers, delegate
			{
				Prefs.WarnPlayers.Value = !Prefs.WarnPlayers.Value;
			});
			Button(parent, new Vector3(0f, -0.08f, 0f), new Vector3(0.4f, 0.07f, 0.02f), "Push policy now", Purple, delegate
			{
				HostActions.EnforceNow();
				Toast("Policy pushed");
			});
		}

		private static void FillAvatars(Transform parent, bool host)
		{
			//IL_001a: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if (!host)
			{
				Locked(parent);
				return;
			}
			ToggleCard(parent, new Vector3(-0.16f, 0.22f, 0f), "Validate avatars", Prefs.AvatarValidate, delegate
			{
				Prefs.AvatarValidate.Value = !Prefs.AvatarValidate.Value;
			});
			ToggleCard(parent, new Vector3(0.18f, 0.22f, 0f), "Kick violators", Prefs.KickOnViolation, delegate
			{
				Prefs.KickOnViolation.Value = !Prefs.KickOnViolation.Value;
			});
			Label(parent, new Vector3(0f, 0.06f, 0f), "Max vitality " + Prefs.MaxVitality.Value.ToString("0.0"), 0.022f, Color.white);
			Button(parent, new Vector3(-0.16f, -0.04f, 0f), new Vector3(0.22f, 0.06f, 0.02f), "Vitality -", Card, delegate
			{
				Prefs.MaxVitality.Value = Mathf.Max(1f, Prefs.MaxVitality.Value - 0.5f);
				Rebuild();
			});
			Button(parent, new Vector3(0.16f, -0.04f, 0f), new Vector3(0.22f, 0.06f, 0.02f), "Vitality +", Card, delegate
			{
				Prefs.MaxVitality.Value = Mathf.Min(20f, Prefs.MaxVitality.Value + 0.5f);
				Rebuild();
			});
		}

		private static void FillServer(Transform parent, bool host)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			if (!host)
			{
				Locked(parent);
				return;
			}
			Button(parent, new Vector3(-0.16f, 0.2f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Kill all", Danger, delegate
			{
				HostActions.Do(GodCommand.Kill);
			});
			Button(parent, new Vector3(0.16f, 0.2f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Respawn all", Accent, delegate
			{
				HostActions.Do(GodCommand.Respawn);
			});
			Button(parent, new Vector3(-0.16f, 0.1f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Freeze all", Purple, delegate
			{
				HostActions.Do(GodCommand.Freeze);
			});
			Button(parent, new Vector3(0.16f, 0.1f, 0f), new Vector3(0.28f, 0.07f, 0.02f), "Unfreeze", Card, delegate
			{
				HostActions.Do(GodCommand.Unfreeze);
			});
			Button(parent, new Vector3(0f, -0.04f, 0f), new Vector3(0.36f, 0.07f, 0.02f), "Bring everyone", Accent, delegate
			{
				//IL_0000: 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_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = HostActions.HostPos();
				HostActions.Do(GodCommand.TeleportTo, byte.MaxValue, val.x, val.y, val.z);
			});
		}

		private static void FillTroll(Transform parent, bool host)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)