Decompiled source of Beetleball Sandbox v0.3.5

Mods/BeetleballSandbox.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BeetleballSandbox;
using HarmonyLib;
using Il2Cpp;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNuiN.NExtensions;
using Il2CppSteamworks;
using Il2CppSystem;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(SandboxMod), "Beetleball Sandbox", "0.3.5", "cody + Codex", null)]
[assembly: MelonGame("Bugfight Studio", "Beetleball")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BeetleballSandbox")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BeetleballSandbox")]
[assembly: AssemblyTitle("BeetleballSandbox")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace BeetleballSandbox
{
	public sealed class SandboxMod : MelonMod
	{
		private sealed class AdminPlayerEntry
		{
			public ulong ClientId;

			public ulong SteamId;

			public string Name = string.Empty;

			public TeamType Team;

			public int ClassIndex;

			public bool HasBeetle;

			public bool IsModded;
		}

		private sealed class HostAdminPlayerState
		{
			public ulong ClientId;

			public float Scale = 1f;

			public bool Frozen;

			public float NextStunAt;

			public IntPtr ActorPointer;

			public BeetleActor? Actor;

			public Vector3 BaseScale = Vector3.one;

			public Vector3 LastAppliedScale = Vector3.one;
		}

		private sealed class GlobalBallSnapshot
		{
			public Vector3 BaseScale;

			public Vector3 LastAppliedScale;

			public DungBall Ball { get; }

			public GlobalBallSnapshot(DungBall ball, Vector3 scale)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				Ball = ball;
				BaseScale = scale;
				LastAppliedScale = scale;
			}
		}

		private sealed class GlobalCooldownSnapshot
		{
			public BeetleActor Actor { get; }

			public BeetleStatModifiersController Controller { get; }

			public float GrabCooldown { get; }

			public float HeadbuttCooldown { get; }

			public float ShootRecovery { get; }

			public float JumpCooldown { get; }

			public float BallJumpCooldown { get; }

			public float GrabTimer { get; }

			public float JumpTimer { get; }

			public float HeadbuttTimer { get; }

			public float BallJumpTimer { get; }

			public float ShootRecoveryTimer { get; }

			public float RestoreGrabCooldown { get; }

			public float RestoreHeadbuttCooldown { get; }

			public float RestoreShootRecovery { get; }

			public float RestoreJumpCooldown { get; }

			public float RestoreBallJumpCooldown { get; }

			public float RestoreGrabTimer { get; }

			public float RestoreJumpTimer { get; }

			public float RestoreHeadbuttTimer { get; }

			public float RestoreBallJumpTimer { get; }

			public float RestoreShootRecoveryTimer { get; }

			public GlobalCooldownSnapshot(BeetleActor actor, BeetleStatModifiersController controller, BeetleStats baselineStats, float baselineJumpCooldown, float baselineBallJumpCooldown)
			{
				Actor = actor;
				Controller = controller;
				BeetleStats stats = actor.Stats;
				RestoreGrabCooldown = stats.GrabCooldownDuration;
				RestoreHeadbuttCooldown = stats.HeadbuttCooldown;
				RestoreShootRecovery = stats.ShootBallRecoveryDuration;
				RestoreJumpCooldown = actor.jumpCooldown;
				RestoreBallJumpCooldown = actor.ballJumpCooldown;
				RestoreGrabTimer = ReadLiveCooldownDuration(actor.GrabCooldownTimer, RestoreGrabCooldown);
				RestoreJumpTimer = ReadLiveCooldownDuration(actor.JumpCooldownTimer, RestoreJumpCooldown);
				RestoreHeadbuttTimer = ReadLiveCooldownDuration(actor.HeadbuttCooldownTimer, RestoreHeadbuttCooldown);
				RestoreBallJumpTimer = ReadLiveCooldownDuration(actor.BallJumpCooldownTimer, RestoreBallJumpCooldown);
				RestoreShootRecoveryTimer = ReadLiveCooldownDuration(actor.ShootBallRecoveryTimer, RestoreShootRecovery);
				GrabCooldown = baselineStats.GrabCooldownDuration;
				HeadbuttCooldown = baselineStats.HeadbuttCooldown;
				ShootRecovery = baselineStats.ShootBallRecoveryDuration;
				JumpCooldown = baselineJumpCooldown;
				BallJumpCooldown = baselineBallJumpCooldown;
				GrabTimer = GrabCooldown;
				JumpTimer = JumpCooldown;
				HeadbuttTimer = HeadbuttCooldown;
				BallJumpTimer = BallJumpCooldown;
				ShootRecoveryTimer = ShootRecovery;
			}
		}

		private enum ServerAdminAction : byte
		{
			ForceIntoMatch = 1,
			FreezePlayer,
			ReleasePlayer,
			SetPlayerScale,
			ResetRound,
			RestartMatch,
			AddSpectators,
			ClearDung,
			ReleaseAllFreezes,
			RestoreAllPlayerSizes,
			SetGlobalCooldown,
			SetGlobalBallScale,
			SetPlayerTeam
		}

		private enum WorldAction : byte
		{
			Ping,
			ChangeBallSize,
			SpawnLooseDung,
			RecallBall,
			LaunchBall,
			StopBall,
			SpinBall,
			ExplodeBall,
			ConfigureBall,
			ClearBallTuning,
			SpawnBall,
			Announcement
		}

		private enum AdminClientAction : byte
		{
			AddExperience = 1,
			NextLevel,
			SetLevel,
			UnlockSkins,
			SetScale,
			SetGlobalCooldown
		}

		private sealed class WorldRequest
		{
			public WorldAction Action;

			public ulong TargetBallId;

			public int IntValue;

			public int SecondaryIntValue;

			public float FloatValue;

			public float SecondaryFloatValue;

			public Vector3 VectorValue;

			public byte Flags;
		}

		private sealed class RemoteBallTuning
		{
			public DungBall Ball { get; }

			public Rigidbody Rigidbody { get; }

			public ulong BallId { get; }

			public float BaseMass { get; }

			public bool BaseUseGravity { get; }

			public Vector3 BaseScale { get; }

			public float MassMultiplier { get; set; } = 1f;

			public float ScaleMultiplier { get; set; } = 1f;

			public bool UseGravity { get; set; } = true;

			public bool Freeze { get; set; }

			public float LastReceivedAt { get; set; }

			public RemoteBallTuning(DungBall ball)
			{
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				Ball = ball;
				Rigidbody = ball.RB;
				BallId = GetBallNetworkId(ball);
				BaseMass = Rigidbody.mass;
				BaseUseGravity = Rigidbody.useGravity;
				BaseScale = ((Component)ball).transform.localScale;
			}
		}

		private sealed class RemotePlayerTuning
		{
			public BeetleActor Actor { get; }

			public BeetleStatModifiersController Controller { get; }

			public IntPtr ActorPointer { get; }

			public Vector3 BaseActorScale { get; }

			public float BaseSize { get; }

			public float BaseMoveSpeed { get; }

			public float BaseSprintSpeed { get; }

			public float BaseJumpForce { get; }

			public float BaseGravity { get; }

			public float BaseBallMinSpeed { get; }

			public float BaseBallMaxSpeed { get; }

			public float BaseThrowMin { get; }

			public float BaseThrowMax { get; }

			public float BaseChargedMultiplier { get; }

			public float BaseHeadbuttLaunch { get; }

			public float BaseHeadbuttForward { get; }

			public float BaseHeadbuttHit { get; }

			public float BaseGrabCooldown { get; }

			public float BaseHeadbuttCooldown { get; }

			public float BaseShootRecovery { get; }

			public float BaseJumpCooldown { get; }

			public float BaseBallJumpCooldown { get; }

			public float BaseGrabCooldownTimer { get; }

			public float BaseJumpCooldownTimer { get; }

			public float BaseHeadbuttCooldownTimer { get; }

			public float BaseBallJumpCooldownTimer { get; }

			public float BaseShootRecoveryTimer { get; }

			public bool BaseUnstunnable { get; }

			public float MoveSpeed { get; set; } = 1f;

			public float SprintSpeed { get; set; } = 1f;

			public float JumpForce { get; set; } = 1f;

			public float Gravity { get; set; } = 1f;

			public float Size { get; set; } = 1f;

			public float BallRollSpeed { get; set; } = 1f;

			public float ThrowForce { get; set; } = 1f;

			public float HeadbuttForce { get; set; } = 1f;

			public float CooldownFactor { get; set; } = 1f;

			public bool NoStun { get; set; }

			public float LastReceivedAt { get; set; }

			public RemotePlayerTuning(BeetleActor actor)
			{
				//IL_009c: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
				Actor = actor;
				Controller = actor.StatModifiersController;
				ActorPointer = ((Il2CppObjectBase)actor).Pointer;
				BeetleStats stats = actor.Stats;
				BaseSize = stats.Size;
				BaseActorScale = Vector3.one * BaseSize;
				BaseMoveSpeed = stats.MoveSpeed;
				BaseSprintSpeed = stats.SprintSpeedMult;
				BaseJumpForce = stats.JumpForce;
				BaseGravity = stats.GravityMult;
				BaseBallMinSpeed = stats.BallMinSizeMaxSpeed;
				BaseBallMaxSpeed = stats.BallMaxSizeMaxSpeed;
				BaseThrowMin = stats.ShootBallForceMinSize;
				BaseThrowMax = stats.ShootBallForceMaxSize;
				BaseChargedMultiplier = stats.ShootBallForceChargedMult;
				BaseHeadbuttLaunch = stats.HeadbuttLaunchForce;
				BaseHeadbuttForward = stats.HeadbuttLaunchForceForwardBonus;
				BaseHeadbuttHit = stats.HeadbuttHitForce;
				BaseGrabCooldown = stats.GrabCooldownDuration;
				BaseHeadbuttCooldown = stats.HeadbuttCooldown;
				BaseShootRecovery = stats.ShootBallRecoveryDuration;
				BaseJumpCooldown = actor.jumpCooldown;
				BaseBallJumpCooldown = actor.ballJumpCooldown;
				BaseGrabCooldownTimer = ReadLiveCooldownDuration(actor.GrabCooldownTimer, BaseGrabCooldown);
				BaseJumpCooldownTimer = ReadLiveCooldownDuration(actor.JumpCooldownTimer, BaseJumpCooldown);
				BaseHeadbuttCooldownTimer = ReadLiveCooldownDuration(actor.HeadbuttCooldownTimer, BaseHeadbuttCooldown);
				BaseBallJumpCooldownTimer = ReadLiveCooldownDuration(actor.BallJumpCooldownTimer, BaseBallJumpCooldown);
				BaseShootRecoveryTimer = ReadLiveCooldownDuration(actor.ShootBallRecoveryTimer, BaseShootRecovery);
				BaseUnstunnable = actor.Unstunnable;
			}
		}

		private sealed class PlayerSnapshot
		{
			public BeetleActor Actor { get; }

			public BeetleStatModifiersController Controller { get; }

			public Transform? VisualRoot { get; }

			public IntPtr ActorPointer { get; }

			public IntPtr ControllerPointer { get; }

			public IntPtr VisualPointer { get; }

			public Vector3 VisualScale { get; }

			public float Size { get; }

			public float MoveSpeed { get; }

			public float SprintSpeedMult { get; }

			public float JumpForce { get; }

			public float GravityMult { get; }

			public float FlutterSpeed { get; }

			public float GlideSpeed { get; }

			public float BallMinSizeMaxSpeed { get; }

			public float BallMaxSizeMaxSpeed { get; }

			public float ShootBallForceMinSize { get; }

			public float ShootBallForceMaxSize { get; }

			public float ShootBallForceChargedMult { get; }

			public float HeadbuttLaunchForce { get; }

			public float HeadbuttLaunchForceForwardBonus { get; }

			public float HeadbuttHitForce { get; }

			public float GrabCooldownDuration { get; }

			public float HeadbuttCooldown { get; }

			public float ShootBallRecoveryDuration { get; }

			public float JumpCooldown { get; }

			public float BallJumpCooldown { get; }

			public float GrabCooldownTimerDuration { get; }

			public float JumpCooldownTimerDuration { get; }

			public float HeadbuttCooldownTimerDuration { get; }

			public float BallJumpCooldownTimerDuration { get; }

			public float ShootBallRecoveryTimerDuration { get; }

			public bool Unstunnable { get; }

			public PlayerSnapshot(BeetleActor actor, BeetleStatModifiersController controller, BeetleStats stats, Transform? visualRoot)
			{
				//IL_0060: 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_0065: Unknown result type (might be due to invalid IL or missing references)
				Actor = actor;
				Controller = controller;
				VisualRoot = visualRoot;
				ActorPointer = ((Il2CppObjectBase)actor).Pointer;
				ControllerPointer = ((Il2CppObjectBase)controller).Pointer;
				VisualPointer = ((visualRoot != null) ? ((Il2CppObjectBase)visualRoot).Pointer : IntPtr.Zero);
				VisualScale = (((Object)(object)visualRoot == (Object)null) ? Vector3.one : visualRoot.localScale);
				Size = stats.Size;
				MoveSpeed = stats.MoveSpeed;
				SprintSpeedMult = stats.SprintSpeedMult;
				JumpForce = stats.JumpForce;
				GravityMult = stats.GravityMult;
				FlutterSpeed = stats.FlutterSpeed;
				GlideSpeed = stats.GlideSpeed;
				BallMinSizeMaxSpeed = stats.BallMinSizeMaxSpeed;
				BallMaxSizeMaxSpeed = stats.BallMaxSizeMaxSpeed;
				ShootBallForceMinSize = stats.ShootBallForceMinSize;
				ShootBallForceMaxSize = stats.ShootBallForceMaxSize;
				ShootBallForceChargedMult = stats.ShootBallForceChargedMult;
				HeadbuttLaunchForce = stats.HeadbuttLaunchForce;
				HeadbuttLaunchForceForwardBonus = stats.HeadbuttLaunchForceForwardBonus;
				HeadbuttHitForce = stats.HeadbuttHitForce;
				GrabCooldownDuration = stats.GrabCooldownDuration;
				HeadbuttCooldown = stats.HeadbuttCooldown;
				ShootBallRecoveryDuration = stats.ShootBallRecoveryDuration;
				JumpCooldown = actor.jumpCooldown;
				BallJumpCooldown = actor.ballJumpCooldown;
				GrabCooldownTimerDuration = ReadLiveCooldownDuration(actor.GrabCooldownTimer, GrabCooldownDuration);
				JumpCooldownTimerDuration = ReadLiveCooldownDuration(actor.JumpCooldownTimer, JumpCooldown);
				HeadbuttCooldownTimerDuration = ReadLiveCooldownDuration(actor.HeadbuttCooldownTimer, HeadbuttCooldown);
				BallJumpCooldownTimerDuration = ReadLiveCooldownDuration(actor.BallJumpCooldownTimer, BallJumpCooldown);
				ShootBallRecoveryTimerDuration = ReadLiveCooldownDuration(actor.ShootBallRecoveryTimer, ShootBallRecoveryDuration);
				Unstunnable = actor.Unstunnable;
			}
		}

		private sealed class BallSnapshot
		{
			public DungBall Ball { get; }

			public Rigidbody Rigidbody { get; }

			public IntPtr BallPointer { get; }

			public float Mass { get; }

			public bool UseGravity { get; }

			public Vector3 LocalScale { get; }

			public BallSnapshot(DungBall ball)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				Ball = ball;
				Rigidbody = ball.RB;
				BallPointer = ((Il2CppObjectBase)ball).Pointer;
				Mass = Rigidbody.mass;
				UseGravity = Rigidbody.useGravity;
				LocalScale = ((Component)ball).transform.localScale;
			}
		}

		private sealed class EggHatchTimingSnapshot
		{
			public EggScreen Screen { get; }

			public float HatchDuration { get; }

			public float FinalizeDelay { get; }

			public Animator? Animator { get; }

			public float AnimatorSpeed { get; }

			public EggHatchTimingSnapshot(EggScreen screen)
			{
				Screen = screen;
				HatchDuration = screen.hatchDuration;
				FinalizeDelay = screen.finalizeHatchDelay;
				Animator = screen.eggHatchAnimation;
				AnimatorSpeed = (((Object)(object)Animator == (Object)null) ? 1f : Animator.speed);
			}

			public void Restore()
			{
				if ((Object)(object)Screen != (Object)null)
				{
					Screen.hatchDuration = HatchDuration;
					Screen.finalizeHatchDelay = FinalizeDelay;
				}
				if ((Object)(object)Animator != (Object)null)
				{
					Animator.speed = AnimatorSpeed;
				}
			}
		}

		private sealed class HiddenUiSnapshot
		{
			public CanvasGroup CanvasGroup { get; }

			public bool AddedByMod { get; }

			public float Alpha { get; }

			public bool Interactable { get; }

			public bool BlocksRaycasts { get; }

			public HiddenUiSnapshot(CanvasGroup canvasGroup, bool addedByMod)
			{
				CanvasGroup = canvasGroup;
				AddedByMod = addedByMod;
				Alpha = canvasGroup.alpha;
				Interactable = canvasGroup.interactable;
				BlocksRaycasts = canvasGroup.blocksRaycasts;
			}
		}

		private const int PlayersPerAdminPage = 4;

		private const int MaxLocalProfileLevel = 1000000;

		private const string CustomLevelPlayerPrefsKey = "BeetleballSandbox.CustomLocalLevel.v1";

		private readonly List<AdminPlayerEntry> _adminPlayers = new List<AdminPlayerEntry>();

		private readonly Dictionary<ulong, HostAdminPlayerState> _hostAdminPlayerStates = new Dictionary<ulong, HostAdminPlayerState>();

		private readonly Dictionary<ulong, HostAdminPlayerState> _joinedClientVisualPlayerStates = new Dictionary<ulong, HostAdminPlayerState>();

		private readonly List<ulong> _adminStateCleanup = new List<ulong>();

		private readonly Dictionary<IntPtr, GlobalBallSnapshot> _globalBallSnapshots = new Dictionary<IntPtr, GlobalBallSnapshot>();

		private readonly List<IntPtr> _globalBallCleanup = new List<IntPtr>();

		private readonly HashSet<IntPtr> _globalBallSeen = new HashSet<IntPtr>();

		private readonly Dictionary<IntPtr, GlobalCooldownSnapshot> _globalCooldownSnapshots = new Dictionary<IntPtr, GlobalCooldownSnapshot>();

		private readonly List<IntPtr> _globalCooldownCleanup = new List<IntPtr>();

		private readonly HashSet<IntPtr> _globalCooldownSeen = new HashSet<IntPtr>();

		private ulong _selectedAdminClientId = ulong.MaxValue;

		private int _adminPlayerPage;

		private float _nextAdminPlayerRefreshAt;

		private float _selectedPlayerScale = 1f;

		private int _localTargetLevel = 10;

		private bool _localTargetLevelInitialized;

		private int _customLocalLevelOverride;

		private int _exactLevelTypingMode;

		private string _exactLevelTypingText = string.Empty;

		private float _pendingForceSpectatorsAt;

		private int _pendingLocalSpawnStage;

		private TeamType _pendingLocalSpawnTeam;

		private int _pendingLocalSpawnClassIndex;

		private int _pendingLocalSpawnAttempts;

		private bool _pendingLocalSpawnSilent;

		private float _pendingLocalSpawnAt;

		private float _pendingLocalSpawnDeadline;

		private bool _globalBallScaleEnabled;

		private float _globalBallScale = 1f;

		private bool _globalCooldownEnabled;

		private float _globalCooldownFactor = 1f;

		private bool _cameraDistanceOverride;

		private bool _cameraAutoScale = true;

		private float _cameraDistance = 1f;

		private bool _cameraDistanceApplied;

		private const string WorldRequestMessage = "BeetleballSandbox.WorldRequest.v1";

		private const string RelayResponseMessage = "BeetleballSandbox.RelayResponse.v1";

		private const string AnnouncementRequestMessage = "BeetleballSandbox.AnnouncementRequest.v1";

		private const string AnnouncementBroadcastMessage = "BeetleballSandbox.AnnouncementBroadcast.v1";

		private const string ServerAnnouncementChatPrefix = "[SERVER ANNOUNCEMENT]";

		private const string CustomAnnouncementChatPrefix = "[CUSTOM MESSAGE]";

		private const string PlayerTuningRequestMessage = "BeetleballSandbox.PlayerTuningRequest.v1";

		private const string AdminCommandMessage = "BeetleballSandbox.AdminCommand.v1";

		private const string AdminResultMessage = "BeetleballSandbox.AdminResult.v1";

		private const string ServerAdminRequestMessage = "BeetleballSandbox.ServerAdminRequest.v1";

		private const string ServerAdminResponseMessage = "BeetleballSandbox.ServerAdminResponse.v1";

		private bool _allowClientWorldRequests;

		private bool _hostRelayDetected;

		private bool _hostRelayAllowed;

		private float _lastRelayAckAt;

		private float _nextRelayHelloAt;

		private float _nextBallTuningRelayAt;

		private float _nextPlayerTuningRelayAt;

		private ulong _lastRelayedBallId;

		private bool _relayedPlayerTuningActive;

		private CustomMessagingManager? _bridgeMessaging;

		private IntPtr _bridgeMessagingPointer;

		private HandleNamedMessageDelegate? _worldRequestHandler;

		private HandleNamedMessageDelegate? _relayResponseHandler;

		private HandleNamedMessageDelegate? _announcementRequestHandler;

		private HandleNamedMessageDelegate? _announcementBroadcastHandler;

		private HandleNamedMessageDelegate? _playerTuningRequestHandler;

		private HandleNamedMessageDelegate? _adminCommandHandler;

		private HandleNamedMessageDelegate? _adminResultHandler;

		private HandleNamedMessageDelegate? _serverAdminRequestHandler;

		private HandleNamedMessageDelegate? _serverAdminResponseHandler;

		private readonly Dictionary<ulong, RemoteBallTuning> _remoteBallTunings = new Dictionary<ulong, RemoteBallTuning>();

		private readonly List<ulong> _expiredRemoteTuningClients = new List<ulong>();

		private readonly Dictionary<ulong, RemotePlayerTuning> _remotePlayerTunings = new Dictionary<ulong, RemotePlayerTuning>();

		private readonly List<ulong> _expiredRemotePlayerClients = new List<ulong>();

		private readonly Dictionary<ulong, float> _lastAnnouncementTimes = new Dictionary<ulong, float>();

		private readonly HashSet<ulong> _moddedClientIds = new HashSet<ulong>();

		private string _announcementText = "Welcome to the custom server!";

		private float _announcementDuration = 6f;

		private int _announcementPosition = 1;

		private int _announcementColorPreset = 1;

		private float _nextAnnouncementSendAt;

		private string _lastLocalAnnouncementPopup = string.Empty;

		private float _lastLocalAnnouncementPopupAt = float.NegativeInfinity;

		private bool _serverCooldownOverrideActive;

		private float _serverCooldownOverrideFactor = 1f;

		private bool _serverCooldownForcedPlayerTuning;

		private const string MenuInputLockKey = "beetleballSandboxMenu";

		private const float IntentionalFlightDescentThreshold = -0.65f;

		private const string AnonymousModePlayerPrefsKey = "BeetleballSandbox.AnonymousMode.v1";

		private const string HideLeaderboardPlayerPrefsKey = "BeetleballSandbox.HideLeaderboard.v1";

		private const string HidePlayerBoardPlayerPrefsKey = "BeetleballSandbox.HidePlayerBoard.v1";

		private const string EggRarityBoostPlayerPrefsKey = "BeetleballSandbox.EggRarityBoost.v1";

		private const string EggMythicalChancePlayerPrefsKey = "BeetleballSandbox.EggMythicalChance.v1";

		private const string FastEggHatchPlayerPrefsKey = "BeetleballSandbox.FastEggHatch.v1";

		private bool _menuOpen = true;

		private bool _guiUnavailable;

		private bool _cursorCaptured;

		private bool _menuInputLockApplied;

		private bool _menuInputLockWarningLogged;

		private CursorLockMode _savedCursorLock;

		private bool _savedCursorVisible;

		private Rect _panelRect = new Rect(24f, 24f, 620f, 860f);

		private int _menuPage;

		private float _uiX;

		private float _uiY;

		private float _uiWidth;

		private float _sceneObjectAccessReadyAt;

		private bool _anonymousMode;

		private bool _hideLeaderboard;

		private bool _hidePlayerBoard;

		private readonly Dictionary<IntPtr, HiddenUiSnapshot> _hiddenLeaderboardObjects = new Dictionary<IntPtr, HiddenUiSnapshot>();

		private readonly Dictionary<IntPtr, HiddenUiSnapshot> _hiddenPlayerBoardObjects = new Dictionary<IntPtr, HiddenUiSnapshot>();

		private readonly Dictionary<IntPtr, EggHatchTimingSnapshot> _eggHatchTimingSnapshots = new Dictionary<IntPtr, EggHatchTimingSnapshot>();

		private bool _eggRarityBoost;

		private float _eggMythicalChance = 100f;

		private bool _fastEggHatch = true;

		private string _status = "Ready - F5 toggles this menu";

		private float _statusUntil;

		private bool _playerTuning;

		private bool _playerApplied;

		private bool _noStun;

		private static SandboxMod? _activeInstance;

		private BeetleActor? _noStunActor;

		private bool _noStunOriginalUnstunnable;

		private bool _noStunOverrideApplied;

		private float _moveSpeed = 1f;

		private float _sprintSpeed = 1f;

		private float _jumpForce = 1f;

		private float _gravity = 1f;

		private float _flySpeed = 1f;

		private bool _holdFlightUntilGround = true;

		private bool _flightMomentumActive;

		private IntPtr _flightMomentumActorPointer;

		private Vector3 _flightMomentumVelocity;

		private float _flightBaseSpeed;

		private float _flightStateUpdatedAt = float.NegativeInfinity;

		private float _flightGroundGraceUntil;

		private static int _flightChargeDrainSuppressionDepth;

		private float _playerSize = 1f;

		private float _ballRollSpeed = 1f;

		private float _throwForce = 1f;

		private float _headbuttForce = 1f;

		private float _cooldownFactor = 1f;

		private PlayerSnapshot? _playerSnapshot;

		private bool _ballTuning;

		private bool _freezeBall;

		private bool _ballUseGravity = true;

		private float _ballMass = 1f;

		private float _ballScale = 1f;

		private float _launchPower = 30f;

		private float _spinPower = 20f;

		private int _dungSpawnSize = 1;

		private BallSnapshot? _ballSnapshot;

		private bool _fovOverride;

		private float _fov = 90f;

		private Camera? _cameraSnapshot;

		private float _originalFov;

		private bool _timeScaleOverride;

		private bool _timeScaleCaptured;

		private float _timeScale = 1f;

		private float _originalTimeScale = 1f;

		public bool ServerCooldownOverrideActive => _serverCooldownOverrideActive;

		public float ServerCooldownOverrideFactor => _serverCooldownOverrideFactor;

		public bool ServerCooldownForcedPlayerTuning => _serverCooldownForcedPlayerTuning;

		private void UpdateAdminTools()
		{
			RefreshAdminPlayerList(force: false);
			ApplyJoinedClientVisualPlayerStates();
			UpdatePendingLocalSpectatorSpawn();
			if (_pendingForceSpectatorsAt > 0f && Time.unscaledTime >= _pendingForceSpectatorsAt)
			{
				_pendingForceSpectatorsAt = 0f;
				ForceAllSpectatorsIntoMatch();
			}
		}

		private void ShutdownAdminTools()
		{
			ResetCameraDistance();
			ResetGlobalBallScale();
			_globalCooldownEnabled = false;
			RestoreGlobalCooldowns();
			RestoreAllHostAdminPlayerStates();
			RestoreAllJoinedClientVisualPlayerStates();
			_adminPlayers.Clear();
			_selectedAdminClientId = ulong.MaxValue;
			_pendingForceSpectatorsAt = 0f;
			_exactLevelTypingMode = 0;
			_exactLevelTypingText = string.Empty;
			ClearPendingLocalSpectatorSpawn();
		}

		private void DrawRawGlobalBallScaleControls()
		{
			RawSection("GLOBAL BALL SCALE");
			bool flag = RawToggle("Apply one physical scale to every ball", _globalBallScaleEnabled);
			if (flag != _globalBallScaleEnabled)
			{
				_globalBallScaleEnabled = flag;
				if (!flag)
				{
					RestoreGlobalBallScale();
				}
				RequestGlobalBallScaleFromServer();
				SetStatus(flag ? "Global ball scale enabled" : "Global ball scale restored");
			}
			float globalBallScale = _globalBallScale;
			_globalBallScale = RawUnboundedStepper("Global scale", _globalBallScale, 0.05f, 0.25f, 1f);
			if (_globalBallScaleEnabled && Math.Abs(globalBallScale - _globalBallScale) > 0.0001f)
			{
				RequestGlobalBallScaleFromServer();
			}
			if (RawRowButton("1x", 0, 4))
			{
				SetGlobalBallScalePreset(1f);
			}
			if (RawRowButton("5x", 1, 4))
			{
				SetGlobalBallScalePreset(5f);
			}
			if (RawRowButton("25x", 2, 4))
			{
				SetGlobalBallScalePreset(25f);
			}
			if (RawRowButton("Double", 3, 4))
			{
				SetGlobalBallScalePreset(SafeDouble(_globalBallScale));
			}
			RawNextRow();
		}

		private void SetGlobalBallScalePreset(float scale)
		{
			_globalBallScale = Mathf.Max(0.05f, scale);
			_globalBallScaleEnabled = true;
			ApplyGlobalBallScale();
			RequestGlobalBallScaleFromServer();
			SetStatus($"Global ball scale set to {_globalBallScale:0.##}x");
		}

		private void RequestGlobalBallScaleFromServer()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(ServerAdminAction.SetGlobalBallScale, ulong.MaxValue, _globalBallScaleEnabled ? 1 : 0, _globalBallScale, quiet: true);
			}
		}

		private void ApplyGlobalBallScale()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00ba: 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_00d9: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_00fb: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (!_globalBallScaleEnabled)
			{
				if (_globalBallSnapshots.Count > 0)
				{
					RestoreGlobalBallScale();
				}
				return;
			}
			try
			{
				Il2CppArrayBase<DungBall> obj = Object.FindObjectsOfType<DungBall>();
				_globalBallSeen.Clear();
				foreach (DungBall item in obj)
				{
					if (!((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).transform == (Object)null))
					{
						IntPtr pointer = ((Il2CppObjectBase)item).Pointer;
						_globalBallSeen.Add(pointer);
						if (!_globalBallSnapshots.TryGetValue(pointer, out GlobalBallSnapshot value))
						{
							value = new GlobalBallSnapshot(item, ((Component)item).transform.localScale);
							_globalBallSnapshots[pointer] = value;
						}
						Vector3 localScale = ((Component)item).transform.localScale;
						Vector3 val = localScale - value.LastAppliedScale;
						if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
						{
							value.BaseScale = localScale;
						}
						EnableNetworkScaleSync((Component)(object)item);
						Vector3 val2 = value.BaseScale * _globalBallScale;
						((Component)item).transform.localScale = val2;
						value.LastAppliedScale = val2;
					}
				}
				_globalBallCleanup.Clear();
				foreach (KeyValuePair<IntPtr, GlobalBallSnapshot> globalBallSnapshot in _globalBallSnapshots)
				{
					if (!_globalBallSeen.Contains(globalBallSnapshot.Key))
					{
						_globalBallCleanup.Add(globalBallSnapshot.Key);
					}
				}
				foreach (IntPtr item2 in _globalBallCleanup)
				{
					_globalBallSnapshots.Remove(item2);
				}
			}
			catch (Exception exception)
			{
				ReportException("applying global ball scale", exception);
			}
		}

		private void RestoreGlobalBallScale()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			foreach (GlobalBallSnapshot value in _globalBallSnapshots.Values)
			{
				try
				{
					if ((Object)(object)value.Ball != (Object)null && (Object)(object)((Component)value.Ball).transform != (Object)null)
					{
						((Component)value.Ball).transform.localScale = value.BaseScale;
					}
				}
				catch
				{
				}
			}
			_globalBallSnapshots.Clear();
		}

		private void ResetGlobalBallScale()
		{
			_globalBallScaleEnabled = false;
			_globalBallScale = 1f;
			RestoreGlobalBallScale();
		}

		private void DrawRawCameraDistanceControls()
		{
			RawSection("LARGE-BEETLE CAMERA");
			bool flag = RawToggle("Auto-distance follows local beetle scale", _cameraAutoScale);
			if (flag != _cameraAutoScale)
			{
				_cameraAutoScale = flag;
				if (!flag && !_cameraDistanceOverride)
				{
					RestoreCameraDistance();
				}
			}
			bool flag2 = RawToggle("Enable manual camera distance", _cameraDistanceOverride);
			if (flag2 != _cameraDistanceOverride)
			{
				_cameraDistanceOverride = flag2;
				if (!flag2 && !_cameraAutoScale)
				{
					RestoreCameraDistance();
				}
			}
			_cameraDistance = RawUnboundedStepper("Manual distance", _cameraDistance, 0.25f, 0.25f, 1f);
			if (RawRowButton("1x", 0, 4))
			{
				_cameraDistance = 1f;
			}
			if (RawRowButton("5x", 1, 4))
			{
				_cameraDistance = 5f;
			}
			if (RawRowButton("20x", 2, 4))
			{
				_cameraDistance = 20f;
			}
			if (RawRowButton("Double", 3, 4))
			{
				_cameraDistance = SafeDouble(_cameraDistance);
			}
			RawNextRow();
		}

		private void ApplyCameraDistance()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (!_cameraDistanceOverride && !_cameraAutoScale)
			{
				if (_cameraDistanceApplied)
				{
					RestoreCameraDistance();
				}
				return;
			}
			try
			{
				PlayerCamera instance = PlayerCamera.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				float num = (_cameraDistanceOverride ? Mathf.Max(0.25f, _cameraDistance) : 1f);
				if (_cameraAutoScale)
				{
					BeetleActor localBeetle = GetLocalBeetle();
					if ((Object)(object)localBeetle != (Object)null)
					{
						float num2 = Mathf.Max(((Component)localBeetle).transform.localScale.x, Mathf.Max(((Component)localBeetle).transform.localScale.y, ((Component)localBeetle).transform.localScale.z));
						num = Mathf.Max(num, Mathf.Max(1f, num2 * 1.15f));
					}
				}
				instance.SetCameraDistanceMult(num);
				_cameraDistanceApplied = true;
			}
			catch
			{
				_cameraDistanceApplied = false;
			}
		}

		private void RestoreCameraDistance()
		{
			try
			{
				PlayerCamera instance = PlayerCamera.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.ResetCameraDistanceMult();
				}
			}
			catch
			{
			}
			_cameraDistanceApplied = false;
		}

		private void ResetCameraDistance()
		{
			_cameraDistanceOverride = false;
			_cameraAutoScale = true;
			_cameraDistance = 1f;
			RestoreCameraDistance();
		}

		private void DrawRawServerMatchControls()
		{
			RawSection("MATCH / SESSION REQUESTS");
			RawLabel(IsNetworkServerHost() ? "Direct server authority." : "Attempts game RPCs or modded-host request.");
			if (RawRowButton("Spawn me Blue", 0, 4))
			{
				SpawnLocalPlayerIntoMatch((TeamType)1);
			}
			if (RawRowButton("Spawn me Red", 1, 4))
			{
				SpawnLocalPlayerIntoMatch((TeamType)2);
			}
			if (RawRowButton("Reset score + round", 2, 4))
			{
				ResetHostedRound();
			}
			if (RawRowButton("Restart + add players", 3, 4))
			{
				RestartHostedMatch();
			}
			RawNextRow();
			if (RawRowButton("Add all spectators", 0, 4))
			{
				ForceAllSpectatorsIntoMatch();
			}
			if (RawRowButton("Clear all dung", 1, 4))
			{
				ClearAllDungAsHost();
			}
			if (RawRowButton("Release all freezes", 2, 4))
			{
				ReleaseAllAdminFreezes();
			}
			if (RawRowButton("Restore player sizes", 3, 4))
			{
				RestoreAllAdminPlayerSizes();
			}
			RawNextRow();
		}

		private void DrawRawPlayersPage()
		{
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			bool flag = IsNetworkServerHost();
			RawSection("CONNECTED PLAYER TOOLS");
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				RawLabel("Join or host a connected session to view its player list.");
				return;
			}
			RawLabel(flag ? "Direct server authority." : "Vanilla RPCs + modded-host requests.");
			RawSection("CONNECTED PLAYER LIST");
			RefreshAdminPlayerList(force: true);
			if (_adminPlayers.Count == 0)
			{
				RawLabel("No connected players are available yet.");
				return;
			}
			int num = Math.Max(1, (_adminPlayers.Count + 4 - 1) / 4);
			_adminPlayerPage = Math.Clamp(_adminPlayerPage, 0, num - 1);
			RawLabel($"Players {_adminPlayers.Count} | page {_adminPlayerPage + 1}/{num}");
			int num2 = _adminPlayerPage * 4;
			int num3 = Math.Min(num2 + 4, _adminPlayers.Count);
			for (int i = num2; i < num3; i += 2)
			{
				AdminPlayerEntry adminPlayerEntry = _adminPlayers[i];
				if (RawRowButton(BuildAdminPlayerButton(adminPlayerEntry), 0, 2))
				{
					SelectAdminPlayer(adminPlayerEntry.ClientId);
				}
				if (i + 1 < num3)
				{
					AdminPlayerEntry adminPlayerEntry2 = _adminPlayers[i + 1];
					if (RawRowButton(BuildAdminPlayerButton(adminPlayerEntry2), 1, 2))
					{
						SelectAdminPlayer(adminPlayerEntry2.ClientId);
					}
				}
				RawNextRow();
			}
			if (RawRowButton("Previous page", 0, 3))
			{
				_adminPlayerPage = Math.Max(0, _adminPlayerPage - 1);
			}
			if (RawRowButton("Refresh", 1, 3))
			{
				RefreshAdminPlayerList(force: true);
			}
			if (RawRowButton("Next page", 2, 3))
			{
				_adminPlayerPage = Math.Min(num - 1, _adminPlayerPage + 1);
			}
			RawNextRow();
			AdminPlayerEntry selectedAdminPlayer = GetSelectedAdminPlayer();
			if (selectedAdminPlayer == null)
			{
				RawLabel("Select a player above.");
				return;
			}
			RawSection("SELECTED PLAYER");
			RawLabel($"{selectedAdminPlayer.Name} | client {selectedAdminPlayer.ClientId} | {selectedAdminPlayer.Team}");
			if (RawRowButton("Spawn Blue", 0, 4))
			{
				ForceClientIntoMatch(selectedAdminPlayer, silent: false, (TeamType)1);
			}
			if (RawRowButton("Spawn Red", 1, 4))
			{
				ForceClientIntoMatch(selectedAdminPlayer, silent: false, (TeamType)2);
			}
			if (RawRowButton("Freeze beetle", 2, 4))
			{
				SetSelectedPlayerFrozen(frozen: true);
			}
			if (RawRowButton("Release / unstun", 3, 4))
			{
				SetSelectedPlayerFrozen(frozen: false);
			}
			RawNextRow();
			if (RawRowButton("Team Blue", 0, 3))
			{
				SetSelectedPlayerTeam((TeamType)1);
			}
			if (RawRowButton("Team Red", 1, 3))
			{
				SetSelectedPlayerTeam((TeamType)2);
			}
			if (RawRowButton("Auto team", 2, 3))
			{
				SetSelectedPlayerTeam((TeamType)0);
			}
			RawNextRow();
			float selectedPlayerScale = _selectedPlayerScale;
			_selectedPlayerScale = RawUnboundedStepper("Scale", _selectedPlayerScale, 0.05f, 0.25f, 1f);
			if (Math.Abs(selectedPlayerScale - _selectedPlayerScale) > 0.0001f)
			{
				SetSelectedPlayerScale(_selectedPlayerScale);
			}
			if (RawRowButton("Micro 0.05x", 0, 4))
			{
				SetSelectedPlayerScalePreset(0.05f);
			}
			if (RawRowButton("Normal 1x", 1, 4))
			{
				SetSelectedPlayerScalePreset(1f);
			}
			if (RawRowButton("Giant 25x", 2, 4))
			{
				SetSelectedPlayerScalePreset(25f);
			}
			if (RawRowButton("Double", 3, 4))
			{
				SetSelectedPlayerScalePreset(SafeDouble(_selectedPlayerScale));
			}
			RawNextRow();
			if (!flag && RawRowButton("Reset local-view state", 0, 1))
			{
				RestoreAllJoinedClientVisualPlayerStates();
			}
			RawNextRow();
			DrawRawGlobalCooldownControls();
			RawSection("PERSISTENT PROFILE LIMIT");
			RawLabel("XP, levels, and skins are stored by each player's local Steam stats.");
		}

		private void RefreshAdminPlayerList(bool force)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			if (!force && Time.unscaledTime < _nextAdminPlayerRefreshAt)
			{
				return;
			}
			_nextAdminPlayerRefreshAt = Time.unscaledTime + 1f;
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
				{
					_adminPlayers.Clear();
					return;
				}
				ulong selectedAdminClientId = _selectedAdminClientId;
				_adminPlayers.Clear();
				LobbyPlayerDataManager instance = LobbyPlayerDataManager.Instance;
				NetworkList<Player> val = ((instance != null) ? instance.Players : null);
				if (val != null)
				{
					for (int i = 0; i < val.Count; i++)
					{
						Player val2 = val[i];
						ulong clientId = val2.clientId;
						AdminPlayerEntry item = new AdminPlayerEntry
						{
							ClientId = clientId,
							SteamId = val2.steamId,
							Name = ResolveSteamPlayerName(val2.steamId, clientId),
							Team = val2.team,
							ClassIndex = Math.Max(0, val2.classIndex),
							IsModded = (clientId == singleton.LocalClientId || _moddedClientIds.Contains(clientId)),
							HasBeetle = ((Object)(object)FindActorForClient(clientId) != (Object)null)
						};
						_adminPlayers.Add(item);
					}
				}
				foreach (BeetleActor actor in Object.FindObjectsOfType<BeetleActor>())
				{
					if (!((Object)(object)actor == (Object)null) && ((NetworkBehaviour)actor).IsSpawned)
					{
						AdminPlayerEntry adminPlayerEntry = _adminPlayers.FirstOrDefault((AdminPlayerEntry p) => p.ClientId == ((NetworkBehaviour)actor).OwnerClientId);
						if (adminPlayerEntry != null)
						{
							adminPlayerEntry.HasBeetle = true;
							continue;
						}
						_adminPlayers.Add(new AdminPlayerEntry
						{
							ClientId = ((NetworkBehaviour)actor).OwnerClientId,
							Name = $"Client {((NetworkBehaviour)actor).OwnerClientId}",
							Team = ((NetworkActor)actor).Team,
							IsModded = (((NetworkBehaviour)actor).OwnerClientId == singleton.LocalClientId || _moddedClientIds.Contains(((NetworkBehaviour)actor).OwnerClientId)),
							HasBeetle = true
						});
					}
				}
				if (_adminPlayers.Count == 0)
				{
					ulong localClientId = singleton.LocalClientId;
					_adminPlayers.Add(new AdminPlayerEntry
					{
						ClientId = localClientId,
						Name = $"Client {localClientId}",
						Team = (TeamType)0,
						IsModded = true,
						HasBeetle = ((Object)(object)FindActorForClient(localClientId) != (Object)null)
					});
				}
				_adminPlayers.Sort((AdminPlayerEntry a, AdminPlayerEntry b) => a.ClientId.CompareTo(b.ClientId));
				_selectedAdminClientId = selectedAdminClientId;
				if (GetSelectedAdminPlayer() == null && _adminPlayers.Count > 0)
				{
					SelectAdminPlayer(_adminPlayers[0].ClientId);
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Could not refresh player list: " + ex.Message);
			}
		}

		private static string ResolveSteamPlayerName(ulong steamId, ulong clientId)
		{
			//IL_002b: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (steamId == 0L)
			{
				return $"Client {clientId}";
			}
			try
			{
				SteamId id = new SteamId
				{
					Value = steamId
				};
				string text = SteamUsersCache.SafeName(new Friend
				{
					Id = id
				});
				return string.IsNullOrWhiteSpace(text) ? $"Steam {steamId}" : text;
			}
			catch
			{
				return $"Steam {steamId}";
			}
		}

		private string BuildAdminPlayerButton(AdminPlayerEntry entry)
		{
			string value = ((entry.ClientId == _selectedAdminClientId) ? "> " : "");
			string value2 = (entry.HasBeetle ? "PLAY" : "SPEC");
			string value3 = ((entry.Name.Length > 20) ? entry.Name.Substring(0, 20) : entry.Name);
			return $"{value}{value3} [{value2}]";
		}

		private void SelectAdminPlayer(ulong clientId)
		{
			_selectedAdminClientId = clientId;
			Dictionary<ulong, HostAdminPlayerState> dictionary = (IsNetworkServerHost() ? _hostAdminPlayerStates : _joinedClientVisualPlayerStates);
			_selectedPlayerScale = (dictionary.TryGetValue(clientId, out var value) ? value.Scale : 1f);
			AdminPlayerEntry selectedAdminPlayer = GetSelectedAdminPlayer();
			if (selectedAdminPlayer != null)
			{
				SetStatus("Selected " + selectedAdminPlayer.Name);
			}
		}

		private AdminPlayerEntry? GetSelectedAdminPlayer()
		{
			return _adminPlayers.FirstOrDefault((AdminPlayerEntry p) => p.ClientId == _selectedAdminClientId);
		}

		private void SpawnLocalPlayerIntoMatch(TeamType requestedTeam)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager manager = NetworkManager.Singleton;
			if ((Object)(object)manager == (Object)null || !manager.IsListening)
			{
				SetStatus("Join or host a session first.");
				return;
			}
			RefreshAdminPlayerList(force: true);
			AdminPlayerEntry adminPlayerEntry = _adminPlayers.FirstOrDefault((AdminPlayerEntry p) => p.ClientId == manager.LocalClientId);
			if (adminPlayerEntry == null)
			{
				adminPlayerEntry = new AdminPlayerEntry
				{
					ClientId = manager.LocalClientId,
					Name = $"Client {manager.LocalClientId}",
					ClassIndex = 0,
					Team = (TeamType)0
				};
			}
			ForceClientIntoMatch(adminPlayerEntry, silent: false, requestedTeam);
		}

		private void ForceClientIntoMatch(AdminPlayerEntry entry, bool silent, TeamType requestedTeam = (TeamType)0)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ForceClientIntoMatchUnsafe(entry, silent, requestedTeam);
			}
			catch (Exception exception)
			{
				ReportException("requesting a player spawn", exception);
			}
		}

		private void ForceClientIntoMatchUnsafe(AdminPlayerEntry entry, bool silent, TeamType requestedTeam)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected I4, but got Unknown
			//IL_0095: 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_009b: 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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected I4, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				if (!silent)
				{
					SetStatus("Join or host a session first.");
				}
			}
			else if (singleton.IsServer)
			{
				TeamType val = ResolveRequestedSpawnTeam(entry, requestedTeam);
				ForceClientIntoMatchOnServer(entry, val);
				if (!silent)
				{
					SetStatus($"Spawned {entry.Name} on {val}");
				}
			}
			else if (entry.ClientId == singleton.LocalClientId)
			{
				TeamType val2 = ResolveRequestedSpawnTeam(entry, requestedTeam);
				if (HasReadyHostRelay())
				{
					SendServerAdminRequest(ServerAdminAction.ForceIntoMatch, entry.ClientId, (int)val2, 0f, silent);
					if (!silent)
					{
						SetStatus($"Requested a {val2} spawn from the modded host");
					}
				}
				else
				{
					BeginPendingLocalSpectatorSpawn(entry, val2, silent);
				}
			}
			else
			{
				SendServerAdminRequest(ServerAdminAction.ForceIntoMatch, entry.ClientId, (int)ResolveRequestedSpawnTeam(entry, requestedTeam), 0f, silent);
			}
		}

		private void BeginPendingLocalSpectatorSpawn(AdminPlayerEntry entry, TeamType team, bool silent)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_00a3: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			NetworkPrefabSpawner instance = NetworkPrefabSpawner.Instance;
			if ((Object)(object)singleton == (Object)null || (Object)(object)instance == (Object)null || !singleton.IsListening || !singleton.IsConnectedClient)
			{
				if (!silent)
				{
					SetStatus("Spawner is not ready for a client spawn.");
				}
				return;
			}
			ClearPendingLocalSpectatorSpawn();
			_pendingLocalSpawnStage = 1;
			_pendingLocalSpawnTeam = team;
			_pendingLocalSpawnClassIndex = Math.Max(0, entry.ClassIndex);
			_pendingLocalSpawnAttempts = 0;
			_pendingLocalSpawnSilent = silent;
			_pendingLocalSpawnAt = Time.unscaledTime + 0.35f;
			_pendingLocalSpawnDeadline = Time.unscaledTime + 5f;
			try
			{
				instance.BecomeSpectator_ServerRpc(CreateDefaultSpawnPositionData(), new RpcParams());
				if (!silent)
				{
					SetStatus($"Resetting spectator state; {team} spawn queued");
				}
			}
			catch (Exception ex)
			{
				ClearPendingLocalSpectatorSpawn();
				if (!silent)
				{
					ReportException("resetting local spectator state", ex);
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("Could not reset local spectator state: " + ex.Message);
				}
			}
		}

		private void UpdatePendingLocalSpectatorSpawn()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (_pendingLocalSpawnStage == 0)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening || !singleton.IsConnectedClient || singleton.IsServer)
			{
				bool pendingLocalSpawnSilent = _pendingLocalSpawnSilent;
				ClearPendingLocalSpectatorSpawn();
				if (!pendingLocalSpawnSilent)
				{
					SetStatus("Queued spectator spawn cancelled because the session changed");
				}
			}
			else if (unscaledTime >= _pendingLocalSpawnDeadline)
			{
				bool pendingLocalSpawnSilent2 = _pendingLocalSpawnSilent;
				ClearPendingLocalSpectatorSpawn();
				if (!pendingLocalSpawnSilent2)
				{
					SetStatus("The server did not create a local beetle after two spawn requests");
				}
			}
			else
			{
				if (unscaledTime < _pendingLocalSpawnAt)
				{
					return;
				}
				if (_pendingLocalSpawnStage == 1)
				{
					if (!SendPendingLocalSpawnRpc())
					{
						ClearPendingLocalSpectatorSpawn();
						return;
					}
					_pendingLocalSpawnAttempts = 1;
					_pendingLocalSpawnStage = 2;
					_pendingLocalSpawnAt = unscaledTime + 1.25f;
					return;
				}
				BeetleActor val = FindActorForClient(singleton.LocalClientId);
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).IsSpawned)
				{
					TeamType pendingLocalSpawnTeam = _pendingLocalSpawnTeam;
					int pendingLocalSpawnAttempts = _pendingLocalSpawnAttempts;
					bool pendingLocalSpawnSilent3 = _pendingLocalSpawnSilent;
					ClearPendingLocalSpectatorSpawn();
					_nextAdminPlayerRefreshAt = 0f;
					if (!pendingLocalSpawnSilent3)
					{
						SetStatus($"Spawned locally on {pendingLocalSpawnTeam} after {pendingLocalSpawnAttempts} request(s)");
					}
				}
				else if (_pendingLocalSpawnAttempts < 2)
				{
					if (!SendPendingLocalSpawnRpc())
					{
						ClearPendingLocalSpectatorSpawn();
						return;
					}
					_pendingLocalSpawnAttempts++;
					_pendingLocalSpawnAt = unscaledTime + 1.5f;
					if (!_pendingLocalSpawnSilent)
					{
						SetStatus($"Server has not spawned the beetle yet; retrying {_pendingLocalSpawnTeam}");
					}
				}
				else
				{
					bool pendingLocalSpawnSilent4 = _pendingLocalSpawnSilent;
					ClearPendingLocalSpectatorSpawn();
					if (!pendingLocalSpawnSilent4)
					{
						SetStatus("The server ignored both local spectator spawn requests");
					}
				}
			}
		}

		private bool SendPendingLocalSpawnRpc()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				NetworkPrefabSpawner instance = NetworkPrefabSpawner.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					throw new InvalidOperationException("Network prefab spawner is unavailable.");
				}
				try
				{
					LobbyPlayerDataManager instance2 = LobbyPlayerDataManager.Instance;
					if (instance2 != null)
					{
						instance2.SetPlayerClassIndexData(_pendingLocalSpawnClassIndex);
					}
					if (instance2 != null)
					{
						instance2.SetPlayerTeamData(_pendingLocalSpawnTeam);
					}
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Warning("Could not update local lobby spawn data: " + ex.Message);
				}
				SetTeamData val = new SetTeamData
				{
					setTeam = true,
					team = _pendingLocalSpawnTeam
				};
				instance.SpawnClass_ServerRpc(_pendingLocalSpawnClassIndex, CreateDefaultSpawnPositionData(), val, new RpcParams());
				return true;
			}
			catch (Exception ex2)
			{
				if (!_pendingLocalSpawnSilent)
				{
					ReportException("sending the local spectator spawn request", ex2);
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("Could not send local spectator spawn request: " + ex2.Message);
				}
				return false;
			}
		}

		private static SpawnPositionData CreateDefaultSpawnPositionData()
		{
			//IL_0002: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new SpawnPositionData
			{
				usePosition = false,
				useRotation = false,
				position = Vector3.zero,
				rotation = Quaternion.identity
			};
		}

		private void ClearPendingLocalSpectatorSpawn()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_pendingLocalSpawnStage = 0;
			_pendingLocalSpawnTeam = (TeamType)0;
			_pendingLocalSpawnClassIndex = 0;
			_pendingLocalSpawnAttempts = 0;
			_pendingLocalSpawnSilent = false;
			_pendingLocalSpawnAt = 0f;
			_pendingLocalSpawnDeadline = 0f;
		}

		private static TeamType ResolveRequestedSpawnTeam(AdminPlayerEntry entry, TeamType requestedTeam)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			if ((int)requestedTeam == 1 || (int)requestedTeam == 2)
			{
				return requestedTeam;
			}
			if ((int)entry.Team == 1 || (int)entry.Team == 2)
			{
				return entry.Team;
			}
			if ((int)MatchStateController.GetLeastRepresentedTeam() == 2)
			{
				return (TeamType)2;
			}
			return (TeamType)1;
		}

		private void ForceClientIntoMatchOnServer(AdminPlayerEntry entry, TeamType requestedTeam = (TeamType)0)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			NetworkPrefabSpawner instance = NetworkPrefabSpawner.Instance;
			if ((Object)(object)singleton == (Object)null || (Object)(object)instance == (Object)null)
			{
				throw new InvalidOperationException("Spawner not ready.");
			}
			NetworkSpawnManager spawnManager = singleton.SpawnManager;
			NetworkObject val = ((spawnManager != null) ? spawnManager.GetPlayerNetworkObject(entry.ClientId) : null);
			if ((Object)(object)val != (Object)null && val.IsSpawned)
			{
				val.Despawn(true);
			}
			TeamType val2 = ResolveRequestedSpawnTeam(entry, requestedTeam);
			instance.SpawnClassAndSetTeam(entry.ClientId, val2, Math.Max(0, entry.ClassIndex));
		}

		private void ForceAllSpectatorsIntoMatch()
		{
			NetworkManager manager = NetworkManager.Singleton;
			if ((Object)(object)manager == (Object)null || !manager.IsListening)
			{
				SetStatus("Join or host a session first.");
				return;
			}
			if (manager.IsServer)
			{
				int num = ForceAllSpectatorsIntoMatchOnServer();
				SetStatus((num == 0) ? "No spectators." : $"Added {num} spectator(s).");
				return;
			}
			RefreshAdminPlayerList(force: true);
			AdminPlayerEntry adminPlayerEntry = _adminPlayers.FirstOrDefault((AdminPlayerEntry p) => p.ClientId == manager.LocalClientId && !p.HasBeetle);
			if (adminPlayerEntry != null)
			{
				ForceClientIntoMatch(adminPlayerEntry, silent: true, (TeamType)0);
			}
			SendServerAdminRequest(ServerAdminAction.AddSpectators, ulong.MaxValue);
		}

		private int ForceAllSpectatorsIntoMatchOnServer()
		{
			RefreshAdminPlayerList(force: true);
			int num = 0;
			foreach (AdminPlayerEntry item in _adminPlayers.Where((AdminPlayerEntry p) => !p.HasBeetle))
			{
				ForceClientIntoMatchOnServer(item, (TeamType)0);
				num++;
			}
			_nextAdminPlayerRefreshAt = 0f;
			return num;
		}

		private void SetSelectedPlayerFrozen(bool frozen)
		{
			AdminPlayerEntry selectedAdminPlayer = GetSelectedAdminPlayer();
			if (selectedAdminPlayer == null)
			{
				return;
			}
			BeetleActor val = FindActorForClient(selectedAdminPlayer.ClientId);
			if ((Object)(object)val == (Object)null)
			{
				SetStatus(selectedAdminPlayer.Name + " has no beetle.");
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			HostAdminPlayerState obj = (((Object)(object)singleton != (Object)null && singleton.IsServer) ? GetOrCreateHostAdminState(selectedAdminPlayer.ClientId) : GetOrCreateJoinedClientVisualState(selectedAdminPlayer.ClientId));
			obj.Frozen = frozen;
			obj.NextStunAt = 0f;
			TryDispatchPlayerStun(val, frozen ? 30f : 0.01f);
			if (!frozen)
			{
				val.UnStun();
			}
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(frozen ? ServerAdminAction.FreezePlayer : ServerAdminAction.ReleasePlayer, selectedAdminPlayer.ClientId);
			}
			SetStatus((frozen ? "Froze" : "Released") + " " + selectedAdminPlayer.Name);
		}

		private static bool TryDispatchPlayerStun(BeetleActor actor, float duration)
		{
			try
			{
				StunForDurationRpcDispatcher val = actor.stunDispatcher ?? ((Component)actor).GetComponent<StunForDurationRpcDispatcher>();
				if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsSpawned)
				{
					return false;
				}
				((SingleTargetParamRpcDispatcher<float>)(object)val).DispatchRpcOrPerformLocal(Mathf.Max(0.01f, duration));
				return true;
			}
			catch
			{
				return false;
			}
		}

		private void SetSelectedPlayerTeam(TeamType requestedTeam)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected I4, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_0083: Expected I4, but got Unknown
			AdminPlayerEntry selectedAdminPlayer = GetSelectedAdminPlayer();
			if (selectedAdminPlayer == null)
			{
				return;
			}
			BeetleActor val = FindActorForClient(selectedAdminPlayer.ClientId);
			if ((Object)(object)val == (Object)null)
			{
				SendServerAdminRequest(ServerAdminAction.SetPlayerTeam, selectedAdminPlayer.ClientId, (int)requestedTeam);
				return;
			}
			TeamType val2 = (((int)requestedTeam == 0) ? MatchStateController.GetLeastRepresentedTeam() : requestedTeam);
			if ((int)val2 == 0)
			{
				val2 = (TeamType)1;
			}
			val.SetTeam_ServerRpc(val2);
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(ServerAdminAction.SetPlayerTeam, selectedAdminPlayer.ClientId, (int)val2);
			}
			SetStatus($"Set {selectedAdminPlayer.Name} to {val2}");
		}

		private void SetSelectedPlayerScalePreset(float scale)
		{
			_selectedPlayerScale = Mathf.Max(0.05f, scale);
			SetSelectedPlayerScale(_selectedPlayerScale);
		}

		private void SetSelectedPlayerScale(float scale)
		{
			AdminPlayerEntry selectedAdminPlayer = GetSelectedAdminPlayer();
			if (selectedAdminPlayer == null)
			{
				return;
			}
			scale = Mathf.Max(0.05f, scale);
			_selectedPlayerScale = scale;
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				SetStatus("Join or host a session first.");
			}
			else if (!singleton.IsServer)
			{
				BeetleActor val = FindActorForClient(selectedAdminPlayer.ClientId);
				if (selectedAdminPlayer.ClientId == singleton.LocalClientId)
				{
					_playerSize = scale;
					_playerTuning = true;
					if ((Object)(object)val != (Object)null)
					{
						RefreshPlayerSnapshot(val);
						ApplyPlayerTuning(val);
					}
				}
				else
				{
					GetOrCreateJoinedClientVisualState(selectedAdminPlayer.ClientId).Scale = scale;
					ApplyJoinedClientVisualPlayerStates();
				}
				SetStatus($"Set {selectedAdminPlayer.Name} scale to {scale:0.##}x (local)");
			}
			else
			{
				if (selectedAdminPlayer.ClientId == singleton.LocalClientId)
				{
					_playerSize = scale;
					_playerTuning = true;
				}
				else
				{
					GetOrCreateHostAdminState(selectedAdminPlayer.ClientId).Scale = scale;
					ApplyHostPlayerAdminStates();
				}
				if (selectedAdminPlayer.IsModded)
				{
					SendAdminClientCommand(selectedAdminPlayer.ClientId, AdminClientAction.SetScale, 0, scale);
					SetStatus($"Sent {scale:0.##}x scale to modded owner {selectedAdminPlayer.Name}");
				}
				else
				{
					SetStatus($"Tried {scale:0.##}x in host view; vanilla owner may overwrite it");
				}
			}
		}

		private HostAdminPlayerState GetOrCreateJoinedClientVisualState(ulong clientId)
		{
			if (!_joinedClientVisualPlayerStates.TryGetValue(clientId, out HostAdminPlayerState value))
			{
				value = new HostAdminPlayerState
				{
					ClientId = clientId
				};
				_joinedClientVisualPlayerStates[clientId] = value;
			}
			return value;
		}

		private void ApplyJoinedClientVisualPlayerStates()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			if (_joinedClientVisualPlayerStates.Count == 0)
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.IsServer)
			{
				RestoreAllJoinedClientVisualPlayerStates();
				return;
			}
			_adminStateCleanup.Clear();
			foreach (KeyValuePair<ulong, HostAdminPlayerState> joinedClientVisualPlayerState in _joinedClientVisualPlayerStates)
			{
				HostAdminPlayerState value = joinedClientVisualPlayerState.Value;
				BeetleActor val = FindActorForClient(value.ClientId);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					if (value.ActorPointer != ((Il2CppObjectBase)val).Pointer)
					{
						value.ActorPointer = ((Il2CppObjectBase)val).Pointer;
						value.Actor = val;
						value.BaseScale = ((Component)val).transform.localScale;
						value.LastAppliedScale = ((Component)val).transform.localScale;
					}
					if (Math.Abs(value.Scale - 1f) <= 0.0001f)
					{
						((Component)val).transform.localScale = value.BaseScale;
						if (!value.Frozen)
						{
							_adminStateCleanup.Add(joinedClientVisualPlayerState.Key);
						}
					}
					else
					{
						Vector3 localScale = ((Component)val).transform.localScale;
						Vector3 val2 = localScale - value.LastAppliedScale;
						if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
						{
							value.BaseScale = localScale;
						}
						Vector3 val3 = value.BaseScale * value.Scale;
						((Component)val).transform.localScale = val3;
						value.LastAppliedScale = val3;
					}
					if (value.Frozen && (Object)(object)((NetworkActor)val).RB != (Object)null)
					{
						((NetworkActor)val).RB.linearVelocity = Vector3.zero;
						((NetworkActor)val).RB.angularVelocity = Vector3.zero;
						if (Time.unscaledTime >= value.NextStunAt)
						{
							TryDispatchPlayerStun(val, 30f);
							value.NextStunAt = Time.unscaledTime + 10f;
						}
					}
				}
				catch
				{
				}
			}
			foreach (ulong item in _adminStateCleanup)
			{
				_joinedClientVisualPlayerStates.Remove(item);
			}
		}

		private void RestoreAllJoinedClientVisualPlayerStates()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			foreach (HostAdminPlayerState value in _joinedClientVisualPlayerStates.Values)
			{
				try
				{
					if ((Object)(object)value.Actor != (Object)null)
					{
						((Component)value.Actor).transform.localScale = value.BaseScale;
						if (value.Frozen)
						{
							TryDispatchPlayerStun(value.Actor, 0.01f);
							value.Actor.UnStun();
						}
					}
				}
				catch
				{
				}
			}
			_joinedClientVisualPlayerStates.Clear();
			_selectedPlayerScale = 1f;
			SetStatus("Restored local-view sizes.");
		}

		private HostAdminPlayerState GetOrCreateHostAdminState(ulong clientId)
		{
			if (!_hostAdminPlayerStates.TryGetValue(clientId, out HostAdminPlayerState value))
			{
				value = new HostAdminPlayerState
				{
					ClientId = clientId
				};
				_hostAdminPlayerStates[clientId] = value;
			}
			return value;
		}

		private void ApplyHostPlayerAdminStates()
		{
			//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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00dc: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			if (_hostAdminPlayerStates.Count == 0)
			{
				return;
			}
			if (!IsNetworkServerHost())
			{
				RestoreAllHostAdminPlayerStates();
				return;
			}
			_adminStateCleanup.Clear();
			foreach (KeyValuePair<ulong, HostAdminPlayerState> hostAdminPlayerState in _hostAdminPlayerStates)
			{
				HostAdminPlayerState value = hostAdminPlayerState.Value;
				BeetleActor val = FindActorForClient(value.ClientId);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					if (value.ActorPointer != ((Il2CppObjectBase)val).Pointer)
					{
						value.ActorPointer = ((Il2CppObjectBase)val).Pointer;
						value.Actor = val;
						value.BaseScale = ((Component)val).transform.localScale;
						value.LastAppliedScale = ((Component)val).transform.localScale;
					}
					if (Math.Abs(value.Scale - 1f) > 0.0001f)
					{
						Vector3 localScale = ((Component)val).transform.localScale;
						Vector3 val2 = localScale - value.LastAppliedScale;
						if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
						{
							value.BaseScale = localScale;
						}
						EnableNetworkScaleSync((Component)(object)val);
						Vector3 val3 = value.BaseScale * value.Scale;
						((Component)val).transform.localScale = val3;
						value.LastAppliedScale = val3;
					}
					if (value.Frozen && (Object)(object)((NetworkActor)val).RB != (Object)null)
					{
						((NetworkActor)val).RB.linearVelocity = Vector3.zero;
						((NetworkActor)val).RB.angularVelocity = Vector3.zero;
						if (Time.unscaledTime >= value.NextStunAt)
						{
							val.Stun(30f);
							value.NextStunAt = Time.unscaledTime + 10f;
						}
					}
					if (!value.Frozen && Math.Abs(value.Scale - 1f) <= 0.0001f)
					{
						if ((Object)(object)value.Actor != (Object)null)
						{
							((Component)value.Actor).transform.localScale = value.BaseScale;
						}
						_adminStateCleanup.Add(hostAdminPlayerState.Key);
					}
				}
				catch
				{
				}
			}
			foreach (ulong item in _adminStateCleanup)
			{
				_hostAdminPlayerStates.Remove(item);
			}
		}

		private void RestoreAllHostAdminPlayerStates()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			foreach (HostAdminPlayerState value in _hostAdminPlayerStates.Values)
			{
				try
				{
					if ((Object)(object)value.Actor != (Object)null)
					{
						((Component)value.Actor).transform.localScale = value.BaseScale;
						if (value.Frozen)
						{
							value.Actor.Stun(0.01f);
							value.Actor.UnStun();
						}
					}
				}
				catch
				{
				}
			}
			_hostAdminPlayerStates.Clear();
		}

		private void ReleaseAllAdminFreezes()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				foreach (HostAdminPlayerState value in _joinedClientVisualPlayerStates.Values)
				{
					value.Frozen = false;
					BeetleActor val = FindActorForClient(value.ClientId);
					if ((Object)(object)val != (Object)null)
					{
						TryDispatchPlayerStun(val, 0.01f);
						val.UnStun();
					}
				}
				ApplyJoinedClientVisualPlayerStates();
				SendServerAdminRequest(ServerAdminAction.ReleaseAllFreezes, ulong.MaxValue);
			}
			else
			{
				ReleaseAllAdminFreezesOnServer();
				SetStatus("Released all freezes.");
			}
		}

		private void ReleaseAllAdminFreezesOnServer()
		{
			foreach (HostAdminPlayerState value in _hostAdminPlayerStates.Values)
			{
				value.Frozen = false;
				BeetleActor val = FindActorForClient(value.ClientId);
				if ((Object)(object)val != (Object)null)
				{
					val.Stun(0.01f);
					val.UnStun();
				}
			}
		}

		private void RestoreAllAdminPlayerSizes()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				foreach (HostAdminPlayerState value in _joinedClientVisualPlayerStates.Values)
				{
					value.Scale = 1f;
				}
				ApplyJoinedClientVisualPlayerStates();
				_selectedPlayerScale = 1f;
				SendServerAdminRequest(ServerAdminAction.RestoreAllPlayerSizes, ulong.MaxValue);
			}
			else
			{
				RestoreAllAdminPlayerSizesOnServer();
				SetStatus("Restored all player sizes.");
			}
		}

		private void RestoreAllAdminPlayerSizesOnServer()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			foreach (HostAdminPlayerState value in _hostAdminPlayerStates.Values)
			{
				value.Scale = 1f;
				if ((Object)(object)value.Actor != (Object)null)
				{
					try
					{
						((Component)value.Actor).transform.localScale = value.BaseScale;
					}
					catch
					{
					}
				}
				if ((Object)(object)NetworkManager.Singleton != (Object)null && _moddedClientIds.Contains(value.ClientId))
				{
					SendAdminClientCommand(value.ClientId, AdminClientAction.SetScale, 0, 1f);
				}
			}
			_selectedPlayerScale = 1f;
		}

		private void ResetHostedRound()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(ServerAdminAction.ResetRound, ulong.MaxValue);
				return;
			}
			try
			{
				ResetRoundOnServer();
				SetStatus("Reset scores and round.");
			}
			catch (Exception exception)
			{
				ReportException("resetting round", exception);
			}
		}

		private static void ResetRoundOnServer()
		{
			MatchStateController instance = MatchStateController.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				throw new InvalidOperationException("MatchStateController unavailable.");
			}
			instance.ResetMatch();
			instance.InitializeRound();
		}

		private void RestartHostedMatch()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(ServerAdminAction.RestartMatch, ulong.MaxValue);
				return;
			}
			try
			{
				RestartMatchOnServer();
				_pendingForceSpectatorsAt = Time.unscaledTime + 1.25f;
				SetStatus("Restarted match; spectators will be added.");
			}
			catch (Exception exception)
			{
				ReportException("restarting match", exception);
			}
		}

		private static void RestartMatchOnServer()
		{
			MatchStateController instance = MatchStateController.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				throw new InvalidOperationException("MatchStateController unavailable.");
			}
			instance.InitializeMatch();
		}

		private void ClearAllDungAsHost()
		{
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				Il2CppArrayBase<DungBall> obj = Object.FindObjectsOfType<DungBall>();
				int num = 0;
				foreach (DungBall item in obj)
				{
					if (!((Object)(object)item == (Object)null) && !((Object)(object)((NetworkBehaviour)item).NetworkObject == (Object)null) && ((NetworkBehaviour)item).NetworkObject.IsSpawned)
					{
						if ((Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer)
						{
							item.Despawn_ServerRpc();
						}
						else
						{
							((NetworkBehaviour)item).NetworkObject.Despawn(true);
						}
						num++;
					}
				}
				SetStatus($"Cleared {num} dung balls.");
			}
			catch (Exception exception)
			{
				ReportException("clearing dung", exception);
			}
		}

		private void DrawRawGlobalCooldownControls()
		{
			RawSection("ALL-PLAYER COOLDOWNS");
			bool flag = RawToggle("Enable global cooldown factor", _globalCooldownEnabled);
			if (flag != _globalCooldownEnabled)
			{
				_globalCooldownEnabled = flag;
				if (!flag)
				{
					RestoreGlobalCooldowns();
				}
				SyncGlobalCooldownToModdedClients(flag);
				RequestGlobalCooldownFromServer();
				SetStatus(flag ? $"Global cooldown at {_globalCooldownFactor:0.00}x" : "Global cooldown restored");
			}
			float globalCooldownFactor = _globalCooldownFactor;
			_globalCooldownFactor = RawStepper("Cooldown factor (0=none)", _globalCooldownFactor, 0f, 2f, 0.05f, 1f);
			if (_globalCooldownEnabled && Math.Abs(globalCooldownFactor - _globalCooldownFactor) > 0.0001f)
			{
				SyncGlobalCooldownToModdedClients(enabled: true);
				RequestGlobalCooldownFromServer();
				SetStatus($"Global cooldown set to {_globalCooldownFactor:0.00}x");
			}
		}

		private void RequestGlobalCooldownFromServer()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsListening && !singleton.IsServer)
			{
				SendServerAdminRequest(ServerAdminAction.SetGlobalCooldown, ulong.MaxValue, _globalCooldownEnabled ? 1 : 0, _globalCooldownFactor, quiet: true);
			}
		}

		private void ApplyGlobalCooldowns()
		{
			if (!_globalCooldownEnabled)
			{
				if (_globalCooldownSnapshots.Count > 0)
				{
					RestoreGlobalCooldowns();
				}
				return;
			}
			try
			{
				float num = Mathf.Clamp(_globalCooldownFactor, 0f, 2f);
				Il2CppArrayBase<BeetleActor> obj = Object.FindObjectsOfType<BeetleActor>();
				_globalCooldownSeen.Clear();
				foreach (BeetleActor item in obj)
				{
					BeetleStatModifiersController val = ((item != null) ? item.StatModifiersController : null);
					if (!((Object)(object)item == (Object)null) && !((Object)(object)val == (Object)null))
					{
						IntPtr pointer = ((Il2CppObjectBase)item).Pointer;
						_globalCooldownSeen.Add(pointer);
						if (!_globalCooldownSnapshots.TryGetValue(pointer, out GlobalCooldownSnapshot value))
						{
							value = CaptureGlobalCooldownSnapshot(item, val);
							_globalCooldownSnapshots[pointer] = value;
						}
						BeetleStats stats = item.Stats;
						stats.GrabCooldownDuration = value.GrabCooldown * num;
						stats.HeadbuttCooldown = value.HeadbuttCooldown * num;
						stats.ShootBallRecoveryDuration = value.ShootRecovery * num;
						val.ModifiedStats = stats;
						item.jumpCooldown = value.JumpCooldown * num;
						item.ballJumpCooldown = value.BallJumpCooldown * num;
						SetLiveCooldownTimer(item.GrabCooldownTimer, value.GrabTimer, num);
						SetLiveCooldownTimer(item.JumpCooldownTimer, value.JumpTimer, num);
						SetLiveCooldownTimer(item.HeadbuttCooldownTimer, value.HeadbuttTimer, num);
						SetLiveCooldownTimer(item.BallJumpCooldownTimer, value.BallJumpTimer, num);
						SetLiveCooldownTimer(item.ShootBallRecoveryTimer, value.ShootRecoveryTimer, num);
					}
				}
				_globalCooldownCleanup.Clear();
				foreach (KeyValuePair<IntPtr, GlobalCooldownSnapshot> globalCooldownSnapshot in _globalCooldownSnapshots)
				{
					if (!_globalCooldownSeen.Contains(globalCooldownSnapshot.Key))
					{
						_globalCooldownCleanup.Add(globalCooldownSnapshot.Key);
					}
				}
				foreach (IntPtr item2 in _globalCooldownCleanup)
				{
					_globalCooldownSnapshots.Remove(item2);
				}
			}
			catch (Exception exception)
			{
				ReportException("applying global cooldowns", exception);
			}
		}

		private GlobalCooldownSnapshot CaptureGlobalCooldownSnapshot(BeetleActor actor, BeetleStatModifiersController controller)
		{
			BeetleStats baselineStats = actor.Stats;
			try
			{
				if ((Object)(object)actor.BaseStats != (Object)null)
				{
					baselineStats = actor.BaseStats.Data;
				}
			}
			catch
			{
			}
			float jumpCooldown = actor.jumpCooldown;
			float ballJumpCooldown = actor.ballJumpCooldown;
			if (_playerSnapshot != null && _playerSnapshot.ActorPointer == ((Il2CppObjectBase)actor).Pointer)
			{
				jumpCooldown = _playerSnapshot.JumpCooldown;
				ballJumpCooldown = _playerSnapshot.BallJumpCooldown;
			}
			return new GlobalCooldownSnapshot(actor, controller, baselineStats, jumpCooldown, ballJumpCooldown);
		}

		private void RestoreGlobalCooldowns()
		{
			foreach (GlobalCooldownSnapshot value in _globalCooldownSnapshots.Values)
			{
				try
				{
					if (!((Object)(object)value.Actor == (Object)null) && !((Object)(object)value.Controller == (Object)null))
					{
						BeetleStats stats = value.Actor.Stats;
						stats.GrabCooldownDuration = value.RestoreGrabCooldown;
						stats.HeadbuttCooldown = value.RestoreHeadbuttCooldown;
						stats.ShootBallRecoveryDuration = value.RestoreShootRecovery;
						value.Controller.ModifiedStats = stats;
						value.Actor.jumpCooldown = value.RestoreJumpCooldown;
						value.Actor.ballJumpCooldown = value.RestoreBallJumpCooldown;
						SetLiveCooldownTimer(value.Actor.GrabCooldownTimer, value.RestoreGrabTimer, 1f);
						SetLiveCooldownTimer(value.Actor.JumpCooldownTimer, value.RestoreJumpTimer, 1f);
						SetLiveCooldownTimer(value.Actor.HeadbuttCooldownTimer, value.RestoreHeadbuttTimer, 1f);
						SetLiveCooldownTimer(value.Actor.BallJumpCooldownTimer, value.RestoreBallJumpTimer, 1f);
						SetLiveCooldownTimer(value.Actor.ShootBallRecoveryTimer, value.RestoreShootRecoveryTimer, 1f);
					}
				}
				catch
				{
				}
			}
			_globalCooldownSnapshots.Clear();
		}

		private void SyncGlobalCooldownToModdedClients(bool enabled)
		{
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if ((Object)(object)singleton == (Object)null || !singleton.IsServer)
				{
					return;
				}
				foreach (ulong moddedClientId in _moddedClientIds)
				{
					if (moddedClientId != singleton.LocalClientId)
					{
						SendAdminClientCommand(moddedClientId, AdminClientAction.SetGlobalCooldown, enabled ? 1 : 0, _globalCooldownFactor, quiet: true);
					}
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Sync cooldown failed: " + ex.Message);
			}
		}

		private void BeginExactLevelTyping()
		{
			_exactLevelTypingMode = 1;
			_exactLevelTypingText = string.Empty;
			SetStatus("Type level number; Enter applies, Escape cancels.");
		}

		private void CaptureExactLevelTyping()
		{
			if (_exactLevelTypingMode == 0 || !_menuOpen || _guiUnavailable || _menuPage != 0)
			{
				return;
			}
			try
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					_exactLevelTypingMode = 0;
					_exactLevelTypingText = string.Empty;
					SetStatus("Cancelled.");
					return;
				}
				if (Input.GetKeyDown((KeyCode)127))
				{
					_exactLevelTypingText = string.Empty;
				}
				if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
				{
					CommitExactLevelTyping();
					return;
				}
				string inputString = Input.inputString;
				if (string.IsNullOrEmpty(inputString))
				{
					return;
				}
				string text = inputString;
				for (int i = 0; i < text.Length; i++)
				{
					char c = text[i];
					switch (c)
					{
					case '\b':
						if (_exactLevelTypingText.Length > 0)
						{
							_exactLevelTypingText = _exactLevelTypingText.Substring(0, _exactLevelTypingText.Length - 1);
						}
						break;
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						if (_exactLevelTypingText.Length < 1000000.ToString().Length)
						{
							_exactLevelTypingText += c;
						}
						break;
					}
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Level typing error: " + ex.Message);
			}
		}

		private void CommitExactLevelTyping()
		{
			if (!int.TryParse(_exactLevelTypingText, out var result))
			{
				SetStatus($"Enter a level from 1 to {1000000:N0}");
				return;
			}
			result = Math.Clamp(result, 1, 1000000);
			_exactLevelTypingMode = 0;
			_exactLevelTypingText = string.Empty;
			_localTargetLevel = result;
			_localTargetLevelInitialized = true;
			ApplyExactLocalLevelFromStepper();
		}

		private string BuildExactLevelTypingLabel()
		{
			return "Typing: " + ((_exactLevelTypingText.Length == 0) ? "(empty)" : _exactLevelTypingText) + "_";
		}

		private void ApplyExactLocalLevelFromStepper()
		{
			_localTargetLevel = Math.Clamp(_localTargetLevel, 1, 1000000);
			_localTargetLevelInitialized = true;
			SetStatus(SetExactLocalLevel(_localTargetLevel));
		}

		private void LoadCustomLocalLevelOverride()
		{
			try
			{
				int num = PlayerPrefs.GetInt("BeetleballSandbox.CustomLocalLevel.v1", 0);
				_customLocalLevelOverride = ((num >= 1 && num <= 1000000) ? num : 0);
			}
			catch
			{
				_customLocalLevelOverride = 0;
			}
		}

		private void SetCustomLocalLevelOverride(int level)
		{
			_customLocalLevelOverride = Math.Clamp(level, 1, 1000000);
			PlayerPrefs.SetInt("BeetleballSandbox.CustomLocalLevel.v1", _customLocalLevelOverride);
			PlayerPrefs.Save();
		}

		private void ClearCustomLocalLevelOverride()
		{
			_customLocalLevelOverride = 0;
			PlayerPrefs.DeleteKey("BeetleballSandbox.CustomLocalLevel.v1");
			PlayerPrefs.Save();
		}

		internal static bool TryGetCustomLocalLevelOverride(out int level)
		{
			level = _activeInstance?._customLocalLevelOverride ?? 0;
			return level > 0;
		}

		private bool ExecuteServerAdminAction(ulong senderClientId, ServerAdminAction action, ulong targetClientId, int intValue, float floatValue, out string result)
		{
			//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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if ((Object)(object)singleton == (Object)null || !singleton.IsServer)
				{
					result = "Server authority unavailable.";
					return false;
				}
				switch (action)
				{
				case ServerAdminAction.ForceIntoMatch:
				{
					AdminPlayerEntry adminPlayerEntry = FindAdminPlayerEntry(targetClientId);
					if (adminPlayerEntry == null)
					{
						result = $"Client {targetClientId} not found.";
						return false;
					}
					TeamType val3 = ResolveRequestedSpawnTeam(adminPlayerEntry, (TeamType)intValue);
					ForceClientIntoMatchOnServer(adminPlayerEntry, val3);
					result = $"Spawned {adminPlayerEntry.Name} on {val3}.";
					break;
				}
				case ServerAdminAction.FreezePlayer:
				case ServerAdminAction.ReleasePlayer:
				{
					BeetleActor val = FindActorForClient(targetClientId);
					if ((Object)(object)val == (Object)null)
					{
						result = $"Client {targetClientId} has no beetle.";
						return false;
					}
					bool flag = action == ServerAdminAction.FreezePlayer;
					HostAdminPlayerState orCreateHostAdminState = GetOrCreateHostAdminState(targetClientId);
					orCreateHostAdminState.Frozen = flag;
					orCreateHostAdminState.NextStunAt = 0f;
					TryDispatchPlayerStun(val, flag ? 30f : 0.01f);
					if (!flag)
					{
						val.UnStun();
					}
					result = (flag ? $"Froze client {targetClientId}." : $"Released client {targetClientId}.");
					break;
				}
				case ServerAdminAction.SetPlayerScale:
				{
					BeetleActor val = FindActorForClient(targetClientId);
					if ((Object)(object)val == (Object)null)
					{
						result = $"Client {targetClientId} has no beetle.";
						return false;
					}
					float num = SanitizeCreativeScale(floatValue);
					GetOrCreateHostAdminState(targetClientId).Scale = num;
					ApplyHostPlayerAdminStates();
					result = $"Set client {targetClientId} scale to {num:0.##}x.";
					break;
				}
				case ServerAdminAction.ResetRound:
					ResetRoundOnServer();
					result = "Reset round.";
					break;
				case ServerAdminAction.RestartMatch:
					RestartMatchOnServer();
					_pendingForceSpectatorsAt = Time.unscaledTime + 1.25f;
					result = "Restarted match.";
					break;
				case ServerAdminAction.AddSpectators:
				{
					int num2 = ForceAllSpectatorsIntoMatchOnServer();
					result = ((num2 == 0) ? "No spectators." : $"Spawned {num2} spectator(s).");
					break;
				}
				case ServerAdminAction.ClearDung:
					result = $"Cleared {ClearAllDungOnServer()} dung balls.";
					break;
				case ServerAdminAction.ReleaseAllFreezes:
					ReleaseAllAdminFreezesOnServer();
					result = "Released all freezes.";
					break;
				case ServerAdminAction.RestoreAllPlayerSizes:
					RestoreAllAdminPlayerSizesOnServer();
					result = "Restored all player sizes.";
					break;
				case ServerAdminAction.SetGlobalCooldown:
					_globalCooldownEnabled = intValue != 0;
					_globalCooldownFactor = Mathf.Clamp(floatValue, 0f, 2f);
					if (!_globalCooldownEnabled)
					{
						RestoreGlobalCooldowns();
					}
					SyncGlobalCooldownToModdedClients(_globalCooldownEnabled);
					result = (_globalCooldownEnabled ? $"Set global cooldown to {_globalCooldownFactor:0.00}x." : "Restored global cooldowns.");
					break;
				case ServerAdminAction.SetGlobalBallScale:
					_globalBallScaleEnabled = intValue != 0;
					_globalBallScale = SanitizeCreativeScale(floatValue);
					if (_globalBallScaleEnabled)
					{
						ApplyGlobalBallScale();
					}
					else
					{
						RestoreGlobalBallScale();
					}
					result = (_globalBallScaleEnabled ? $"Set global ball scale to {_globalBallScale:0.##}x." : "Restored global ball scale.");
					break;
				case ServerAdminAction.SetPlayerTeam:
				{
					BeetleActor val = FindActorForClient(targetClientId);
					if ((Object)(object)val == (Object)null)
					{
						result = $"Client {targetClientId} has no beetle.";
						return false;
					}
					TeamType val2 = (TeamType)(intValue switch
					{
						1 => 1, 
						2 => 2, 
						_ => (int)MatchStateController.GetLeastRepresentedTeam(), 
					});
					if ((int)val2 == 0)
					{
						val2 = (TeamType)1;
					}
					val.SetTeam_ServerRpc(val2);
					result = $"Moved client {targetClientId} to {val2}.";
					break;
				}
				default:
					result = "Unknown action.";
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				result = ex.Message;
				return false;
			}
		}

		private AdminPlayerEntry? FindAdminPlayerEntry(ulong clientId)
		{
			RefreshAdminPlayerList(force: true);
			return _adminPlayers.FirstOrDefault((AdminPlayerEntry p) => p.ClientId == clientId);
		}

		private static float SanitizeCreativeScale(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				return 1f;
			}
			return Mathf.Clamp(value, 0.05f, 1000000f);
		}

		private string ExecuteAdminClientAction(AdminClientAction action, int intValue, float floatValue)
		{
			switch (action)
			{
			case AdminClientAction.AddExperience:
			{
				int num2 = Math.Clamp(intValue, 1, 1000000);
				PlayerLevelManager instance = PlayerLevelManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return "Level manager unavailable.";
				}
				instance.AddExperience(num2);
				return $"Granted {num2:N0} XP.";
			}
			case AdminClientAction.NextLevel:
			{
				PlayerLevelManager instance = PlayerLevelManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return "Level manager unavailable.";
				}
				int num = Math.Max(1, instance.RequiredLevelUpExperience(instance.Level) - instance.Experience);
				instance.AddExperience(num);
				return $"Advanced to next level (+{num:N0} XP).";
			}
			case AdminClientAction.SetLevel:
				return SetExactLocalLevel(Math.Clamp(intValue, 1, 1000000));
			case AdminClientAction.UnlockSkins:
				return UnlockEveryLocalSkin();
			case AdminClientAction.SetScale:
				_playerSize = Mathf.Max(0.05f, floatValue);
				_playerTuning = true;
				return $"Player scale set to {_playerSize:0.##}x.";
			case AdminClientAction.SetGlobalCooldown:
				return SetServerCooldownOverridePublic(intValue != 0, floatValue);
			default:
				return "Unknown action.";
			}
		}

		private static string SetExactLocalLevel(int level)
		{
			try
			{
				level = Math.Clamp(level, 1, 1000000);
				StatsManager instance = StatsManager.Instance;
				IStatsService val = ((instance != null) ? instance.Service : null);
				if (val == null)
				{
					return "Stats service unavailable.";
				}
				bool flag = val.SetInt("demo_level_new", level);
				bool flag2 = val.SetInt("demo_experience_new", 0);
				if (flag)
				{
					_activeInstance?.ClearCustomLocalLevelOverride();
				}
				else
				{
					_activeInstance?.SetCustomLocalLevelOverride(level);
				}
				if (!(flag && flag2))
				{
					return $"Requested level {level:N0} (save warning).";
				}
				return $"Level set to {level:N0}.";
			}
			catch (Exception ex)
			{
				return "Level change failed: " + ex.Message;
			}
		}

		private static string UnlockEveryLocalSkin()
		{
			try
			{
				InventoryManager instance = InventoryManager.Instance;
				IInventoryService val = ((instance != null) ? instance.Service : null);
				if (val == null)
				{
					return "Inventory unavailable.";
				}
				Il2CppArrayBase<BeetleSkinDataSO> obj = Resources.FindObjectsOfTypeAll<BeetleSkinDataSO>();
				int num = 0;
				int num2 = 0;
				foreach (BeetleSkinDataSO item in obj)
				{
					if (!((Object)(object)item == (Object)null) && !string.IsNullOrWhiteSpace(((ItemSO)item).Id))
					{
						if (val.LocalPlayerHasItem(((ItemSO)item).Id))
						{
							num2++;
						}
						else if (val.AddItem(((ItemSO)item).Id))
						{
							num++;
						}
					}
				}
				CosmeticEvents.InvokeCosmeticRefreshRequested();
				return $"Unlocked {num} skins; {num2} already owned.";
			}
			catch (Exception ex)
			{
				return "Skin unlock failed: " + ex.Message;
			}
		}

		private int ClearAllDungOnServer()
		{
			Il2CppArrayBase<DungBall> obj = Object.FindObjectsOfType<DungBall>();
			int num = 0;
			foreach (DungBall item in obj)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)((NetworkBehaviour)item).NetworkObject == (Object)null) && ((NetworkBehaviour)item).NetworkObject.IsSpawned)
				{
					((NetworkBehaviour)item).NetworkObject.Despawn(true);
					num++;
				}
			}
			return num;
		}

		private void UpdateNetworkBridge()
		{
			//IL_02b3: 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)
			if (_serverCooldownOverrideActive && !_playerTuning)
			{
				_playerTuning = true;
			}
			NetworkManager val = null;
			CustomMessagingManager val2 = null;
			try
			{
				val = NetworkManager.Singleton;
				if ((Object)(object)val != (Object)null && val.IsListening)
				{
					val2 = val.CustomMessagingManager;
				}
			}
			catch
			{
				val = null;
				val2 = null;
			}
			if ((Object)(object)val == (Object)null || val2 == null)
			{
				if (_bridgeMessaging != null)
				{
					ResetNetworkBridge();
				}
				return;
			}
			if (_bridgeMessaging == null || _bridgeMessagingPointer != ((Il2CppObjectBase)val2).Pointer)
			{
				ResetNetworkBridge();
				_bridgeMessaging = val2;
				_bridgeMessagingPointer = ((Il2CppObjectBase)val2).Pointer;
				try
				{
					_relayResponseHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnRelayResponseReceived);
					_announcementBroadcastHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnAnnouncementBroadcastReceived);
					_adminCommandHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnAdminCommandReceived);
					_serverAdminResponseHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnServerAdminResponseReceived);
					val2.RegisterNamedMessageHandler("BeetleballSandbox.RelayResponse.v1", _relayResponseHandler);
					val2.RegisterNamedMessageHandler("BeetleballSandbox.AnnouncementBroadcast.v1", _announcementBroadcastHandler);
					val2.RegisterNamedMessageHandler("BeetleballSandbox.AdminCommand.v1", _adminCommandHandler);
					val2.RegisterNamedMessageHandler("BeetleballSandbox.ServerAdminResponse.v1", _serverAdminResponseHandler);
					if (val.IsServer)
					{
						_worldRequestHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnWorldRequestReceived);
						_announcementRequestHandler = HandleNamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)OnAnnoun