Decompiled source of LobbyControlMidSessionJoin v0.3.3

BepInEx\plugins\LobbyControlMidSessionJoin\LobbyControlMidSessionJoin.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LobbyControlMidSessionJoin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.3.0")]
[assembly: AssemblyInformationalVersion("0.3.3+4ef58c63cbceb6d9eafdc25449a79e356817cc91")]
[assembly: AssemblyProduct("LobbyControlMidSessionJoin")]
[assembly: AssemblyTitle("LobbyControlMidSessionJoin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LobbyControlMidSessionJoin
{
	internal static class LobbyControlBridge
	{
		private static readonly Type? LateJoinType = AccessTools.TypeByName("LobbyControl.Patches.LateJoinPatches");

		private static readonly FieldInfo? AllowNewConnection = ((LateJoinType == null) ? null : AccessTools.Field(LateJoinType, "_allowNewConnection"));

		private static readonly Type? MainType = AccessTools.TypeByName("LobbyControl.LobbyControl");

		private static readonly FieldInfo? CanModifyLobby = ((MainType == null) ? null : AccessTools.Field(MainType, "CanModifyLobby"));

		internal static bool Available => AllowNewConnection != null;

		internal static void PermitConnections(bool value)
		{
			try
			{
				AllowNewConnection?.SetValue(null, value);
				CanModifyLobby?.SetValue(null, value);
				Plugin.Debug($"LobbyControl bridge: allow={value}, canModify={value}");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not update LobbyControl state: " + ex.Message));
			}
		}
	}
	internal static class MidJoinState
	{
		internal static int SnapshotsSent;

		internal static int LandingSequencesSuppressed;

		internal static bool ClientLateJoinSyncActive;

		internal static bool ClientLateJoinSyncCompleted;

		internal static bool ClientPlayerPositioned;

		internal static string LastStatus = "No synchronization attempted yet.";

		internal static bool IsActiveMoon
		{
			get
			{
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance != (Object)null && !instance.inShipPhase)
				{
					return instance.shipHasLanded;
				}
				return false;
			}
		}

		internal static void ResetClientState()
		{
			ClientLateJoinSyncActive = false;
			ClientLateJoinSyncCompleted = false;
			ClientPlayerPositioned = false;
		}
	}
	internal static class NetworkSync
	{
		private const uint GENERATE_LEVEL_RPC_ID = 3073943002u;

		private const uint FINISH_GENERATING_LEVEL_RPC_ID = 2729232387u;

		private const float GENERATION_TIMEOUT_SECONDS = 60f;

		private const float SNAPSHOT_ACK_TIMEOUT_SECONDS = 10f;

		private static readonly MethodInfo? BeginSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendClientRpc", (Type[])null, (Type[])null);

		private static readonly MethodInfo? EndSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__endSendClientRpc", (Type[])null, (Type[])null);

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

		internal static void StartLateClientSynchronization(StartOfRound owner, ulong clientId)
		{
			if (!ActiveSynchronizations.Add(clientId))
			{
				Plugin.Debug($"Ignored duplicate synchronization request for client {clientId}.");
				return;
			}
			try
			{
				((MonoBehaviour)owner).StartCoroutine(SynchronizeLateClientGuarded(clientId));
			}
			catch
			{
				ActiveSynchronizations.Remove(clientId);
				throw;
			}
		}

		internal static void ResetSynchronizations()
		{
			ActiveSynchronizations.Clear();
		}

		private static IEnumerator SynchronizeLateClientGuarded(ulong clientId)
		{
			try
			{
				yield return SynchronizeLateClientCore(clientId);
			}
			finally
			{
				ActiveSynchronizations.Remove(clientId);
				WorldStateSync.ClearSnapshotAcknowledgement(clientId);
			}
		}

		private static IEnumerator SynchronizeLateClientCore(ulong clientId)
		{
			if (!Plugin.Enabled.Value || !MidJoinState.IsActiveMoon)
			{
				yield break;
			}
			NetworkManager network = NetworkManager.Singleton;
			RoundManager manager = RoundManager.Instance;
			if ((Object)(object)network == (Object)null || (Object)(object)manager == (Object)null || !network.IsServer)
			{
				yield break;
			}
			yield return null;
			yield return null;
			if (!IsClientConnected(network, clientId))
			{
				SetStatus($"Client {clientId} disconnected before synchronization.");
				yield break;
			}
			if (!MidJoinState.IsActiveMoon)
			{
				SetStatus("Round left the landed state before synchronization.");
				yield break;
			}
			try
			{
				WorldStateSync.ResetSnapshotAcknowledgement(clientId);
				WorldStateSync.SendSnapshot(clientId, includeInterior: false);
				SetStatus($"Waiting for client {clientId} to acknowledge the landed ship snapshot.");
			}
			catch (Exception ex)
			{
				SetStatus("Landed ship snapshot synchronization failed: " + ex.Message);
				Plugin.Log.LogError((object)ex);
				yield break;
			}
			float acknowledgementDeadline = Time.realtimeSinceStartup + 10f;
			float nextSnapshotResend = Time.realtimeSinceStartup + 0.5f;
			while (!WorldStateSync.HasSnapshotAcknowledgement(clientId))
			{
				if (!IsClientConnected(network, clientId))
				{
					WorldStateSync.ClearSnapshotAcknowledgement(clientId);
					SetStatus($"Client {clientId} disconnected before acknowledging the landed ship state.");
					yield break;
				}
				if (!MidJoinState.IsActiveMoon)
				{
					WorldStateSync.ClearSnapshotAcknowledgement(clientId);
					SetStatus("Round left the landed state before the late client acknowledged ship state.");
					yield break;
				}
				if (Time.realtimeSinceStartup >= acknowledgementDeadline)
				{
					WorldStateSync.ClearSnapshotAcknowledgement(clientId);
					SetStatus($"Timed out waiting for client {clientId} to acknowledge the landed ship state.");
					yield break;
				}
				if (Time.realtimeSinceStartup >= nextSnapshotResend)
				{
					try
					{
						WorldStateSync.SendSnapshot(clientId, includeInterior: false);
					}
					catch (Exception ex2)
					{
						Plugin.Debug("Could not resend landed ship snapshot: " + ex2.Message);
					}
					nextSnapshotResend = Time.realtimeSinceStartup + 0.5f;
				}
				yield return null;
			}
			WorldStateSync.ClearSnapshotAcknowledgement(clientId);
			try
			{
				manager.playersFinishedGeneratingFloor.Remove(clientId);
				SendGenerateLevelRpc(manager, clientId);
				SetStatus($"Waiting for client {clientId} to finish generating the interior.");
			}
			catch (Exception ex3)
			{
				SetStatus("Native moon generation synchronization failed: " + ex3.Message);
				Plugin.Log.LogError((object)ex3);
				yield break;
			}
			if (StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				float deadline = Time.realtimeSinceStartup + 60f;
				while (!manager.playersFinishedGeneratingFloor.Contains(clientId))
				{
					if (!IsClientConnected(network, clientId))
					{
						SetStatus($"Client {clientId} disconnected while generating the interior.");
						yield break;
					}
					if (!MidJoinState.IsActiveMoon)
					{
						SetStatus("Round left the landed state while the late client was generating.");
						yield break;
					}
					if (Time.realtimeSinceStartup >= deadline)
					{
						SetStatus($"Timed out waiting for client {clientId} to finish generating the interior.");
						yield break;
					}
					yield return null;
				}
			}
			try
			{
				SendEmptyClientRpc((NetworkBehaviour)(object)manager, 2729232387u, clientId);
				manager.playersFinishedGeneratingFloor.Remove(clientId);
			}
			catch (Exception ex4)
			{
				SetStatus("Late-client finalization failed: " + ex4.Message);
				Plugin.Log.LogError((object)ex4);
				yield break;
			}
			yield return (object)new WaitForSeconds(0.25f);
			try
			{
				WorldStateSync.SendSnapshot(clientId, includeInterior: true);
				MidJoinState.SnapshotsSent++;
				SetStatus($"Completed ship, interior, door, and lighting synchronization for client {clientId}.");
			}
			catch (Exception ex5)
			{
				SetStatus("Late-client world-state synchronization failed: " + ex5.Message);
				Plugin.Log.LogError((object)ex5);
			}
		}

		private static bool IsClientConnected(NetworkManager network, ulong clientId)
		{
			return network.ConnectedClients.ContainsKey(clientId);
		}

		private static void SendGenerateLevelRpc(RoundManager manager, ulong clientId)
		{
			//IL_0029: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0054: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected I4, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected I4, but got Unknown
			//IL_00cc: 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)
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null)
			{
				throw new InvalidOperationException("Round state is not ready.");
			}
			ClientRpcParams rpcParams = TargetClient(clientId);
			FastBufferWriter val = BeginRpc((NetworkBehaviour)(object)manager, 3073943002u, rpcParams);
			BytePacker.WriteValueBitPacked(val, instance.randomMapSeed);
			BytePacker.WriteValueBitPacked(val, instance.currentLevelID);
			BytePacker.WriteValueBitPacked(val, instance.currentLevel.moldSpreadIterations);
			BytePacker.WriteValueBitPacked(val, instance.currentLevel.moldStartPosition);
			MoldSpreadManager val2 = Object.FindObjectOfType<MoldSpreadManager>();
			bool flag = (Object)(object)val2 != (Object)null && instance.currentLevelID >= 0;
			((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
			if (flag)
			{
				int[] array = val2.planetMoldStates[instance.currentLevelID].destroyedMold.ToArray();
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(array, default(ForPrimitives));
			}
			BytePacker.WriteValueBitPacked(val, instance.currentLevel.currentWeather + 255);
			EndRpc((NetworkBehaviour)(object)manager, val, 3073943002u, rpcParams);
			Plugin.Debug($"Started native level sync client={clientId}, seed={instance.randomMapSeed}, " + $"level={instance.currentLevelID}, mold={instance.currentLevel.moldSpreadIterations}/" + $"{instance.currentLevel.moldStartPosition}, weather={(int)instance.currentLevel.currentWeather}, " + $"moldState={flag}");
		}

		private static void SendEmptyClientRpc(NetworkBehaviour target, uint rpcId, ulong clientId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			ClientRpcParams rpcParams = TargetClient(clientId);
			FastBufferWriter writer = BeginRpc(target, rpcId, rpcParams);
			EndRpc(target, writer, rpcId, rpcParams);
		}

		private static FastBufferWriter BeginRpc(NetworkBehaviour target, uint rpcId, ClientRpcParams rpcParams)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (BeginSendClientRpc == null || EndSendClientRpc == null)
			{
				throw new MissingMethodException("Unity Netcode ClientRpc send methods were not found.");
			}
			return (FastBufferWriter)BeginSendClientRpc.Invoke(target, new object[3]
			{
				rpcId,
				rpcParams,
				(object)(RpcDelivery)0
			});
		}

		private static void EndRpc(NetworkBehaviour target, FastBufferWriter writer, uint rpcId, ClientRpcParams rpcParams)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			EndSendClientRpc.Invoke(target, new object[4]
			{
				writer,
				rpcId,
				rpcParams,
				(object)(RpcDelivery)0
			});
		}

		private static ClientRpcParams TargetClient(ulong clientId)
		{
			//IL_0002: 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_0025: 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)
			return new ClientRpcParams
			{
				Send = new ClientRpcSendParams
				{
					TargetClientIds = new List<ulong> { clientId }
				}
			};
		}

		private static void SetStatus(string status)
		{
			MidJoinState.LastStatus = status;
			Plugin.Debug(status);
		}
	}
	[HarmonyPatch]
	internal static class Patches
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		private static void ConnectionApprovalPostfix(GameNetworkManager __instance, ConnectionApprovalRequest request, ConnectionApprovalResponse response)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Enabled.Value && MidJoinState.IsActiveMoon && request.ClientNetworkId != NetworkManager.Singleton.LocalClientId && !response.Approved && response.Reason == "Ship has already landed!")
			{
				response.Approved = true;
				response.Reason = string.Empty;
				response.CreatePlayerObject = true;
				response.Pending = false;
				Plugin.Debug("Overrode LobbyControl's landed-ship rejection.");
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		private static void StartGamePostfix(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && Plugin.Enabled.Value)
			{
				LobbyControlBridge.PermitConnections(value: true);
				if (Plugin.AutoOpenLobby.Value)
				{
					GameNetworkManager.Instance.SetLobbyJoinable(true);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
		private static void ShipLandedPostfix(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && Plugin.Enabled.Value)
			{
				LobbyControlBridge.PermitConnections(value: true);
				if (Plugin.AutoOpenLobby.Value)
				{
					GameNetworkManager.Instance.SetLobbyJoinable(true);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		private static void StartOfRoundStartPostfix()
		{
			WorldStateSync.RegisterHandler();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		private static void ConnectClientToPlayerObjectPostfix()
		{
			WorldStateSync.RegisterHandler();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "SetInstanceValuesBackToDefault")]
		private static void ResetNetworkStatePostfix()
		{
			WorldStateSync.UnregisterHandler();
			NetworkSync.ResetSynchronizations();
			MidJoinState.ResetClientState();
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		private static bool OpeningDoorsSequencePrefix(StartOfRound __instance, ref IEnumerator __result)
		{
			if (!Plugin.Enabled.Value || ((NetworkBehaviour)__instance).IsServer || !MidJoinState.ClientLateJoinSyncActive)
			{
				return true;
			}
			MidJoinState.LandingSequencesSuppressed++;
			__result = WorldStateSync.RunLateJoinLandedSequence(__instance);
			Plugin.Debug("Suppressed the native openingDoorsSequence for a mid-session joining client.");
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")]
		private static void PlayerConnectedPostfix(StartOfRound __instance, ulong clientId)
		{
			if (((NetworkBehaviour)__instance).IsServer && clientId != 0L && MidJoinState.IsActiveMoon)
			{
				NetworkSync.StartLateClientSynchronization(__instance, clientId);
			}
		}
	}
	[BepInPlugin("amevirus.LobbyControlMidSessionJoin", "LobbyControl Mid-Session Join", "0.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static Plugin Instance;

		public const string Guid = "amevirus.LobbyControlMidSessionJoin";

		public const string Name = "LobbyControl Mid-Session Join";

		public const string Version = "0.3.3";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AutoOpenLobby;

		internal static ConfigEntry<bool> SpawnInShip;

		internal static ConfigEntry<bool> DebugLogging;

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Allow players to join while the ship is landed on a moon.");
			AutoOpenLobby = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoOpenLobby", true, "Keep/reopen the Steam lobby while a moon round is active.");
			SpawnInShip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SpawnInShip", true, "Move a newly joined local player to the ship after level synchronization.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enabled", false, "Write verbose synchronization information to the BepInEx log.");
			_harmony = new Harmony("amevirus.LobbyControlMidSessionJoin");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LobbyControl Mid-Session Join 0.3.3 loaded.");
		}

		internal static void Debug(string text)
		{
			if (DebugLogging.Value)
			{
				Log.LogInfo((object)("[debug] " + text));
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal static class TerminalCommands
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(Terminal __instance, ref TerminalNode __result)
		{
			string[] array = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Trim().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0 || !array[0].Equals("midjoin", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			__result = Node(Execute(array));
			return false;
		}

		private static string Execute(string[] args)
		{
			if (!GameNetworkManager.Instance.isHostingGame)
			{
				return "MIDJOIN commands are host-only.\n\n";
			}
			if (args.Length == 1 || args[1].Equals("help", StringComparison.OrdinalIgnoreCase))
			{
				return "MIDJOIN COMMANDS\n\nmidjoin status\nmidjoin enable|disable\nmidjoin debug on|off\nmidjoin autoopen on|off\nmidjoin spawninship on|off\n\n";
			}
			switch (args[1].ToLowerInvariant())
			{
			case "status":
				return Status();
			case "enable":
				Plugin.Enabled.Value = true;
				LobbyControlBridge.PermitConnections(value: true);
				return "Mid-session joining enabled.\n\n";
			case "disable":
				Plugin.Enabled.Value = false;
				return "Mid-session joining disabled.\n\n";
			case "debug":
				return SetBool(args, Plugin.DebugLogging, "Debug logging");
			case "autoopen":
				return SetBool(args, Plugin.AutoOpenLobby, "Automatic lobby reopening");
			case "spawninship":
				return SetBool(args, Plugin.SpawnInShip, "Spawn-in-ship");
			default:
				return "Unknown MIDJOIN command. Type 'midjoin help'.\n\n";
			}
		}

		private static string SetBool(string[] args, ConfigEntry<bool> entry, string label)
		{
			if (args.Length < 3 || (args[2] != "on" && args[2] != "off"))
			{
				return "Usage: midjoin " + args[1] + " on|off\n\n";
			}
			entry.Value = args[2] == "on";
			return label + ": " + (entry.Value ? "ON" : "OFF") + "\n\n";
		}

		private static string Status()
		{
			StartOfRound instance = StartOfRound.Instance;
			string text = (((Object)(object)instance == (Object)null) ? "no round" : (instance.inShipPhase ? "orbit/ship phase" : (instance.shipHasLanded ? "landed moon" : "transition")));
			return "MID-SESSION JOIN STATUS\n\n" + $"Enabled: {Plugin.Enabled.Value}\n" + "Phase: " + text + "\nLobbyControl bridge: " + (LobbyControlBridge.Available ? "OK" : "NOT FOUND") + "\n" + $"Native syncs sent: {MidJoinState.SnapshotsSent}\n" + $"Auto-open lobby: {Plugin.AutoOpenLobby.Value}\n" + $"Spawn in ship: {Plugin.SpawnInShip.Value}\n" + $"Debug: {Plugin.DebugLogging.Value}\n" + "Last result: " + MidJoinState.LastStatus + "\n\n";
		}

		private static TerminalNode Node(string text)
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.displayText = text;
			obj.clearPreviousText = true;
			obj.maxCharactersToType = 50;
			return obj;
		}
	}
	internal static class WorldStateSync
	{
		private sealed class WorldSnapshot
		{
			internal bool IncludeInterior;

			internal bool SpawnInShip;

			internal bool InShipPhase;

			internal bool ShipHasLanded;

			internal bool ShipIsLeaving;

			internal bool ShipDoorsEnabled;

			internal bool HangarDoorsClosed;

			internal bool NewGameIsLoading;

			internal bool TravellingToNewLevel;

			internal bool ShipAmbiancePlaying;

			internal bool ShipTravelAudioPlaying;

			internal bool PowerOffPermanently;

			internal bool PowerOn;

			internal bool CurrentPlanetActive;

			internal bool OuterSpaceSunActive;

			internal bool StarSphereActive;

			internal TransformSnapshot ShipTransform = new TransformSnapshot();

			internal TransformSnapshot CurrentPlanetTransform = new TransformSnapshot();

			internal AnimatorSnapshot ShipAnimator = new AnimatorSnapshot();

			internal AnimatorSnapshot ShipBodyAnimator = new AnimatorSnapshot();

			internal AnimatorSnapshot ShipDoorsAnimator = new AnimatorSnapshot();

			internal AnimatorSnapshot CurrentPlanetAnimator = new AnimatorSnapshot();

			internal AnimatorSnapshot OuterSpaceSunAnimator = new AnimatorSnapshot();

			internal readonly List<DoorSnapshot> Doors = new List<DoorSnapshot>();

			internal readonly List<TerminalDoorSnapshot> TerminalDoors = new List<TerminalDoorSnapshot>();
		}

		private sealed class TransformSnapshot
		{
			internal bool Exists;

			internal Vector3 LocalPosition;

			internal Quaternion LocalRotation;

			internal Vector3 LocalScale;
		}

		private sealed class AnimatorSnapshot
		{
			internal bool Exists;

			internal bool Enabled;

			internal float Speed;

			internal readonly List<AnimatorParameterSnapshot> Parameters = new List<AnimatorParameterSnapshot>();

			internal readonly List<AnimatorLayerSnapshot> Layers = new List<AnimatorLayerSnapshot>();
		}

		private sealed class AnimatorParameterSnapshot
		{
			internal int NameHash;

			internal AnimatorControllerParameterType Type;

			internal bool BoolValue;

			internal int IntValue;

			internal float FloatValue;
		}

		private sealed class AnimatorLayerSnapshot
		{
			internal int StateHash;

			internal float NormalizedTime;

			internal float Weight;
		}

		private sealed class DoorSnapshot
		{
			internal Vector3 Position;

			internal bool IsOpen;

			internal bool IsLocked;

			internal bool IsPickingLock;

			internal float LockPickTimeLeft;

			internal bool TriggerInteractable;

			internal float TriggerTimeToHold;

			internal float TriggerSpeedMultiplier;
		}

		private sealed class TerminalDoorSnapshot
		{
			internal Vector3 Position;

			internal bool IsOpen;

			internal bool IsPoweredOn;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__ReceiveSnapshot;

			public static HandleNamedMessageDelegate <1>__ReceiveSnapshotAcknowledgement;
		}

		private const string MESSAGE_NAME = "LobbyControlMidSessionJoin.WorldState.v2";

		private const string ACK_MESSAGE_NAME = "LobbyControlMidSessionJoin.WorldStateAck.v1";

		private const int MESSAGE_VERSION = 2;

		private const float OBJECT_MATCH_DISTANCE = 0.75f;

		private const float APPLY_TIMEOUT_SECONDS = 15f;

		private const BindingFlags INSTANCE_FIELD_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo? ShipTravelCoroutineField = FindInstanceField(typeof(StartOfRound), "shipTravelCoroutine");

		private static readonly FieldInfo? DoorIsOpenedField = FindInstanceField(typeof(DoorLock), "isDoorOpened");

		private static readonly FieldInfo? TerminalDoorOpenField = FindInstanceField(typeof(TerminalAccessibleObject), "isDoorOpen");

		private static readonly FieldInfo? TerminalPoweredField = FindInstanceField(typeof(TerminalAccessibleObject), "isPoweredOn");

		private static readonly FieldInfo? LoadingScreenAnimatorField = FindInstanceField(typeof(HUDManager), "LoadingScreen");

		private static readonly FieldInfo? LegacyLoadingDarkenScreenField = FindInstanceField(typeof(HUDManager), "loadingDarkenScreen");

		private static readonly FieldInfo? PlayerFallValueField = FindInstanceField(typeof(PlayerControllerB), "fallValue");

		private static readonly FieldInfo? PlayerFallValueUncappedField = FindInstanceField(typeof(PlayerControllerB), "fallValueUncapped");

		private static readonly FieldInfo? PlayerTakingFallDamageField = FindInstanceField(typeof(PlayerControllerB), "takingFallDamage");

		private static readonly FieldInfo? PlayerFallingFromJumpField = FindInstanceField(typeof(PlayerControllerB), "isFallingFromJump");

		private static readonly FieldInfo? PlayerAverageVelocityField = FindInstanceField(typeof(PlayerControllerB), "averageVelocity");

		private static readonly FieldInfo? PlayerPreviousYField = FindInstanceField(typeof(PlayerControllerB), "previousYPosition");

		private static readonly FieldInfo? PlayerExternalForcesField = FindInstanceField(typeof(PlayerControllerB), "externalForces");

		private static readonly FieldInfo? PlayerIsInElevatorField = FindInstanceField(typeof(PlayerControllerB), "isInElevator");

		private static readonly FieldInfo? PlayerIsInHangarField = FindInstanceField(typeof(PlayerControllerB), "isInHangarShipRoom");

		private static readonly FieldInfo? PlayerIsInsideFactoryField = FindInstanceField(typeof(PlayerControllerB), "isInsideFactory");

		private static readonly FieldInfo? PlayerVelocityLastFrameField = FindInstanceField(typeof(PlayerControllerB), "velocityLastFrame");

		private static readonly FieldInfo? PlayerIsSlidingField = FindInstanceField(typeof(PlayerControllerB), "isPlayerSliding");

		private static readonly FieldInfo? PlayerSlidingTimerField = FindInstanceField(typeof(PlayerControllerB), "playerSlidingTimer");

		private static readonly FieldInfo? PlayerIsFallingNoJumpField = FindInstanceField(typeof(PlayerControllerB), "isFallingNoJump");

		private static readonly FieldInfo? PlayerTeleportedLastFrameField = FindInstanceField(typeof(PlayerControllerB), "teleportedLastFrame");

		private static readonly FieldInfo? PlayerWasInElevatorLastFrameField = FindInstanceField(typeof(PlayerControllerB), "wasInElevatorLastFrame");

		private static readonly FieldInfo? PlayerPreviousElevatorPositionField = FindInstanceField(typeof(PlayerControllerB), "previousElevatorPosition");

		private static readonly FieldInfo? PlayerOldPositionField = FindInstanceField(typeof(PlayerControllerB), "oldPlayerPosition");

		private static readonly FieldInfo? PlayerServerPositionField = FindInstanceField(typeof(PlayerControllerB), "serverPlayerPosition");

		private static readonly FieldInfo? PlayerSnapToServerPositionField = FindInstanceField(typeof(PlayerControllerB), "snapToServerPosition");

		private static readonly FieldInfo? PlayerUpdatePositionForNewClientField = FindInstanceField(typeof(PlayerControllerB), "updatePositionForNewlyJoinedClient");

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

		private static NetworkManager? _registeredNetwork;

		private static WorldSnapshot? _latestClientSnapshot;

		private static Coroutine? _applySnapshotCoroutine;

		internal static void RegisterHandler()
		{
			//IL_0041: 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_004c: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null && _registeredNetwork != singleton)
			{
				UnregisterHandler();
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				object obj = <>O.<0>__ReceiveSnapshot;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = ReceiveSnapshot;
					<>O.<0>__ReceiveSnapshot = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("LobbyControlMidSessionJoin.WorldState.v2", (HandleNamedMessageDelegate)obj);
				CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager;
				object obj2 = <>O.<1>__ReceiveSnapshotAcknowledgement;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = ReceiveSnapshotAcknowledgement;
					<>O.<1>__ReceiveSnapshotAcknowledgement = val2;
					obj2 = (object)val2;
				}
				customMessagingManager2.RegisterNamedMessageHandler("LobbyControlMidSessionJoin.WorldStateAck.v1", (HandleNamedMessageDelegate)obj2);
				_registeredNetwork = singleton;
				Plugin.Debug("Registered targeted world-state synchronization handler.");
			}
		}

		internal static void UnregisterHandler()
		{
			NetworkManager registeredNetwork = _registeredNetwork;
			_registeredNetwork = null;
			_latestClientSnapshot = null;
			ShipSnapshotAcknowledgements.Clear();
			if ((Object)(object)registeredNetwork != (Object)null && _applySnapshotCoroutine != null)
			{
				((MonoBehaviour)registeredNetwork).StopCoroutine(_applySnapshotCoroutine);
				_applySnapshotCoroutine = null;
			}
			if ((Object)(object)registeredNetwork == (Object)null || registeredNetwork.CustomMessagingManager == null)
			{
				return;
			}
			try
			{
				registeredNetwork.CustomMessagingManager.UnregisterNamedMessageHandler("LobbyControlMidSessionJoin.WorldState.v2");
				registeredNetwork.CustomMessagingManager.UnregisterNamedMessageHandler("LobbyControlMidSessionJoin.WorldStateAck.v1");
			}
			catch (Exception ex)
			{
				Plugin.Debug("Could not unregister world-state handler: " + ex.Message);
			}
		}

		internal static void ResetSnapshotAcknowledgement(ulong clientId)
		{
			ShipSnapshotAcknowledgements.Remove(clientId);
		}

		internal static bool HasSnapshotAcknowledgement(ulong clientId)
		{
			return ShipSnapshotAcknowledgements.Contains(clientId);
		}

		internal static void ClearSnapshotAcknowledgement(ulong clientId)
		{
			ShipSnapshotAcknowledgements.Remove(clientId);
		}

		internal static void SendSnapshot(ulong clientId, bool includeInterior)
		{
			//IL_007e: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || singleton.CustomMessagingManager == null)
			{
				throw new InvalidOperationException("The server custom messaging manager is not ready.");
			}
			RegisterHandler();
			WorldSnapshot worldSnapshot = CaptureSnapshot(includeInterior);
			int num = 32768 + worldSnapshot.Doors.Count * 80 + worldSnapshot.TerminalDoors.Count * 64;
			FastBufferWriter writer = default(FastBufferWriter);
			((FastBufferWriter)(ref writer))..ctor(num, (Allocator)2, -1);
			try
			{
				WriteSnapshot(ref writer, worldSnapshot);
				NetworkDelivery val = (NetworkDelivery)((((FastBufferWriter)(ref writer)).Capacity > 1300) ? 4 : 2);
				singleton.CustomMessagingManager.SendNamedMessage("LobbyControlMidSessionJoin.WorldState.v2", clientId, writer, val);
			}
			finally
			{
				((FastBufferWriter)(ref writer)).Dispose();
			}
			Plugin.Debug(string.Format("Sent {0} world snapshot to client {1}: ", includeInterior ? "complete" : "ship-only", clientId) + $"doors={worldSnapshot.Doors.Count}, terminalDoors={worldSnapshot.TerminalDoors.Count}, " + $"power={worldSnapshot.PowerOn}, landed={worldSnapshot.ShipHasLanded}");
		}

		private static WorldSnapshot CaptureSnapshot(bool includeInterior)
		{
			StartOfRound val = StartOfRound.Instance ?? throw new InvalidOperationException("StartOfRound is not ready.");
			RoundManager instance = RoundManager.Instance;
			BreakerBox val2 = Object.FindObjectOfType<BreakerBox>();
			WorldSnapshot worldSnapshot = new WorldSnapshot
			{
				IncludeInterior = includeInterior,
				SpawnInShip = Plugin.SpawnInShip.Value,
				InShipPhase = val.inShipPhase,
				ShipHasLanded = val.shipHasLanded,
				ShipIsLeaving = val.shipIsLeaving,
				ShipDoorsEnabled = val.shipDoorsEnabled,
				HangarDoorsClosed = val.hangarDoorsClosed,
				NewGameIsLoading = val.newGameIsLoading,
				TravellingToNewLevel = val.travellingToNewLevel,
				ShipAmbiancePlaying = ((Object)(object)val.shipAmbianceAudio != (Object)null && val.shipAmbianceAudio.isPlaying),
				ShipTravelAudioPlaying = ((Object)(object)val.ship3DAudio != (Object)null && val.ship3DAudio.isPlaying),
				PowerOffPermanently = ((Object)(object)instance != (Object)null && instance.powerOffPermanently),
				PowerOn = ((Object)(object)instance != (Object)null && !instance.powerOffPermanently && ((Object)(object)val2 == (Object)null || val2.isPowerOn)),
				ShipTransform = CaptureTransform(((Object)(object)val.shipAnimatorObject != (Object)null) ? ((Component)val.shipAnimatorObject).transform : val.elevatorTransform),
				CurrentPlanetTransform = CaptureTransform(((Object)(object)val.currentPlanetPrefab != (Object)null) ? val.currentPlanetPrefab.transform : null),
				CurrentPlanetActive = ((Object)(object)val.currentPlanetPrefab != (Object)null && val.currentPlanetPrefab.activeSelf),
				OuterSpaceSunActive = ((Object)(object)val.outerSpaceSunAnimator != (Object)null && ((Component)val.outerSpaceSunAnimator).gameObject.activeSelf),
				StarSphereActive = ((Object)(object)val.starSphereObject != (Object)null && val.starSphereObject.activeSelf),
				ShipAnimator = CaptureAnimator(val.shipAnimator),
				ShipBodyAnimator = CaptureAnimator(((Object)(object)val.shipAnimatorObject != (Object)null) ? ((Component)val.shipAnimatorObject).GetComponent<Animator>() : null),
				ShipDoorsAnimator = CaptureAnimator(val.shipDoorsAnimator),
				CurrentPlanetAnimator = CaptureAnimator(val.currentPlanetAnimator),
				OuterSpaceSunAnimator = CaptureAnimator(val.outerSpaceSunAnimator)
			};
			if (!includeInterior)
			{
				return worldSnapshot;
			}
			DoorLock[] array = Object.FindObjectsOfType<DoorLock>();
			foreach (DoorLock door in array)
			{
				worldSnapshot.Doors.Add(CaptureDoor(door));
			}
			TerminalAccessibleObject[] array2 = Object.FindObjectsOfType<TerminalAccessibleObject>();
			foreach (TerminalAccessibleObject val3 in array2)
			{
				if (val3.isBigDoor)
				{
					worldSnapshot.TerminalDoors.Add(CaptureTerminalDoor(val3));
				}
			}
			return worldSnapshot;
		}

		private static DoorSnapshot CaptureDoor(DoorLock door)
		{
			//IL_0038: 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)
			AnimatedObjectTrigger component = ((Component)door).GetComponent<AnimatedObjectTrigger>();
			InteractTrigger component2 = ((Component)door).GetComponent<InteractTrigger>();
			bool isOpen = (((Object)(object)component != (Object)null) ? component.boolValue : ReadField(DoorIsOpenedField, door, fallback: false));
			return new DoorSnapshot
			{
				Position = ((Component)door).transform.position,
				IsOpen = isOpen,
				IsLocked = door.isLocked,
				IsPickingLock = door.isPickingLock,
				LockPickTimeLeft = door.lockPickTimeLeft,
				TriggerInteractable = ((Object)(object)component2 == (Object)null || component2.interactable),
				TriggerTimeToHold = (component2?.timeToHold ?? 0.3f),
				TriggerSpeedMultiplier = (component2?.timeToHoldSpeedMultiplier ?? 1f)
			};
		}

		private static TerminalDoorSnapshot CaptureTerminalDoor(TerminalAccessibleObject door)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			AnimatedObjectTrigger component = ((Component)door).GetComponent<AnimatedObjectTrigger>();
			return new TerminalDoorSnapshot
			{
				Position = ((Component)door).transform.position,
				IsOpen = ReadField(TerminalDoorOpenField, door, (Object)(object)component != (Object)null && component.boolValue),
				IsPoweredOn = ReadField(TerminalPoweredField, door, fallback: true)
			};
		}

		private static TransformSnapshot CaptureTransform(Transform? transform)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002e: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)transform == (Object)null)
			{
				return new TransformSnapshot();
			}
			return new TransformSnapshot
			{
				Exists = true,
				LocalPosition = transform.localPosition,
				LocalRotation = transform.localRotation,
				LocalScale = transform.localScale
			};
		}

		private static AnimatorSnapshot CaptureAnimator(Animator? animator)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected I4, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			AnimatorSnapshot animatorSnapshot = new AnimatorSnapshot();
			if ((Object)(object)animator == (Object)null)
			{
				return animatorSnapshot;
			}
			animatorSnapshot.Exists = true;
			animatorSnapshot.Enabled = ((Behaviour)animator).enabled;
			animatorSnapshot.Speed = animator.speed;
			AnimatorControllerParameter[] parameters = animator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type != 9)
				{
					AnimatorParameterSnapshot animatorParameterSnapshot = new AnimatorParameterSnapshot
					{
						NameHash = val.nameHash,
						Type = val.type
					};
					AnimatorControllerParameterType type = val.type;
					switch (type - 1)
					{
					case 3:
						animatorParameterSnapshot.BoolValue = animator.GetBool(val.nameHash);
						break;
					case 2:
						animatorParameterSnapshot.IntValue = animator.GetInteger(val.nameHash);
						break;
					case 0:
						animatorParameterSnapshot.FloatValue = animator.GetFloat(val.nameHash);
						break;
					}
					animatorSnapshot.Parameters.Add(animatorParameterSnapshot);
				}
			}
			for (int j = 0; j < animator.layerCount; j++)
			{
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(j);
				animatorSnapshot.Layers.Add(new AnimatorLayerSnapshot
				{
					StateHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash,
					NormalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime,
					Weight = animator.GetLayerWeight(j)
				});
			}
			return animatorSnapshot;
		}

		private static void ReceiveSnapshot(ulong senderClientId, FastBufferReader reader)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || senderClientId != 0L)
			{
				return;
			}
			try
			{
				WorldSnapshot snapshot = (_latestClientSnapshot = ReadSnapshot(ref reader));
				if (!MidJoinState.ClientLateJoinSyncCompleted)
				{
					MidJoinState.ClientLateJoinSyncActive = true;
				}
				if (_applySnapshotCoroutine != null)
				{
					((MonoBehaviour)singleton).StopCoroutine(_applySnapshotCoroutine);
				}
				_applySnapshotCoroutine = ((MonoBehaviour)singleton).StartCoroutine(ApplySnapshot(snapshot));
				SendSnapshotAcknowledgement();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to receive late-join world snapshot: " + ex));
			}
		}

		private static void SendSnapshotAcknowledgement()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsClient || singleton.IsServer || singleton.CustomMessagingManager == null)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
			try
			{
				int num = 2;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				singleton.CustomMessagingManager.SendNamedMessage("LobbyControlMidSessionJoin.WorldStateAck.v1", 0uL, val, (NetworkDelivery)2);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void ReceiveSnapshotAcknowledgement(ulong senderClientId, FastBufferReader reader)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || senderClientId == 0L)
			{
				return;
			}
			try
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
				if (num == 2)
				{
					ShipSnapshotAcknowledgements.Add(senderClientId);
					Plugin.Debug($"Client {senderClientId} acknowledged the landed ship snapshot.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Debug($"Could not read landed ship snapshot acknowledgement from client {senderClientId}: " + ex.Message);
			}
		}

		private static IEnumerator ApplySnapshot(WorldSnapshot snapshot)
		{
			float deadline = Time.realtimeSinceStartup + 15f;
			while ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				if (Time.realtimeSinceStartup >= deadline)
				{
					yield break;
				}
				yield return null;
			}
			ApplyShipState(snapshot, !MidJoinState.ClientPlayerPositioned, ShouldHoldShipAnimations());
			yield return null;
			ApplyShipState(snapshot, moveLocalPlayer: false, ShouldHoldShipAnimations());
			if (snapshot.IncludeInterior)
			{
				while (((Object)(object)RoundManager.Instance == (Object)null || !RoundManager.Instance.dungeonCompletedGenerating) && Time.realtimeSinceStartup < deadline)
				{
					yield return null;
				}
				yield return null;
				yield return null;
				ApplyInteriorState(snapshot);
			}
			yield return (object)new WaitForSeconds(0.25f);
			ApplyShipState(snapshot, moveLocalPlayer: false, ShouldHoldShipAnimations());
			if (snapshot.IncludeInterior)
			{
				ApplyInteriorState(snapshot);
				MidJoinState.ClientLateJoinSyncCompleted = true;
				MidJoinState.ClientLateJoinSyncActive = false;
				ApplyShipState(snapshot, moveLocalPlayer: false, holdAnimations: false);
			}
			MidJoinState.LastStatus = (snapshot.IncludeInterior ? "Applied ship, door, lock, and facility-power snapshot." : "Applied landed ship snapshot.");
			Plugin.Debug(MidJoinState.LastStatus);
			_applySnapshotCoroutine = null;
		}

		private static bool ShouldHoldShipAnimations()
		{
			if (MidJoinState.ClientLateJoinSyncActive)
			{
				return !MidJoinState.ClientLateJoinSyncCompleted;
			}
			return false;
		}

		private static void ApplyShipState(WorldSnapshot snapshot, bool moveLocalPlayer, bool holdAnimations)
		{
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				StopShipTravelCoroutine(instance);
				instance.inShipPhase = snapshot.InShipPhase;
				instance.shipHasLanded = snapshot.ShipHasLanded;
				instance.shipIsLeaving = snapshot.ShipIsLeaving;
				instance.shipDoorsEnabled = snapshot.ShipDoorsEnabled;
				instance.hangarDoorsClosed = snapshot.HangarDoorsClosed;
				instance.newGameIsLoading = snapshot.NewGameIsLoading;
				instance.travellingToNewLevel = snapshot.TravellingToNewLevel;
				ApplyAnimator(instance.shipAnimator, snapshot.ShipAnimator, holdAnimations);
				ApplyAnimator(((Object)(object)instance.shipAnimatorObject != (Object)null) ? ((Component)instance.shipAnimatorObject).GetComponent<Animator>() : null, snapshot.ShipBodyAnimator, holdAnimations);
				ApplyAnimator(instance.shipDoorsAnimator, snapshot.ShipDoorsAnimator, holdAnimations);
				ApplyAnimator(instance.currentPlanetAnimator, snapshot.CurrentPlanetAnimator, holdAnimations);
				ApplyAnimator(instance.outerSpaceSunAnimator, snapshot.OuterSpaceSunAnimator, holdAnimations);
				ApplyTransform(((Object)(object)instance.shipAnimatorObject != (Object)null) ? ((Component)instance.shipAnimatorObject).transform : instance.elevatorTransform, snapshot.ShipTransform);
				ApplyTransform(((Object)(object)instance.currentPlanetPrefab != (Object)null) ? instance.currentPlanetPrefab.transform : null, snapshot.CurrentPlanetTransform);
				if ((Object)(object)instance.currentPlanetPrefab != (Object)null)
				{
					instance.currentPlanetPrefab.SetActive(snapshot.CurrentPlanetActive);
				}
				if ((Object)(object)instance.outerSpaceSunAnimator != (Object)null)
				{
					((Component)instance.outerSpaceSunAnimator).gameObject.SetActive(snapshot.OuterSpaceSunActive);
				}
				if ((Object)(object)instance.starSphereObject != (Object)null)
				{
					instance.starSphereObject.SetActive(snapshot.StarSphereActive);
				}
				SynchronizeAudio(instance.shipAmbianceAudio, snapshot.ShipAmbiancePlaying);
				SynchronizeAudio(instance.ship3DAudio, snapshot.ShipTravelAudioPlaying);
				PlayerControllerB val = instance.localPlayerController ?? GameNetworkManager.Instance?.localPlayerController;
				if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && snapshot.SpawnInShip && moveLocalPlayer && MoveLocalPlayerIntoShip(instance, val))
				{
					MidJoinState.ClientPlayerPositioned = true;
					ResetPlayerMotion(instance, val);
					Plugin.Debug($"Positioned the local late-join player at {((Component)val).transform.position} and cleared stale motion state.");
				}
			}
		}

		internal static IEnumerator RunLateJoinLandedSequence(StartOfRound round)
		{
			float deadline = Time.realtimeSinceStartup + 15f + 60f;
			WorldSnapshot latestClientSnapshot = _latestClientSnapshot;
			if (latestClientSnapshot != null)
			{
				ApplyShipState(latestClientSnapshot, !MidJoinState.ClientPlayerPositioned, holdAnimations: true);
			}
			ApplyImmediateLandedState(round, resetPlayerMotion: true);
			while (MidJoinState.ClientLateJoinSyncActive && Time.realtimeSinceStartup < deadline && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
			{
				yield return null;
			}
			WorldSnapshot latestClientSnapshot2 = _latestClientSnapshot;
			if (latestClientSnapshot2 != null)
			{
				ApplyShipState(latestClientSnapshot2, moveLocalPlayer: false, holdAnimations: false);
			}
			ApplyImmediateLandedState(round, resetPlayerMotion: true);
		}

		private static void ApplyImmediateLandedState(StartOfRound round, bool resetPlayerMotion)
		{
			StopShipTravelCoroutine(round);
			round.inShipPhase = false;
			round.shipHasLanded = true;
			round.shipIsLeaving = false;
			round.newGameIsLoading = false;
			round.travellingToNewLevel = false;
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				GameNetworkManager.Instance.gameHasStarted = true;
			}
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				HideLoadingScreen(HUDManager.Instance);
			}
			StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.triggerScript != (Object)null)
			{
				val.triggerScript.timeToHold = 0.7f;
				val.triggerScript.animationString = "SA_PushLeverBack";
				val.triggerScript.disabledHoverTip = string.Empty;
				val.triggerScript.interactable = true;
				val.hasDisplayedTimeWarning = false;
			}
			HangarShipDoor val2 = Object.FindObjectOfType<HangarShipDoor>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.SetDoorButtonsEnabled(round.shipDoorsEnabled);
			}
			if ((Object)(object)round.currentLevel != (Object)null && round.currentLevel.planetHasTime && (Object)(object)TimeOfDay.Instance != (Object)null)
			{
				TimeOfDay.Instance.currentDayTimeStarted = true;
				TimeOfDay.Instance.movingGlobalTimeForward = true;
			}
			if (resetPlayerMotion)
			{
				PlayerControllerB val3 = round.localPlayerController ?? GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val3 != (Object)null && !val3.isPlayerDead)
				{
					ResetPlayerMotion(round, val3);
				}
			}
		}

		private static void HideLoadingScreen(HUDManager hud)
		{
			if ((Object)(object)hud.loadingText != (Object)null)
			{
				((Behaviour)hud.loadingText).enabled = false;
			}
			object? obj = LoadingScreenAnimatorField?.GetValue(hud);
			Animator val = (Animator)((obj is Animator) ? obj : null);
			if (val != null)
			{
				val.SetBool("IsLoading", false);
			}
			object? obj2 = LegacyLoadingDarkenScreenField?.GetValue(hud);
			Behaviour val2 = (Behaviour)((obj2 is Behaviour) ? obj2 : null);
			if (val2 != null)
			{
				val2.enabled = false;
			}
		}

		private static void ApplyInteriorState(WorldSnapshot snapshot)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ApplyPowerState(instance, snapshot.PowerOn, snapshot.PowerOffPermanently);
			DoorLock[] candidates = Object.FindObjectsOfType<DoorLock>();
			HashSet<int> hashSet = new HashSet<int>();
			int num = 0;
			foreach (DoorSnapshot door in snapshot.Doors)
			{
				DoorLock val = FindClosest<DoorLock>(candidates, hashSet, door.Position, (Func<DoorLock, bool>?)null);
				if (!((Object)(object)val == (Object)null))
				{
					ApplyDoor(val, door);
					hashSet.Add(((Object)val).GetInstanceID());
					num++;
				}
			}
			TerminalAccessibleObject[] candidates2 = Object.FindObjectsOfType<TerminalAccessibleObject>();
			HashSet<int> hashSet2 = new HashSet<int>();
			int num2 = 0;
			foreach (TerminalDoorSnapshot terminalDoor in snapshot.TerminalDoors)
			{
				TerminalAccessibleObject val2 = FindClosest<TerminalAccessibleObject>(candidates2, hashSet2, terminalDoor.Position, (Func<TerminalAccessibleObject, bool>?)((TerminalAccessibleObject x) => x.isBigDoor));
				if (!((Object)(object)val2 == (Object)null))
				{
					ApplyTerminalDoor(val2, terminalDoor);
					hashSet2.Add(((Object)val2).GetInstanceID());
					num2++;
				}
			}
			Plugin.Debug($"Applied interior snapshot: regularDoors={num}/{snapshot.Doors.Count}, " + $"terminalDoors={num2}/{snapshot.TerminalDoors.Count}, power={snapshot.PowerOn}");
		}

		private static void ApplyPowerState(RoundManager manager, bool powerOn, bool permanentlyOff)
		{
			manager.powerOffPermanently = permanentlyOff;
			BreakerBox val = Object.FindObjectOfType<BreakerBox>();
			if ((Object)(object)val != (Object)null)
			{
				val.isPowerOn = powerOn;
			}
			((UnityEvent<bool>)(object)manager.onPowerSwitch).Invoke(powerOn);
			manager.TurnOnAllLights(powerOn);
		}

		private static void ApplyDoor(DoorLock door, DoorSnapshot snapshot)
		{
			door.isLocked = snapshot.IsLocked;
			door.isPickingLock = snapshot.IsPickingLock;
			door.lockPickTimeLeft = snapshot.LockPickTimeLeft;
			SetAnimatedBoolean(((Component)door).GetComponent<AnimatedObjectTrigger>(), snapshot.IsOpen);
			door.SetDoorAsOpen(snapshot.IsOpen);
			SetField(DoorIsOpenedField, door, snapshot.IsOpen);
			InteractTrigger component = ((Component)door).GetComponent<InteractTrigger>();
			if ((Object)(object)component != (Object)null)
			{
				component.interactable = snapshot.TriggerInteractable;
				component.timeToHold = snapshot.TriggerTimeToHold;
				component.timeToHoldSpeedMultiplier = snapshot.TriggerSpeedMultiplier;
				component.hoverTip = (snapshot.IsLocked ? "Locked (pickable)" : "Use door : [LMB]");
				component.holdTip = (snapshot.IsLocked ? "Picking lock" : string.Empty);
			}
			NavMeshObstacle component2 = ((Component)door).GetComponent<NavMeshObstacle>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Behaviour)component2).enabled = !snapshot.IsOpen;
				component2.carving = snapshot.IsLocked && !snapshot.IsOpen;
				component2.carveOnlyStationary = true;
			}
		}

		private static void ApplyTerminalDoor(TerminalAccessibleObject door, TerminalDoorSnapshot snapshot)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				door.InitializeValues();
				SetField(TerminalPoweredField, door, true);
				SetField(TerminalDoorOpenField, door, !snapshot.IsOpen);
				door.SetDoorOpen(snapshot.IsOpen);
				SetField(TerminalDoorOpenField, door, snapshot.IsOpen);
				door.OnPowerSwitch(snapshot.IsPoweredOn);
			}
			catch (Exception ex)
			{
				Plugin.Debug($"Terminal door native state application failed at {((Component)door).transform.position}: {ex.Message}");
			}
			SetField(TerminalDoorOpenField, door, snapshot.IsOpen);
			SetField(TerminalPoweredField, door, snapshot.IsPoweredOn);
			SetAnimatedBoolean(((Component)door).GetComponent<AnimatedObjectTrigger>(), snapshot.IsOpen || !snapshot.IsPoweredOn);
		}

		private static void SetAnimatedBoolean(AnimatedObjectTrigger? animated, bool value)
		{
			if (!((Object)(object)animated == (Object)null))
			{
				animated.boolValue = value;
				if ((Object)(object)animated.triggerAnimator != (Object)null && !string.IsNullOrEmpty(animated.animationString))
				{
					animated.triggerAnimator.SetBool(animated.animationString, value);
				}
				if ((Object)(object)animated.triggerAnimatorB != (Object)null)
				{
					animated.triggerAnimatorB.SetBool("on", value);
				}
			}
		}

		private static T? FindClosest<T>(T[] candidates, HashSet<int> used, Vector3 position, Func<T, bool>? predicate = null) where T : Component
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			T result = default(T);
			float num = 0.5625f;
			foreach (T val in candidates)
			{
				if (!((Object)(object)val == (Object)null) && !used.Contains(((Object)(object)val).GetInstanceID()) && (predicate == null || predicate(val)))
				{
					Vector3 val2 = ((Component)val).transform.position - position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (!(sqrMagnitude > num))
					{
						num = sqrMagnitude;
						result = val;
					}
				}
			}
			return result;
		}

		private static void StopShipTravelCoroutine(StartOfRound round)
		{
			if (ShipTravelCoroutineField == null)
			{
				return;
			}
			try
			{
				object? value = ShipTravelCoroutineField.GetValue(round);
				Coroutine val = (Coroutine)((value is Coroutine) ? value : null);
				if (val != null)
				{
					((MonoBehaviour)round).StopCoroutine(val);
				}
				ShipTravelCoroutineField.SetValue(round, null);
			}
			catch (Exception ex)
			{
				Plugin.Debug("Could not stop stale ship-travel coroutine: " + ex.Message);
			}
		}

		private static bool MoveLocalPlayerIntoShip(StartOfRound round, PlayerControllerB player)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			int num = Array.IndexOf(round.allPlayerScripts, player);
			if (num < 0 || num >= round.playerSpawnPositions.Length)
			{
				num = Mathf.Clamp(round.thisClientPlayerId, 0, round.playerSpawnPositions.Length - 1);
			}
			if (num < 0 || num >= round.playerSpawnPositions.Length)
			{
				return false;
			}
			Transform val = round.playerSpawnPositions[num];
			player.TeleportPlayer(val.position, false, 0f, false, true);
			((Component)player).transform.SetPositionAndRotation(val.position, val.rotation);
			player.ResetZAndXRotation();
			SetField(PlayerIsInElevatorField, player, true);
			SetField(PlayerIsInHangarField, player, true);
			SetField(PlayerIsInsideFactoryField, player, false);
			Physics.SyncTransforms();
			return true;
		}

		private static void ResetPlayerMotion(StartOfRound round, PlayerControllerB player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_013c: 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)
			Vector3 position = ((Component)player).transform.position;
			SetField(PlayerFallValueField, player, 0f);
			SetField(PlayerFallValueUncappedField, player, -7f);
			SetField(PlayerTakingFallDamageField, player, false);
			SetField(PlayerFallingFromJumpField, player, false);
			SetField(PlayerIsFallingNoJumpField, player, false);
			SetField(PlayerAverageVelocityField, player, 0f);
			SetField(PlayerVelocityLastFrameField, player, Vector3.zero);
			SetField(PlayerPreviousYField, player, position.y);
			SetField(PlayerExternalForcesField, player, Vector3.zero);
			SetField(PlayerIsSlidingField, player, false);
			SetField(PlayerSlidingTimerField, player, 0f);
			SetField(PlayerTeleportedLastFrameField, player, true);
			SetField(PlayerWasInElevatorLastFrameField, player, true);
			SetField(PlayerPreviousElevatorPositionField, player, ((Object)(object)round.elevatorTransform != (Object)null) ? round.elevatorTransform.position : Vector3.zero);
			SetField(PlayerOldPositionField, player, position);
			SetField(PlayerServerPositionField, player, position);
			SetField(PlayerSnapToServerPositionField, player, false);
			SetField(PlayerUpdatePositionForNewClientField, player, false);
		}

		private static void SynchronizeAudio(AudioSource? source, bool shouldPlay)
		{
			if ((Object)(object)source == (Object)null)
			{
				return;
			}
			if (shouldPlay)
			{
				if (!source.isPlaying && (Object)(object)source.clip != (Object)null)
				{
					source.Play();
				}
			}
			else if (source.isPlaying)
			{
				source.Stop();
			}
		}

		private static void ApplyTransform(Transform? transform, TransformSnapshot snapshot)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)transform == (Object)null) && snapshot.Exists)
			{
				transform.localPosition = snapshot.LocalPosition;
				transform.localRotation = snapshot.LocalRotation;
				transform.localScale = snapshot.LocalScale;
			}
		}

		private static void ApplyAnimator(Animator? animator, AnimatorSnapshot snapshot, bool holdAnimation)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_008c: Expected I4, but got Unknown
			if ((Object)(object)animator == (Object)null || !snapshot.Exists)
			{
				return;
			}
			bool enabled = snapshot.Enabled;
			((Behaviour)animator).enabled = true;
			AnimatorControllerParameter[] parameters = animator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 9)
				{
					animator.ResetTrigger(val.nameHash);
				}
			}
			foreach (AnimatorParameterSnapshot parameter in snapshot.Parameters)
			{
				AnimatorControllerParameterType type = parameter.Type;
				switch (type - 1)
				{
				case 3:
					animator.SetBool(parameter.NameHash, parameter.BoolValue);
					break;
				case 2:
					animator.SetInteger(parameter.NameHash, parameter.IntValue);
					break;
				case 0:
					animator.SetFloat(parameter.NameHash, parameter.FloatValue);
					break;
				}
			}
			int num = Math.Min(animator.layerCount, snapshot.Layers.Count);
			for (int j = 0; j < num; j++)
			{
				AnimatorLayerSnapshot animatorLayerSnapshot = snapshot.Layers[j];
				animator.SetLayerWeight(j, animatorLayerSnapshot.Weight);
				if (animatorLayerSnapshot.StateHash != 0)
				{
					animator.Play(animatorLayerSnapshot.StateHash, j, Mathf.Clamp01(animatorLayerSnapshot.NormalizedTime));
				}
			}
			animator.Update(0f);
			animator.speed = (holdAnimation ? 0f : snapshot.Speed);
			((Behaviour)animator).enabled = enabled;
		}

		private static FieldInfo? FindInstanceField(Type type, string name)
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private static bool ReadField(FieldInfo? field, object target, bool fallback)
		{
			if (field == null)
			{
				return fallback;
			}
			try
			{
				return (field.GetValue(target) is bool flag) ? flag : fallback;
			}
			catch
			{
				return fallback;
			}
		}

		private static void SetField(FieldInfo? field, object target, object? value)
		{
			if (field == null)
			{
				return;
			}
			try
			{
				field.SetValue(target, value);
			}
			catch (Exception ex)
			{
				Plugin.Debug("Could not set " + field.DeclaringType?.Name + "." + field.Name + ": " + ex.Message);
			}
		}

		private static void WriteSnapshot(ref FastBufferWriter writer, WorldSnapshot snapshot)
		{
			//IL_0007: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_004c: 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_0061: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			int num = 2;
			((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.IncludeInterior, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.SpawnInShip, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.InShipPhase, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.ShipHasLanded, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.ShipIsLeaving, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.ShipDoorsEnabled, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.HangarDoorsClosed, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.NewGameIsLoading, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.TravellingToNewLevel, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.ShipAmbiancePlaying, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.ShipTravelAudioPlaying, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.PowerOffPermanently, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.PowerOn, default(ForPrimitives));
			WriteTransform(ref writer, snapshot.ShipTransform);
			WriteTransform(ref writer, snapshot.CurrentPlanetTransform);
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.CurrentPlanetActive, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.OuterSpaceSunActive, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.StarSphereActive, default(ForPrimitives));
			WriteAnimator(ref writer, snapshot.ShipAnimator);
			WriteAnimator(ref writer, snapshot.ShipBodyAnimator);
			WriteAnimator(ref writer, snapshot.ShipDoorsAnimator);
			WriteAnimator(ref writer, snapshot.CurrentPlanetAnimator);
			WriteAnimator(ref writer, snapshot.OuterSpaceSunAnimator);
			num = snapshot.Doors.Count;
			((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			foreach (DoorSnapshot door in snapshot.Doors)
			{
				WriteVector3(ref writer, door.Position);
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref door.IsOpen, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref door.IsLocked, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref door.IsPickingLock, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref door.LockPickTimeLeft, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref door.TriggerInteractable, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref door.TriggerTimeToHold, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref door.TriggerSpeedMultiplier, default(ForPrimitives));
			}
			num = snapshot.TerminalDoors.Count;
			((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			foreach (TerminalDoorSnapshot terminalDoor in snapshot.TerminalDoors)
			{
				WriteVector3(ref writer, terminalDoor.Position);
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref terminalDoor.IsOpen, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref terminalDoor.IsPoweredOn, default(ForPrimitives));
			}
		}

		private static WorldSnapshot ReadSnapshot(ref FastBufferReader reader)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0101: 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_0117: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (num != 2)
			{
				throw new InvalidOperationException($"Unsupported world snapshot version {num}.");
			}
			WorldSnapshot worldSnapshot = new WorldSnapshot();
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.IncludeInterior, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.SpawnInShip, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.InShipPhase, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.ShipHasLanded, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.ShipIsLeaving, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.ShipDoorsEnabled, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.HangarDoorsClosed, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.NewGameIsLoading, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.TravellingToNewLevel, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.ShipAmbiancePlaying, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.ShipTravelAudioPlaying, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.PowerOffPermanently, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.PowerOn, default(ForPrimitives));
			worldSnapshot.ShipTransform = ReadTransform(ref reader);
			worldSnapshot.CurrentPlanetTransform = ReadTransform(ref reader);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.CurrentPlanetActive, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.OuterSpaceSunActive, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref worldSnapshot.StarSphereActive, default(ForPrimitives));
			worldSnapshot.ShipAnimator = ReadAnimator(ref reader);
			worldSnapshot.ShipBodyAnimator = ReadAnimator(ref reader);
			worldSnapshot.ShipDoorsAnimator = ReadAnimator(ref reader);
			worldSnapshot.CurrentPlanetAnimator = ReadAnimator(ref reader);
			worldSnapshot.OuterSpaceSunAnimator = ReadAnimator(ref reader);
			int num2 = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
			if (num2 < 0 || num2 > 4096)
			{
				throw new InvalidOperationException($"Invalid regular door count {num2}.");
			}
			for (int i = 0; i < num2; i++)
			{
				DoorSnapshot doorSnapshot = new DoorSnapshot
				{
					Position = ReadVector3(ref reader)
				};
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref doorSnapshot.IsOpen, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref doorSnapshot.IsLocked, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref doorSnapshot.IsPickingLock, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref doorSnapshot.LockPickTimeLeft, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref doorSnapshot.TriggerInteractable, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref doorSnapshot.TriggerTimeToHold, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref doorSnapshot.TriggerSpeedMultiplier, default(ForPrimitives));
				worldSnapshot.Doors.Add(doorSnapshot);
			}
			int num3 = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num3, default(ForPrimitives));
			if (num3 < 0 || num3 > 4096)
			{
				throw new InvalidOperationException($"Invalid terminal door count {num3}.");
			}
			for (int j = 0; j < num3; j++)
			{
				TerminalDoorSnapshot terminalDoorSnapshot = new TerminalDoorSnapshot
				{
					Position = ReadVector3(ref reader)
				};
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref terminalDoorSnapshot.IsOpen, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref terminalDoorSnapshot.IsPoweredOn, default(ForPrimitives));
				worldSnapshot.TerminalDoors.Add(terminalDoorSnapshot);
			}
			return worldSnapshot;
		}

		private static void WriteTransform(ref FastBufferWriter writer, TransformSnapshot snapshot)
		{
			//IL_0009: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.Exists, default(ForPrimitives));
			if (snapshot.Exists)
			{
				WriteVector3(ref writer, snapshot.LocalPosition);
				WriteQuaternion(ref writer, snapshot.LocalRotation);
				WriteVector3(ref writer, snapshot.LocalScale);
			}
		}

		private static TransformSnapshot ReadTransform(ref FastBufferReader reader)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0040: 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)
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			if (!flag)
			{
				return new TransformSnapshot();
			}
			return new TransformSnapshot
			{
				Exists = true,
				LocalPosition = ReadVector3(ref reader),
				LocalRotation = ReadQuaternion(ref reader),
				LocalScale = ReadVector3(ref reader)
			};
		}

		private static void WriteAnimator(ref FastBufferWriter writer, AnimatorSnapshot snapshot)
		{
			//IL_0009: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0059: 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_0087: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected I4, but got Unknown
			//IL_009f: 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_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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected I4, but got Unknown
			//IL_0105: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_00dd: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.Exists, default(ForPrimitives));
			if (!snapshot.Exists)
			{
				return;
			}
			((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref snapshot.Enabled, default(ForPrimitives));
			((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref snapshot.Speed, default(ForPrimitives));
			int count = snapshot.Parameters.Count;
			((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref count, default(ForPrimitives));
			foreach (AnimatorParameterSnapshot parameter in snapshot.Parameters)
			{
				((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref parameter.NameHash, default(ForPrimitives));
				count = (int)parameter.Type;
				((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref count, default(ForPrimitives));
				AnimatorControllerParameterType type = parameter.Type;
				switch (type - 1)
				{
				case 3:
					((FastBufferWriter)(ref writer)).WriteValueSafe<bool>(ref parameter.BoolValue, default(ForPrimitives));
					break;
				case 2:
					((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref parameter.IntValue, default(ForPrimitives));
					break;
				case 0:
					((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref parameter.FloatValue, default(ForPrimitives));
					break;
				}
			}
			count = snapshot.Layers.Count;
			((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref count, default(ForPrimitives));
			foreach (AnimatorLayerSnapshot layer in snapshot.Layers)
			{
				((FastBufferWriter)(ref writer)).WriteValueSafe<int>(ref layer.StateHash, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref layer.NormalizedTime, default(ForPrimitives));
				((FastBufferWriter)(ref writer)).WriteValueSafe<float>(ref layer.Weight, default(ForPrimitives));
			}
		}

		private static AnimatorSnapshot ReadAnimator(ref FastBufferReader reader)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0055: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected I4, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			AnimatorSnapshot animatorSnapshot = new AnimatorSnapshot
			{
				Exists = flag
			};
			if (!flag)
			{
				return animatorSnapshot;
			}
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref animatorSnapshot.Enabled, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref animatorSnapshot.Speed, default(ForPrimitives));
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (num < 0 || num > 512)
			{
				throw new InvalidOperationException($"Invalid animator parameter count {num}.");
			}
			int num2 = default(int);
			for (int i = 0; i < num; i++)
			{
				AnimatorParameterSnapshot animatorParameterSnapshot = new AnimatorParameterSnapshot();
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref animatorParameterSnapshot.NameHash, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
				animatorParameterSnapshot.Type = (AnimatorControllerParameterType)num2;
				AnimatorControllerParameterType type = animatorParameterSnapshot.Type;
				switch (type - 1)
				{
				case 3:
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref animatorParameterSnapshot.BoolValue, default(ForPrimitives));
					break;
				case 2:
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref animatorParameterSnapshot.IntValue, default(ForPrimitives));
					break;
				case 0:
					((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref animatorParameterSnapshot.FloatValue, default(ForPrimiti