Decompiled source of Empress LateJoin v2.4.0

EmpressLateJoin.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.6.0")]
[assembly: AssemblyInformationalVersion("2.0.6+5f1b735e473ca4ccf3b383128fbebd889cb564da")]
[assembly: AssemblyProduct("EmpressLateJoin")]
[assembly: AssemblyTitle("EmpressLateJoin")]
[assembly: AssemblyVersion("2.0.6.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EmpressLateJoin
{
	[BepInPlugin("empress.repo.empresslatejoin", "EmpressLateJoin", "2.0.6")]
	public sealed class EmpressLateJoinPlugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "empress.repo.empresslatejoin";

		internal const string PluginName = "EmpressLateJoin";

		internal const string PluginVersion = "2.0.6";

		private Harmony? _empressHarmony;

		internal ConfigEntry<bool> EmpressEnabled;

		internal ConfigEntry<bool> EmpressKeepRoomJoinable;

		internal ConfigEntry<bool> EmpressLiveJoinActiveLevels;

		internal ConfigEntry<bool> EmpressQueueDuringActiveLevels;

		internal ConfigEntry<float> EmpressWaitingLeashRadius;

		internal ConfigEntry<float> EmpressWaitingSnapCooldown;

		internal ConfigEntry<float> EmpressSceneSwitchSettleDelay;

		internal ConfigEntry<float> EmpressSceneSwitchSettleTimeout;

		internal ConfigEntry<float> EmpressTruckStartFallbackDelay;

		internal static EmpressLateJoinPlugin? Instance { get; private set; }

		internal static EmpressLateJoinRuntime? Runtime { get; private set; }

		internal ManualLogSource EmpressLog => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Expected O, but got Unknown
			((Component)this).gameObject.transform.parent = null;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Instance = this;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			EmpressEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for EmpressLateJoin.");
			EmpressKeepRoomJoinable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "KeepRoomJoinable", true, "Keeps the active multiplayer room joinable after the host starts the run.");
			EmpressLiveJoinActiveLevels = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LiveJoinActiveLevels", true, "Lets mid-level joiners load straight into the active scene and replay the missing live state from the host.");
			EmpressQueueDuringActiveLevels = ((BaseUnityPlugin)this).Config.Bind<bool>("WaitingRoom", "QueueDuringActiveLevels", true, "Parks mid-level late joiners in the Empress holding cell and lets them enter normal play on the next scene.");
			EmpressWaitingLeashRadius = ((BaseUnityPlugin)this).Config.Bind<float>("WaitingRoom", "WaitingLeashRadius", 7f, "How far a waiting player can stray from the holding cell anchor before EmpressLateJoin snaps them back.");
			EmpressWaitingSnapCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("WaitingRoom", "WaitingSnapCooldown", 0.75f, "Minimum delay between holding-cell snapbacks.");
			EmpressSceneSwitchSettleDelay = ((BaseUnityPlugin)this).Config.Bind<float>("WaitingRoom", "SceneSwitchSettleDelay", 1.25f, "Minimum amount of time EmpressLateJoin waits for a late joiner to settle before allowing the next scene switch.");
			EmpressSceneSwitchSettleTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("WaitingRoom", "SceneSwitchSettleTimeout", 8f, "Maximum amount of time EmpressLateJoin will delay a scene switch while a late joiner settles.");
			EmpressTruckStartFallbackDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Truck", "TruckStartFallbackDelay", 8f, "How long EmpressLateJoin waits after the truck starts before forcing the same transition as the /level next debug command if vanilla did not switch scenes.");
			Runtime = Resources.FindObjectsOfTypeAll<EmpressLateJoinRuntime>().FirstOrDefault();
			if ((Object)(object)Runtime == (Object)null)
			{
				GameObject val = new GameObject("EmpressLateJoin.Runtime")
				{
					hideFlags = (HideFlags)61
				};
				val.transform.parent = null;
				Object.DontDestroyOnLoad((Object)val);
				Runtime = val.AddComponent<EmpressLateJoinRuntime>();
			}
			else
			{
				((Component)Runtime).gameObject.transform.parent = null;
				Object.DontDestroyOnLoad((Object)(object)((Component)Runtime).gameObject);
				((Object)((Component)Runtime).gameObject).hideFlags = (HideFlags)61;
			}
			_empressHarmony = new Harmony("empress.repo.empresslatejoin");
			_empressHarmony.PatchAll();
		}
	}
	internal sealed class EmpressLateJoinRuntime : MonoBehaviour
	{
		private sealed class EmpressDelayedSceneChangeRequest
		{
			internal RunManager RunManager;

			internal bool CompletedLevel;

			internal bool LevelFailed;

			internal ChangeLevelType ChangeLevelType;

			internal float RequestedAt;
		}

		private const float EmpressJoinabilityRefreshInterval = 1f;

		private const float EmpressSupportAuditInterval = 1f;

		private const float EmpressWaitingAnchorRadiusBase = 1.3f;

		private const float EmpressLateJoinReadyHoldTime = 0.2f;

		private const float EmpressLateJoinMinimumIdentityTime = 0.5f;

		private const float EmpressLiveJoinUpdateLevelDelay = 2f;

		private const float EmpressLiveJoinGenerateDoneDelay = 3.5f;

		private const float EmpressLiveJoinReplayDelay = 4.5f;

		private static readonly FieldInfo? EmpressGameManagerConnectRandomField = AccessTools.Field(typeof(GameManager), "connectRandom");

		private static readonly FieldInfo? EmpressDebugCommandHandlerInstanceField = AccessTools.Field(typeof(DebugCommandHandler), "instance");

		private static readonly FieldInfo? EmpressPlayerAvatarSpawnedField = AccessTools.Field(typeof(PlayerAvatar), "spawned");

		private static readonly FieldInfo? EmpressPlayerAvatarDeathHeadField = AccessTools.Field(typeof(PlayerAvatar), "playerDeathHead");

		private static readonly FieldInfo? EmpressPlayerAvatarTumbleField = AccessTools.Field(typeof(PlayerAvatar), "tumble");

		private static readonly FieldInfo? EmpressPlayerAvatarPlayerHealthField = AccessTools.Field(typeof(PlayerAvatar), "playerHealth");

		private static readonly FieldInfo? EmpressPlayerAvatarDeadSetField = AccessTools.Field(typeof(PlayerAvatar), "deadSet");

		private static readonly FieldInfo? EmpressPlayerAvatarIsDisabledField = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");

		private static readonly FieldInfo? EmpressPlayerAvatarRoomVolumeCheckField = AccessTools.Field(typeof(PlayerAvatar), "RoomVolumeCheck");

		private static readonly FieldInfo? EmpressPlayerAvatarSelfDestructPreventedField = AccessTools.Field(typeof(PlayerAvatar), "selfDestructPrevented");

		private static readonly FieldInfo? EmpressPlayerHealthHealthField = AccessTools.Field(typeof(PlayerHealth), "health");

		private static readonly FieldInfo? EmpressPlayerHealthMaxHealthField = AccessTools.Field(typeof(PlayerHealth), "maxHealth");

		private static readonly FieldInfo? EmpressPlayerDeathHeadPhysGrabObjectField = AccessTools.Field(typeof(PlayerDeathHead), "physGrabObject");

		private static readonly FieldInfo? EmpressPlayerDeathHeadSetupField = AccessTools.Field(typeof(PlayerDeathHead), "setup");

		private static readonly FieldInfo? EmpressPlayerTumblePhysGrabObjectField = AccessTools.Field(typeof(PlayerTumble), "physGrabObject");

		private static readonly FieldInfo? EmpressPlayerTumblePhotonViewField = AccessTools.Field(typeof(PlayerTumble), "photonView");

		private static readonly FieldInfo? EmpressPlayerTumbleSetupField = AccessTools.Field(typeof(PlayerTumble), "setup");

		private static readonly FieldInfo? EmpressPlayerTumbleIsTumblingField = AccessTools.Field(typeof(PlayerTumble), "isTumbling");

		private static readonly FieldInfo? EmpressPlayerTumbleOverrideField = AccessTools.Field(typeof(PlayerTumble), "tumbleOverride");

		private static readonly FieldInfo? EmpressPlayerAvatarSteamIdField = AccessTools.Field(typeof(PlayerAvatar), "steamID");

		private static readonly FieldInfo? EmpressPlayerAvatarPlayerNameField = AccessTools.Field(typeof(PlayerAvatar), "playerName");

		private static readonly FieldInfo? EmpressPlayerAvatarLevelAnimationCompletedField = AccessTools.Field(typeof(PlayerAvatar), "levelAnimationCompleted");

		private static readonly FieldInfo? EmpressRoomVolumeCheckInTruckField = AccessTools.Field(typeof(RoomVolumeCheck), "inTruck");

		private static readonly FieldInfo? EmpressTruckScreenTextSelfDestructingPlayersField = AccessTools.Field(typeof(TruckScreenText), "selfDestructingPlayers");

		private static readonly FieldInfo? EmpressPunManagerPhotonViewField = AccessTools.Field(typeof(PunManager), "photonView");

		private static readonly FieldInfo? EmpressRoundDirectorPhotonViewField = AccessTools.Field(typeof(RoundDirector), "photonView");

		private static readonly FieldInfo? EmpressRoundDirectorTotalHaulField = AccessTools.Field(typeof(RoundDirector), "totalHaul");

		private static readonly FieldInfo? EmpressRoundDirectorExtractionPointActiveField = AccessTools.Field(typeof(RoundDirector), "extractionPointActive");

		private static readonly FieldInfo? EmpressRoundDirectorExtractionPointCurrentField = AccessTools.Field(typeof(RoundDirector), "extractionPointCurrent");

		private static readonly FieldInfo? EmpressRoundDirectorAllExtractionPointsCompletedField = AccessTools.Field(typeof(RoundDirector), "allExtractionPointsCompleted");

		private static readonly FieldInfo? EmpressExtractionPointPhotonViewField = AccessTools.Field(typeof(ExtractionPoint), "photonView");

		private static readonly FieldInfo? EmpressShopManagerTotalCostField = AccessTools.Field(typeof(ShopManager), "totalCost");

		private static readonly FieldInfo? EmpressStatsManagerDictionaryOfDictionariesField = AccessTools.Field(typeof(StatsManager), "dictionaryOfDictionaries");

		private static readonly FieldInfo? EmpressRunManagerLevelCurrentField = AccessTools.Field(typeof(RunManager), "levelCurrent");

		private static readonly FieldInfo? EmpressRunManagerLevelsCompletedField = AccessTools.Field(typeof(RunManager), "levelsCompleted");

		private static readonly FieldInfo? EmpressRunManagerGameOverField = AccessTools.Field(typeof(RunManager), "gameOver");

		private static readonly FieldInfo? EmpressRunManagerPunField = AccessTools.Field(typeof(RunManager), "runManagerPUN");

		private static readonly FieldInfo? EmpressRunManagerPunPhotonViewField = AccessTools.Field(typeof(RunManagerPUN), "photonView");

		private static readonly MethodInfo? EmpressDebugCommandHandlerExecuteMethod = AccessTools.Method(typeof(DebugCommandHandler), "Execute", new Type[2]
		{
			typeof(string),
			typeof(bool)
		}, (Type[])null);

		private static readonly MethodInfo? EmpressRunManagerChangeLevelMethod = AccessTools.Method(typeof(RunManager), "ChangeLevel", new Type[3]
		{
			typeof(bool),
			typeof(bool),
			typeof(ChangeLevelType)
		}, (Type[])null);

		private static readonly FieldInfo? EmpressLevelGeneratorPhotonViewField = AccessTools.Field(typeof(LevelGenerator), "PhotonView");

		private static readonly FieldInfo? EmpressLevelGeneratorDeathHeadPrefabField = AccessTools.Field(typeof(LevelGenerator), "PlayerDeathHeadPrefab");

		private static readonly FieldInfo? EmpressLevelGeneratorTumblePrefabField = AccessTools.Field(typeof(LevelGenerator), "PlayerTumblePrefab");

		private static readonly FieldInfo? EmpressPhotonRemoveFilterField = AccessTools.Field(typeof(PhotonNetwork), "removeFilter");

		private static readonly FieldInfo? EmpressPhotonKeyByteSevenField = AccessTools.Field(typeof(PhotonNetwork), "keyByteSeven");

		private static readonly FieldInfo? EmpressPhotonServerCleanOptionsField = AccessTools.Field(typeof(PhotonNetwork), "ServerCleanOptions");

		private static readonly MethodInfo? EmpressPhotonRaiseEventInternalMethod = AccessTools.Method(typeof(PhotonNetwork), "RaiseEventInternal", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EmpressRoomVolumeCheckCheckSetMethod = AccessTools.Method(typeof(RoomVolumeCheck), "CheckSet", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EmpressPlayerDeathHeadSetupDoneMethod = AccessTools.Method(typeof(PlayerDeathHead), "SetupDone", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EmpressPlayerTumbleSetupDoneMethod = AccessTools.Method(typeof(PlayerTumble), "SetupDone", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EmpressTruckScreenTextChatMessageResultSuccessMethod = AccessTools.Method(typeof(TruckScreenText), "ChatMessageResultSuccess", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EmpressTruckScreenTextPlayerChatBoxStateUpdateMethod = AccessTools.Method(typeof(TruckScreenText), "PlayerChatBoxStateUpdate", new Type[1] { typeof(PlayerChatBoxState) }, (Type[])null);

		private static readonly MethodInfo? EmpressTruckScreenTextGotoPageMethod = AccessTools.Method(typeof(TruckScreenText), "GotoPage", new Type[1] { typeof(int) }, (Type[])null);

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

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

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

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

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

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

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

		private readonly Dictionary<int, float> _empressLateJoinDetectedAt = new Dictionary<int, float>();

		private readonly Dictionary<int, float> _empressLateJoinReadyAt = new Dictionary<int, float>();

		private readonly Dictionary<int, float> _empressNextSnapByActor = new Dictionary<int, float>();

		private EmpressDelayedSceneChangeRequest? _empressDelayedSceneChange;

		private bool _empressRunningDelayedSceneChange;

		private bool _empressLiveJoinCachePrepared;

		private bool _empressSteamLobbyUnlockApplied;

		private bool _empressRunLevelCachePruned;

		private float _empressNextJoinabilityRefreshTime;

		private float _empressNextSupportAuditTime;

		private Coroutine? _empressTruckStartFallbackCoroutine;

		private int _empressTruckStartFallbackSceneToken;

		private string _empressSteamLobbyUnlockRoomName = string.Empty;

		private void Awake()
		{
			((Component)this).gameObject.transform.parent = null;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += EmpressOnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= EmpressOnSceneLoaded;
		}

		private void Update()
		{
			if (!((Object)(object)EmpressLateJoinPlugin.Instance == (Object)null) && EmpressLateJoinPlugin.Instance.EmpressEnabled.Value)
			{
				if (Time.unscaledTime >= _empressNextJoinabilityRefreshTime)
				{
					EmpressRefreshJoinability();
					_empressNextJoinabilityRefreshTime = Time.unscaledTime + 1f;
				}
				EmpressMaybePruneRunLevelCache();
				EmpressMaintainSupportObjects();
				EmpressMaintainLateJoinState();
				EmpressMaintainWaitingPlayers();
				EmpressRepairExtractionActivationState();
				EmpressProcessDelayedSceneChange();
			}
		}

		internal bool EmpressTryHandleLateJoinSpawn()
		{
			if (!EmpressCanHostLateJoinLogic())
			{
				return false;
			}
			List<PlayerAvatar> list = (from avatar in SemiFunc.PlayerGetList()
				where (Object)(object)avatar != (Object)null && (Object)(object)avatar.photonView != (Object)null && !EmpressGetAvatarSpawned(avatar)
				select avatar).ToList();
			if (list.Count == 0)
			{
				return false;
			}
			if (SemiFunc.RunIsShop())
			{
				foreach (PlayerAvatar item in list)
				{
					_empressTruckDepartureIgnoredActors.Add(item.photonView.OwnerActorNr);
				}
				return false;
			}
			foreach (PlayerAvatar item2 in list)
			{
				int ownerActorNr = item2.photonView.OwnerActorNr;
				if (EmpressEnsureRunLevelWaitingRoomMode())
				{
					EmpressBackfillLateJoinerIntoEnemySystems(item2);
					_empressDeferredWaitingRoomActors.Add(ownerActorNr);
					continue;
				}
				EmpressTrackLateJoin(ownerActorNr);
				EmpressEnsureSupportObjects(item2);
				if (EmpressShouldQueueLateJoiner())
				{
					EmpressQueueLateJoiner(item2);
				}
				else
				{
					EmpressAdmitLateJoiner(item2);
				}
			}
			return true;
		}

		internal void EmpressHandlePlayerLeft(Player player)
		{
			_empressHostWaitingActors.Remove(player.ActorNumber);
			_empressDeferredWaitingRoomActors.Remove(player.ActorNumber);
			_empressEnemyRegisteredActors.Remove(player.ActorNumber);
			_empressLiveJoinLevelUpdateSentActors.Remove(player.ActorNumber);
			_empressLiveJoinBootstrapSentActors.Remove(player.ActorNumber);
			_empressLiveStateReplayedActors.Remove(player.ActorNumber);
			_empressTruckDepartureIgnoredActors.Remove(player.ActorNumber);
			_empressNextSnapByActor.Remove(player.ActorNumber);
			EmpressClearLateJoinTracking(player.ActorNumber);
		}

		internal void EmpressHandlePlayerEntered(Player player)
		{
			if (EmpressCanHostRoomControl())
			{
				if (SemiFunc.RunIsShop())
				{
					_empressTruckDepartureIgnoredActors.Add(player.ActorNumber);
				}
				else if (EmpressCanHostLateJoinLogic() && SemiFunc.RunIsLevel() && !EmpressEnsureRunLevelWaitingRoomMode())
				{
					EmpressTrackLateJoin(player.ActorNumber);
				}
			}
		}

		internal bool EmpressTryDelaySceneChange(RunManager runManager, bool completedLevel, bool levelFailed, ChangeLevelType changeLevelType)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (_empressRunningDelayedSceneChange || !EmpressCanHostRoomControl() || !SemiFunc.RunIsLevel())
			{
				return false;
			}
			if (EmpressEnsureRunLevelWaitingRoomMode())
			{
				return false;
			}
			if (completedLevel && !levelFailed)
			{
				return false;
			}
			if (_empressLateJoinDetectedAt.Count == 0)
			{
				return false;
			}
			if ((int)changeLevelType == 4 || (int)changeLevelType == 3)
			{
				return false;
			}
			if (_empressDelayedSceneChange == null)
			{
				_empressDelayedSceneChange = new EmpressDelayedSceneChangeRequest
				{
					RunManager = runManager,
					CompletedLevel = completedLevel,
					LevelFailed = levelFailed,
					ChangeLevelType = changeLevelType,
					RequestedAt = Time.unscaledTime
				};
			}
			else
			{
				_empressDelayedSceneChange.RunManager = runManager;
				_empressDelayedSceneChange.CompletedLevel = completedLevel;
				_empressDelayedSceneChange.LevelFailed = levelFailed;
				_empressDelayedSceneChange.ChangeLevelType = changeLevelType;
			}
			return true;
		}

		internal void EmpressHandleChangeLevelCompleted(RunManager runManager, ChangeLevelType changeLevelType)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			EmpressPrepareLiveJoinLevelDescriptor(runManager, changeLevelType);
			EmpressEnsureRunLevelWaitingRoomMode();
		}

		private void EmpressOnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			_empressHostWaitingActors.Clear();
			_empressDeferredWaitingRoomActors.Clear();
			_empressEnemyRegisteredActors.Clear();
			_empressLiveJoinLevelUpdateSentActors.Clear();
			_empressLiveJoinBootstrapSentActors.Clear();
			_empressLiveStateReplayedActors.Clear();
			_empressTruckDepartureIgnoredActors.Clear();
			_empressLateJoinDetectedAt.Clear();
			_empressLateJoinReadyAt.Clear();
			_empressNextSnapByActor.Clear();
			_empressDelayedSceneChange = null;
			_empressRunningDelayedSceneChange = false;
			_empressLiveJoinCachePrepared = false;
			_empressSteamLobbyUnlockApplied = false;
			_empressRunLevelCachePruned = false;
			_empressNextJoinabilityRefreshTime = 0f;
			_empressNextSupportAuditTime = 0f;
			_empressTruckStartFallbackSceneToken++;
			if (_empressTruckStartFallbackCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_empressTruckStartFallbackCoroutine);
			}
			_empressTruckStartFallbackCoroutine = null;
			_empressSteamLobbyUnlockRoomName = string.Empty;
			EmpressRefreshJoinability();
		}

		private void EmpressRefreshJoinability()
		{
			if (EmpressIsFrontEndRoomState())
			{
				_empressSteamLobbyUnlockApplied = false;
			}
			else if (!EmpressCanHostRoomControl())
			{
				_empressSteamLobbyUnlockApplied = false;
				_empressSteamLobbyUnlockRoomName = string.Empty;
			}
			else
			{
				EmpressForceJoinabilityRefresh();
			}
		}

		internal void EmpressForceJoinabilityRefresh(bool forceSteamLobbyUnlock = false)
		{
			if (EmpressIsFrontEndRoomState() && !forceSteamLobbyUnlock)
			{
				_empressSteamLobbyUnlockApplied = false;
				return;
			}
			if (!EmpressCanHostRoomControl() || !EmpressLateJoinPlugin.Instance.EmpressKeepRoomJoinable.Value)
			{
				_empressSteamLobbyUnlockApplied = false;
				_empressSteamLobbyUnlockRoomName = string.Empty;
				return;
			}
			Room currentRoom = PhotonNetwork.CurrentRoom;
			if (currentRoom == null)
			{
				_empressSteamLobbyUnlockApplied = false;
				_empressSteamLobbyUnlockRoomName = string.Empty;
				return;
			}
			if (!string.Equals(_empressSteamLobbyUnlockRoomName, currentRoom.Name, StringComparison.Ordinal))
			{
				_empressSteamLobbyUnlockRoomName = currentRoom.Name;
				_empressSteamLobbyUnlockApplied = false;
			}
			currentRoom.IsOpen = true;
			if (EmpressGetConnectRandom())
			{
				currentRoom.IsVisible = true;
				_empressSteamLobbyUnlockApplied = false;
			}
			if (EmpressGetConnectRandom() || !((Object)(object)SteamManager.instance != (Object)null) || (_empressSteamLobbyUnlockApplied && !forceSteamLobbyUnlock))
			{
				return;
			}
			try
			{
				SteamManager.instance.UnlockLobby(false);
				_empressSteamLobbyUnlockApplied = true;
			}
			catch
			{
				_empressSteamLobbyUnlockApplied = false;
			}
		}

		private bool EmpressGetCurrentRunGameOver()
		{
			return EmpressGetFieldValue<bool>(EmpressRunManagerGameOverField, RunManager.instance);
		}

		private bool EmpressLiveJoinEnabled()
		{
			return EmpressLateJoinPlugin.Instance?.EmpressLiveJoinActiveLevels.Value ?? false;
		}

		private void EmpressPrepareLiveJoinLevelDescriptor(RunManager runManager, ChangeLevelType changeLevelType)
		{
			Level val = EmpressGetRunManagerLevelCurrent(runManager);
			if (EmpressLiveJoinEnabled() && EmpressCanHostRoomControl() && !((Object)(object)runManager == (Object)null) && !((Object)(object)val == (Object)null) && SemiFunc.RunIsLevel())
			{
				PhotonView val2 = EmpressGetRunManagerPhotonView();
				if (!((Object)(object)val2 == (Object)null) && val2.ViewID > 0)
				{
					PhotonNetwork.RemoveBufferedRPCs(val2.ViewID, "UpdateLevelRPC", (int[])null);
				}
			}
		}

		private void EmpressPrepareLiveJoinRoomState()
		{
			if (!_empressLiveJoinCachePrepared && EmpressLiveJoinEnabled() && EmpressCanHostRoomControl() && SemiFunc.RunIsLevel())
			{
				PhotonView val = EmpressGetFieldValue<PhotonView>(EmpressLevelGeneratorPhotonViewField, LevelGenerator.Instance);
				if (!((Object)(object)val == (Object)null) && val.ViewID > 0)
				{
					PhotonNetwork.RemoveBufferedRPCs(val.ViewID, "GenerateDone", (int[])null);
					_empressLiveJoinCachePrepared = true;
				}
			}
		}

		private void EmpressMaybePruneRunLevelCache()
		{
			EmpressPrepareLiveJoinRoomState();
			EmpressEnsureRunLevelWaitingRoomMode();
		}

		private void EmpressMaintainSupportObjects()
		{
			if (!EmpressLiveJoinEnabled() || !EmpressCanHostRoomControl() || (Object)(object)LevelGenerator.Instance == (Object)null || SemiFunc.MenuLevel() || Time.unscaledTime < _empressNextSupportAuditTime)
			{
				return;
			}
			_empressNextSupportAuditTime = Time.unscaledTime + 1f;
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!((Object)(object)item == (Object)null))
				{
					EmpressEnsureSupportObjects(item);
				}
			}
		}

		private void EmpressMaintainLateJoinState()
		{
			if (!EmpressCanHostRoomControl() || _empressLateJoinDetectedAt.Count == 0)
			{
				return;
			}
			float num = Mathf.Max(1f, EmpressLateJoinPlugin.Instance.EmpressSceneSwitchSettleTimeout.Value);
			foreach (int item in _empressLateJoinDetectedAt.Keys.ToList())
			{
				if (!EmpressIsActorStillConnected(item))
				{
					EmpressClearLateJoinTracking(item);
					continue;
				}
				float num2 = _empressLateJoinDetectedAt[item];
				PlayerAvatar val = EmpressFindAvatar(item);
				if ((Object)(object)val == (Object)null || (Object)(object)val.photonView == (Object)null)
				{
					if (Time.unscaledTime - num2 >= num)
					{
						EmpressClearLateJoinTracking(item);
					}
					continue;
				}
				EmpressEnsureSupportObjects(val);
				EmpressBackfillLateJoinerIntoEnemySystems(val);
				EmpressAdvanceLiveJoinBootstrap(val, num2);
				if (EmpressIsLateJoinerSettled(val, num2))
				{
					if (!_empressLateJoinReadyAt.ContainsKey(item))
					{
						_empressLateJoinReadyAt[item] = Time.unscaledTime;
					}
					else if (Time.unscaledTime - _empressLateJoinReadyAt[item] >= 0.2f)
					{
						EmpressClearLateJoinTracking(item);
					}
				}
				else
				{
					_empressLateJoinReadyAt.Remove(item);
					if (Time.unscaledTime - num2 >= num)
					{
						EmpressClearLateJoinTracking(item);
					}
				}
			}
		}

		private void EmpressAdvanceLiveJoinBootstrap(PlayerAvatar avatar, float detectedAt)
		{
			if (!EmpressLiveJoinEnabled() || (Object)(object)avatar.photonView == (Object)null || !EmpressGetAvatarSpawned(avatar))
			{
				return;
			}
			int ownerActorNr = avatar.photonView.OwnerActorNr;
			if (ownerActorNr <= 0 || PhotonNetwork.CurrentRoom == null || !PhotonNetwork.CurrentRoom.Players.TryGetValue(ownerActorNr, out var value))
			{
				return;
			}
			float num = Time.unscaledTime - detectedAt;
			try
			{
				if (!_empressLiveJoinLevelUpdateSentActors.Contains(ownerActorNr) && num >= 2f)
				{
					if (!EmpressHasLateJoinIdentity(avatar, detectedAt))
					{
						return;
					}
					PhotonView val = EmpressGetRunManagerPhotonView();
					if ((Object)(object)val != (Object)null)
					{
						Player obj = value;
						object[] array = new object[3];
						Level? obj2 = EmpressGetRunManagerLevelCurrent(RunManager.instance);
						array[0] = ((obj2 != null) ? ((Object)obj2).name : null) ?? string.Empty;
						array[1] = EmpressGetRunManagerLevelsCompleted(RunManager.instance);
						array[2] = EmpressGetCurrentRunGameOver();
						val.RPC("UpdateLevelRPC", obj, array);
						_empressLiveJoinLevelUpdateSentActors.Add(ownerActorNr);
					}
				}
				if (_empressLiveJoinLevelUpdateSentActors.Contains(ownerActorNr) && !_empressLiveJoinBootstrapSentActors.Contains(ownerActorNr) && num >= 3.5f)
				{
					PhotonView val2 = EmpressGetFieldValue<PhotonView>(EmpressLevelGeneratorPhotonViewField, LevelGenerator.Instance);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.RPC("GenerateDone", value, Array.Empty<object>());
						_empressLiveJoinBootstrapSentActors.Add(ownerActorNr);
					}
				}
				if (_empressLiveJoinBootstrapSentActors.Contains(ownerActorNr) && !_empressLiveStateReplayedActors.Contains(ownerActorNr) && num >= 4.5f)
				{
					EmpressReplayStatsToJoiner(value);
					EmpressReplayItemsToJoiner(value);
					EmpressReplayPlayerStateToJoiner(value);
					EmpressReplayRoundStateToJoiner(value);
					_empressLiveStateReplayedActors.Add(ownerActorNr);
				}
			}
			catch
			{
			}
		}

		private bool EmpressHasLateJoinIdentity(PlayerAvatar avatar, float detectedAt)
		{
			if (!EmpressGetAvatarSpawned(avatar))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(EmpressGetAvatarSteamId(avatar)) || string.IsNullOrWhiteSpace(EmpressGetAvatarPlayerName(avatar)))
			{
				return false;
			}
			EmpressEnsureSupportObjects(avatar);
			if (!EmpressHasSupportObjectsReady(avatar))
			{
				return false;
			}
			int num = (((Object)(object)avatar.photonView != (Object)null) ? avatar.photonView.OwnerActorNr : 0);
			if (num > 0 && !_empressEnemyRegisteredActors.Contains(num))
			{
				return false;
			}
			return Time.unscaledTime - detectedAt >= 0.5f;
		}

		private void EmpressReplayStatsToJoiner(Player targetPlayer)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			PhotonView val = EmpressGetPunManagerPhotonView();
			if ((Object)(object)PunManager.instance == (Object)null || (Object)(object)val == (Object)null || (Object)(object)StatsManager.instance == (Object)null)
			{
				return;
			}
			SortedDictionary<string, Dictionary<string, int>> sortedDictionary = EmpressGetFieldValue<SortedDictionary<string, Dictionary<string, int>>>(EmpressStatsManagerDictionaryOfDictionariesField, StatsManager.instance);
			if (sortedDictionary == null)
			{
				return;
			}
			List<KeyValuePair<string, Dictionary<string, int>>> list = sortedDictionary.ToList();
			if (list.Count == 0)
			{
				return;
			}
			Hashtable val2 = new Hashtable();
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				KeyValuePair<string, Dictionary<string, int>> keyValuePair = list[i];
				val2[(object)keyValuePair.Key] = EmpressConvertDictionaryToHashtable(keyValuePair.Value);
				num++;
				if (num >= 4 || i >= list.Count - 1)
				{
					bool flag = i >= list.Count - 1;
					val.RPC("ReceiveSyncData", targetPlayer, new object[2] { val2, flag });
					val2 = new Hashtable();
					num = 0;
				}
			}
		}

		private void EmpressReplayItemsToJoiner(Player targetPlayer)
		{
			//IL_0102: 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_0129: Expected I4, but got Unknown
			PhotonView val = EmpressGetPunManagerPhotonView();
			if ((Object)(object)PunManager.instance == (Object)null || (Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (ItemAttributes item in from item in Object.FindObjectsOfType<ItemAttributes>()
				where (Object)(object)item != (Object)null && (Object)(object)item.photonView != (Object)null && item.photonView.ViewID > 0
				orderby item.photonView.ViewID
				select item)
			{
				string text = ((!string.IsNullOrWhiteSpace(item.instanceName)) ? item.instanceName : item.itemAssetName);
				if (!string.IsNullOrWhiteSpace(text))
				{
					val.RPC("SetItemNameRPC", targetPlayer, new object[2]
					{
						text,
						item.photonView.ViewID
					});
				}
				item.photonView.RPC("GetValueRPC", targetPlayer, new object[1] { item.value });
				ItemEquippable itemEquippable = item.itemEquippable;
				if ((Object)(object)itemEquippable != (Object)null && (int)itemEquippable.currentState != 0)
				{
					item.photonView.RPC("RPC_UpdateItemState", targetPlayer, new object[3]
					{
						(int)itemEquippable.currentState,
						itemEquippable.inventorySpotIndex,
						itemEquippable.ownerPlayerId
					});
				}
			}
		}

		private void EmpressReplayPlayerStateToJoiner(Player targetPlayer)
		{
			foreach (PlayerAvatar item in from player in SemiFunc.PlayerGetList()
				where (Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null
				select player)
			{
				PlayerHealth val = EmpressGetAvatarPlayerHealth(item);
				if ((Object)(object)val != (Object)null)
				{
					item.photonView.RPC("UpdateHealthRPC", targetPlayer, new object[3]
					{
						EmpressGetPlayerHealthHealth(val),
						EmpressGetPlayerHealthMaxHealth(val),
						false
					});
				}
				if (EmpressGetAvatarDeadSet(item) || EmpressGetAvatarIsDisabled(item) || !((Component)item).gameObject.activeSelf)
				{
					item.photonView.RPC("PlayerDeathRPC", targetPlayer, new object[1] { -1 });
				}
				PlayerTumble val2 = EmpressGetAvatarTumble(item);
				PhotonView val3 = (((Object)(object)val2 != (Object)null) ? EmpressGetTumblePhotonView(val2) : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null && EmpressGetTumbleIsTumbling(val2))
				{
					val3.RPC("TumbleSetRPC", targetPlayer, new object[2] { true, false });
					if (EmpressGetTumbleOverride(val2))
					{
						val3.RPC("TumbleOverrideRPC", targetPlayer, new object[1] { true });
					}
				}
			}
		}

		private void EmpressReplayRoundStateToJoiner(Player targetPlayer)
		{
			PhotonView val = EmpressGetPunManagerPhotonView();
			if ((Object)(object)val != (Object)null)
			{
				if (!string.IsNullOrWhiteSpace(SessionManager.instance?.crownedPlayerSteamID))
				{
					val.RPC("CrownPlayerRPC", targetPlayer, new object[1] { SessionManager.instance.crownedPlayerSteamID });
				}
				if ((Object)(object)RoundDirector.instance != (Object)null)
				{
					val.RPC("SyncHaul", targetPlayer, new object[1] { EmpressGetRoundDirectorTotalHaul() });
				}
				if (SemiFunc.RunIsShop() && (Object)(object)ShopManager.instance != (Object)null)
				{
					val.RPC("UpdateShoppingCostRPC", targetPlayer, new object[1] { EmpressGetShopManagerTotalCost() });
				}
			}
			PhotonView val2 = EmpressGetRoundDirectorPhotonView();
			if (!((Object)(object)val2 == (Object)null))
			{
				ExtractionPoint val3 = EmpressGetRoundDirectorExtractionPointCurrent();
				PhotonView val4 = (((Object)(object)val3 != (Object)null) ? EmpressGetExtractionPointPhotonView(val3) : null);
				if (EmpressGetRoundDirectorExtractionPointActive() && (Object)(object)val4 != (Object)null && (Object)(object)PhotonView.Find(val4.ViewID) != (Object)null)
				{
					val2.RPC("ExtractionPointActivateRPC", targetPlayer, new object[1] { val4.ViewID });
				}
				else
				{
					val2.RPC("ExtractionPointsUnlockRPC", targetPlayer, Array.Empty<object>());
				}
				if (EmpressGetRoundDirectorAllExtractionPointsCompleted())
				{
					val2.RPC("ExtractionCompletedAllRPC", targetPlayer, Array.Empty<object>());
				}
			}
		}

		private void EmpressMaintainWaitingPlayers()
		{
			//IL_0082: 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_0088: 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_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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (!EmpressCanHostLateJoinLogic() || _empressHostWaitingActors.Count == 0)
			{
				return;
			}
			foreach (int item3 in _empressHostWaitingActors.ToList())
			{
				PlayerAvatar val = EmpressFindAvatar(item3);
				if ((Object)(object)val == (Object)null || (Object)(object)val.photonView == (Object)null)
				{
					_empressHostWaitingActors.Remove(item3);
					_empressNextSnapByActor.Remove(item3);
				}
				else
				{
					if (!SemiFunc.RunIsLevel())
					{
						continue;
					}
					(Vector3 position, Quaternion rotation) tuple = EmpressGetWaitingSpawn(item3);
					Vector3 item = tuple.position;
					Quaternion item2 = tuple.rotation;
					float num = Mathf.Max(1f, EmpressLateJoinPlugin.Instance.EmpressWaitingLeashRadius.Value);
					if (!(Vector3.Distance(((Component)val).transform.position, item) <= num))
					{
						float value;
						float num2 = (_empressNextSnapByActor.TryGetValue(item3, out value) ? value : 0f);
						if (!(Time.unscaledTime < num2))
						{
							val.Spawn(item, item2);
							_empressNextSnapByActor[item3] = Time.unscaledTime + Mathf.Max(0.1f, EmpressLateJoinPlugin.Instance.EmpressWaitingSnapCooldown.Value);
						}
					}
				}
			}
		}

		internal bool EmpressTryBlockInvalidExtractionActivation(int photonViewId)
		{
			if (!EmpressCanHostRoomControl() || !SemiFunc.RunIsLevel())
			{
				return false;
			}
			if (photonViewId <= 0)
			{
				EmpressRepairMissingExtractionActivation();
				return true;
			}
			PhotonView val = PhotonView.Find(photonViewId);
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<ExtractionPoint>() != (Object)null)
			{
				return false;
			}
			EmpressRepairMissingExtractionActivation();
			return true;
		}

		private void EmpressRepairMissingExtractionActivation()
		{
			if (!((Object)(object)RoundDirector.instance == (Object)null) && EmpressGetRoundDirectorExtractionPointActive())
			{
				ExtractionPoint val = EmpressGetRoundDirectorExtractionPointCurrent();
				PhotonView val2 = (((Object)(object)val != (Object)null) ? EmpressGetExtractionPointPhotonView(val) : null);
				if (!((Object)(object)val != (Object)null) || !((Object)(object)val2 != (Object)null) || !((Object)(object)PhotonView.Find(val2.ViewID) != (Object)null))
				{
					EmpressSetRoundDirectorExtractionPointActive(value: false);
					EmpressSetRoundDirectorExtractionPointCurrent(null);
				}
			}
		}

		private void EmpressRepairExtractionActivationState()
		{
			if (EmpressCanHostRoomControl() && SemiFunc.RunIsLevel() && !((Object)(object)RoundDirector.instance == (Object)null) && EmpressGetRoundDirectorExtractionPointActive())
			{
				ExtractionPoint val = EmpressGetRoundDirectorExtractionPointCurrent();
				PhotonView val2 = (((Object)(object)val != (Object)null) ? EmpressGetExtractionPointPhotonView(val) : null);
				if (!((Object)(object)val != (Object)null) || !((Object)(object)val2 != (Object)null) || !((Object)(object)PhotonView.Find(val2.ViewID) != (Object)null))
				{
					EmpressSetRoundDirectorExtractionPointActive(value: false);
					EmpressSetRoundDirectorExtractionPointCurrent(null);
				}
			}
		}

		internal void EmpressScheduleTruckStartFallback(PlayerChatBoxState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)state == 3 && !((Object)(object)EmpressLateJoinPlugin.Instance == (Object)null) && EmpressLateJoinPlugin.Instance.EmpressEnabled.Value && !((Object)(object)RunManager.instance == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer() && !SemiFunc.RunIsLobbyMenu() && !SemiFunc.MenuLevel() && _empressTruckStartFallbackCoroutine == null)
			{
				float delay = Mathf.Max(1f, EmpressLateJoinPlugin.Instance.EmpressTruckStartFallbackDelay.Value);
				_empressTruckStartFallbackCoroutine = ((MonoBehaviour)this).StartCoroutine(EmpressTruckStartFallback(delay, _empressTruckStartFallbackSceneToken));
			}
		}

		private IEnumerator EmpressTruckStartFallback(float delay, int sceneToken)
		{
			yield return (object)new WaitForSeconds(delay);
			_empressTruckStartFallbackCoroutine = null;
			if (sceneToken == _empressTruckStartFallbackSceneToken && !((Object)(object)RunManager.instance == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer() && !SemiFunc.RunIsLobbyMenu() && !SemiFunc.MenuLevel() && !EmpressTryExecuteLevelNextCommand())
			{
				EmpressInvokeRunManagerChangeLevel(RunManager.instance, completedLevel: true, SemiFunc.RunIsArena(), (ChangeLevelType)0);
			}
		}

		private bool EmpressTryExecuteLevelNextCommand()
		{
			DebugCommandHandler val = EmpressGetDebugCommandHandlerInstance();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			object obj = EmpressInvokeMethod(EmpressDebugCommandHandlerExecuteMethod, val, "level next", true);
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private void EmpressProcessDelayedSceneChange()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (_empressDelayedSceneChange == null)
			{
				return;
			}
			EmpressDelayedSceneChangeRequest empressDelayedSceneChange = _empressDelayedSceneChange;
			if ((Object)(object)empressDelayedSceneChange.RunManager == (Object)null || ((object)empressDelayedSceneChange.RunManager).Equals((object?)null))
			{
				_empressDelayedSceneChange = null;
				return;
			}
			float num = Mathf.Max(1f, EmpressLateJoinPlugin.Instance.EmpressSceneSwitchSettleTimeout.Value);
			bool flag = Time.unscaledTime - empressDelayedSceneChange.RequestedAt >= num;
			if (_empressLateJoinDetectedAt.Count > 0 && !flag)
			{
				return;
			}
			_empressDelayedSceneChange = null;
			_empressRunningDelayedSceneChange = true;
			try
			{
				EmpressInvokeRunManagerChangeLevel(empressDelayedSceneChange.RunManager, empressDelayedSceneChange.CompletedLevel, empressDelayedSceneChange.LevelFailed, empressDelayedSceneChange.ChangeLevelType);
			}
			finally
			{
				_empressRunningDelayedSceneChange = false;
			}
		}

		internal bool EmpressTryEvaluatePlayersAllInTruck(out bool result)
		{
			result = false;
			if (!EmpressCanHostRoomControl() || (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsShop()))
			{
				return false;
			}
			bool result2 = false;
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!((Object)(object)item == (Object)null) && !EmpressGetAvatarIsDisabled(item) && !EmpressGetAvatarInTruck(item))
				{
					if (!EmpressShouldIgnoreForTruckDeparture(item))
					{
						return result2;
					}
					result2 = true;
				}
			}
			result = true;
			return result2;
		}

		internal bool EmpressTryHandlePlayerSelfDestruction(TruckScreenText truckScreenText)
		{
			if ((Object)(object)truckScreenText == (Object)null || !EmpressCanHostRoomControl() || !SemiFunc.RunIsLevel())
			{
				return false;
			}
			if (!SemiFunc.PerSecond(5f, (Object)(object)truckScreenText) || !EmpressGetTruckScreenSelfDestructingPlayers(truckScreenText))
			{
				return false;
			}
			bool flag = false;
			bool flag2 = true;
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!((Object)(object)item == (Object)null) && !EmpressGetAvatarIsDisabled(item))
				{
					if (EmpressGetAvatarInTruck(item) && !EmpressGetAvatarSelfDestructPrevented(item))
					{
						EmpressSetAvatarSelfDestructPrevented(item, value: true);
					}
					else if (EmpressShouldIgnoreForTruckDeparture(item))
					{
						flag = true;
					}
					else if (!EmpressGetAvatarSelfDestructPrevented(item))
					{
						flag2 = false;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			if (flag2)
			{
				EmpressInvokeTruckScreenChatMessageResultSuccess(truckScreenText);
				EmpressInvokeTruckScreenPlayerChatBoxStateUpdate(truckScreenText, (PlayerChatBoxState)3);
				EmpressInvokeTruckScreenGotoPage(truckScreenText, 2);
				EmpressSetTruckScreenSelfDestructingPlayers(truckScreenText, value: false);
			}
			return true;
		}

		private bool EmpressShouldIgnoreForTruckDeparture(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar.photonView == (Object)null)
			{
				return false;
			}
			int ownerActorNr = avatar.photonView.OwnerActorNr;
			if (ownerActorNr <= 0 || !EmpressIsActorStillConnected(ownerActorNr))
			{
				return false;
			}
			if (!_empressHostWaitingActors.Contains(ownerActorNr) && !_empressDeferredWaitingRoomActors.Contains(ownerActorNr) && !_empressTruckDepartureIgnoredActors.Contains(ownerActorNr) && (!SemiFunc.RunIsShop() || EmpressGetAvatarSpawned(avatar)))
			{
				return _empressLateJoinDetectedAt.ContainsKey(ownerActorNr);
			}
			return true;
		}

		private void EmpressQueueLateJoiner(PlayerAvatar avatar)
		{
			//IL_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			int ownerActorNr = avatar.photonView.OwnerActorNr;
			_empressHostWaitingActors.Add(ownerActorNr);
			var (val, val2) = EmpressGetWaitingSpawn(ownerActorNr);
			avatar.Spawn(val, val2);
			EmpressRefreshAvatarRoomState(avatar);
			EmpressBackfillLateJoinerIntoEnemySystems(avatar);
		}

		private void EmpressAdmitLateJoiner(PlayerAvatar avatar)
		{
			//IL_003e: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			int ownerActorNr = avatar.photonView.OwnerActorNr;
			_empressHostWaitingActors.Remove(ownerActorNr);
			_empressNextSnapByActor.Remove(ownerActorNr);
			Vector3 val;
			Quaternion val2;
			if (EmpressLiveJoinEnabled() && SemiFunc.RunIsLevel())
			{
				(val, val2) = EmpressGetWaitingSpawn(ownerActorNr);
			}
			else
			{
				(val, val2) = EmpressGetAdmissionSpawn(avatar);
			}
			avatar.Spawn(val, val2);
			EmpressRefreshAvatarRoomState(avatar);
			EmpressBackfillLateJoinerIntoEnemySystems(avatar);
		}

		private void EmpressEnsureSupportObjects(PlayerAvatar avatar)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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)
			if ((Object)(object)avatar == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null || SemiFunc.MenuLevel() || !EmpressHasAvatarSteamIdentity(avatar))
			{
				return;
			}
			bool flag = false;
			GameObject val = EmpressGetLevelDeathHeadPrefab();
			PlayerDeathHead val2 = EmpressGetAvatarDeathHead(avatar);
			if ((Object)(object)val2 != (Object)null)
			{
				flag |= EmpressRepairDeathHeadSupport(avatar, val2);
			}
			else if ((Object)(object)val != (Object)null)
			{
				val2 = (GameManager.Multiplayer() ? PhotonNetwork.Instantiate(((Object)val).name, new Vector3(0f, 3000f, 0f), Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(val, new Vector3(0f, 3000f, 0f), Quaternion.identity)).GetComponent<PlayerDeathHead>();
				if ((Object)(object)val2 != (Object)null)
				{
					val2.playerAvatar = avatar;
					EmpressSetAvatarDeathHead(avatar, val2);
					flag = true;
				}
			}
			GameObject val3 = EmpressGetLevelTumblePrefab();
			PlayerTumble val4 = EmpressGetAvatarTumble(avatar);
			if ((Object)(object)val4 != (Object)null)
			{
				flag |= EmpressRepairTumbleSupport(avatar, val4);
			}
			else if ((Object)(object)val3 != (Object)null)
			{
				val4 = (GameManager.Multiplayer() ? PhotonNetwork.Instantiate(((Object)val3).name, new Vector3(0f, 3000f, 0f), Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(val3, new Vector3(0f, 3000f, 0f), Quaternion.identity)).GetComponent<PlayerTumble>();
				if ((Object)(object)val4 != (Object)null)
				{
					val4.playerAvatar = avatar;
					EmpressSetAvatarTumble(avatar, val4);
					flag = true;
				}
			}
		}

		private bool EmpressRepairDeathHeadSupport(PlayerAvatar avatar, PlayerDeathHead deathHead)
		{
			bool result = false;
			if ((Object)(object)deathHead.playerAvatar != (Object)(object)avatar)
			{
				deathHead.playerAvatar = avatar;
				EmpressSetAvatarDeathHead(avatar, deathHead);
				result = true;
			}
			if (!EmpressGetDeathHeadSetup(deathHead) && (Object)(object)EmpressGetDeathHeadPhysGrabObject(deathHead) != (Object)null)
			{
				try
				{
					EmpressInvokePlayerDeathHeadSetupDone(deathHead);
					EmpressSetDeathHeadSetup(deathHead, setup: true);
					result = true;
				}
				catch
				{
				}
			}
			return result;
		}

		private bool EmpressRepairTumbleSupport(PlayerAvatar avatar, PlayerTumble tumble)
		{
			bool result = false;
			if ((Object)(object)tumble.playerAvatar != (Object)(object)avatar)
			{
				tumble.playerAvatar = avatar;
				EmpressSetAvatarTumble(avatar, tumble);
				result = true;
			}
			if (!EmpressGetTumbleSetup(tumble) && (Object)(object)EmpressGetTumblePhysGrabObject(tumble) != (Object)null)
			{
				try
				{
					EmpressInvokePlayerTumbleSetupDone(tumble);
					EmpressSetTumbleSetup(tumble, setup: true);
					result = true;
				}
				catch
				{
				}
			}
			return result;
		}

		private (Vector3 position, Quaternion rotation) EmpressGetAdmissionSpawn(PlayerAvatar lateJoiner)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			List<SpawnPoint> list = EmpressFindSceneObjects<SpawnPoint>();
			if (list.Count == 0)
			{
				return EmpressGetFallbackSpawn();
			}
			SpawnPoint val = list[0];
			float num = float.NegativeInfinity;
			foreach (SpawnPoint item in list)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				float num2 = float.PositiveInfinity;
				foreach (PlayerAvatar item2 in SemiFunc.PlayerGetList())
				{
					if (!((Object)(object)item2 == (Object)null) && !((Object)(object)item2 == (Object)(object)lateJoiner) && EmpressGetAvatarSpawned(item2) && !((Object)(object)item2.photonView == (Object)null) && !_empressHostWaitingActors.Contains(item2.photonView.OwnerActorNr))
					{
						num2 = Mathf.Min(num2, Vector3.Distance(((Component)item).transform.position, ((Component)item2).transform.position));
					}
				}
				float num3 = (float.IsPositiveInfinity(num2) ? 9999f : num2);
				if (num3 > num)
				{
					num = num3;
					val = item;
				}
			}
			return (((Component)val).transform.position, ((Component)val).transform.rotation);
		}

		private (Vector3 position, Quaternion rotation) EmpressGetWaitingSpawn(int actorNumber)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			(Vector3 position, Quaternion rotation) tuple = EmpressGetWaitingAnchor();
			Vector3 item = tuple.position;
			Quaternion item2 = tuple.rotation;
			float num = (float)actorNumber * 47f;
			float num2 = 1.3f + (float)(actorNumber % 3) * 0.45f;
			Vector3 val = Quaternion.Euler(0f, num, 0f) * new Vector3(0f, 0f, num2);
			return (item + val, item2);
		}

		private (Vector3 position, Quaternion rotation) EmpressGetWaitingAnchor()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			TruckSafetySpawnPoint val = EmpressFindSceneObjects<TruckSafetySpawnPoint>().FirstOrDefault();
			if ((Object)(object)val != (Object)null)
			{
				return (((Component)val).transform.position, ((Component)val).transform.rotation);
			}
			List<SpawnPoint> list = EmpressFindSceneObjects<SpawnPoint>();
			if (list.Count > 0 && (Object)(object)list[0] != (Object)null)
			{
				return (((Component)list[0]).transform.position, ((Component)list[0]).transform.rotation);
			}
			return EmpressGetFallbackSpawn();
		}

		private static (Vector3 position, Quaternion rotation) EmpressGetFallbackSpawn()
		{
			//IL_0017: 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_0062: 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)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerController.instance != (Object)null)
			{
				return (((Component)PlayerController.instance).transform.position, ((Component)PlayerController.instance).transform.rotation);
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				return (((Component)Camera.main).transform.position, ((Component)Camera.main).transform.rotation);
			}
			return (Vector3.zero, Quaternion.identity);
		}

		private static PlayerAvatar? EmpressFindAvatar(int actorNumber)
		{
			return ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar player) => (Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null && player.photonView.OwnerActorNr == actorNumber));
		}

		private bool EmpressShouldQueueLateJoiner()
		{
			if (!SemiFunc.RunIsLevel())
			{
				return false;
			}
			if (EmpressLiveJoinEnabled())
			{
				return false;
			}
			return EmpressLateJoinPlugin.Instance.EmpressQueueDuringActiveLevels.Value;
		}

		private void EmpressTrackLateJoin(int actorNumber)
		{
			if (!_empressLateJoinDetectedAt.ContainsKey(actorNumber))
			{
				_empressLateJoinDetectedAt[actorNumber] = Time.unscaledTime;
			}
			_empressTruckDepartureIgnoredActors.Add(actorNumber);
			_empressDeferredWaitingRoomActors.Remove(actorNumber);
			_empressEnemyRegisteredActors.Remove(actorNumber);
			_empressLiveJoinLevelUpdateSentActors.Remove(actorNumber);
			_empressLiveJoinBootstrapSentActors.Remove(actorNumber);
			_empressLiveStateReplayedActors.Remove(actorNumber);
			_empressLateJoinReadyAt.Remove(actorNumber);
		}

		private void EmpressClearLateJoinTracking(int actorNumber)
		{
			_empressLateJoinDetectedAt.Remove(actorNumber);
			_empressLateJoinReadyAt.Remove(actorNumber);
		}

		private bool EmpressEnsureRunLevelWaitingRoomMode()
		{
			if (EmpressLiveJoinEnabled())
			{
				return false;
			}
			if (_empressRunLevelCachePruned)
			{
				return true;
			}
			if (!EmpressCanHostRoomControl() || !SemiFunc.RunIsLevel())
			{
				return false;
			}
			if ((Object)(object)EmpressGetRunManagerPhotonView() == (Object)null)
			{
				return false;
			}
			if (EmpressPruneBufferedRunLevelState() <= 0)
			{
				return false;
			}
			_empressRunLevelCachePruned = true;
			_empressHostWaitingActors.Clear();
			_empressLateJoinDetectedAt.Clear();
			_empressLateJoinReadyAt.Clear();
			_empressDelayedSceneChange = null;
			return true;
		}

		private bool EmpressIsLateJoinerSettled(PlayerAvatar avatar, float detectedAt)
		{
			if (!EmpressGetAvatarSpawned(avatar))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(EmpressGetAvatarSteamId(avatar)) || string.IsNullOrWhiteSpace(EmpressGetAvatarPlayerName(avatar)))
			{
				return false;
			}
			if (!EmpressHasSupportObjectsReady(avatar))
			{
				return false;
			}
			int num = (((Object)(object)avatar.photonView != (Object)null) ? avatar.photonView.OwnerActorNr : 0);
			if (num > 0 && !_empressEnemyRegisteredActors.Contains(num))
			{
				return false;
			}
			float num2 = Time.unscaledTime - detectedAt;
			if (num2 < 0.5f)
			{
				return false;
			}
			if (EmpressGetAvatarLevelAnimationCompleted(avatar))
			{
				return true;
			}
			return num2 >= Mathf.Max(0.75f, EmpressLateJoinPlugin.Instance.EmpressSceneSwitchSettleDelay.Value);
		}

		private void EmpressBackfillLateJoinerIntoEnemySystems(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar.photonView == (Object)null)
			{
				return;
			}
			int ownerActorNr = avatar.photonView.OwnerActorNr;
			int viewID = avatar.photonView.ViewID;
			if (ownerActorNr <= 0 || viewID <= 0 || _empressEnemyRegisteredActors.Contains(ownerActorNr))
			{
				return;
			}
			HashSet<Enemy> hashSet = new HashSet<Enemy>(from enemy in EmpressFindSceneObjects<Enemy>()
				where (Object)(object)enemy != (Object)null
				select enemy);
			if (hashSet.Count == 0)
			{
				return;
			}
			int num = 0;
			foreach (Enemy item in hashSet)
			{
				try
				{
					item.PlayerAdded(viewID);
					num++;
				}
				catch
				{
				}
			}
			_empressEnemyRegisteredActors.Add(ownerActorNr);
		}

		private static void EmpressRefreshAvatarRoomState(PlayerAvatar avatar)
		{
			RoomVolumeCheck instance = EmpressGetAvatarRoomVolumeCheck(avatar);
			EmpressInvokeMethod(EmpressRoomVolumeCheckCheckSetMethod, instance);
		}

		private int EmpressPruneBufferedRunLevelState()
		{
			int num = 0;
			PhotonView val = EmpressGetRunManagerPhotonView();
			if ((Object)(object)val != (Object)null)
			{
				PhotonNetwork.RemoveBufferedRPCs(val.ViewID, "UpdateLevelRPC", (int[])null);
				num++;
			}
			PhotonView val2 = EmpressGetFieldValue<PhotonView>(EmpressLevelGeneratorPhotonViewField, LevelGenerator.Instance);
			if ((Object)(object)val2 != (Object)null)
			{
				PhotonNetwork.RemoveBufferedRPCs(val2.ViewID, (string)null, (int[])null);
				num++;
			}
			return num;
		}

		private void EmpressRemoveInstantiationCache(PhotonView photonView)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (photonView.InstantiationId == 0 || EmpressPhotonRaiseEventInternalMethod == null)
			{
				return;
			}
			object obj = EmpressPhotonKeyByteSevenField?.GetValue(null);
			if (obj == null)
			{
				return;
			}
			Hashtable val = EmpressGetFieldValue<Hashtable>(EmpressPhotonRemoveFilterField, null);
			Hashtable val2 = new Hashtable();
			if (val != null)
			{
				DictionaryEntryEnumerator enumerator = val.GetEnumerator();
				try
				{
					while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext())
					{
						DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current;
						val2[current.Key] = current.Value;
					}
				}
				finally
				{
					((IDisposable)(DictionaryEntryEnumerator)(ref enumerator)).Dispose();
				}
			}
			val2[obj] = photonView.InstantiationId;
			RaiseEventOptions val3 = EmpressGetFieldValue<RaiseEventOptions>(EmpressPhotonServerCleanOptionsField, null);
			EventCaching cachingOption = (EventCaching)((val3 != null) ? ((int)val3.CachingOption) : 0);
			RaiseEventOptions val4 = (RaiseEventOptions)(((object)val3) ?? ((object)new RaiseEventOptions()));
			val4.CachingOption = (EventCaching)6;
			try
			{
				EmpressPhotonRaiseEventInternalMethod.Invoke(null, new object[4]
				{
					(byte)202,
					val2,
					val4,
					SendOptions.SendReliable
				});
			}
			catch
			{
			}
			finally
			{
				if (val3 != null)
				{
					val3.CachingOption = cachingOption;
				}
			}
		}

		private static PhotonView? EmpressGetRunManagerPhotonView()
		{
			RunManagerPUN val = EmpressGetFieldValue<RunManagerPUN>(EmpressRunManagerPunField, RunManager.instance);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return EmpressGetFieldValue<PhotonView>(EmpressRunManagerPunPhotonViewField, val);
		}

		private static bool EmpressIsActorStillConnected(int actorNumber)
		{
			if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
			{
				return false;
			}
			return PhotonNetwork.CurrentRoom.Players.ContainsKey(actorNumber);
		}

		private string EmpressDescribeTrackedLateJoiners()
		{
			List<string> list = new List<string>();
			foreach (int item in _empressLateJoinDetectedAt.Keys.OrderBy((int value) => value))
			{
				PlayerAvatar val = EmpressFindAvatar(item);
				Player value2;
				if ((Object)(object)val != (Object)null)
				{
					list.Add($"{EmpressGetAvatarDisplayName(val)} ({item})");
				}
				else if (PhotonNetwork.CurrentRoom != null && PhotonNetwork.CurrentRoom.Players.TryGetValue(item, out value2))
				{
					list.Add($"{value2.NickName} ({item})");
				}
				else
				{
					list.Add(item.ToString());
				}
			}
			if (list.Count != 0)
			{
				return string.Join(", ", list);
			}
			return "unknown players";
		}

		private static bool EmpressCanHostRoomControl()
		{
			if ((Object)(object)EmpressLateJoinPlugin.Instance == (Object)null || !EmpressLateJoinPlugin.Instance.EmpressEnabled.Value)
			{
				return false;
			}
			if ((Object)(object)GameManager.instance == (Object)null || !PhotonNetwork.InRoom || !GameManager.Multiplayer() || !PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			return true;
		}

		private static bool EmpressIsFrontEndRoomState()
		{
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return true;
			}
			return SemiFunc.MenuLevel();
		}

		private static bool EmpressCanHostLateJoinLogic()
		{
			if (!EmpressCanHostRoomControl())
			{
				return false;
			}
			if ((Object)(object)GameDirector.instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null)
			{
				return false;
			}
			return SemiFunc.LevelGenDone();
		}

		private static bool EmpressGetConnectRandom()
		{
			return EmpressGetFieldValue<bool>(EmpressGameManagerConnectRandomField, GameManager.instance);
		}

		private static DebugCommandHandler? EmpressGetDebugCommandHandlerInstance()
		{
			return EmpressGetFieldValue<DebugCommandHandler>(EmpressDebugCommandHandlerInstanceField, null);
		}

		private static Level? EmpressGetRunManagerLevelCurrent(RunManager? runManager)
		{
			return EmpressGetFieldValue<Level>(EmpressRunManagerLevelCurrentField, runManager);
		}

		private static int EmpressGetRunManagerLevelsCompleted(RunManager? runManager)
		{
			return EmpressGetFieldValue<int>(EmpressRunManagerLevelsCompletedField, runManager);
		}

		private static bool EmpressGetAvatarSpawned(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerAvatarSpawnedField, avatar);
		}

		private static string EmpressGetAvatarSteamId(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<string>(EmpressPlayerAvatarSteamIdField, avatar) ?? string.Empty;
		}

		private static bool EmpressHasAvatarSteamIdentity(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				return !string.IsNullOrWhiteSpace(EmpressGetAvatarSteamId(avatar));
			}
			return false;
		}

		private static string EmpressGetAvatarPlayerName(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<string>(EmpressPlayerAvatarPlayerNameField, avatar) ?? string.Empty;
		}

		private static PlayerHealth? EmpressGetAvatarPlayerHealth(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<PlayerHealth>(EmpressPlayerAvatarPlayerHealthField, avatar);
		}

		private static bool EmpressGetAvatarDeadSet(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerAvatarDeadSetField, avatar);
		}

		private static bool EmpressGetAvatarLevelAnimationCompleted(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerAvatarLevelAnimationCompletedField, avatar);
		}

		private static bool EmpressGetAvatarIsDisabled(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerAvatarIsDisabledField, avatar);
		}

		private static RoomVolumeCheck? EmpressGetAvatarRoomVolumeCheck(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<RoomVolumeCheck>(EmpressPlayerAvatarRoomVolumeCheckField, avatar);
		}

		private static bool EmpressGetAvatarInTruck(PlayerAvatar avatar)
		{
			RoomVolumeCheck val = EmpressGetAvatarRoomVolumeCheck(avatar);
			if ((Object)(object)val != (Object)null)
			{
				return EmpressGetFieldValue<bool>(EmpressRoomVolumeCheckInTruckField, val);
			}
			return false;
		}

		private static bool EmpressGetAvatarSelfDestructPrevented(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerAvatarSelfDestructPreventedField, avatar);
		}

		private static void EmpressSetAvatarSelfDestructPrevented(PlayerAvatar avatar, bool value)
		{
			EmpressSetFieldValue(EmpressPlayerAvatarSelfDestructPreventedField, avatar, value);
		}

		private static int EmpressGetPlayerHealthHealth(PlayerHealth playerHealth)
		{
			return EmpressGetFieldValue<int>(EmpressPlayerHealthHealthField, playerHealth);
		}

		private static int EmpressGetPlayerHealthMaxHealth(PlayerHealth playerHealth)
		{
			return EmpressGetFieldValue<int>(EmpressPlayerHealthMaxHealthField, playerHealth);
		}

		private static bool EmpressGetTruckScreenSelfDestructingPlayers(TruckScreenText truckScreenText)
		{
			return EmpressGetFieldValue<bool>(EmpressTruckScreenTextSelfDestructingPlayersField, truckScreenText);
		}

		private static void EmpressSetTruckScreenSelfDestructingPlayers(TruckScreenText truckScreenText, bool value)
		{
			EmpressSetFieldValue(EmpressTruckScreenTextSelfDestructingPlayersField, truckScreenText, value);
		}

		private static void EmpressInvokeTruckScreenChatMessageResultSuccess(TruckScreenText truckScreenText)
		{
			EmpressInvokeMethod(EmpressTruckScreenTextChatMessageResultSuccessMethod, truckScreenText);
		}

		private static void EmpressInvokeTruckScreenPlayerChatBoxStateUpdate(TruckScreenText truckScreenText, PlayerChatBoxState state)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			EmpressInvokeMethod(EmpressTruckScreenTextPlayerChatBoxStateUpdateMethod, truckScreenText, state);
		}

		private static void EmpressInvokeTruckScreenGotoPage(TruckScreenText truckScreenText, int pageIndex)
		{
			EmpressInvokeMethod(EmpressTruckScreenTextGotoPageMethod, truckScreenText, pageIndex);
		}

		private static void EmpressInvokePlayerDeathHeadSetupDone(PlayerDeathHead deathHead)
		{
			EmpressInvokeMethod(EmpressPlayerDeathHeadSetupDoneMethod, deathHead);
		}

		private static void EmpressInvokePlayerTumbleSetupDone(PlayerTumble tumble)
		{
			EmpressInvokeMethod(EmpressPlayerTumbleSetupDoneMethod, tumble);
		}

		private static void EmpressInvokeRunManagerChangeLevel(RunManager runManager, bool completedLevel, bool levelFailed, ChangeLevelType changeLevelType)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			EmpressInvokeMethod(EmpressRunManagerChangeLevelMethod, runManager, completedLevel, levelFailed, changeLevelType);
		}

		private static PhotonView? EmpressGetPunManagerPhotonView()
		{
			return EmpressGetFieldValue<PhotonView>(EmpressPunManagerPhotonViewField, PunManager.instance);
		}

		private static PhotonView? EmpressGetRoundDirectorPhotonView()
		{
			return EmpressGetFieldValue<PhotonView>(EmpressRoundDirectorPhotonViewField, RoundDirector.instance);
		}

		private static int EmpressGetRoundDirectorTotalHaul()
		{
			return EmpressGetFieldValue<int>(EmpressRoundDirectorTotalHaulField, RoundDirector.instance);
		}

		private static bool EmpressGetRoundDirectorExtractionPointActive()
		{
			return EmpressGetFieldValue<bool>(EmpressRoundDirectorExtractionPointActiveField, RoundDirector.instance);
		}

		private static void EmpressSetRoundDirectorExtractionPointActive(bool value)
		{
			EmpressSetFieldValue(EmpressRoundDirectorExtractionPointActiveField, RoundDirector.instance, value);
		}

		private static ExtractionPoint? EmpressGetRoundDirectorExtractionPointCurrent()
		{
			return EmpressGetFieldValue<ExtractionPoint>(EmpressRoundDirectorExtractionPointCurrentField, RoundDirector.instance);
		}

		private static void EmpressSetRoundDirectorExtractionPointCurrent(ExtractionPoint? value)
		{
			EmpressSetFieldValue(EmpressRoundDirectorExtractionPointCurrentField, RoundDirector.instance, value);
		}

		private static bool EmpressGetRoundDirectorAllExtractionPointsCompleted()
		{
			return EmpressGetFieldValue<bool>(EmpressRoundDirectorAllExtractionPointsCompletedField, RoundDirector.instance);
		}

		private static PhotonView? EmpressGetExtractionPointPhotonView(ExtractionPoint extractionPoint)
		{
			return EmpressGetFieldValue<PhotonView>(EmpressExtractionPointPhotonViewField, extractionPoint);
		}

		private static int EmpressGetShopManagerTotalCost()
		{
			return EmpressGetFieldValue<int>(EmpressShopManagerTotalCostField, ShopManager.instance);
		}

		private static bool EmpressHasSupportObjectsReady(PlayerAvatar avatar)
		{
			PlayerDeathHead val = EmpressGetAvatarDeathHead(avatar);
			if ((Object)(object)val == (Object)null || (Object)(object)val.playerAvatar != (Object)(object)avatar || !EmpressGetDeathHeadSetup(val))
			{
				return false;
			}
			PlayerTumble val2 = EmpressGetAvatarTumble(avatar);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.playerAvatar == (Object)(object)avatar)
			{
				return EmpressGetTumbleSetup(val2);
			}
			return false;
		}

		private static PlayerDeathHead? EmpressGetAvatarDeathHead(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<PlayerDeathHead>(EmpressPlayerAvatarDeathHeadField, avatar);
		}

		private static void EmpressSetAvatarDeathHead(PlayerAvatar avatar, PlayerDeathHead deathHead)
		{
			EmpressSetFieldValue(EmpressPlayerAvatarDeathHeadField, avatar, deathHead);
		}

		private static PlayerTumble? EmpressGetAvatarTumble(PlayerAvatar avatar)
		{
			return EmpressGetFieldValue<PlayerTumble>(EmpressPlayerAvatarTumbleField, avatar);
		}

		private static void EmpressSetAvatarTumble(PlayerAvatar avatar, PlayerTumble tumble)
		{
			EmpressSetFieldValue(EmpressPlayerAvatarTumbleField, avatar, tumble);
		}

		private static bool EmpressGetDeathHeadSetup(PlayerDeathHead deathHead)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerDeathHeadSetupField, deathHead);
		}

		private static PhysGrabObject? EmpressGetDeathHeadPhysGrabObject(PlayerDeathHead deathHead)
		{
			return EmpressGetFieldValue<PhysGrabObject>(EmpressPlayerDeathHeadPhysGrabObjectField, deathHead);
		}

		private static void EmpressSetDeathHeadSetup(PlayerDeathHead deathHead, bool setup)
		{
			EmpressSetFieldValue(EmpressPlayerDeathHeadSetupField, deathHead, setup);
		}

		private static PhysGrabObject? EmpressGetTumblePhysGrabObject(PlayerTumble tumble)
		{
			return EmpressGetFieldValue<PhysGrabObject>(EmpressPlayerTumblePhysGrabObjectField, tumble);
		}

		private static PhotonView? EmpressGetTumblePhotonView(PlayerTumble tumble)
		{
			return EmpressGetFieldValue<PhotonView>(EmpressPlayerTumblePhotonViewField, tumble);
		}

		private static bool EmpressGetTumbleSetup(PlayerTumble tumble)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerTumbleSetupField, tumble);
		}

		private static void EmpressSetTumbleSetup(PlayerTumble tumble, bool setup)
		{
			EmpressSetFieldValue(EmpressPlayerTumbleSetupField, tumble, setup);
		}

		private static bool EmpressGetTumbleIsTumbling(PlayerTumble tumble)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerTumbleIsTumblingField, tumble);
		}

		private static bool EmpressGetTumbleOverride(PlayerTumble tumble)
		{
			return EmpressGetFieldValue<bool>(EmpressPlayerTumbleOverrideField, tumble);
		}

		private static GameObject? EmpressGetLevelDeathHeadPrefab()
		{
			return EmpressGetFieldValue<GameObject>(EmpressLevelGeneratorDeathHeadPrefabField, LevelGenerator.Instance);
		}

		private static GameObject? EmpressGetLevelTumblePrefab()
		{
			return EmpressGetFieldValue<GameObject>(EmpressLevelGeneratorTumblePrefabField, LevelGenerator.Instance);
		}

		private static List<T> EmpressFindSceneObjects<T>() where T : Object
		{
			//IL_0060: 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)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			List<T> list = new List<T>();
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			foreach (T val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				T val2 = val;
				object obj = val2;
				Component val3 = (Component)((obj is Component) ? obj : null);
				Scene scene;
				if (val3 == null)
				{
					object obj2 = val2;
					GameObject val4 = (GameObject)((obj2 is GameObject) ? obj2 : null);
					if (val4 == null)
					{
						continue;
					}
					GameObject val5 = val4;
					scene = val5.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						scene = val5.scene;
						if (!string.IsNullOrWhiteSpace(((Scene)(ref scene)).name))
						{
							list.Add(val);
						}
					}
					continue;
				}
				Component val6 = val3;
				scene = val6.gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					scene = val6.gameObject.scene;
					if (!string.IsNullOrWhiteSpace(((Scene)(ref scene)).name))
					{
						list.Add(val);
					}
				}
			}
			return list;
		}

		private static string EmpressGetAvatarDisplayName(PlayerAvatar avatar)
		{
			PhotonView photonView = avatar.photonView;
			if (((photonView != null) ? photonView.Owner : null) != null && !string.IsNullOrWhiteSpace(avatar.photonView.Owner.NickName))
			{
				return avatar.photonView.Owner.NickName;
			}
			string text = EmpressGetAvatarPlayerName(avatar);
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return ((Object)avatar).name;
		}

		private static Hashtable EmpressConvertDictionaryToHashtable(Dictionary<string, int> dictionary)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			Hashtable val = new Hashtable();
			foreach (KeyValuePair<string, int> item in dictionary)
			{
				val[(object)item.Key] = item.Value;
			}
			return val;
		}

		private static T EmpressGetFieldValue<T>(FieldInfo? fieldInfo, object? instance)
		{
			if (fieldInfo == null || (!fieldInfo.IsStatic && instance == null))
			{
				return default(T);
			}
			try
			{
				object value = fieldInfo.GetValue(fieldInfo.IsStatic ? null : instance);
				if (value is T)
				{
					return (T)value;
				}
			}
			catch
			{
			}
			return default(T);
		}

		private static void EmpressSetFieldValue(FieldInfo? fieldInfo, object? instance, object? value)
		{
			if (fieldInfo == null || (!fieldInfo.IsStatic && instance == null))
			{
				return;
			}
			try
			{
				fieldInfo.SetValue(fieldInfo.IsStatic ? null : instance, value);
			}
			catch
			{
			}
		}

		private static object? EmpressInvokeMethod(MethodInfo? methodInfo, object? instance, params object?[] parameters)
		{
			if (methodInfo == null || (!methodInfo.IsStatic && instance == null))
			{
				return null;
			}
			try
			{
				return methodInfo.Invoke(methodInfo.IsStatic ? null : instance, parameters);
			}
			catch
			{
				return null;
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "PlayerSpawn")]
	internal static class EmpressLateJoinLevelGeneratorPatch
	{
		private static bool Prefix()
		{
			return !(EmpressLateJoinPlugin.Runtime?.EmpressTryHandleLateJoinSpawn() ?? false);
		}
	}
	[HarmonyPatch(typeof(NetworkManager), "OnPlayerEnteredRoom")]
	internal static class EmpressLateJoinPlayerEnteredPatch
	{
		private static void Postfix(Player newPlayer)
		{
			EmpressLateJoinPlugin.Runtime?.EmpressHandlePlayerEntered(newPlayer);
		}
	}
	[HarmonyPatch(typeof(NetworkManager), "OnPlayerLeftRoom")]
	internal static class EmpressLateJoinPlayerLeftPatch
	{
		private static void Postfix(Player otherPlayer)
		{
			EmpressLateJoinPlugin.Runtime?.EmpressHandlePlayerLeft(otherPlayer);
		}
	}
	[HarmonyPatch(typeof(MenuPageLobby), "ButtonStart")]
	internal static class EmpressLateJoinLobbyStartPatch
	{
		private static void Postfix()
		{
			EmpressLateJoinPlugin.Runtime?.EmpressForceJoinabilityRefresh(forceSteamLobbyUnlock: true);
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	internal static class EmpressLateJoinChangeLevelPatch
	{
		private static bool Prefix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return !(EmpressLateJoinPlugin.Runtime?.EmpressTryDelaySceneChange(__instance, _completedLevel, _levelFailed, _changeLevelType) ?? false);
		}

		private static void Postfix(RunManager __instance, ChangeLevelType _changeLevelType)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			EmpressLateJoinPlugin.Runtime?.EmpressHandleChangeLevelCompleted(__instance, _changeLevelType);
		}
	}
	[HarmonyPatch(typeof(RoundDirector), "RequestExtractionPointActivationRPC")]
	internal static class EmpressLateJoinExtractionActivationPatch
	{
		private static bool Prefix(int photonViewID)
		{
			return !(EmpressLateJoinPlugin.Runtime?.EmpressTryBlockInvalidExtractionActivation(photonViewID) ?? false);
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "PlayersAllInTruck")]
	internal static class EmpressLateJoinPlayersAllInTruckPatch
	{
		private static bool Prefix(ref bool __result)
		{
			EmpressLateJoinRuntime? runtime = EmpressLateJoinPlugin.Runtime;
			if (runtime != null && runtime.EmpressTryEvaluatePlayersAllInTruck(out var result))
			{
				__result = result;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TruckScreenText), "PlayerSelfDestruction")]
	internal static class EmpressLateJoinPlayerSelfDestructionPatch
	{
		private static bool Prefix(TruckScreenText __instance)
		{
			return !(EmpressLateJoinPlugin.Runtime?.EmpressTryHandlePlayerSelfDestruction(__instance) ?? false);
		}
	}
	[HarmonyPatch(typeof(TruckScreenText), "PlayerChatBoxStateUpdate")]
	internal static class EmpressLateJoinTruckStartStatePatch
	{
		private static void Postfix(PlayerChatBoxState _state)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			EmpressLateJoinPlugin.Runtime?.EmpressScheduleTruckStartFallback(_state);
		}
	}
	internal static class EmpressLateJoinGrabGuard
	{
		internal static bool TryResolveGrabber(int playerPhotonId, string rpcName)
		{
			if (playerPhotonId <= 0)
			{
				return false;
			}
			PhotonView val = PhotonView.Find(playerPhotonId);
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<PhysGrabber>() != (Object)null)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabLinkRPC", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(Vector3),
		typeof(Vector3),
		typeof(Vector3),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabLinkPatch
	{
		private static bool Prefix(PhysGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "PhysGrabObject.GrabLinkRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabPointSyncRPC", new Type[]
	{
		typeof(int),
		typeof(Vector3),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabPointSyncPatch
	{
		private static bool Prefix(PhysGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "PhysGrabObject.GrabPointSyncRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStartedRPC", new Type[]
	{
		typeof(int),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabStartedPatch
	{
		private static bool Prefix(PhysGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "PhysGrabObject.GrabStartedRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerAddRPC", new Type[]
	{
		typeof(int),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabPlayerAddPatch
	{
		private static bool Prefix(PhysGrabObject __instance, int photonViewID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(photonViewID, "PhysGrabObject.GrabPlayerAddRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerRemoveRPC", new Type[]
	{
		typeof(int),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabPlayerRemovePatch
	{
		private static bool Prefix(PhysGrabObject __instance, int photonViewID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(photonViewID, "PhysGrabObject.GrabPlayerRemoveRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabEndedRPC", new Type[]
	{
		typeof(int),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinPhysGrabObjectGrabEndedPatch
	{
		private static bool Prefix(PhysGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "PhysGrabObject.GrabEndedRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(StaticGrabObject), "GrabLinkRPC", new Type[]
	{
		typeof(int),
		typeof(Vector3),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinStaticGrabObjectGrabLinkPatch
	{
		private static bool Prefix(StaticGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "StaticGrabObject.GrabLinkRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(StaticGrabObject), "GrabPointSyncRPC", new Type[]
	{
		typeof(int),
		typeof(Vector3),
		typeof(PhotonMessageInfo)
	})]
	internal static class EmpressLateJoinStaticGrabObjectGrabPointSyncPatch
	{
		private static bool Prefix(StaticGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "StaticGrabObject.GrabPointSyncRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(StaticGrabObject), "GrabStartedRPC", new Type[] { typeof(int) })]
	internal static class EmpressLateJoinStaticGrabObjectGrabStartedPatch
	{
		private static bool Prefix(StaticGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "StaticGrabObject.GrabStartedRPC on " + ((Object)__instance).name);
		}
	}
	[HarmonyPatch(typeof(StaticGrabObject), "GrabEndedRPC", new Type[] { typeof(int) })]
	internal static class EmpressLateJoinStaticGrabObjectGrabEndedPatch
	{
		private static bool Prefix(StaticGrabObject __instance, int playerPhotonID)
		{
			return EmpressLateJoinGrabGuard.TryResolveGrabber(playerPhotonID, "StaticGrabObject.GrabEndedRPC on " + ((Object)__instance).name);
		}
	}
}