Decompiled source of CrewTrials v0.1.1

plugins/CrewTrials.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CrewTrials
{
	[BepInPlugin("tgamert.crewtrials", "Crew Trials", "0.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static GameObject RecorderPrefab;

		internal static ConfigEntry<bool> Samples;

		internal static ConfigEntry<bool> RenderPreview;

		internal static ConfigEntry<int> Duration;

		internal static ConfigEntry<int> FailureDamage;

		private void Awake()
		{
			//IL_00f8: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: 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_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Samples = ((BaseUnityPlugin)this).Config.Bind<bool>("Trials", "ShipRecorder", true, "Ein Rekorder je Lobby im Schiff.");
			Duration = ((BaseUnityPlugin)this).Config.Bind<int>("Trials", "DurationSeconds", 240, "Zeit fuer alle drei Aufgaben (30-900 Sekunden).");
			FailureDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Trials", "FailureDamage", 20, "Normaler Spielschaden bei Scheitern (0-50), nur fuer Teilnehmer.");
			RenderPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "RenderPreview", false, "Nur eigene HDRP-Vorschaubilder im isolierten RuntimeProbe; kein Spieltest.");
			GameObject val = NetworkPrefabs.CreateNetworkPrefab("TGamerT.CrewTrials.Recorder.v1");
			val.layer = 6;
			val.tag = "PhysicsProp";
			NetworkObject component = val.GetComponent<NetworkObject>();
			component.AutoObjectParentSync = false;
			component.DontDestroyWithOwner = true;
			GameObject val2 = TrialVisuals.Recorder(val.transform);
			Rigidbody val3 = val.AddComponent<Rigidbody>();
			val3.isKinematic = true;
			val3.useGravity = false;
			BoxCollider val4 = val.AddComponent<BoxCollider>();
			val4.size = new Vector3(0.35f, 0.215f, 0.165f);
			val4.center = new Vector3(0f, 0.016f, 0.0075f);
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.spatialBlend = 1f;
			GameObject val5 = new GameObject("RecorderScanNode")
			{
				layer = 22
			};
			val5.transform.SetParent(val.transform, false);
			BoxCollider obj2 = val5.AddComponent<BoxCollider>();
			((Collider)obj2).isTrigger = true;
			obj2.size = new Vector3(0.35f, 0.22f, 0.17f);
			ScanNodeProperties obj3 = val5.AddComponent<ScanNodeProperties>();
			obj3.headerText = "Pruefungsrekorder";
			obj3.subText = "LMB: Mondpruefung | Q/E: Pruefungsanlage";
			obj3.nodeType = 0;
			obj3.minRange = 0;
			obj3.maxRange = 18;
			obj3.requiresLineOfSight = true;
			Item val6 = ScriptableObject.CreateInstance<Item>();
			((Object)val6).name = "CrewTrials_RecorderAsset";
			val6.itemName = "Pruefungsrekorder";
			val6.spawnPrefab = val;
			val6.weight = 1.06f;
			val6.twoHanded = false;
			val6.itemSpawnsOnGround = true;
			val6.canBeGrabbedBeforeGameStart = true;
			val6.requiresBattery = false;
			val6.syncUseFunction = false;
			val6.syncInteractLRFunction = false;
			val6.positionOffset = new Vector3(0.06f, -0.06f, 0.12f);
			val6.verticalOffset = 0.095f;
			val6.restingRotation = Vector3.zero;
			val6.automaticallySetUsingPower = false;
			val6.toolTips = new string[3] { "Mondpruefung starten : Hauptaktion", "Pruefungsanlage betreten : Zweite Funktion", "Erst landen. Nahe Crew nimmt teil. Reihenfolge, Bodenplatten, Ausgang. Notaus am roten Schalter." };
			val6.itemIcon = TrialVisuals.Icon();
			val6.creditsWorth = 35;
			TrialRecorder trialRecorder = val.AddComponent<TrialRecorder>();
			((GrabbableObject)trialRecorder).itemProperties = val6;
			((GrabbableObject)trialRecorder).grabbable = true;
			((GrabbableObject)trialRecorder).grabbableToEnemies = false;
			((GrabbableObject)trialRecorder).propBody = val3;
			((GrabbableObject)trialRecorder).propColliders = (Collider[])(object)new Collider[1] { (Collider)val4 };
			((GrabbableObject)trialRecorder).mainObjectRenderer = val2.GetComponentInChildren<MeshRenderer>();
			((GrabbableObject)trialRecorder).originalScale = Vector3.one;
			TerminalNode val7 = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val7).name = "CrewTrials_RecorderInfo";
			val7.clearPreviousText = true;
			val7.buyItemIndex = -1;
			val7.displayText = "\nPRUEFUNGSREKORDER\n\nHauptaktion: gemeinsame Pruefung auf dem aktuellen Mond.\nZweite Funktion: eigene Pruefungsanlage betreten.\n\nErst nach der Landung. Lebende Crew in 12m Naehe und\nim selben Bereich nimmt teil, bis zu 16 Personen.\n\nDrei Aufgaben: Blau, Rot, Gelb; Bodenplatten besetzen;\ngemeinsam am Ausgang sammeln. Uhr und Aufgaben\nstehen am Bildschirm. Roter Schalter bricht ab.\nScheitern verursacht normalen, einstellbaren Schaden.\n\nDies ist eine Anlage ueber den Rekorder, kein eigener\nEintrag im Mond-Terminal. Preis: 35 Credits.\n\n";
			Items.RegisterShopItem(val6, (TerminalNode)null, (TerminalNode)null, val7, 35);
			RecorderPrefab = val;
			GameObject val8 = new GameObject("CrewTrials_Runtime");
			((Object)val8).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val8);
			val8.AddComponent<TrialNet>();
			val8.AddComponent<TrialPresentation>();
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "RuntimeProbe", false, "Nur isolierte lokale Komponentenpruefung; kein Spielstart/Transport.").Value)
			{
				Application.runInBackground = true;
				val8.AddComponent<RuntimeTrialProbe>();
			}
			Log.LogInfo((object)"Crew Trials0.1.1: eigener Rekorder mit Scanner-Markierung und Laufzeit registriert.");
		}
	}
	public sealed class TrialRecorder : GrabbableObject
	{
		private float next;

		public bool AiSafeToTest => false;

		public void Awake()
		{
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)0;
		}

		public override void SetControlTipsForItem()
		{
			((GrabbableObject)this).SetControlTipsForItem();
			if (((NetworkBehaviour)this).IsOwner && (Object)(object)base.playerHeldBy != (Object)null)
			{
				base.playerHeldBy.equippedUsableItemQE = true;
			}
		}

		public override void OnNetworkSpawn()
		{
			//IL_002e: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			((NetworkBehaviour)this).OnNetworkSpawn();
			StartOfRound instance = StartOfRound.Instance;
			if (!base.isHeld && (Object)(object)instance?.shipBounds != (Object)null)
			{
				Bounds bounds = instance.shipBounds.bounds;
				if (((Bounds)(ref bounds)).Contains(((Component)this).transform.position))
				{
					base.isInElevator = true;
					base.isInShipRoom = true;
					((Component)this).transform.SetParent(instance.elevatorTransform, true);
				}
			}
			TrialNet.Register(this);
		}

		public override void OnNetworkDespawn()
		{
			TrialNet.Unregister(this);
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (buttonDown)
			{
				Use(0);
			}
		}

		public override void ItemInteractLeftRight(bool right)
		{
			Use(1);
		}

		private void Use(int mode)
		{
			if (((NetworkBehaviour)this).IsOwner && !((Object)(object)base.playerHeldBy == (Object)null) && !base.isPocketed && base.isHeld && !(Time.time < next))
			{
				next = Time.time + 2f;
				TrialNet.Request(this, mode);
			}
		}
	}
	public sealed class RuntimeTrialPreview : MonoBehaviour
	{
		private const int Layer = 30;

		private GameObject studio;

		private TrialArena arena;

		private Camera camera;

		private RenderTexture target;

		private Texture2D pixels;

		private VolumeProfile profile;

		private Exposure exposure;

		private int view;

		private int nextFrame;

		private bool ready;

		private string folder;

		private Vector3 origin = new Vector3(12000f, 500f, 12000f);

		public void Update()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!ready)
				{
					Setup();
					Select();
					ready = true;
				}
				else if (Time.frameCount >= nextFrame)
				{
					RenderTexture active = RenderTexture.active;
					try
					{
						RenderTexture.active = target;
						this.pixels.ReadPixels(new Rect(0f, 0f, (float)((Texture)target).width, (float)((Texture)target).height), 0, 0);
						this.pixels.Apply();
					}
					finally
					{
						RenderTexture.active = active;
					}
					Color32[] pixels = this.pixels.GetPixels32();
					int num = pixels.Max((Color32 c) => c.r + c.g + c.b) - pixels.Min((Color32 c) => c.r + c.g + c.b);
					if (num < 30)
					{
						throw new InvalidOperationException("Uniform preview");
					}
					string text = ((view == 0) ? "Pruefungsraum-I" : ((view == 1) ? "Pruefungsraum-II" : ((view == 2) ? "Pruefungsraum-III" : "Pruefungsrekorder")));
					File.WriteAllBytes(Path.Combine(folder, text + ".png"), ImageConversion.EncodeToPNG(this.pixels));
					Plugin.Log.LogInfo((object)("TrialPreview saved " + text + ", native HDRP range=" + num));
					if (++view == 4)
					{
						Plugin.Log.LogInfo((object)"TrialPreview PASS: four native own-geometry artifacts; lighting is a preview setup, no lobby.");
						Cleanup();
					}
					else
					{
						Select();
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("TrialPreview unavailable: " + ex));
				Cleanup();
			}
		}

		private void Setup()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			folder = Path.Combine(Paths.BepInExRootPath, "qa-renders");
			Directory.CreateDirectory(folder);
			studio = new GameObject("CrewTrials_PreviewStudio");
			studio.transform.position = origin;
			arena = new TrialArena();
			arena.Build(enclosed: true, origin, bake: false);
			arena.Apply(TrialPhase.Exit);
			InteractTrigger[] componentsInChildren = arena.Root.GetComponentsInChildren<InteractTrigger>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			GameObject val = new GameObject("preview_fill");
			val.transform.SetParent(studio.transform, false);
			val.transform.rotation = Quaternion.Euler(35f, -25f, 0f);
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)1;
			obj.cullingMask = 1073741824;
			val.AddComponent<HDAdditionalLightData>().intensity = 1500f;
			GameObject val2 = new GameObject("preview_camera");
			val2.transform.SetParent(studio.transform, false);
			camera = val2.AddComponent<Camera>();
			camera.fieldOfView = 66f;
			camera.nearClipPlane = 0.03f;
			camera.farClipPlane = 40f;
			camera.aspect = 1.7777778f;
			camera.cullingMask = 1073741824;
			camera.clearFlags = (CameraClearFlags)2;
			camera.backgroundColor = new Color(0.025f, 0.035f, 0.025f);
			HDAdditionalCameraData obj2 = val2.GetComponent<HDAdditionalCameraData>() ?? val2.AddComponent<HDAdditionalCameraData>();
			obj2.volumeLayerMask = LayerMask.op_Implicit(1073741824);
			obj2.clearColorMode = (ClearColorMode)1;
			obj2.backgroundColorHDR = camera.backgroundColor;
			GameObject val3 = new GameObject("preview_exposure");
			val3.transform.SetParent(studio.transform, false);
			BoxCollider obj3 = val3.AddComponent<BoxCollider>();
			((Collider)obj3).isTrigger = true;
			obj3.size = new Vector3(80f, 80f, 80f);
			Volume obj4 = val3.AddComponent<Volume>();
			obj4.priority = 1000f;
			obj4.isGlobal = false;
			profile = ScriptableObject.CreateInstance<VolumeProfile>();
			obj4.sharedProfile = profile;
			exposure = profile.Add<Exposure>(true);
			((VolumeParameter<ExposureMode>)(object)exposure.mode).Override((ExposureMode)0);
			((VolumeParameter<float>)(object)exposure.fixedExposure).Override(6f);
			Transform[] componentsInChildren2 = studio.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Component)componentsInChildren2[i]).gameObject.layer = 30;
			}
			componentsInChildren2 = arena.Root.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Component)componentsInChildren2[i]).gameObject.layer = 30;
			}
			target = new RenderTexture(960, 540, 24, (RenderTextureFormat)0);
			target.Create();
			camera.targetTexture = target;
			pixels = new Texture2D(960, 540, (TextureFormat)3, false);
		}

		private void Select()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0122: 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)
			if (view < 3)
			{
				((Component)camera).transform.position = origin + new Vector3(0.7f, 1.65f, 1.7f + (float)(view * 10));
				((Component)camera).transform.LookAt(origin + new Vector3(0f, 1.2f, (float)(8 + view * 10)));
			}
			else
			{
				arena.Root.SetActive(false);
				GameObject obj = TrialVisuals.Recorder(studio.transform);
				obj.transform.localPosition = new Vector3(0f, 1f, 0f);
				Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Component)componentsInChildren[i]).gameObject.layer = 30;
				}
				((Component)camera).transform.position = origin + new Vector3(0.42f, 1.3f, 0.65f);
				((Component)camera).transform.LookAt(origin + Vector3.up);
				((VolumeParameter<float>)(object)exposure.fixedExposure).Override(8f);
			}
			nextFrame = Time.frameCount + 6;
		}

		private void Cleanup()
		{
			if ((Object)(object)camera != (Object)null)
			{
				camera.targetTexture = null;
			}
			arena?.Clear();
			if ((Object)(object)studio != (Object)null)
			{
				Object.Destroy((Object)(object)studio);
			}
			if ((Object)(object)target != (Object)null)
			{
				target.Release();
				Object.Destroy((Object)(object)target);
			}
			if ((Object)(object)pixels != (Object)null)
			{
				Object.Destroy((Object)(object)pixels);
			}
			if ((Object)(object)profile != (Object)null)
			{
				Object.Destroy((Object)(object)profile);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	public sealed class RuntimeTrialProbe : MonoBehaviour
	{
		private int checks;

		private TrialArena arena;

		private void Check(bool condition, string name)
		{
			if (!condition)
			{
				throw new InvalidOperationException(name);
			}
			checks++;
			Plugin.Log.LogInfo((object)("TrialQA PASS " + name));
		}

		public IEnumerator Start()
		{
			yield return null;
			try
			{
				Wire();
				Assets();
				Arena();
				Plugin.Log.LogInfo((object)("TrialRuntimeQA PASS: " + checks + " native component/buffer/geometry checks; no lobby, transport, AI request, player transfer, or save created."));
				File.WriteAllText(Path.Combine(Paths.BepInExRootPath, "trial-qa-result.json"), "{\"passed\":true,\"checks\":" + checks + ",\"lobby_tested\":false,\"live_transfer_tested\":false,\"external_ai_tested\":false}");
				if (Plugin.RenderPreview.Value)
				{
					((Component)this).gameObject.AddComponent<RuntimeTrialPreview>();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("TrialRuntimeQA FAIL: " + ex));
				File.WriteAllText(Path.Combine(Paths.BepInExRootPath, "trial-qa-result.json"), "{\"passed\":false}");
			}
			finally
			{
				arena?.Clear();
				TrialNet.Instance?.Arena.Clear();
				TrialPresentation.Clear();
			}
			Object.Destroy((Object)(object)this);
		}

		private void Wire()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			TrialPacket trialPacket = new TrialPacket
			{
				Kind = TrialMessage.State,
				Epoch = 3,
				Sequence = 77,
				Source = 9223372036854775860uL,
				Slot = 17,
				Code = 1,
				A = 3,
				B = 12,
				Position = new Vector3(9000f, 500f, 9000f),
				Vector = new Vector3(50f, 2f, 3f)
			};
			foreach (TrialMessage value in Enum.GetValues(typeof(TrialMessage)))
			{
				TrialPacket p = trialPacket;
				p.Kind = value;
				TrialPacket trialPacket2 = RoundTrip(p);
				Check(trialPacket2.Kind == value && trialPacket2.Source == p.Source && trialPacket2.Position == p.Position && trialPacket2.Vector == p.Vector && trialPacket2.Epoch == 3 && trialPacket2.Sequence == 77 && trialPacket2.Slot == 17 && trialPacket2.Code == 1 && trialPacket2.A == 3 && trialPacket2.B == 12, "actual NGO roundtrip " + value);
			}
			TrialPacket p2 = trialPacket;
			p2.Position.y = float.NaN;
			Check(Rejected(p2), "NaN rejected");
			p2 = trialPacket;
			p2.Vector.x = float.PositiveInfinity;
			Check(Rejected(p2), "infinity rejected");
			p2 = trialPacket;
			p2.Position.x = 100000f;
			Check(Rejected(p2), "implausible coordinate rejected");
			p2 = trialPacket;
			p2.Slot = 256;
			Check(Rejected(p2), "invalid slot rejected");
			p2 = trialPacket;
			p2.Kind = (TrialMessage)255;
			Check(Rejected(p2), "unknown kind rejected");
			p2 = trialPacket;
			p2.Epoch = -1;
			Check(Rejected(p2), "negative epoch rejected");
			p2 = trialPacket;
			p2.Sequence = 0;
			Check(Rejected(p2), "zero sequence rejected");
			TrialNet instance = TrialNet.Instance;
			int num = (int)typeof(TrialNet).GetField("epoch", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance);
			TrialPacket p3 = new TrialPacket
			{
				Kind = TrialMessage.Reset,
				Epoch = num + 1,
				Sequence = 10,
				Slot = -1
			};
			instance.Handle(72uL, p3);
			Check((int)typeof(TrialNet).GetField("epoch", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance) == num, "forged reset rejected before state mutation");
			instance.Handle(0uL, p3);
			TrialPacket p4 = trialPacket;
			p4.Epoch = p3.Epoch;
			p4.Sequence = 30;
			p4.A = 0;
			p4.B = 12;
			instance.Handle(0uL, p4);
			Check(instance.Count == 12, "authenticated real handler state accepted");
			p3.Sequence = 20;
			instance.Handle(0uL, p3);
			p4.Sequence = 29;
			p4.B = 7;
			instance.Handle(0uL, p4);
			Check(instance.Count == 12, "delayed reset cannot replay older state");
			p4.Sequence = 31;
			instance.Handle(72uL, p4);
			Check(instance.Count == 12, "forged state rejected");
			IDictionary dictionary = (IDictionary)typeof(TrialNet).GetField("pendingCargo", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance);
			TrialPacket p5 = new TrialPacket
			{
				Kind = TrialMessage.Cargo,
				Epoch = p3.Epoch,
				Sequence = 32,
				Slot = -1,
				Source = 999uL,
				Position = new Vector3(1f, 2f, 3f),
				Code = 1
			};
			instance.Handle(72uL, p5);
			Check(dictionary.Count == 0, "forged deferred cargo cannot enter inbox");
			instance.Handle(0uL, p5);
			Check(dictionary.Count == 1, "authenticated cargo waits for actual native spawn");
			p5.Sequence = 33;
			p5.Position = new Vector3(4f, 5f, 6f);
			instance.Handle(0uL, p5);
			Check(dictionary.Count == 1, "newer return replaces same-object deferred cargo");
			typeof(TrialNet).GetMethod("Clear", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, null);
			Check(dictionary.Count == 0, "session cleanup clears deferred native effects");
			static bool Rejected(TrialPacket p6)
			{
				try
				{
					RoundTrip(p6);
					return false;
				}
				catch (ArgumentException)
				{
					return true;
				}
			}
			unsafe static TrialPacket RoundTrip(TrialPacket trialPacket3)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				FastBufferWriter val = trialPacket3.Write();
				try
				{
					FastBufferReader reader = default(FastBufferReader);
					((FastBufferReader)(ref reader))..ctor(val, (Allocator)2, -1, 0, (Allocator)2);
					try
					{
						return TrialPacket.Read(reader);
					}
					finally
					{
						((IDisposable)(*(FastBufferReader*)(&reader))/*cast due to .constrained prefix*/).Dispose();
					}
				}
				finally
				{
					((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
				}
			}
		}

		private void Assets()
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			GameObject recorderPrefab = Plugin.RecorderPrefab;
			TrialRecorder component = recorderPrefab.GetComponent<TrialRecorder>();
			Check((Object)(object)recorderPrefab.GetComponent<NetworkObject>() != (Object)null && (Object)(object)component != (Object)null, "native registered recorder components");
			Check((Object)(object)((GrabbableObject)component).itemProperties.itemIcon != (Object)null && !component.AiSafeToTest, "recorder icon and AI automatic-test opt-out");
			Check(((GrabbableObject)component).itemProperties.toolTips.Length == 3 && ((GrabbableObject)component).itemProperties.creditsWorth == 35, "both controls and shop price");
			ScanNodeProperties componentInChildren = recorderPrefab.GetComponentInChildren<ScanNodeProperties>(true);
			Check((Object)(object)componentInChildren != (Object)null && componentInChildren.headerText == "Pruefungsrekorder" && ((Component)componentInChildren).gameObject.layer == 22 && componentInChildren.maxRange == 18 && componentInChildren.requiresLineOfSight, "recorder now exposes actual native scan label and controls at 18m");
			BoxCollider component2 = recorderPrefab.GetComponent<BoxCollider>();
			Renderer[] componentsInChildren = recorderPrefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				_ = val.localBounds;
				_ = ((Component)val).transform;
				Bounds bounds = val.bounds;
				bool condition = true;
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						for (int l = -1; l <= 1; l += 2)
						{
							Vector3 val2 = recorderPrefab.transform.InverseTransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)j, (float)k, (float)l)));
							Bounds val3 = new Bounds(component2.center, component2.size + Vector3.one * 0.005f);
							if (!((Bounds)(ref val3)).Contains(val2))
							{
								condition = false;
							}
						}
					}
				}
				Check(condition, "pickup collider encloses " + ((Object)val).name);
				Check((Object)(object)val.sharedMaterial != (Object)null && (Object)(object)val.sharedMaterial.shader != (Object)null, "native material " + ((Object)val).name);
			}
			for (int m = 0; m < 10; m++)
			{
				AudioClip val4 = TrialPresentation.Clip(m);
				Check((Object)(object)val4 != (Object)null && val4.channels == 1 && val4.frequency == 22050 && val4.length > 0.5f && val4.length < 20f, "embedded original German cue " + m);
				float[] array = new float[val4.samples];
				val4.GetData(array, 0);
				Check(array.All((float n) => TrialPolicy.Finite(n) && Math.Abs(n) <= 1f) && array.Any((float n) => (double)Math.Abs(n) > 0.1), "finite nonempty PCM " + m);
			}
			Check(Assembly.GetExecutingAssembly().GetManifestResourceNames().Count((string n) => n.EndsWith(".wav")) == 10, "exactly ten embedded cues");
		}

		private void Arena()
		{
			//IL_0028: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: 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_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: 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_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Expected O, but got Unknown
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05db: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0647: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_0698: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_070c: Unknown result type (might be due to invalid IL or missing references)
			//IL_072f: Unknown result type (might be due to invalid IL or missing references)
			//IL_074b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0752: Expected O, but got Unknown
			//IL_0755: Unknown result type (might be due to invalid IL or missing references)
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0773: Invalid comparison between Unknown and I4
			//IL_0880: Unknown result type (might be due to invalid IL or missing references)
			//IL_0881: Unknown result type (might be due to invalid IL or missing references)
			//IL_088b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0890: Unknown result type (might be due to invalid IL or missing references)
			//IL_0924: Unknown result type (might be due to invalid IL or missing references)
			//IL_092e: Unknown result type (might be due to invalid IL or missing references)
			arena = new TrialArena();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(9000f, 500f, 9000f);
			arena.Build(enclosed: true, val, bake: true);
			InteractTrigger[] componentsInChildren = arena.Root.GetComponentsInChildren<InteractTrigger>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			Physics.SyncTransforms();
			Check(arena.Switches.Count == 4 && arena.Plates.Length == 2, "three buttons, Notaus, two plates");
			RaycastHit val3 = default(RaycastHit);
			for (int j = 0; j < 3; j++)
			{
				Vector3 val2 = val + new Vector3(0f, 1f, (float)(5 + j * 10));
				Check(Physics.Raycast(val2, Vector3.down, ref val3, 2f, TrialNet.WorldMask, (QueryTriggerInteraction)1) && (double)Math.Abs(((RaycastHit)(ref val3)).point.y - val.y) < 0.01, "actual room floor " + j);
			}
			Check(Physics.Raycast(val + new Vector3(0f, 1f, 5f), Vector3.down, 2f, 268437760, (QueryTriggerInteraction)1), "floor participates in actual native item falling layer mask");
			GameObject val4 = Object.Instantiate<GameObject>(Plugin.RecorderPrefab);
			((Behaviour)val4.GetComponent<TrialRecorder>()).enabled = false;
			try
			{
				TrialRecorder component = val4.GetComponent<TrialRecorder>();
				TrialTransfer.Cargo((GrabbableObject)(object)component, val + new Vector3(0f, 0.5f, 5f), 1);
				Check(Mathf.Abs(((GrabbableObject)component).targetFloorPosition.y - (val.y + ((GrabbableObject)component).itemProperties.verticalOffset)) < 0.005f, "actual native item FallToGround finds trial floor with correct vertical offset");
				((GrabbableObject)component).isHeld = true;
				Vector3 position = val4.transform.position;
				TrialTransfer.Cargo((GrabbableObject)(object)component, Vector3.zero, 0);
				Check(val4.transform.position == position, "cargo return cannot steal a held item");
				((GrabbableObject)component).isHeld = false;
			}
			finally
			{
				Object.Destroy((Object)(object)val4);
			}
			GameObject val5 = new GameObject("TrialQA_native_corpse");
			val5.SetActive(false);
			GameObject val6 = Object.Instantiate<GameObject>(Plugin.RecorderPrefab);
			((Behaviour)val6.GetComponent<TrialRecorder>()).enabled = false;
			try
			{
				Rigidbody val7 = val5.AddComponent<Rigidbody>();
				val7.isKinematic = true;
				DeadBodyInfo val8 = val5.AddComponent<DeadBodyInfo>();
				((Behaviour)val8).enabled = false;
				val8.bodyParts = (Rigidbody[])(object)new Rigidbody[1] { val7 };
				Vector3 val9 = val + new Vector3(1f, 0f, 5f);
				TrialTransfer.Body(val8, val9, 6);
				Check(Vector3.Distance(((Component)val8).transform.position, val9 + Vector3.up * 2.5f) < 0.005f, "native corpse safe relocation executed");
				Check(val8.parentedToShip && val8.isInShip, "corpse return records native ship flags");
				val8.grabBodyObject = (GrabbableObject)(object)val6.GetComponent<TrialRecorder>();
				val8.grabBodyObject.isHeld = true;
				Vector3 position2 = ((Component)val8).transform.position;
				TrialTransfer.Body(val8, Vector3.zero, 0);
				Check(((Component)val8).transform.position == position2, "corpse held by a player is not detached or stolen");
				val8.grabBodyObject.isHeld = false;
				TrialTransfer.Body(val8, val9, 1);
				Check(!val8.isInShip && !val8.parentedToShip, "corpse outside return clears native ship flags");
			}
			finally
			{
				Object.Destroy((Object)(object)val5);
				Object.Destroy((Object)(object)val6);
			}
			arena.Apply(TrialPhase.Sequence);
			Check(Physics.Linecast(val + new Vector3(0f, 1f, 9f), val + new Vector3(0f, 1f, 11f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "first gate physically closed during sequence");
			Check(Physics.Linecast(val + new Vector3(0f, 1f, 19f), val + new Vector3(0f, 1f, 21f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "second gate physically closed");
			GameObject val10 = new GameObject("TrialQA_native_controller");
			val10.transform.position = val + new Vector3(0f, 0.05f, 8f);
			try
			{
				CharacterController val11 = val10.AddComponent<CharacterController>();
				val11.height = 1.8f;
				val11.radius = 0.3f;
				val11.center = Vector3.up * 0.9f;
				val11.skinWidth = 0.03f;
				for (int k = 0; k < 35; k++)
				{
					val11.Move(new Vector3(0f, -0.05f, 0.1f));
				}
				Check(val10.transform.position.z < val.z + 9.65f && val10.transform.position.z > val.z + 9.4f, "actual native character controller cannot walk through closed gate");
				Check(Mathf.Abs(val10.transform.position.y - val.y) < 0.1f, "actual native character controller stays grounded");
				arena.Apply(TrialPhase.Plates);
				for (int l = 0; l < 35; l++)
				{
					val11.Move(new Vector3(0f, -0.05f, 0.1f));
				}
				Check(val10.transform.position.z > val.z + 12f, "actual native character controller passes opened gate");
			}
			finally
			{
				Object.Destroy((Object)(object)val10);
			}
			arena.Apply(TrialPhase.Plates);
			Check(!Physics.Linecast(val + new Vector3(0f, 1f, 9f), val + new Vector3(0f, 1f, 11f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "first gate actually opens after sequence");
			Check(Physics.Linecast(val + new Vector3(0f, 1f, 19f), val + new Vector3(0f, 1f, 21f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "second gate stays closed during plates");
			arena.Apply(TrialPhase.Exit);
			Check(!Physics.Linecast(val + new Vector3(0f, 1f, 19f), val + new Vector3(0f, 1f, 21f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "second gate actually opens after plates");
			Check(Physics.Linecast(val + new Vector3(0f, 1f, 5f), val + new Vector3(-6f, 1f, 5f), TrialNet.WorldMask, (QueryTriggerInteraction)1), "outer wall collision");
			NavMeshHit val12 = default(NavMeshHit);
			Check(NavMesh.SamplePosition(arena.Spawn(0), ref val12, 2f, -1), "native navigation at spawn");
			NavMeshHit val13 = default(NavMeshHit);
			Check(NavMesh.SamplePosition(arena.Exit, ref val13, 2f, -1), "native navigation at exit");
			NavMeshPath val14 = new NavMeshPath();
			Check(NavMesh.CalculatePath(((NavMeshHit)(ref val12)).position, ((NavMeshHit)(ref val13)).position, -1, val14) && (int)val14.status == 0, "actual native path through all three rooms");
			foreach (KeyValuePair<int, Transform> @switch in arena.Switches)
			{
				InteractTrigger component2 = ((Component)@switch.Value).GetComponent<InteractTrigger>();
				bool invoked = false;
				((UnityEvent<PlayerControllerB>)(object)component2.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
				{
					invoked = true;
				});
				((UnityEvent<PlayerControllerB>)(object)component2.onInteract).Invoke((PlayerControllerB)null);
				Check(invoked && ((Component)component2).CompareTag("InteractTrigger") && ((Component)component2).gameObject.layer == 9 && !component2.holdInteraction, "native simple button event and interaction layer " + @switch.Key);
			}
			arena.Clear();
			Check(!arena.Exists, "arena cleanup removes root reference and nav registration");
			arena.Build(enclosed: false, val + Vector3.right * 50f, bake: false);
			componentsInChildren = arena.Root.GetComponentsInChildren<InteractTrigger>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			Check(arena.Root.GetComponentsInChildren<Collider>().All((Collider c) => c.isTrigger || !c.enabled), "moon mode adds no blocking ground or walls");
			Check(arena.Switches.Count == 4 && arena.Exit.z == val.z + 9f, "moon mode has real stations and exit");
		}
	}
	public sealed class TrialNet : MonoBehaviour
	{
		private sealed class Member
		{
			internal int Slot;

			internal int Flags;

			internal ulong Client;

			internal Vector3 Return;
		}

		private sealed class DeferredCargo
		{
			internal TrialPacket Packet;

			internal float Until;
		}

		private const string Channel = "TGamerT.CrewTrials.v1";

		private static readonly Dictionary<ulong, TrialRecorder> recorders = new Dictionary<ulong, TrialRecorder>();

		internal static TrialNet Instance;

		internal readonly TrialArena Arena = new TrialArena();

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

		private readonly List<Member> members = new List<Member>();

		private readonly Dictionary<ulong, DeferredCargo> pendingCargo = new Dictionary<ulong, DeferredCargo>();

		private readonly TrialReplay replay = new TrialReplay();

		private TrialPolicy policy = new TrialPolicy();

		private readonly Dictionary<ulong, int> requests = new Dictionary<ulong, int>();

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

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

		private NetworkManager manager;

		private CustomMessagingManager messaging;

		private StartOfRound round;

		private int epoch = 1;

		private int serial;

		private int requestSerial;

		private int mode;

		private int sequence;

		private float remaining;

		private float held;

		private float stateAt;

		private float nextState;

		private float nextStart;

		private float finishedAt;

		private float startedAt;

		private bool delivered;

		private bool warn30;

		private bool warn10;

		internal TrialPhase Phase { get; private set; }

		internal int Count { get; private set; }

		internal float Remaining => Mathf.Max(0f, remaining - (Time.time - stateAt));

		internal string ProgressText
		{
			get
			{
				if (Phase != TrialPhase.Sequence)
				{
					return Mathf.Min((float)((Phase == TrialPhase.Plates) ? 5 : 3), held).ToString("0.0") + " s";
				}
				return sequence + " / 3";
			}
		}

		internal bool LocalParticipant
		{
			get
			{
				if (Phase != TrialPhase.Idle)
				{
					return localMembers.Contains((int)(((long?)round?.localPlayerController?.playerClientId) ?? (-1L)));
				}
				return false;
			}
		}

		private static bool Server
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return false;
			}
		}

		internal static int WorldMask => LayerMask.GetMask(new string[3] { "Default", "Room", "Colliders" });

		private void Awake()
		{
			Instance = this;
		}

		internal static void Register(TrialRecorder item)
		{
			recorders[((NetworkBehaviour)item).NetworkObjectId] = item;
		}

		internal static void Unregister(TrialRecorder item)
		{
			recorders.Remove(((NetworkBehaviour)item).NetworkObjectId);
		}

		internal static void Request(TrialRecorder item, int mode)
		{
			if (!((Object)(object)Instance == (Object)null) && !((Object)(object)item == (Object)null) && ((NetworkBehaviour)item).IsSpawned && !((Object)(object)((GrabbableObject)item).playerHeldBy == (Object)null))
			{
				TrialPacket p = Instance.RequestPacket(TrialMessage.Use);
				p.Source = ((NetworkBehaviour)item).NetworkObjectId;
				p.Slot = (int)((GrabbableObject)item).playerHeldBy.playerClientId;
				p.Code = mode;
				Instance.SendHost(p);
			}
		}

		internal static void RequestSwitch(PlayerControllerB player, int id)
		{
			if (!((Object)(object)Instance == (Object)null) && !((Object)(object)player == (Object)null))
			{
				TrialPacket p = Instance.RequestPacket(TrialMessage.Press);
				p.Slot = (int)player.playerClientId;
				p.Code = id;
				Instance.SendHost(p);
			}
		}

		private TrialPacket RequestPacket(TrialMessage kind)
		{
			return new TrialPacket
			{
				Kind = kind,
				Epoch = epoch,
				Sequence = ++requestSerial,
				Slot = -1
			};
		}

		private TrialPacket Packet(TrialMessage kind, ulong source = 0uL)
		{
			return new TrialPacket
			{
				Kind = kind,
				Epoch = epoch,
				Sequence = ++serial,
				Source = source,
				Slot = -1
			};
		}

		private unsafe void SendHost(TrialPacket p)
		{
			//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)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)manager == (Object)null || !manager.IsListening)
			{
				return;
			}
			if (Server)
			{
				Handle(manager.LocalClientId, p);
				return;
			}
			FastBufferWriter val = p.Write();
			try
			{
				messaging.SendNamedMessage("TGamerT.CrewTrials.v1", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private unsafe void Send(ulong client, TrialPacket p)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!Server || (Object)(object)manager == (Object)null)
			{
				return;
			}
			if (client == manager.LocalClientId)
			{
				Handle(0uL, p);
				return;
			}
			FastBufferWriter val = p.Write();
			try
			{
				messaging.SendNamedMessage("TGamerT.CrewTrials.v1", client, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private void Broadcast(TrialPacket p)
		{
			if (!Server || (Object)(object)manager == (Object)null)
			{
				return;
			}
			foreach (ulong connectedClientsId in manager.ConnectedClientsIds)
			{
				Send(connectedClientsId, p);
			}
		}

		private void Receive(ulong sender, FastBufferReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Handle(sender, TrialPacket.Read(reader));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewTrials: Nachricht verworfen: " + ex.Message));
			}
		}

		internal void Handle(ulong sender, TrialPacket p)
		{
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			if ((int)p.Kind >= 128)
			{
				if (sender != 0L)
				{
					return;
				}
				if (p.Kind == TrialMessage.Reset)
				{
					if (replay.Reset(p.Epoch, p.Sequence))
					{
						if (epoch != p.Epoch)
						{
							Arena.Clear();
							localMembers.Clear();
							pendingCargo.Clear();
							TrialPresentation.Clear();
							Phase = TrialPhase.Idle;
						}
						epoch = p.Epoch;
					}
				}
				else if (replay.Admit(p.Epoch, p.Sequence, (byte)p.Kind, p.Source))
				{
					Apply(p);
				}
			}
			else
			{
				if (!Server || (Object)(object)manager == (Object)null || !manager.ConnectedClients.ContainsKey(sender))
				{
					return;
				}
				if (p.Kind == TrialMessage.Sync)
				{
					if (syncDue.TryGetValue(sender, out var value) && Time.time < value)
					{
						return;
					}
					syncDue[sender] = Time.time + 1f;
					Send(sender, Packet(TrialMessage.Reset, 0uL));
					foreach (Member member in members)
					{
						Send(sender, MemberPacket(member));
					}
					Send(sender, StatePacket());
				}
				else
				{
					if (p.Epoch != epoch || (Object)(object)round == (Object)null || round.shipIsLeaving || round.firingPlayersCutsceneRunning || p.Sequence < 1 || (requests.TryGetValue(sender, out var value2) && p.Sequence <= value2))
					{
						return;
					}
					requests[sender] = p.Sequence;
					if (inputDue.TryGetValue(sender, out var value3) && Time.time < value3)
					{
						return;
					}
					inputDue[sender] = Time.time + 0.12f;
					PlayerControllerB player = Player(p.Slot);
					if ((Object)(object)player == (Object)null || !Alive(player) || !Owns(player, sender))
					{
						return;
					}
					if (p.Kind == TrialMessage.Use)
					{
						if (p.Code >= 0 && p.Code <= 1 && recorders.TryGetValue(p.Source, out var value4) && !((Object)(object)value4 == (Object)null) && ((NetworkBehaviour)value4).IsSpawned && ((NetworkBehaviour)value4).OwnerClientId == sender && !((Object)(object)((GrabbableObject)value4).playerHeldBy != (Object)(object)player))
						{
							bool flag = ((GrabbableObject)value4).isHeld && !((GrabbableObject)value4).isPocketed && (Object)(object)player.currentlyHeldObjectServer == (Object)(object)value4;
							bool busy = player.inTerminalMenu || player.isClimbingLadder || player.inSpecialInteractAnimation || player.isGrabbingObjectAnimation;
							bool flag2 = round.shipHasLanded && !round.inShipPhase;
							PlayerControllerB[] array = round.allPlayerScripts.Where((PlayerControllerB x) => Alive(x) && x.isInsideFactory == player.isInsideFactory && Vector3.Distance(((Component)x).transform.position, ((Component)player).transform.position) <= 12f).Take(17).ToArray();
							if (!TrialPolicy.Admission(Server, Alive(player), owner: true, flag, busy, flag2, policy.Active || Time.time < nextStart, array.Length, Vector3.Distance(((Component)value4).transform.position, ((Component)player).transform.position), clear: true))
							{
								Notice(sender, p.Slot, flag2 ? "Noch eine Pruefung aktiv, Abklingzeit, oder Aktion gerade nicht moeglich." : "Erst landen, dann den Rekorder benutzen.");
							}
							else
							{
								Begin(player, array, p.Code, sender);
							}
						}
					}
					else
					{
						if (p.Kind != TrialMessage.Press || !policy.Active || Time.time < startedAt + 0.5f || !members.Any((Member x) => x.Slot == p.Slot) || p.Code < 0 || p.Code > 3 || !Arena.Switches.TryGetValue(p.Code, out var value5) || Vector3.Distance(((Component)player).transform.position, value5.position) > 2.7f || Physics.Linecast(((Component)player).transform.position + Vector3.up * 0.8f, value5.position, WorldMask, (QueryTriggerInteraction)1))
						{
							return;
						}
						if (p.Code == 3)
						{
							policy.Abort();
							Finish(ship: false);
						}
						else if (policy.Phase == TrialPhase.Sequence)
						{
							double deadline = policy.Deadline;
							TrialPhase phase = policy.Phase;
							if (!policy.Press(p.Code, Time.time) && policy.Deadline < deadline)
							{
								Speak(9);
							}
							if (phase != policy.Phase)
							{
								Changed();
							}
							else
							{
								Broadcast(StatePacket());
							}
						}
					}
				}
			}
		}

		private static bool Alive(PlayerControllerB player)
		{
			if ((Object)(object)player != (Object)null && player.isPlayerControlled)
			{
				return !player.isPlayerDead;
			}
			return false;
		}

		private static bool Owns(PlayerControllerB player, ulong sender)
		{
			object obj = TrialTransfer.Intern(player);
			if (obj != null)
			{
				return (ulong)(obj.GetType().GetProperty("OwnerClientId")?.GetValue(obj) ?? ((object)ulong.MaxValue)) == sender;
			}
			return player.actualClientId == sender;
		}

		internal static PlayerControllerB Player(int slot)
		{
			if (StartOfRound.Instance?.allPlayerScripts == null || slot < 0 || slot >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				return null;
			}
			return StartOfRound.Instance.allPlayerScripts[slot];
		}

		private void Notice(ulong client, int slot, string text)
		{
			TrialPacket p = Packet(TrialMessage.Notice, 0uL);
			p.Slot = slot;
			p.Code = ((!text.StartsWith("Erst")) ? (text.StartsWith("Zu wenig") ? 1 : (text.StartsWith("Anlage") ? 2 : 3)) : 0);
			Send(client, p);
		}

		private void Begin(PlayerControllerB starter, PlayerControllerB[] candidates, int chosenMode, ulong sender)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			Vector3 origin = default(Vector3);
			((Vector3)(ref origin))..ctor(9000f, 500f, 9000f);
			if (chosenMode == 0 && !MoonLayout(starter, out origin))
			{
				Notice(sender, (int)starter.playerClientId, "Zu wenig freier, ebener Boden. Draussen eine freie Flaeche suchen.");
				return;
			}
			try
			{
				Arena.Build(chosenMode == 1, origin, bake: true);
				Physics.SyncTransforms();
				members.Clear();
				foreach (PlayerControllerB val in candidates)
				{
					members.Add(new Member
					{
						Slot = (int)val.playerClientId,
						Client = val.actualClientId,
						Return = ((Component)val).transform.position,
						Flags = Flags(val)
					});
				}
				mode = chosenMode;
				epoch++;
				Broadcast(Packet(TrialMessage.Reset, 0uL));
				localMembers.Clear();
				if (!policy.Begin(Time.time, members.Count, Mathf.Clamp(Plugin.Duration.Value, 30, 900)))
				{
					throw new InvalidOperationException("Pruefung konnte nicht gestartet werden.");
				}
				warn10 = (warn30 = false);
				finishedAt = 0f;
				startedAt = Time.time;
				foreach (Member member in members)
				{
					Broadcast(MemberPacket(member));
				}
				Broadcast(StatePacket());
				if (mode == 1)
				{
					for (int j = 0; j < members.Count; j++)
					{
						Transfer(members[j], Arena.Spawn(j), 1);
					}
				}
				Speak(0);
				Inform(entering: true);
				Plugin.Log.LogInfo((object)("CrewTrials begonnen: " + ((mode == 1) ? "Anlage" : "Mond") + ", Teilnehmer=" + members.Count));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewTrials: Start abgebrochen: " + ex));
				policy.Abort();
				foreach (Member member2 in members)
				{
					Transfer(member2, member2.Return, member2.Flags);
				}
				Clear();
				Broadcast(StatePacket());
				Notice(sender, (int)starter.playerClientId, "Anlage konnte nicht sicher erstellt werden.");
			}
		}

		private static int Flags(PlayerControllerB player)
		{
			return (int)((player.isInsideFactory ? 1u : 0u) | (uint)(player.isInElevator ? 2 : 0)) | (player.isInHangarShipRoom ? 4 : 0);
		}

		internal static bool MoonLayout(PlayerControllerB player, out Vector3 origin)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			origin = ((Component)player).transform.position + ((Component)player).transform.forward * 3f;
			if (player.isInHangarShipRoom || player.isInElevator)
			{
				return false;
			}
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(origin + Vector3.up * 2f, Vector3.down, ref val, 5f, WorldMask, (QueryTriggerInteraction)1))
			{
				return false;
			}
			origin = ((RaycastHit)(ref val)).point;
			if (Physics.CheckBox(origin + new Vector3(0f, 1.05f, 5f), new Vector3(3.4f, 0.9f, 5.4f), Quaternion.identity, WorldMask, (QueryTriggerInteraction)1))
			{
				return false;
			}
			RaycastHit val3 = default(RaycastHit);
			for (int i = -3; i <= 3; i += 3)
			{
				for (int j = 0; j <= 10; j += 2)
				{
					Vector3 val2 = origin + new Vector3((float)i, 0f, (float)j);
					if (!Physics.Raycast(val2 + Vector3.up, Vector3.down, ref val3, 2f, WorldMask, (QueryTriggerInteraction)1) || Mathf.Abs(((RaycastHit)(ref val3)).point.y - origin.y) > 0.3f)
					{
						return false;
					}
					if (Physics.CheckBox(val2 + Vector3.up * 1.05f, new Vector3(0.5f, 0.9f, 0.5f), Quaternion.identity, WorldMask, (QueryTriggerInteraction)1))
					{
						return false;
					}
				}
			}
			return true;
		}

		private TrialPacket MemberPacket(Member member)
		{
			TrialPacket result = Packet(TrialMessage.Participant, (ulong)member.Slot + 1uL);
			result.Slot = member.Slot;
			return result;
		}

		private TrialPacket StatePacket()
		{
			//IL_0047: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			TrialPacket result = Packet(TrialMessage.State, 0uL);
			result.A = (int)policy.Phase;
			result.B = members.Count;
			result.Code = mode;
			result.Position = Arena.Origin;
			result.Vector = new Vector3((float)Math.Max(0.0, policy.Deadline - (double)Time.time), (float)policy.HeldSeconds, (float)policy.SequenceProgress);
			return result;
		}

		private void Transfer(Member member, Vector3 position, int flags)
		{
			//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)
			TrialPacket p = Packet(TrialMessage.Transfer, (ulong)member.Slot + 1uL);
			p.Slot = member.Slot;
			p.Position = position;
			p.Code = flags;
			Broadcast(p);
		}

		private void Speak(int cue, Vector3? position = null)
		{
			//IL_0055: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			TrialPacket p = Packet(TrialMessage.Speech, 0uL);
			p.Code = cue;
			p.Position = (Vector3)(((??)position) ?? (Arena.Origin + new Vector3(0f, 1f, (float)((mode == 1) ? 15 : 4))));
			Broadcast(p);
		}

		private void Apply(TrialPacket p)
		{
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			switch (p.Kind)
			{
			case TrialMessage.Participant:
				if (p.Slot >= 0)
				{
					localMembers.Add(p.Slot);
				}
				break;
			case TrialMessage.State:
				if (p.A < 0 || p.A > 6 || p.B < 0 || p.B > 16 || p.Code < 0 || p.Code > 1)
				{
					break;
				}
				Phase = (TrialPhase)p.A;
				Count = p.B;
				remaining = p.Vector.x;
				held = p.Vector.y;
				sequence = (int)p.Vector.z;
				stateAt = Time.time;
				if (Phase >= TrialPhase.Sequence && Phase <= TrialPhase.Exit)
				{
					if (!Arena.Exists || Arena.Enclosed != (p.Code == 1) || Vector3.Distance(Arena.Origin, p.Position) > 0.01f)
					{
						Arena.Build(p.Code == 1, p.Position, bake: true);
					}
					Arena.Apply(Phase);
				}
				else if (Arena.Exists)
				{
					Arena.Apply(Phase);
				}
				if (Phase == TrialPhase.Idle)
				{
					Arena.Clear();
					localMembers.Clear();
				}
				break;
			case TrialMessage.Transfer:
				if (localMembers.Contains(p.Slot) && p.Code >= 0 && p.Code <= 7)
				{
					TrialTransfer.Move(Player(p.Slot), p.Position, p.Code);
				}
				break;
			case TrialMessage.Cargo:
				if (!TryCargo(p) && (pendingCargo.ContainsKey(p.Source) || pendingCargo.Count < 256))
				{
					pendingCargo[p.Source] = new DeferredCargo
					{
						Packet = p,
						Until = Time.time + 10f
					};
				}
				break;
			case TrialMessage.Speech:
				TrialPresentation.Say(p.Code, p.Position, p.Code == 4 || p.Code == 5 || p.Code == 6);
				break;
			case TrialMessage.Damage:
				if (localMembers.Contains(p.Slot))
				{
					TrialTransfer.Damage(Player(p.Slot), p.Code);
				}
				break;
			case TrialMessage.Notice:
				if ((Object)(object)Player(p.Slot) == (Object)(object)round?.localPlayerController)
				{
					HUDManager instance = HUDManager.Instance;
					if (instance != null)
					{
						instance.DisplayTip("Crew-Pruefung", (p.Code == 0) ? "Erst landen, dann den Rekorder benutzen." : ((p.Code == 1) ? "Zu wenig freie, ebene Flaeche. Draussen mit 10m Platz erneut versuchen." : ((p.Code == 2) ? "Anlage konnte nicht sicher erstellt werden. Niemand wird eingeschlossen." : "Eine Pruefung laeuft noch, 30s Abklingzeit, oder Aktion gerade blockiert.")), false, false, "LC_Tip1");
					}
				}
				break;
			}
		}

		private bool TryCargo(TrialPacket p)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager obj = manager;
			if (((obj != null) ? obj.SpawnManager : null) == null || !manager.SpawnManager.SpawnedObjects.TryGetValue(p.Source, out var value))
			{
				return false;
			}
			TrialTransfer.Cargo(((Component)value).GetComponent<GrabbableObject>(), p.Position, p.Code);
			pendingCargo.Remove(p.Source);
			return true;
		}

		public void Update()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				if (messaging != null)
				{
					messaging.UnregisterNamedMessageHandler("TGamerT.CrewTrials.v1");
					messaging = null;
					manager = null;
					round = null;
					Clear();
					recorders.Clear();
					replay.Clear();
					epoch = 1;
					serial = (requestSerial = 0);
					delivered = false;
				}
				return;
			}
			if (singleton.CustomMessagingManager != messaging)
			{
				if (messaging != null)
				{
					messaging.UnregisterNamedMessageHandler("TGamerT.CrewTrials.v1");
				}
				manager = singleton;
				messaging = singleton.CustomMessagingManager;
				messaging.RegisterNamedMessageHandler("TGamerT.CrewTrials.v1", new HandleNamedMessageDelegate(Receive));
			}
			if ((Object)(object)round != (Object)(object)StartOfRound.Instance)
			{
				round = StartOfRound.Instance;
				if (Server && policy.Active)
				{
					policy.Abort();
					Finish(ship: true);
				}
				Clear();
				delivered = false;
				if (Server)
				{
					epoch++;
					Broadcast(Packet(TrialMessage.Reset, 0uL));
					Broadcast(StatePacket());
				}
				else
				{
					SendHost(RequestPacket(TrialMessage.Sync));
				}
			}
			KeyValuePair<ulong, DeferredCargo>[] array = pendingCargo.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<ulong, DeferredCargo> keyValuePair = array[i];
				if (keyValuePair.Value.Packet.Epoch != epoch || Time.time >= keyValuePair.Value.Until || TryCargo(keyValuePair.Value.Packet))
				{
					pendingCargo.Remove(keyValuePair.Key);
				}
			}
			if (!Server || (Object)(object)round == (Object)null)
			{
				return;
			}
			if (policy.Active && (round.shipIsLeaving || round.firingPlayersCutsceneRunning || round.inShipPhase))
			{
				policy.Abort();
				Finish(ship: true);
			}
			if (!delivered && Plugin.Samples.Value && (Object)(object)round.localPlayerController != (Object)null && round.localPlayerController.isPlayerControlled && (Object)(object)round.middleOfShipNode != (Object)null)
			{
				delivered = true;
				Object.Instantiate<GameObject>(Plugin.RecorderPrefab, round.middleOfShipNode.position + new Vector3(0.3f, 0.35f, 1.4f), Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
			}
			if (policy.Active)
			{
				bool participantLost = members.Any((Member m) => !Alive(Player(m.Slot)) || (TrialTransfer.Intern(Player(m.Slot)) == null && !manager.ConnectedClients.ContainsKey(m.Client)));
				bool distinctPlateOccupants = PlatesOccupied();
				bool everyoneAtExit = members.All((Member m) => At(Player(m.Slot), Arena.Exit, 1.9f, 1.4f));
				TrialPhase phase = policy.Phase;
				policy.Tick(Time.time, distinctPlateOccupants, everyoneAtExit, participantLost);
				if (!policy.Active)
				{
					Finish(ship: false);
					return;
				}
				if (phase != policy.Phase)
				{
					Changed();
				}
				if (!warn30 && policy.Deadline - (double)Time.time <= 30.0)
				{
					warn30 = true;
					Speak(7);
				}
				if (!warn10 && policy.Deadline - (double)Time.time <= 10.0)
				{
					warn10 = true;
					Speak(8);
				}
				if (Time.time >= nextState)
				{
					nextState = Time.time + 0.25f;
					Broadcast(StatePacket());
				}
			}
			else if (finishedAt > 0f && Time.time >= finishedAt + 5f)
			{
				Clear();
				Broadcast(StatePacket());
			}
		}

		internal bool PlatesOccupied()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if (!Arena.Exists || Arena.Plates == null)
			{
				return false;
			}
			if (members.Count == 1)
			{
				return Arena.Plates.Any((Vector3 plate) => At(Player(members[0].Slot), plate, 0.9f, 0.9f));
			}
			foreach (Member member in members)
			{
				if (!At(Player(member.Slot), Arena.Plates[0], 0.9f, 0.9f))
				{
					continue;
				}
				if (members.Count == 1)
				{
					return true;
				}
				foreach (Member member2 in members)
				{
					if (member.Slot != member2.Slot && At(Player(member2.Slot), Arena.Plates[1], 0.9f, 0.9f))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool At(PlayerControllerB player, Vector3 target, float x, float z)
		{
			//IL_000e: 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)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (Alive(player) && Mathf.Abs(((Component)player).transform.position.x - target.x) <= x && Mathf.Abs(((Component)player).transform.position.z - target.z) <= z)
			{
				return Mathf.Abs(((Component)player).transform.position.y - target.y) < 1.3f;
			}
			return false;
		}

		private void Changed()
		{
			Broadcast(StatePacket());
			Speak((policy.Phase != TrialPhase.Plates) ? 3 : ((members.Count > 1) ? 1 : 2));
			Inform(entering: false);
		}

		private void Inform(bool entering)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			string text = ((policy.Phase == TrialPhase.Sequence) ? "Druecke echte Interaktionsschalter in Reihenfolge BLAU, ROT, GELB (use_world_object)." : ((policy.Phase == TrialPhase.Plates) ? "Fuenf Sekunden auf einer noch freien gelben Bodenplatte stehen. Die andere Person nimmt die andere Platte." : "Mit allen Teilnehmern drei Sekunden auf dem gruenen Ausgang stehen."));
			string text2 = ((policy.Phase == TrialPhase.Sequence) ? ("Tastenpositionen: " + string.Join("; ", from x in Arena.Switches
				where x.Key < 3
				select x.Key + "=" + point(x.Value.position))) : ((policy.Phase == TrialPhase.Plates) ? ("Plattenpositionen: " + string.Join("; ", Arena.Plates.Select(point))) : ("Ausgang: " + point(Arena.Exit))));
			TrialTransfer.InformBots(members.Select((Member m) => m.Slot).ToArray(), "Echte Crew-Pruefung, Phase " + policy.Phase.ToString() + ". " + text + " " + text2 + ". Nur echte Aktionen und Positionen zaehlen. Ihr seid weiterhin Morty/Cartman; menschliche Teilnehmer bleiben Menschen. Bei Abbruch kehrt ihr sicher zurueck.", entering);
			static string point(Vector3 v)
			{
				return v.x.ToString("0.00", CultureInfo.InvariantCulture) + ", " + v.y.ToString("0.00", CultureInfo.InvariantCulture) + ", " + v.z.ToString("0.00", CultureInfo.InvariantCulture);
			}
		}

		private void Finish(bool ship)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: 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_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			Broadcast(StatePacket());
			bool flag = policy.Phase == TrialPhase.Failed;
			Vector3 val = ((mode != 1) ? (Arena.Origin + Vector3.forward * 4f) : ((ship && (Object)(object)round?.middleOfShipNode != (Object)null) ? round.middleOfShipNode.position : (members.FirstOrDefault()?.Return ?? Arena.Origin)));
			Speak((policy.Phase == TrialPhase.Won) ? 4 : ((policy.Phase == TrialPhase.Failed) ? 5 : 6), val + Vector3.up);
			if (mode == 1 && Arena.Exists)
			{
				Member member = members.FirstOrDefault();
				Vector3 val2 = ((ship && (Object)(object)round?.middleOfShipNode != (Object)null) ? round.middleOfShipNode.position : (member?.Return ?? Vector3.zero));
				int code = (ship ? 6 : (member?.Flags ?? 0));
				GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
				foreach (GrabbableObject val3 in array)
				{
					if (!((Object)(object)val3 == (Object)null) && ((NetworkBehaviour)val3).IsSpawned && !val3.isHeld && !val3.isHeldByEnemy && !((Object)(object)val3.playerHeldBy != (Object)null) && !((Object)(object)val3.parentObject != (Object)null) && InArena(((Component)val3).transform.position))
					{
						TrialPacket p = Packet(TrialMessage.Cargo, ((NetworkBehaviour)val3).NetworkObjectId);
						p.Position = val2 + Vector3.up * 0.15f;
						p.Code = code;
						Broadcast(p);
					}
				}
				foreach (Member member2 in members)
				{
					Transfer(member2, (ship && (Object)(object)round?.middleOfShipNode != (Object)null) ? (round.middleOfShipNode.position + new Vector3((float)(member2.Slot % 3 - 1) * 0.6f, 0.1f, 0f)) : member2.Return, ship ? 6 : member2.Flags);
				}
			}
			if (flag && !ship)
			{
				foreach (Member member3 in members)
				{
					TrialPacket p2 = Packet(TrialMessage.Damage, (ulong)member3.Slot + 1uL);
					p2.Slot = member3.Slot;
					p2.Code = Mathf.Clamp(Plugin.FailureDamage.Value, 0, 50);
					Broadcast(p2);
				}
			}
			TrialTransfer.InformBots(members.Select((Member x) => x.Slot).ToArray(), "Die Crew-Pruefung ist beendet: " + policy.Phase.ToString() + ". Ihr koennt wieder normale Aufgaben uebernehmen.", entering: true);
			finishedAt = Time.time;
			nextStart = Time.time + 30f;
			Plugin.Log.LogInfo((object)("CrewTrials beendet: " + policy.Phase.ToString() + ", Abflug=" + ship));
		}

		private bool InArena(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = position - Arena.Origin;
			if (Mathf.Abs(val.x) < 30f && val.z > -30f && val.z < 60f)
			{
				return Mathf.Abs(val.y) < 30f;
			}
			return false;
		}

		private void Clear()
		{
			Arena.Clear();
			TrialPresentation.Clear();
			policy = new TrialPolicy();
			Phase = TrialPhase.Idle;
			Count = 0;
			members.Clear();
			localMembers.Clear();
			pendingCargo.Clear();
			requests.Clear();
			inputDue.Clear();
			syncDue.Clear();
			finishedAt = 0f;
		}

		public void OnDestroy()
		{
			if (messaging != null)
			{
				messaging.UnregisterNamedMessageHandler("TGamerT.CrewTrials.v1");
			}
			Clear();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal enum TrialMessage : byte
	{
		Use = 1,
		Press = 2,
		Sync = 3,
		Reset = 128,
		State = 129,
		Transfer = 130,
		Cargo = 131,
		Speech = 132,
		Damage = 133,
		Participant = 134,
		Notice = 135
	}
	internal struct TrialPacket
	{
		internal TrialMessage Kind;

		internal int Epoch;

		internal int Sequence;

		internal int Slot;

		internal int Code;

		internal int A;

		internal int B;

		internal ulong Source;

		internal Vector3 Position;

		internal Vector3 Vector;

		internal FastBufferWriter Write()
		{
			//IL_001a: 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_0032: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_006e: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b0: 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_00c6: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter result = default(FastBufferWriter);
			((FastBufferWriter)(ref result))..ctor(96, (Allocator)2, -1);
			byte b = 1;
			byte kind = (byte)Kind;
			((FastBufferWriter)(ref result)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<byte>(ref kind, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Epoch, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Sequence, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Slot, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Code, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref A, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref B, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<ulong>(ref Source, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe(ref Position);
			((FastBufferWriter)(ref result)).WriteValueSafe(ref Vector);
			return result;
		}

		internal static TrialPacket Read(FastBufferReader reader)
		{
			//IL_0006: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0073: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00e6: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			byte b = default(byte);
			((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
			byte b2 = default(byte);
			((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b2, default(ForPrimitives));
			if (b == 1)
			{
				switch (b2)
				{
				case 1:
				case 2:
				case 3:
				case 128:
				case 129:
				case 130:
				case 131:
				case 132:
				case 133:
				case 134:
				case 135:
				{
					TrialPacket result = new TrialPacket
					{
						Kind = (TrialMessage)b2
					};
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.Epoch, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.Sequence, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.Slot, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.Code, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.A, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref result.B, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref result.Source, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe(ref result.Position);
					((FastBufferReader)(ref reader)).ReadValueSafe(ref result.Vector);
					if (result.Epoch < 0 || result.Sequence < 1 || result.Slot < -1 || result.Slot > 255 || !Finite(result.Position) || !Finite(result.Vector))
					{
						throw new ArgumentException("Invalid trial packet");
					}
					return result;
				}
				}
			}
			throw new ArgumentException("Unknown trial protocol");
		}

		private static bool Finite(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (TrialPolicy.Finite(v.x) && TrialPolicy.Finite(v.y) && TrialPolicy.Finite(v.z) && Math.Abs(v.x) < 100000f && Math.Abs(v.y) < 100000f)
			{
				return Math.Abs(v.z) < 100000f;
			}
			return false;
		}
	}
	internal enum TrialPhase
	{
		Idle,
		Sequence,
		Plates,
		Exit,
		Won,
		Failed,
		Aborted
	}
	internal sealed class TrialPolicy
	{
		private double lastTick;

		private double lastPress = -100.0;

		internal TrialPhase Phase { get; private set; }

		internal double Deadline { get; private set; }

		internal int SequenceProgress { get; private set; }

		internal double HeldSeconds { get; private set; }

		internal int Participants { get; private set; }

		internal bool Active
		{
			get
			{
				if (Phase >= TrialPhase.Sequence)
				{
					return Phase <= TrialPhase.Exit;
				}
				return false;
			}
		}

		internal int RequiredPlates
		{
			get
			{
				if (Participants <= 1)
				{
					return 1;
				}
				return 2;
			}
		}

		internal bool Begin(double now, int participants, double duration)
		{
			if (Active || !Finite(now) || participants < 1 || participants > 16 || !Finite(duration) || duration < 30.0 || duration > 900.0)
			{
				return false;
			}
			Phase = TrialPhase.Sequence;
			Deadline = now + duration;
			Participants = participants;
			SequenceProgress = 0;
			HeldSeconds = 0.0;
			lastTick = now;
			lastPress = -100.0;
			return true;
		}

		internal bool Press(int button, double now)
		{
			if (Phase != TrialPhase.Sequence || !Finite(now) || now < lastPress + 0.25 || now >= Deadline || button < 0 || button > 2)
			{
				return false;
			}
			lastPress = now;
			int num = ((SequenceProgress == 0) ? 2 : ((SequenceProgress != 1) ? 1 : 0));
			if (button != num)
			{
				SequenceProgress = 0;
				Deadline = Math.Max(now, Deadline - 5.0);
				return false;
			}
			SequenceProgress++;
			if (SequenceProgress == 3)
			{
				Phase = TrialPhase.Plates;
				HeldSeconds = 0.0;
				lastTick = now;
			}
			return true;
		}

		internal void Tick(double now, bool distinctPlateOccupants, bool everyoneAtExit, bool participantLost)
		{
			if (!Active || !Finite(now))
			{
				return;
			}
			if (participantLost || now >= Deadline)
			{
				Phase = TrialPhase.Failed;
				HeldSeconds = 0.0;
				return;
			}
			double num = Math.Max(0.0, Math.Min(0.25, now - lastTick));
			lastTick = now;
			if (Phase == TrialPhase.Plates)
			{
				HeldSeconds = (distinctPlateOccupants ? (HeldSeconds + num) : 0.0);
				if (HeldSeconds >= 5.0)
				{
					Phase = TrialPhase.Exit;
					HeldSeconds = 0.0;
				}
			}
			else if (Phase == TrialPhase.Exit)
			{
				HeldSeconds = (everyoneAtExit ? (HeldSeconds + num) : 0.0);
				if (HeldSeconds >= 3.0)
				{
					Phase = TrialPhase.Won;
				}
			}
		}

		internal void Abort()
		{
			if (Active)
			{
				Phase = TrialPhase.Aborted;
				HeldSeconds = 0.0;
			}
		}

		internal static bool Finite(double n)
		{
			if (!double.IsNaN(n))
			{
				return !double.IsInfinity(n);
			}
			return false;
		}

		internal static bool Admission(bool host, bool alive, bool owner, bool held, bool busy, bool landed, bool active, int count, double distance, bool clear)
		{
			return host && alive && owner && held && !busy && landed && !active && count >= 1 && count <= 16 && Finite(distance) && distance >= 0.0 && distance <= 3.0 && clear;
		}
	}
	internal sealed class TrialReplay
	{
		private readonly Dictionary<(byte, ulong), int> seen = new Dictionary<(byte, ulong), int>();

		private int epoch;

		private int highest;

		private int floor;

		internal bool Reset(int generation, int sequence)
		{
			if (generation < 1 || sequence < 1 || generation < epoch || (generation == epoch && sequence <= highest))
			{
				return false;
			}
			epoch = generation;
			floor = (highest = sequence);
			seen.Clear();
			return true;
		}

		internal bool Admit(int generation, int sequence, byte kind, ulong source)
		{
			if (generation != epoch || sequence <= floor)
			{
				return false;
			}
			(byte, ulong) key = (kind, source);
			if (seen.TryGetValue(key, out var value) && sequence <= value)
			{
				return false;
			}
			seen[key] = sequence;
			highest = Math.Max(highest, sequence);
			return true;
		}

		internal void Clear()
		{
			seen.Clear();
			epoch = 0;
			floor = (highest = 0);
		}
	}
	public sealed class TrialPresentation : MonoBehaviour
	{
		private static AudioSource speaker;

		private static GameObject soundRoot;

		private static readonly Dictionary<int, AudioClip> clips = new Dictionary<int, AudioClip>();

		private static readonly Queue<int> queue = new Queue<int>();

		private static Vector3 soundAt;

		private static float nextClip;

		internal static AudioClip Clip(int cue)
		{
			if (clips.TryGetValue(cue, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CrewTrials.Audio." + cue + ".wav");
			if (stream == null)
			{
				return null;
			}
			using BinaryReader binaryReader = new BinaryReader(stream);
			if (new string(binaryReader.ReadChars(4)) != "RIFF")
			{
				throw new InvalidDataException("Not a wave resource");
			}
			binaryReader.ReadInt32();
			binaryReader.ReadChars(4);
			int num = 22050;
			int num2 = 1;
			int num3 = 16;
			byte[] array = null;
			while (stream.Position + 8 <= stream.Length)
			{
				string text = new string(binaryReader.ReadChars(4));
				int num4 = binaryReader.ReadInt32();
				long num5 = stream.Position + num4;
				if (num4 < 0 || num5 > stream.Length)
				{
					throw new InvalidDataException("Invalid audio resource chunk");
				}
				if (text == "fmt ")
				{
					if (binaryReader.ReadInt16() != 1)
					{
						throw new InvalidDataException("Only PCM audio");
					}
					num2 = binaryReader.ReadInt16();
					num = binaryReader.ReadInt32();
					binaryReader.ReadInt32();
					binaryReader.ReadInt16();
					num3 = binaryReader.ReadInt16();
				}
				else if (text == "data")
				{
					array = binaryReader.ReadBytes(num4);
				}
				stream.Position = num5 + num4 % 2;
			}
			if (array == null || num3 != 16 || num2 != 1 || array.Length > 8000000)
			{
				throw new InvalidDataException("Invalid trial PCM");
			}
			float[] array2 = new float[array.Length / 2];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = (float)(short)(array[i * 2] | (array[i * 2 + 1] << 8)) / 32768f;
			}
			value = AudioClip.Create("CrewTrials_Announcement_" + cue, array2.Length, 1, num, false);
			value.SetData(array2, 0);
			clips[cue] = value;
			return value;
		}

		internal static void Say(int cue, Vector3 position, bool priority = false)
		{
			//IL_0038: 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)
			if (cue < 0 || cue > 9)
			{
				return;
			}
			if (priority)
			{
				queue.Clear();
				if ((Object)(object)speaker != (Object)null)
				{
					speaker.Stop();
				}
				nextClip = 0f;
			}
			soundAt = position;
			if (queue.Count < 4)
			{
				queue.Enqueue(cue);
			}
		}

		internal static void Clear()
		{
			queue.Clear();
			if ((Object)(object)soundRoot != (Object)null)
			{
				Object.Destroy((Object)(object)soundRoot);
			}
			soundRoot = null;
			speaker = null;
			nextClip = 0f;
		}

		public void Update()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (queue.Count != 0 && !(Time.time < nextClip))
			{
				if ((Object)(object)speaker == (Object)null)
				{
					soundRoot = new GameObject("CrewTrials_Announcer");
					speaker = soundRoot.AddComponent<AudioSource>();
					speaker.playOnAwake = false;
					speaker.spatialBlend = 1f;
					speaker.minDistance = 6f;
					speaker.maxDistance = 45f;
					speaker.volume = 0.8f;
				}
				soundRoot.transform.position = soundAt;
				AudioClip val = Clip(queue.Dequeue());
				if (!((Object)(object)val == (Object)null))
				{
					speaker.PlayOneShot(val);
					nextClip = Time.time + val.length + 0.15f;
				}
			}
		}

		public void OnGUI()
		{
			//IL_007e: 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_0098: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			TrialNet instance = TrialNet.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.LocalParticipant)
			{
				string text = ((instance.Phase == TrialPhase.Sequence) ? "I: BLAU > ROT > GELB" : ((instance.Phase != TrialPhase.Plates) ? ((instance.Phase == TrialPhase.Exit) ? "III: ALLE ZUM AUSGANG - 3 SEKUNDEN" : ((instance.Phase == TrialPhase.Won) ? "PRUEFUNG BESTANDEN" : ((instance.Phase == TrialPhase.Failed) ? "PRUEFUNG GESCHEITERT" : "PRUEFUNG ABGEBROCHEN"))) : ((instance.Count > 1) ? "II: ZWEI PLATTEN - 5 SEKUNDEN" : "II: EINE PLATTE - 5 SEKUNDEN")));
				Color color = GUI.color;
				GUI.color = new Color(0.06f, 0.07f, 0.06f, 0.9f);
				GUI.Box(new Rect((float)(Screen.width / 2 - 235), 22f, 470f, 100f), "");
				GUI.color = new Color(0.85f, 0.9f, 0.78f);
				GUI.Label(new Rect((float)(Screen.width / 2 - 220), 30f, 450f, 24f), "CREW-PRUEFUNG | " + Mathf.CeilToInt(instance.Remaining) + " s | " + instance.Count + " Teilnehmer");
				GUI.Label(new Rect((float)(Screen.width / 2 - 220), 57f, 450f, 24f), text);
				GUI.Label(new Rect((float)(Screen.width / 2 - 220), 82f, 450f, 24f), "Fortschritt: " + instance.ProgressText + "   |   Roter Schalter = Notaus");
				GUI.color = color;
			}
		}

		public void OnDestroy()
		{
			Clear();
		}
	}
	internal static class TrialTransfer
	{
		internal static object Intern(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			try
			{
				object obj = Type.GetType("LethalInternship.SharedAbstractions.ManagerProviders.InternManagerProvider, LethalInternship.SharedAbstractio