Decompiled source of LethalCCTV v1.3.0

LethalCCTV.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 System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using DunGen;
using DunGen.Graph;
using DunGen.Tags;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCCTV.NetcodePatcher;
using LethalCompanyInputUtils.Api;
using LethalLib.Modules;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;
using Y4NGZ.Compatibility;
using Y4NGZCompany.Bootstrap;
using Y4NGZCompany.Core;
using Y4NGZCompany.Core.Compat;
using Y4NGZCompany.Facility.Cameras;
using Y4NGZCompany.Facility.Cameras.Placement;
using Y4NGZCompany.Facility.Cameras.Probe;
using Y4NGZCompany.Facility.Interior;
using Y4NGZCompany.Facility.Interior.Placement;
using Y4NGZCompany.Facility.Interior.Placement.Authored;
using Y4NGZCompany.Facility.Mainframe;
using Y4NGZCompany.Facility.Security;
using Y4NGZCompany.Facility.Shared;
using Y4NGZCompany.Facility.Stash;
using Y4NGZCompany.ShipSystems.Rendering;
using Y4NGZCompany.ShipSystems.Surveillance;
using Y4NGZCompany.ShipSystems.Surveillance.OutlineEffect;
using Y4NGZCore.Diagnostics;
using Y4NGZCore.Lifecycle;
using Y4NGZCore.Modules;
using Y4NGZCore.Modules.Net;
using Y4NGZCore.Modules.Objectives;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalCCTV")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Y4NGZ surveillance and CCTV systems")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+6f44b085df0098adc5a88045ff9b04daa05d9ad9")]
[assembly: AssemblyProduct("LethalCCTV")]
[assembly: AssemblyTitle("LethalCCTV")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 Y4NGZ.Compatibility
{
	internal sealed class SlidingLeafJambClipper
	{
		private sealed class LeafMesh
		{
			internal MeshFilter Filter;

			internal Mesh Source;

			internal Mesh Working;

			internal Vector3[] Vertices;

			internal Vector3[] Normals;

			internal Vector4[] Tangents;

			internal Vector2[] Uv;

			internal Vector2[] Uv2;

			internal Color32[] Colors;

			internal int[][] SubMeshes;

			internal float[] Distances;

			internal bool ShowingSource;
		}

		private const float KeepEpsilon = 0.0005f;

		private readonly Transform _space;

		private readonly float _outwardSign;

		private readonly float _jambX;

		private readonly List<LeafMesh> _meshes;

		private readonly List<Vector3> _outVertices = new List<Vector3>();

		private readonly List<Vector3> _outNormals = new List<Vector3>();

		private readonly List<Vector4> _outTangents = new List<Vector4>();

		private readonly List<Vector2> _outUv = new List<Vector2>();

		private readonly List<Vector2> _outUv2 = new List<Vector2>();

		private readonly List<Color32> _outColors = new List<Color32>();

		private readonly List<int> _outIndices = new List<int>();

		private readonly int[] _polygon = new int[4];

		private bool _disposed;

		private SlidingLeafJambClipper(Transform space, float outwardSign, float jambX, List<LeafMesh> meshes)
		{
			_space = space;
			_outwardSign = outwardSign;
			_jambX = jambX;
			_meshes = meshes;
		}

		internal static SlidingLeafJambClipper TryCreate(Transform leaf, Transform space, float outwardSign, float jambX, out string failure)
		{
			//IL_00e1: 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_00ff: Expected O, but got Unknown
			failure = null;
			if ((Object)(object)leaf == (Object)null || (Object)(object)space == (Object)null)
			{
				failure = "missing leaf or gate space";
				return null;
			}
			outwardSign = ((outwardSign < 0f) ? (-1f) : 1f);
			List<LeafMesh> list = new List<LeafMesh>();
			MeshFilter[] componentsInChildren = ((Component)leaf).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null);
				if ((Object)(object)val2 == (Object)null || val2.vertexCount == 0)
				{
					continue;
				}
				if (!val2.isReadable)
				{
					failure = "mesh '" + ((Object)val2).name + "' is not readable";
					continue;
				}
				Vector3[] vertices = val2.vertices;
				int num = vertices.Length;
				int[][] array = new int[val2.subMeshCount][];
				for (int j = 0; j < array.Length; j++)
				{
					array[j] = val2.GetTriangles(j);
				}
				Mesh val3 = new Mesh
				{
					name = ((Object)val2).name + "_JambClipped"
				};
				val3.MarkDynamic();
				list.Add(new LeafMesh
				{
					Filter = val,
					Source = val2,
					Working = val3,
					Vertices = vertices,
					Normals = SizedOrNull(val2.normals, num),
					Tangents = SizedOrNull(val2.tangents, num),
					Uv = SizedOrNull(val2.uv, num),
					Uv2 = SizedOrNull(val2.uv2, num),
					Colors = SizedOrNull(val2.colors32, num),
					SubMeshes = array,
					Distances = new float[num],
					ShowingSource = true
				});
			}
			if (list.Count == 0)
			{
				if (failure == null)
				{
					failure = "no mesh filters under the leaf";
				}
				return null;
			}
			failure = null;
			return new SlidingLeafJambClipper(space, outwardSign, jambX, list);
		}

		internal void Apply()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//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_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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (_disposed || (Object)(object)_space == (Object)null)
			{
				return;
			}
			Matrix4x4 worldToLocalMatrix = _space.worldToLocalMatrix;
			for (int i = 0; i < _meshes.Count; i++)
			{
				LeafMesh leafMesh = _meshes[i];
				if ((Object)(object)leafMesh.Filter == (Object)null || (Object)(object)leafMesh.Working == (Object)null)
				{
					continue;
				}
				Matrix4x4 val = worldToLocalMatrix * ((Component)leafMesh.Filter).transform.localToWorldMatrix;
				Vector3[] vertices = leafMesh.Vertices;
				float[] distances = leafMesh.Distances;
				bool flag = false;
				bool flag2 = false;
				for (int j = 0; j < vertices.Length; j++)
				{
					Vector3 val2 = vertices[j];
					float num = val.m00 * val2.x + val.m01 * val2.y + val.m02 * val2.z + val.m03;
					if ((distances[j] = _outwardSign * (_jambX - num)) >= -0.0005f)
					{
						flag2 = true;
					}
					else
					{
						flag = true;
					}
				}
				if (!flag)
				{
					ShowSource(leafMesh);
				}
				else if (!flag2)
				{
					leafMesh.Working.Clear();
					ShowWorking(leafMesh);
				}
				else
				{
					BuildClipped(leafMesh);
					ShowWorking(leafMesh);
				}
			}
		}

		internal void Restore()
		{
			for (int i = 0; i < _meshes.Count; i++)
			{
				ShowSource(_meshes[i]);
			}
		}

		internal void Dispose()
		{
			if (_disposed)
			{
				return;
			}
			_disposed = true;
			Restore();
			for (int i = 0; i < _meshes.Count; i++)
			{
				if ((Object)(object)_meshes[i].Working != (Object)null)
				{
					Object.Destroy((Object)(object)_meshes[i].Working);
				}
				_meshes[i].Working = null;
			}
		}

		private static void ShowSource(LeafMesh leaf)
		{
			if (!leaf.ShowingSource && !((Object)(object)leaf.Filter == (Object)null))
			{
				leaf.Filter.sharedMesh = leaf.Source;
				leaf.ShowingSource = true;
			}
		}

		private static void ShowWorking(LeafMesh leaf)
		{
			if (leaf.ShowingSource && !((Object)(object)leaf.Filter == (Object)null))
			{
				leaf.Filter.sharedMesh = leaf.Working;
				leaf.ShowingSource = false;
			}
		}

		private void BuildClipped(LeafMesh leaf)
		{
			_outVertices.Clear();
			_outNormals.Clear();
			_outTangents.Clear();
			_outUv.Clear();
			_outUv2.Clear();
			_outColors.Clear();
			Mesh working = leaf.Working;
			working.Clear();
			int num = leaf.SubMeshes.Length;
			List<int>[] array = new List<int>[num];
			for (int i = 0; i < num; i++)
			{
				_outIndices.Clear();
				int[] array2 = leaf.SubMeshes[i];
				for (int j = 0; j + 2 < array2.Length; j += 3)
				{
					ClipTriangle(leaf, array2[j], array2[j + 1], array2[j + 2]);
				}
				array[i] = new List<int>(_outIndices);
			}
			working.SetVertices(_outVertices);
			if (leaf.Normals != null)
			{
				working.SetNormals(_outNormals);
			}
			if (leaf.Tangents != null)
			{
				working.SetTangents(_outTangents);
			}
			if (leaf.Uv != null)
			{
				working.SetUVs(0, _outUv);
			}
			if (leaf.Uv2 != null)
			{
				working.SetUVs(1, _outUv2);
			}
			if (leaf.Colors != null)
			{
				working.SetColors(_outColors);
			}
			working.subMeshCount = num;
			for (int k = 0; k < num; k++)
			{
				working.SetTriangles(array[k], k, false);
			}
			working.RecalculateBounds();
		}

		private void ClipTriangle(LeafMesh leaf, int a, int b, int c)
		{
			float[] distances = leaf.Distances;
			bool flag = distances[a] >= -0.0005f;
			bool flag2 = distances[b] >= -0.0005f;
			bool flag3 = distances[c] >= -0.0005f;
			if (flag && flag2 && flag3)
			{
				int item = Emit(leaf, a);
				int item2 = Emit(leaf, b);
				int item3 = Emit(leaf, c);
				_outIndices.Add(item);
				_outIndices.Add(item2);
				_outIndices.Add(item3);
			}
			else if (flag || flag2 || flag3)
			{
				int corners = 0;
				AppendEdge(leaf, a, b, flag, flag2, ref corners);
				AppendEdge(leaf, b, c, flag2, flag3, ref corners);
				AppendEdge(leaf, c, a, flag3, flag, ref corners);
				for (int i = 1; i + 1 < corners; i++)
				{
					_outIndices.Add(_polygon[0]);
					_outIndices.Add(_polygon[i]);
					_outIndices.Add(_polygon[i + 1]);
				}
			}
		}

		private void AppendEdge(LeafMesh leaf, int from, int to, bool fromIn, bool toIn, ref int corners)
		{
			if (fromIn)
			{
				_polygon[corners++] = Emit(leaf, from);
			}
			if (fromIn != toIn)
			{
				float num = leaf.Distances[from];
				float num2 = leaf.Distances[to];
				float num3 = num - num2;
				float t = ((Mathf.Abs(num3) > 1E-09f) ? Mathf.Clamp01(num / num3) : 0.5f);
				_polygon[corners++] = EmitLerp(leaf, from, to, t);
			}
		}

		private int Emit(LeafMesh leaf, int index)
		{
			//IL_0018: 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_0056: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			int count = _outVertices.Count;
			_outVertices.Add(leaf.Vertices[index]);
			if (leaf.Normals != null)
			{
				_outNormals.Add(leaf.Normals[index]);
			}
			if (leaf.Tangents != null)
			{
				_outTangents.Add(leaf.Tangents[index]);
			}
			if (leaf.Uv != null)
			{
				_outUv.Add(leaf.Uv[index]);
			}
			if (leaf.Uv2 != null)
			{
				_outUv2.Add(leaf.Uv2[index]);
			}
			if (leaf.Colors != null)
			{
				_outColors.Add(leaf.Colors[index]);
			}
			return count;
		}

		private int EmitLerp(LeafMesh leaf, int from, int to, float t)
		{
			//IL_0018: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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)
			int count = _outVertices.Count;
			_outVertices.Add(Vector3.LerpUnclamped(leaf.Vertices[from], leaf.Vertices[to], t));
			if (leaf.Normals != null)
			{
				Vector3 val = Vector3.LerpUnclamped(leaf.Normals[from], leaf.Normals[to], t);
				_outNormals.Add((((Vector3)(ref val)).sqrMagnitude > 1E-12f) ? ((Vector3)(ref val)).normalized : leaf.Normals[from]);
			}
			if (leaf.Tangents != null)
			{
				Vector4 item = Vector4.LerpUnclamped(leaf.Tangents[from], leaf.Tangents[to], t);
				item.w = leaf.Tangents[from].w;
				_outTangents.Add(item);
			}
			if (leaf.Uv != null)
			{
				_outUv.Add(Vector2.LerpUnclamped(leaf.Uv[from], leaf.Uv[to], t));
			}
			if (leaf.Uv2 != null)
			{
				_outUv2.Add(Vector2.LerpUnclamped(leaf.Uv2[from], leaf.Uv2[to], t));
			}
			if (leaf.Colors != null)
			{
				_outColors.Add(Color32.Lerp(leaf.Colors[from], leaf.Colors[to], t));
			}
			return count;
		}

		private static T[] SizedOrNull<T>(T[] array, int expectedLength)
		{
			if (array == null || array.Length != expectedLength)
			{
				return null;
			}
			return array;
		}
	}
}
namespace LethalCCTV
{
	[BepInPlugin("com.y4ngz.company.lethalcctv", "LethalCCTV", "1.3.0")]
	[BepInDependency("com.y4ngz.core", "1.0.10")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class LethalCCTVPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.y4ngz.company.lethalcctv";

		public const string PluginName = "LethalCCTV";

		public const string PluginVersion = "1.3.0";

		public const int CctvProtocolRevision = 3;

		private SurveillanceBootstrap _host;

		internal const string HostObjectName = "LethalCCTV_Host";

		public static LethalCCTVPlugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			DependencyVersionAudit.RunForLethalCCTV(((BaseUnityPlugin)this).Logger);
			NetcodeRuntimeBootstrap.Initialize(((BaseUnityPlugin)this).Logger, typeof(LethalCCTVPlugin).Assembly, true);
			ModuleHandshakeService.Publish("cctv", 3, "1.3.0");
			GameObject val = new GameObject("LethalCCTV_Host")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)(object)val);
			_host = val.AddComponent<SurveillanceBootstrap>();
			_host.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			Log.LogInfo((object)"LethalCCTV 1.3.0 loaded.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalCCTV";

		public const string PLUGIN_NAME = "LethalCCTV";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace Y4NGZCompany.ShipSystems.Surveillance
{
	[HarmonyPatch(typeof(HUDManager), "PingScan_performed")]
	internal static class CameraOperatorPingScanPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref CallbackContext context)
		{
			if (!MonitorFocus.IsFocused)
			{
				return true;
			}
			_ = Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive;
			return false;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "UpdateScanNodes")]
	internal static class CameraOperatorScanNodesPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !MonitorFocus.IsFocused;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ActivateItem_performed")]
	internal static class CameraOperatorActivateItemPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !MonitorFocus.IsFocused;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ActivateItem_canceled")]
	internal static class CameraOperatorActivateItemCancelPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !MonitorFocus.IsFocused;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")]
	internal static class CameraOperatorJumpPerformedPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance)
		{
			return !MonitorFocus.ShouldSuppressPlayerInput(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	internal static class CameraOperatorPlayerUpdatePatch
	{
		[HarmonyPrefix]
		private static void Prefix(PlayerControllerB __instance)
		{
			if (MonitorFocus.ShouldSuppressPlayerInput(__instance))
			{
				MonitorFocus.ApplyFocusInputLock(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "PlayerLookInput")]
	internal static class CameraOperatorPlayerLookInputPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance)
		{
			return !MonitorFocus.ShouldSuppressPlayerInput(__instance);
		}
	}
	internal static class CCTVAccessButton
	{
		private const string RootName = "LethalCCTV_AccessButton";

		private const string TemplateChildName = "ButtonContainer/ButtonAnimContainer";

		private const string RedButtonChildName = "RedButton";

		private const string HoverTip = "View cameras : [LMB]";

		private const string PressTriggerName = "press";

		private const string GlassOpenBoolName = "GlassOpen";

		private const float StateRefreshIntervalSeconds = 0.2f;

		private const float PressSfxVolume = 0.9f;

		private const string ScanNodeName = "LethalCCTV_AccessButtonScanNode";

		private const string ScanNodeHeader = "CCTV Station";

		private const string ScanNodeSubText = "View cameras";

		private const int ScanNodeMaxRange = 8;

		private const int ScanNodeFallbackLayer = 22;

		private static GameObject _root;

		private static Animator _buttonAnimator;

		private static InteractTrigger _trigger;

		private static AudioSource _audio;

		private static AudioClip _pressSfx;

		private static UnityAction<PlayerControllerB> _listener;

		private static float _nextStateRefreshAt;

		private static bool _templateMissingLogged;

		private static bool _spawnLogged;

		internal static bool IsAvailable
		{
			get
			{
				if ((Object)(object)_root != (Object)null)
				{
					return (Object)(object)_trigger != (Object)null;
				}
				return false;
			}
		}

		internal static Transform Root
		{
			get
			{
				if (!((Object)(object)_root != (Object)null))
				{
					return null;
				}
				return _root.transform;
			}
		}

		internal static Transform PressContactTransform
		{
			get
			{
				if (!((Object)(object)_trigger != (Object)null))
				{
					return null;
				}
				return ((Component)_trigger).transform;
			}
		}

		internal static bool TryGetPressSurface(out Vector3 point, out Vector3 normal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			point = Vector3.zero;
			normal = Vector3.up;
			Transform pressContactTransform = PressContactTransform;
			if ((Object)(object)pressContactTransform == (Object)null)
			{
				return false;
			}
			Vector3 bestAxis = pressContactTransform.up;
			float bestScore = Mathf.Abs(Vector3.Dot(bestAxis, Vector3.up));
			ConsiderAxis(pressContactTransform.right);
			ConsiderAxis(pressContactTransform.forward);
			if (Vector3.Dot(bestAxis, Vector3.up) < 0f)
			{
				bestAxis = -bestAxis;
			}
			normal = ((((Vector3)(ref bestAxis)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref bestAxis)).normalized : Vector3.up);
			Renderer val = ((Component)pressContactTransform).GetComponent<Renderer>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)pressContactTransform).GetComponentInChildren<Renderer>(true);
			}
			if ((Object)(object)val == (Object)null)
			{
				point = pressContactTransform.position + normal * 0.015f;
				return true;
			}
			Bounds bounds = val.bounds;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			float num = Mathf.Abs(normal.x) * extents.x + Mathf.Abs(normal.y) * extents.y + Mathf.Abs(normal.z) * extents.z;
			point = ((Bounds)(ref bounds)).center + normal * num;
			return true;
			void ConsiderAxis(Vector3 candidate)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references)
				float num2 = Mathf.Abs(Vector3.Dot(candidate, Vector3.up));
				if (!(num2 <= bestScore))
				{
					bestAxis = candidate;
					bestScore = num2;
				}
			}
		}

		internal static void Ensure(Transform stationRoot)
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)stationRoot == (Object)null || (Object)(object)_root != (Object)null)
			{
				return;
			}
			AudioClip pressSfx;
			Transform val = ResolveTemplateButtonContainer(out pressSfx);
			if ((Object)(object)val == (Object)null)
			{
				if (!_templateMissingLogged)
				{
					_templateMissingLogged = true;
					ManualLogSource log = SurveillanceBootstrap.Log;
					if (log != null)
					{
						log.LogWarning((object)"[LethalCCTV] Access button template unavailable (teleporter unlockable prefab or ButtonContainer not found); red bezel button remains the CCTV entry.");
					}
				}
				return;
			}
			GameObject val2;
			try
			{
				val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, stationRoot, false);
			}
			catch (Exception ex)
			{
				if (!_templateMissingLogged)
				{
					_templateMissingLogged = true;
					ManualLogSource log2 = SurveillanceBootstrap.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[LethalCCTV] Access button clone failed: " + ex.Message));
					}
				}
				return;
			}
			((Object)val2).name = "LethalCCTV_AccessButton";
			_root = val2;
			_pressSfx = pressSfx;
			StripClonedBehaviours(val2);
			_buttonAnimator = val2.GetComponentInChildren<Animator>(true);
			_audio = val2.AddComponent<AudioSource>();
			_audio.playOnAwake = false;
			_audio.spatialBlend = 1f;
			_audio.minDistance = 0.8f;
			_audio.maxDistance = 12f;
			WireInteractTrigger(val2);
			CCTVOperatorStation.ApplyAccessButtonPlacement(val2.transform);
			BuildScanNode(val2);
			if ((Object)(object)_buttonAnimator != (Object)null)
			{
				_buttonAnimator.SetBool("GlassOpen", true);
			}
			if (_spawnLogged)
			{
				return;
			}
			_spawnLogged = true;
			ManualLogSource log3 = SurveillanceBootstrap.Log;
			if (log3 != null)
			{
				string[] obj = new string[8]
				{
					$"[LethalCCTV] Access button spawned from teleporter template: local={val2.transform.localPosition} ",
					"trigger=",
					((Object)(object)_trigger != (Object)null) ? "wired" : "MISSING",
					" animator=",
					null,
					null,
					null,
					null
				};
				object obj2;
				if (!((Object)(object)_buttonAnimator != (Object)null))
				{
					obj2 = "MISSING";
				}
				else
				{
					RuntimeAnimatorController runtimeAnimatorController = _buttonAnimator.runtimeAnimatorController;
					obj2 = ((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "<none>";
				}
				obj[4] = (string)obj2;
				obj[5] = " pressSfx=";
				obj[6] = (((Object)(object)_pressSfx != (Object)null) ? ((Object)_pressSfx).name : "<none>");
				obj[7] = ".";
				log3.LogInfo((object)string.Concat(obj));
			}
		}

		internal static void Shutdown()
		{
			if ((Object)(object)_trigger != (Object)null && _listener != null && _trigger.onInteract != null)
			{
				((UnityEvent<PlayerControllerB>)(object)_trigger.onInteract).RemoveListener(_listener);
			}
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_buttonAnimator = null;
			_trigger = null;
			_audio = null;
			_pressSfx = null;
			_listener = null;
			_nextStateRefreshAt = 0f;
			_spawnLogged = false;
		}

		internal static void Tick()
		{
			if ((Object)(object)_trigger == (Object)null || Time.unscaledTime < _nextStateRefreshAt)
			{
				return;
			}
			_nextStateRefreshAt = Time.unscaledTime + 0.2f;
			if ((Object)(object)_buttonAnimator != (Object)null)
			{
				try
				{
					_buttonAnimator.SetBool("GlassOpen", true);
				}
				catch
				{
				}
			}
			if (CCTVMonitorFeedSync.IsEntryAvailable(out var unavailableReason))
			{
				_trigger.interactable = true;
				_trigger.hoverTip = "View cameras : [LMB]";
			}
			else
			{
				_trigger.interactable = false;
				_trigger.disabledHoverTip = unavailableReason ?? string.Empty;
			}
		}

		internal static void PlayPressAnimation()
		{
			if ((Object)(object)_buttonAnimator != (Object)null)
			{
				try
				{
					_buttonAnimator.SetBool("GlassOpen", true);
					_buttonAnimator.ResetTrigger("press");
					_buttonAnimator.SetTrigger("press");
				}
				catch (Exception ex)
				{
					ManualLogSource log = SurveillanceBootstrap.Log;
					if (log != null)
					{
						log.LogDebug((object)("[LethalCCTV] Access button press animation failed: " + ex.Message));
					}
				}
			}
			if ((Object)(object)_audio != (Object)null && (Object)(object)_pressSfx != (Object)null)
			{
				_audio.PlayOneShot(_pressSfx, 0.9f);
			}
		}

		private static void BuildScanNode(GameObject clone)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)_trigger != (Object)null) ? ((Component)_trigger).transform : clone.transform);
			GameObject val2 = new GameObject("LethalCCTV_AccessButtonScanNode");
			val2.transform.SetParent(clone.transform, false);
			val2.transform.position = val.position;
			int num = LayerMask.NameToLayer("ScanNode");
			val2.layer = ((num >= 0) ? num : 22);
			try
			{
				val2.tag = "DoNotSet";
			}
			catch (UnityException)
			{
			}
			SphereCollider obj = val2.AddComponent<SphereCollider>();
			((Collider)obj).isTrigger = true;
			obj.radius = 0.3f;
			ScanNodeProperties obj2 = val2.AddComponent<ScanNodeProperties>();
			obj2.headerText = "CCTV Station";
			obj2.subText = "View cameras";
			obj2.minRange = 0;
			obj2.maxRange = 8;
			obj2.requiresLineOfSight = false;
			obj2.nodeType = 0;
			obj2.scrapValue = 0;
			obj2.creatureScanID = -1;
		}

		private static void OnPressed(PlayerControllerB player)
		{
			CCTVVanillaMonitorButtons.RequestEntry(player);
		}

		private static Transform ResolveTemplateButtonContainer(out AudioClip pressSfx)
		{
			pressSfx = null;
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.unlockablesList == (Object)null || instance.unlockablesList.unlockables == null)
			{
				return null;
			}
			for (int i = 0; i < instance.unlockablesList.unlockables.Count; i++)
			{
				GameObject val = instance.unlockablesList.unlockables[i]?.prefabObject;
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				ShipTeleporter component = val.GetComponent<ShipTeleporter>();
				if (!((Object)(object)component == (Object)null) && !component.isInverseTeleporter)
				{
					Transform val2 = val.transform.Find("ButtonContainer/ButtonAnimContainer");
					if (!((Object)(object)val2 == (Object)null))
					{
						pressSfx = component.buttonPressSFX;
						return val2;
					}
				}
			}
			return null;
		}

		private static void StripClonedBehaviours(GameObject clone)
		{
			MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && (!(val is InteractTrigger) || !string.Equals(((Object)((Component)val).gameObject).name, "RedButton", StringComparison.Ordinal)))
				{
					Object.Destroy((Object)(object)val);
				}
			}
			Transform val2 = FindChildRecursive(clone.transform, "ButtonGlass");
			if ((Object)(object)val2 != (Object)null)
			{
				Collider[] components = ((Component)val2).GetComponents<Collider>();
				for (int j = 0; j < components.Length; j++)
				{
					Object.Destroy((Object)(object)components[j]);
				}
			}
		}

		private static void WireInteractTrigger(GameObject clone)
		{
			Transform val = FindChildRecursive(clone.transform, "RedButton");
			_trigger = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<InteractTrigger>() : null);
			if ((Object)(object)_trigger == (Object)null)
			{
				ManualLogSource log = SurveillanceBootstrap.Log;
				if (log != null)
				{
					log.LogWarning((object)"[LethalCCTV] Access button clone has no RedButton InteractTrigger; entry stays on the bezel button.");
				}
				return;
			}
			if (_trigger.onInteract != null)
			{
				int persistentEventCount = ((UnityEventBase)_trigger.onInteract).GetPersistentEventCount();
				for (int i = 0; i < persistentEventCount; i++)
				{
					((UnityEventBase)_trigger.onInteract).SetPersistentListenerState(i, (UnityEventCallState)0);
				}
			}
			_listener = OnPressed;
			((UnityEvent<PlayerControllerB>)(object)_trigger.onInteract).AddListener(_listener);
			_trigger.hoverTip = "View cameras : [LMB]";
			_trigger.interactable = true;
		}

		private static Transform FindChildRecursive(Transform root, string childName)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			if (string.Equals(((Object)root).name, childName, StringComparison.Ordinal))
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindChildRecursive(root.GetChild(i), childName);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class CctvCommandTargetBridge
	{
		internal sealed class TargetInfo
		{
			internal Component Component;

			internal string DisplayName;

			internal string CommandHint;

			internal Vector3 Position;

			internal float Radius;
		}

		private const string ApiTypeName = "Y4NGZCompany.Facility.Security.CctvCommandTargetApi, LethalCCTV";

		private static Type _apiType;

		private static bool _resolved;

		private static MethodInfo _describeTargetMethod;

		private static MethodInfo _getActiveTargetsMethod;

		private static MethodInfo _executeCommandMethod;

		internal static bool TryDescribeTarget(Component component, out TargetInfo info)
		{
			info = null;
			Resolve();
			if (_describeTargetMethod == null || (Object)(object)component == (Object)null)
			{
				return false;
			}
			try
			{
				object descriptor = _describeTargetMethod.Invoke(null, new object[1] { component });
				info = ReadDescriptor(descriptor);
				return info != null;
			}
			catch
			{
				return false;
			}
		}

		internal static List<TargetInfo> GetActiveTargets()
		{
			Resolve();
			List<TargetInfo> list = new List<TargetInfo>();
			if (_getActiveTargetsMethod == null)
			{
				return list;
			}
			try
			{
				if (!(_getActiveTargetsMethod.Invoke(null, Array.Empty<object>()) is IEnumerable enumerable))
				{
					return list;
				}
				foreach (object item in enumerable)
				{
					TargetInfo targetInfo = ReadDescriptor(item);
					if (targetInfo != null)
					{
						list.Add(targetInfo);
					}
				}
			}
			catch
			{
			}
			return list;
		}

		internal static bool TryExecuteCommand(Component component, string command, out string statusText)
		{
			statusText = "UNSUPPORTED TARGET";
			Resolve();
			if (_executeCommandMethod == null || (Object)(object)component == (Object)null)
			{
				return false;
			}
			try
			{
				object obj = _executeCommandMethod.Invoke(null, new object[2]
				{
					component,
					command ?? string.Empty
				});
				if (obj == null)
				{
					statusText = "NO RESPONSE";
					return false;
				}
				statusText = ReadString(obj, "StatusText", "COMMAND FAILED");
				return ReadBool(obj, "Success", fallback: false);
			}
			catch
			{
				statusText = "COMMAND FAILED";
				return false;
			}
		}

		internal static bool TryFindMainframeTarget(out Component target, out string displayName, out string commandHint)
		{
			target = null;
			displayName = "MAINFRAME";
			commandHint = "hack";
			Resolve();
			if (_apiType == null)
			{
				return false;
			}
			try
			{
				object obj = null;
				PropertyInfo propertyInfo = _apiType.GetProperty("MainframeSupport", BindingFlags.Static | BindingFlags.Public) ?? _apiType.GetProperty("Mainframe", BindingFlags.Static | BindingFlags.Public);
				if (propertyInfo != null)
				{
					obj = propertyInfo.GetValue(null);
				}
				if (obj == null)
				{
					PropertyInfo propertyInfo2 = Type.GetType("Y4NGZCompany.Facility.Mainframe.MainframeSupport, LethalCCTV", throwOnError: false)?.GetProperty("Active", BindingFlags.Static | BindingFlags.Public);
					if (propertyInfo2 != null)
					{
						obj = propertyInfo2.GetValue(null);
					}
				}
				if (obj == null || !ReadBool(obj, "IsPhysicalMainframe", fallback: true))
				{
					return false;
				}
				target = (Component)((obj is Component) ? obj : null);
				if ((Object)(object)target == (Object)null)
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static void Resolve()
		{
			if (!_resolved || !(_apiType != null))
			{
				_resolved = true;
				_apiType = Type.GetType("Y4NGZCompany.Facility.Security.CctvCommandTargetApi, LethalCCTV", throwOnError: false);
				_describeTargetMethod = _apiType?.GetMethod("DescribeTarget", BindingFlags.Static | BindingFlags.Public);
				_getActiveTargetsMethod = _apiType?.GetMethod("GetActiveTargets", BindingFlags.Static | BindingFlags.Public);
				_executeCommandMethod = _apiType?.GetMethod("ExecuteCommand", BindingFlags.Static | BindingFlags.Public);
			}
		}

		private static TargetInfo ReadDescriptor(object descriptor)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (descriptor == null)
			{
				return null;
			}
			Component val = ReadComponent(descriptor, "Target");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return new TargetInfo
			{
				Component = val,
				DisplayName = ReadString(descriptor, "DisplayName", "SUPPORT NODE"),
				CommandHint = ReadString(descriptor, "CommandHint", string.Empty),
				Position = ReadVector3(descriptor, "Position", val.transform.position),
				Radius = Mathf.Clamp(ReadFloat(descriptor, "Radius", 0.9f), 0.35f, 4f)
			};
		}

		private static Component ReadComponent(object target, string memberName)
		{
			object obj = ReadMember(target, memberName);
			return (Component)((obj is Component) ? obj : null);
		}

		private static string ReadString(object target, string memberName, string fallback)
		{
			return (ReadMember(target, memberName) as string) ?? fallback;
		}

		private static bool ReadBool(object target, string memberName, bool fallback)
		{
			object obj = ReadMember(target, memberName);
			if (obj is bool)
			{
				return (bool)obj;
			}
			return fallback;
		}

		private static float ReadFloat(object target, string memberName, float fallback)
		{
			object obj = ReadMember(target, memberName);
			if (obj is float)
			{
				return (float)obj;
			}
			if (obj is double num)
			{
				return (float)num;
			}
			return fallback;
		}

		private static Vector3 ReadVector3(object target, string memberName, Vector3 fallback)
		{
			//IL_0019: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			object obj = ReadMember(target, memberName);
			if (obj is Vector3)
			{
				return (Vector3)obj;
			}
			return fallback;
		}

		private static object ReadMember(object target, string memberName)
		{
			if (target == null)
			{
				return null;
			}
			Type type = target.GetType();
			PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public);
			if (property != null)
			{
				return property.GetValue(target);
			}
			return type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public)?.GetValue(target);
		}
	}
	internal static class CctvControlGeometry
	{
		internal static readonly Vector3 BlueButton = new Vector3(2.14224f, -3.48693f, 0.8256f);

		internal static readonly Vector3 GreenButton = new Vector3(5.93751f, 4.87375f, -1.69817f);

		internal static readonly Vector3 RedButton = new Vector3(0.27866f, 4.76938f, 3.2164f);

		internal static readonly Vector3 ButtonNormal;

		internal static Quaternion PalmDown(Vector3 normal, Vector3 fingersForward)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(fingersForward, normal);
			return Quaternion.LookRotation(normal, ((Vector3)(ref val)).normalized);
		}

		internal static bool TryLeverHandleTop(Transform transform, Mesh mesh, out Vector3 top)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002d: 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_00e9: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0125: 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_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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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_0072: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_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_00de: Unknown result type (might be due to invalid IL or missing references)
			top = default(Vector3);
			if ((Object)(object)mesh == (Object)null || mesh.subMeshCount < 2)
			{
				return false;
			}
			SubMeshDescriptor subMesh = mesh.GetSubMesh(1);
			Bounds bounds = ((SubMeshDescriptor)(ref subMesh)).bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (((Vector3)(ref size)).sqrMagnitude < 1E-06f)
			{
				return false;
			}
			if (mesh.isReadable)
			{
				Vector3[] vertices = mesh.vertices;
				int[] indices = mesh.GetIndices(1);
				if (indices.Length == 0)
				{
					return false;
				}
				Bounds val = default(Bounds);
				((Bounds)(ref val))..ctor(transform.TransformPoint(vertices[indices[0]]), Vector3.zero);
				int[] array = indices;
				foreach (int num in array)
				{
					((Bounds)(ref val)).Encapsulate(transform.TransformPoint(vertices[num]));
				}
				top = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y, ((Bounds)(ref val)).center.z);
			}
			else
			{
				Vector3 val2 = transform.TransformVector(Vector3.right * ((Bounds)(ref bounds)).extents.x);
				Vector3 val3 = transform.TransformVector(Vector3.up * ((Bounds)(ref bounds)).extents.y);
				Vector3 val4 = transform.TransformVector(Vector3.forward * ((Bounds)(ref bounds)).extents.z);
				float num2 = Mathf.Sqrt(val2.y * val2.y + val3.y * val3.y + val4.y * val4.y);
				if (num2 < 0.0001f)
				{
					return false;
				}
				top = transform.TransformPoint(((Bounds)(ref bounds)).center) + Vector3.up * num2;
			}
			return true;
		}

		internal static Vector3 FitMonitorEye(Vector3 eye, Quaternion rotation, Vector3 center, Vector3 right, Vector3 up, float halfWidth, float halfHeight, float fov, float aspect)
		{
			//IL_0029: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0074: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Tan(fov * 0.5f * (MathF.PI / 180f));
			float num2 = num * Mathf.Max(0.25f, aspect);
			float num3 = 0f;
			Quaternion val = Quaternion.Inverse(rotation);
			for (int i = -1; i <= 1; i += 2)
			{
				for (int j = -1; j <= 1; j += 2)
				{
					Vector3 val2 = center + right * (halfWidth * (float)i) + up * (halfHeight * (float)j);
					Vector3 val3 = val * (val2 - eye);
					num3 = Mathf.Max(num3, Mathf.Abs(val3.x) / (num2 * 0.84f) - val3.z);
					num3 = Mathf.Max(num3, Mathf.Abs(val3.y) / (num * 0.84f) - val3.z);
				}
			}
			return eye - rotation * Vector3.forward * Mathf.Max(0f, num3);
		}

		internal static bool TryKeepElbowBehindWrist(Vector3 center, Vector3 aim, float radius, Vector3 proposed, Vector3 wrist, Vector3 forward, out Vector3 elbow)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00af: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			elbow = proposed;
			if (Vector3.Dot(proposed - wrist, forward) <= 0f)
			{
				return true;
			}
			Vector3 val = Vector3.ProjectOnPlane(forward, aim);
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (radius < 1E-06f || magnitude < 1E-06f)
			{
				return false;
			}
			float num = Vector3.Dot(wrist - center, forward) / (radius * magnitude);
			if (num < -1f)
			{
				return false;
			}
			Vector3 val2 = val / magnitude;
			Vector3 val3 = Vector3.Cross(aim, val2);
			Vector3 val4 = ((Vector3)(ref val3)).normalized;
			if (Vector3.Dot(proposed - center, val4) < 0f)
			{
				val4 = -val4;
			}
			float num2 = Mathf.Clamp(num, -1f, 1f);
			elbow = center + radius * (val2 * num2 + val4 * Mathf.Sqrt(1f - num2 * num2));
			return true;
		}

		internal static Vector3 PressPosition(float seconds, Vector3 start, Vector3 rest, Vector3 contact, Vector3 normal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0029: 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_0038: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = contact + normal * 0.07f;
			if (seconds < 0.3f)
			{
				return Vector3.Lerp(start, val, Ease(seconds / 0.3f));
			}
			if (seconds < 0.44f)
			{
				return Vector3.Lerp(val, contact, Ease((seconds - 0.3f) / 0.14f));
			}
			if (seconds < 0.51f)
			{
				return contact;
			}
			if (seconds < 0.66f)
			{
				return Vector3.Lerp(contact, val, Ease((seconds - 0.51f) / 0.15f));
			}
			return Vector3.Lerp(val, rest, Ease((seconds - 0.66f) / 0.34f));
		}

		internal static Vector3 EntryHandPosition(float seconds, Vector3 rest, Vector3 contact, Vector3 grip, Vector3 normal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0029: 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_0038: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_009e: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = contact + normal * 0.055f;
			if (seconds < 0.27f)
			{
				return Vector3.Lerp(rest, val, Ease(seconds / 0.27f));
			}
			if (seconds < 0.38f)
			{
				return Vector3.Lerp(val, contact, Ease((seconds - 0.27f) / 0.109999985f));
			}
			if (seconds < 0.47f)
			{
				return contact;
			}
			if (seconds < 0.59f)
			{
				return Vector3.Lerp(contact, val, Ease((seconds - 0.47f) / 0.12f));
			}
			float num = Ease((seconds - 0.47f - 0.12f) / 0.54999995f);
			return Vector3.Lerp(val, grip, num) + normal * (0.025f * Mathf.Sin(num * MathF.PI));
		}

		internal static float Ease(float t)
		{
			return CctvIntroTiming.Ease(Mathf.Clamp01(t));
		}

		static CctvControlGeometry()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = new Vector3(0.5209f, 0.005f, 0.8536f);
			ButtonNormal = ((Vector3)(ref val)).normalized;
		}
	}
	internal static class CctvDeviceCommandLine
	{
		private static TerminalAccessibleObject _target;

		private static CCTVCamera _camera;

		private static CCTVCamera _pendingCamera;

		private static string _code;

		private static string _label;

		private static string _text = "";

		private static string _pending;

		private static Keyboard _keyboard;

		private static RectTransform _root;

		private static TextMeshProUGUI _readout;

		private static float _statusUntil;

		private static float _nextHoverAt;

		private static int _closedFrame = -1;

		internal static bool IsOpen => _keyboard != null;

		internal static bool ConsumesInput
		{
			get
			{
				if (!IsOpen)
				{
					return _closedFrame == Time.frameCount;
				}
				return true;
			}
		}

		internal static bool TryOpen(CCTVCamera camera)
		{
			if (IsOpen)
			{
				return true;
			}
			if ((Object)(object)camera?.Cam == (Object)null || camera.IsSecurityBroken || !MonitorFocus.IsStationCameraControlActive)
			{
				return false;
			}
			TerminalAccessibleObject val = CctvDeviceCommands.Hover(camera.Cam);
			if (!CctvDeviceCommands.TryDescribe(val, out var label))
			{
				return false;
			}
			if (!CCTVShipSystemsBridge.CanUseRemoteOperations(out var reason))
			{
				ShowStatus(reason);
				return true;
			}
			if (Keyboard.current == null)
			{
				ShowStatus("KEYBOARD UNAVAILABLE");
				return true;
			}
			EnsureUi();
			if ((Object)(object)_root == (Object)null)
			{
				return true;
			}
			_target = val;
			_camera = camera;
			_code = val.objectCode;
			_label = label;
			_text = "";
			_pending = null;
			_keyboard = Keyboard.current;
			_keyboard.onTextInput += OnText;
			CCTVWalkieTalkieBridge.SetLocalSpeaking(speaking: false);
			UpdateReadout();
			CCTVStationEvents.RaiseActionButtonPressed("device-command-open");
			return true;
		}

		private static void OnText(char character)
		{
			if (IsOpen && !char.IsControl(character) && _text.Length < 24)
			{
				_text += character;
				UpdateReadout();
			}
		}

		internal static void Tick()
		{
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			if (!MonitorFocus.IsFocused || (Object)(object)val == (Object)null || val.isPlayerDead || !MonitorFocus.IsFacilityFeedActive || !CCTVShipSystemsBridge.IsShipPowerOnline())
			{
				Close(clearStatus: true);
				return;
			}
			CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot);
			if ((Object)(object)boundCamera?.Cam == (Object)null || boundCamera.IsSecurityBroken)
			{
				Close(clearStatus: true);
				return;
			}
			if (_pending != null && (Object)(object)boundCamera != (Object)(object)_pendingCamera)
			{
				Close(clearStatus: true);
				return;
			}
			if (IsOpen)
			{
				bool flag = (Object)(object)_root == (Object)null;
				EnsureUi();
				if ((Object)(object)_target == (Object)null || (Object)(object)boundCamera != (Object)(object)_camera || _target.objectCode != _code)
				{
					Close(clearStatus: true);
					return;
				}
				if (flag)
				{
					UpdateReadout();
				}
				if (((ButtonControl)_keyboard.escapeKey).wasPressedThisFrame)
				{
					Close();
				}
				else if (((ButtonControl)_keyboard.enterKey).wasPressedThisFrame || ((ButtonControl)_keyboard.numpadEnterKey).wasPressedThisFrame)
				{
					Submit();
				}
				else if (((ButtonControl)_keyboard.backspaceKey).wasPressedThisFrame && _text.Length > 0)
				{
					_text = _text.Substring(0, _text.Length - 1);
					UpdateReadout();
				}
				return;
			}
			if (_pending != null && Time.unscaledTime >= _statusUntil)
			{
				_pending = null;
				ShowStatus("NO RESPONSE FROM HOST");
			}
			if (!(Time.unscaledTime < _statusUntil) && !(Time.unscaledTime < _nextHoverAt))
			{
				_nextHoverAt = Time.unscaledTime + 0.1f;
				if (CctvDeviceCommands.TryDescribe(CctvDeviceCommands.Hover(boundCamera.Cam), out var label))
				{
					EnsureUi();
					SetText(label + "   /   LMB COMMAND");
				}
				else if ((Object)(object)_root != (Object)null)
				{
					((Component)_root).gameObject.SetActive(false);
				}
			}
		}

		private static void Submit()
		{
			TerminalAccessibleObject target = _target;
			CCTVCamera camera = _camera;
			string text = _text;
			bool num = (Object)(object)target != (Object)null && target.objectCode == _code && (Object)(object)camera?.Cam != (Object)null && (Object)(object)camera == (Object)(object)QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot) && !camera.IsSecurityBroken && (Object)(object)CctvDeviceCommands.Hover(camera.Cam) == (Object)(object)target;
			Close();
			if (!num)
			{
				ShowStatus("TARGET LOST");
				return;
			}
			string text2 = text.Trim().ToLowerInvariant();
			bool num2;
			if (!target.isBigDoor)
			{
				num2 = text2 != "disable";
			}
			else
			{
				if (!(text2 != "unlock"))
				{
					goto IL_00e5;
				}
				num2 = text2 != "open";
			}
			if (num2)
			{
				ShowStatus(target.isBigDoor ? "USE UNLOCK" : "USE DISABLE");
				return;
			}
			goto IL_00e5;
			IL_00e5:
			try
			{
				if (CctvDeviceCommands.Submit(target, camera, text2) == null)
				{
					ShowStatus("HOST COMMAND CHANNEL UNAVAILABLE");
				}
			}
			catch
			{
				_pending = null;
				ShowStatus("COMMAND COULD NOT BE SENT");
			}
		}

		internal static void SetPending(string requestId, CCTVCamera camera)
		{
			_pending = requestId;
			_pendingCamera = camera;
			ShowStatus("COMMAND PENDING", 4f);
		}

		internal static void ReceiveResult(string requestId, string status)
		{
			if (!(_pending != requestId) && MonitorFocus.IsFocused)
			{
				_pending = null;
				ShowStatus(status);
			}
		}

		internal static void Close(bool clearStatus = false)
		{
			if (_keyboard != null)
			{
				_keyboard.onTextInput -= OnText;
				_keyboard = null;
				_closedFrame = Time.frameCount;
			}
			_target = null;
			_camera = null;
			_text = "";
			if (clearStatus)
			{
				_pending = null;
				_pendingCamera = null;
				_statusUntil = 0f;
			}
			if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf)
			{
				((Component)_root).gameObject.SetActive(false);
				CCTVVanillaMonitorDisplay.InvalidateMachineVisionUi();
			}
		}

		internal static void Shutdown()
		{
			Close(clearStatus: true);
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			_readout = null;
		}

		private static void ShowStatus(string status, float seconds = 2f)
		{
			_statusUntil = Time.unscaledTime + seconds;
			EnsureUi();
			SetText(status);
		}

		private static void UpdateReadout()
		{
			string text = (((Object)(object)_target != (Object)null && _target.isBigDoor) ? "unlock" : "disable");
			SetText(_label + "  >  " + _text + "_\n" + text + "   /   ENTER SEND   /   ESC CANCEL");
		}

		private static void SetText(string text)
		{
			if (!((Object)(object)_root == (Object)null) && !((Object)(object)_readout == (Object)null))
			{
				((Component)_root).gameObject.SetActive(true);
				((TMP_Text)_readout).text = text ?? "";
				CCTVVanillaMonitorDisplay.InvalidateMachineVisionUi();
			}
		}

		private static void EnsureUi()
		{
			//IL_0033: 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_009f: 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_00d1: 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_012f: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root != (Object)null))
			{
				_root = new GameObject("CCTV_DeviceCommand", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				}).GetComponent<RectTransform>();
				if (!CCTVVanillaMonitorDisplay.TryAttachToLowerLeftOverlay(((Component)_root).gameObject))
				{
					Object.Destroy((Object)(object)((Component)_root).gameObject);
					_root = null;
					return;
				}
				RectTransform root = _root;
				RectTransform root2 = _root;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0f);
				root2.anchorMax = val;
				root.anchorMin = val;
				_root.pivot = new Vector2(0.5f, 0f);
				_root.anchoredPosition = new Vector2(0f, 48f);
				_root.sizeDelta = new Vector2(510f, 48f);
				Image component = ((Component)_root).GetComponent<Image>();
				((Graphic)component).color = new Color(0.015f, 0.035f, 0.045f, 0.9f);
				((Graphic)component).raycastTarget = false;
				_readout = new GameObject("Text", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				}).GetComponent<TextMeshProUGUI>();
				((TMP_Text)_readout).transform.SetParent((Transform)(object)_root, false);
				((Component)_readout).gameObject.layer = ((Component)_root).gameObject.layer;
				((TMP_Text)_readout).rectTransform.anchorMin = Vector2.zero;
				((TMP_Text)_readout).rectTransform.anchorMax = Vector2.one;
				((TMP_Text)_readout).rectTransform.offsetMin = new Vector2(12f, 4f);
				((TMP_Text)_readout).rectTransform.offsetMax = new Vector2(-12f, -4f);
				((TMP_Text)_readout).fontSize = 13f;
				((TMP_Text)_readout).richText = false;
				((Graphic)_readout).color = new Color(0.7f, 0.94f, 0.96f);
				((TMP_Text)_readout).alignment = (TextAlignmentOptions)4097;
				((Graphic)_readout).raycastTarget = false;
			}
		}
	}
	internal enum CctvDeviceAction
	{
		Invalid,
		OpenDoor,
		AlreadyOpen,
		Unpowered,
		DisableTurret,
		Cooldown
	}
	internal static class CctvDeviceCommandPolicy
	{
		internal static CctvDeviceAction Decide(string input, bool door, bool open, bool powered, bool cooling, bool turretActive)
		{
			string text = (input ?? string.Empty).Trim();
			if (door)
			{
				if (!text.Equals("unlock", StringComparison.OrdinalIgnoreCase) && !text.Equals("open", StringComparison.OrdinalIgnoreCase))
				{
					return CctvDeviceAction.Invalid;
				}
				if (!powered)
				{
					return CctvDeviceAction.Unpowered;
				}
				if (!open)
				{
					return CctvDeviceAction.OpenDoor;
				}
				return CctvDeviceAction.AlreadyOpen;
			}
			if (!text.Equals("disable", StringComparison.OrdinalIgnoreCase))
			{
				return CctvDeviceAction.Invalid;
			}
			if (!cooling && turretActive)
			{
				return CctvDeviceAction.DisableTurret;
			}
			return CctvDeviceAction.Cooldown;
		}
	}
	[Serializable]
	public sealed class CctvDeviceCommandMessage
	{
		public bool IsResult;

		public string RequestId;

		public string Code;

		public string Command;

		public string Status;

		public ulong TargetId;

		public ulong ClientId;

		public int CameraIndex;

		public int MapSeed;

		public Vector3 CameraPosition;

		public Vector3 Direction;
	}
	internal static class CctvDeviceCommands
	{
		private static LNetworkMessage<CctvDeviceCommandMessage> _channel;

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

		private static readonly Dictionary<ulong, string> LastRequest = new Dictionary<ulong, string>();

		internal static void Initialize()
		{
			if (_channel != null)
			{
				return;
			}
			try
			{
				_channel = LNetworkMessage<CctvDeviceCommandMessage>.Connect("y4ngz_cctv_device_v1", (Action<CctvDeviceCommandMessage, ulong>)ReceiveRequest, (Action<CctvDeviceCommandMessage>)ReceiveResult, (Action<CctvDeviceCommandMessage, ulong>)null);
			}
			catch (Exception ex)
			{
				ManualLogSource log = SurveillanceBootstrap.Log;
				if (log != null)
				{
					log.LogWarning((object)("[LethalCCTV] Coded device channel unavailable: " + ex.Message));
				}
			}
		}

		internal static void Reset()
		{
			NextRequest.Clear();
			LastRequest.Clear();
			CctvDeviceCommandLine.Close(clearStatus: true);
		}

		internal static void Shutdown()
		{
			Reset();
			_channel?.ClearSubscriptions();
			_channel = null;
			CctvDeviceCommandLine.Shutdown();
		}

		internal static Turret TurretFor(TerminalAccessibleObject device)
		{
			if ((Object)(object)device == (Object)null || device.isBigDoor)
			{
				return null;
			}
			return ((Component)device).GetComponent<Turret>() ?? ((Component)device).GetComponentInParent<Turret>() ?? ((Component)device).GetComponentInChildren<Turret>();
		}

		internal static bool TryDescribe(TerminalAccessibleObject device, out string label)
		{
			label = null;
			if ((Object)(object)device == (Object)null || !((Component)device).gameObject.activeInHierarchy || string.IsNullOrWhiteSpace(device.objectCode))
			{
				return false;
			}
			bool flag = false;
			if (device.codeMaterials != null)
			{
				MeshRenderer[] codeMaterials = device.codeMaterials;
				foreach (MeshRenderer val in codeMaterials)
				{
					if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			if (!device.isBigDoor && (Object)(object)TurretFor(device) == (Object)null)
			{
				return false;
			}
			label = (device.isBigDoor ? "DOOR " : "TURRET ") + device.objectCode.ToUpperInvariant();
			return true;
		}

		internal static TerminalAccessibleObject Hover(Camera camera)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)camera == (Object)null))
			{
				return RayTarget(((Component)camera).transform.position, ((Component)camera).transform.forward);
			}
			return null;
		}

		private static TerminalAccessibleObject RayTarget(Vector3 origin, Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!CctvSquadPing.TryRayHit(origin, direction, out var hit) || ((RaycastHit)(ref hit)).distance > 60f)
			{
				return null;
			}
			TerminalAccessibleObject val = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<TerminalAccessibleObject>();
			if ((Object)(object)val == (Object)null)
			{
				Turret componentInParent = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Turret>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					val = ((Component)componentInParent).GetComponent<TerminalAccessibleObject>() ?? ((Component)componentInParent).GetComponentInChildren<TerminalAccessibleObject>();
				}
			}
			if (!TryDescribe(val, out var _))
			{
				return null;
			}
			return val;
		}

		internal static string Submit(TerminalAccessibleObject target, CCTVCamera camera, string command)
		{
			//IL_0095: 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_00ab: 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)
			if (_channel == null || (Object)(object)target == (Object)null || (Object)(object)((NetworkBehaviour)target).NetworkObject == (Object)null || !((NetworkBehaviour)target).NetworkObject.IsSpawned || (Object)(object)camera?.Cam == (Object)null)
			{
				return null;
			}
			CctvDeviceCommandMessage cctvDeviceCommandMessage = new CctvDeviceCommandMessage
			{
				RequestId = Guid.NewGuid().ToString("N"),
				TargetId = ((NetworkBehaviour)target).NetworkObjectId,
				Code = target.objectCode,
				Command = command,
				CameraIndex = camera.CameraIndex,
				CameraPosition = ((Component)camera.Cam).transform.position,
				Direction = ((Component)camera.Cam).transform.forward,
				MapSeed = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.randomMapSeed : 0)
			};
			CctvDeviceCommandLine.SetPending(cctvDeviceCommandMessage.RequestId, camera);
			_channel.SendServer(cctvDeviceCommandMessage);
			return cctvDeviceCommandMessage.RequestId;
		}

		private static void ReceiveRequest(CctvDeviceCommandMessage request, ulong sender)
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || request == null || request.IsResult || string.IsNullOrEmpty(request.RequestId) || request.RequestId.Length > 40 || (LastRequest.TryGetValue(sender, out var value) && value == request.RequestId))
			{
				return;
			}
			string status;
			if (NextRequest.TryGetValue(sender, out var value2) && Time.unscaledTime < value2)
			{
				status = "PLEASE WAIT";
			}
			else
			{
				NextRequest[sender] = Time.unscaledTime + 0.4f;
				LastRequest[sender] = request.RequestId;
				try
				{
					status = Execute(request, sender);
				}
				catch (Exception ex)
				{
					ManualLogSource log = SurveillanceBootstrap.Log;
					if (log != null)
					{
						log.LogWarning((object)("[LethalCCTV] Coded device command failed: " + ex.Message));
					}
					status = "COMMAND FAILED";
				}
			}
			_channel?.SendClients(new CctvDeviceCommandMessage
			{
				IsResult = true,
				ClientId = sender,
				RequestId = request.RequestId,
				Status = status
			});
		}

		private static string Execute(CctvDeviceCommandMessage request, ulong sender)
		{
			//IL_00b9: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: 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_01db: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: 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_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || instance.inShipPhase || instance.shipIsLeaving || request.MapSeed != instance.randomMapSeed)
			{
				return "FEED UNAVAILABLE";
			}
			PlayerControllerB val = null;
			PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
			foreach (PlayerControllerB val2 in allPlayerScripts)
			{
				if ((Object)(object)val2 != (Object)null && val2.actualClientId == sender)
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled || CCTVMonitorFeedSync.OperatorId != (int)val.playerClientId || !CCTVMonitorFeedSync.IsFeedCctv)
			{
				return "OPERATOR REQUIRED";
			}
			Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor;
			if ((Object)(object)operatorPoseAnchor == (Object)null || Vector3.Distance(((Component)val).transform.position, operatorPoseAnchor.position) > 5f)
			{
				return "OPERATOR OUT OF RANGE";
			}
			if (!CCTVShipSystemsBridge.CanUseRemoteOperations(out var reason))
			{
				return reason;
			}
			LethalCCTVConfig config = SurveillanceBootstrap.Config;
			if (config != null && config.AllowTargetScanning?.Value == false)
			{
				return "TARGET COMMANDS DISABLED BY HOST";
			}
			if (!CCTVShipSystemsBridge.IsShipPowerOnline())
			{
				return "NO SHIP POWER";
			}
			CCTVCamera cCTVCamera = null;
			if (QuadCameraAssignment.AllAssignedCameras != null)
			{
				foreach (CCTVCamera allAssignedCamera in QuadCameraAssignment.AllAssignedCameras)
				{
					if ((Object)(object)allAssignedCamera != (Object)null && allAssignedCamera.CameraIndex == request.CameraIndex)
					{
						cCTVCamera = allAssignedCamera;
						break;
					}
				}
			}
			if ((Object)(object)cCTVCamera?.Cam == (Object)null || cCTVCamera.IsSecurityBroken || !Finite(request.CameraPosition) || !Finite(request.Direction) || Vector3.Distance(((Component)cCTVCamera.Cam).transform.position, request.CameraPosition) > 0.5f || ((Vector3)(ref request.Direction)).sqrMagnitude < 0.9f || ((Vector3)(ref request.Direction)).sqrMagnitude > 1.1f)
			{
				return "FEED LOST";
			}
			Vector3 normalized = ((Vector3)(ref request.Direction)).normalized;
			float num = Mathf.Atan2(normalized.x, normalized.z) * 57.29578f;
			float num2 = (0f - Mathf.Asin(Mathf.Clamp(normalized.y, -1f, 1f))) * 57.29578f;
			if (cCTVCamera.AllowsOperatorRotation)
			{
				if (Mathf.Abs(Mathf.DeltaAngle(cCTVCamera.BaseYawDeg, num)) > (SurveillanceBootstrap.Config?.YawClampDeg ?? 80f) + 1f || num2 < -6f || num2 > (SurveillanceBootstrap.Config?.PitchClampDeg ?? 80f) + 1f)
				{
					return "OUTSIDE CAMERA VIEW";
				}
			}
			else if (Vector3.Angle(((Component)cCTVCamera.Cam).transform.forward, normalized) > 1f)
			{
				return "OUTSIDE CAMERA VIEW";
			}
			if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(request.TargetId, out var value))
			{
				return "TARGET LOST";
			}
			TerminalAccessibleObject val3 = RayTarget(((Component)cCTVCamera.Cam).transform.position, normalized);
			if (!TryDescribe(val3, out var _) || (Object)(object)((NetworkBehaviour)val3).NetworkObject != (Object)(object)value || val3.objectCode != request.Code)
			{
				return "TARGET NOT VISIBLE";
			}
			if (request.Command == null || request.Command.Length > 24)
			{
				return "INVALID COMMAND";
			}
			Turret val4 = TurretFor(val3);
			switch (CctvDeviceCommandPolicy.Decide(request.Command, val3.isBigDoor, val3.isDoorOpen, val3.isPoweredOn, val3.inCooldown, (Object)(object)val4 != (Object)null && val4.turretActive))
			{
			case CctvDeviceAction.Invalid:
				if (!val3.isBigDoor)
				{
					return "USE DISABLE";
				}
				return "USE UNLOCK";
			case CctvDeviceAction.Unpowered:
				return "DOOR UNPOWERED";
			case CctvDeviceAction.AlreadyOpen:
				return "ALREADY OPEN";
			case CctvDeviceAction.Cooldown:
				return "DEVICE IN COOLDOWN";
			default:
				if (val3.isBigDoor)
				{
					if (!CCTVShipSystemsBridge.TrySpendRemoteOperationPower())
					{
						return "INSUFFICIENT POWER";
					}
					val3.SetDoorLocalClient(true);
					if (!val3.isDoorOpen)
					{
						return "DOOR DID NOT OPEN";
					}
					return "DOOR OPEN";
				}
				if ((Object)(object)val4 == (Object)null || val3.codeAccessCooldownTimer <= 0f)
				{
					return "DEVICE UNAVAILABLE";
				}
				if (!CCTVShipSystemsBridge.TrySpendRemoteOperationPower())
				{
					return "INSUFFICIENT POWER";
				}
				val3.CallFunctionFromTerminal();
				if (val4.turretActive || !val3.inCooldown)
				{
					return "DEVICE DID NOT RESPOND";
				}
				return "TURRET TEMPORARILY DISABLED";
			}
		}

		private static bool Finite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
			{
				return !float.IsInfinity(value.z);
			}
			return false;
		}

		private static void ReceiveResult(CctvDeviceCommandMessage result)
		{
			if (result != null && result.IsResult && !((Object)(object)NetworkManager.Singleton == (Object)null) && result.ClientId == NetworkManager.Singleton.LocalClientId)
			{
				CctvDeviceCommandLine.ReceiveResult(result.RequestId, result.Status);
			}
		}
	}
	internal sealed class CctvExposure
	{
		internal bool LowLight { get; private set; }

		internal float Meter { get; private set; } = 0.18f;

		internal float Gain { get; private set; } = 1f;

		internal float NightBlend { get; private set; }

		internal void Measure(float[] luminance)
		{
			if (luminance != null && luminance.Length != 0)
			{
				Array.Sort(luminance);
				int num = luminance.Length / 20;
				int num2 = Math.Max(num + 1, luminance.Length * 9 / 10);
				double num3 = 0.0;
				for (int i = num; i < num2; i++)
				{
					num3 += Math.Log(Math.Max(0.0001, luminance[i]));
				}
				Meter = (float)Math.Exp(num3 / (double)(num2 - num));
				if (Meter < 0.045f)
				{
					LowLight = true;
				}
				else if (Meter > 0.085f)
				{
					LowLight = false;
				}
			}
		}

		internal void Tick(float seconds, float ceiling, bool enabled, bool automaticMode, bool autoGain)
		{
			float dt = Math.Max(0f, Math.Min(seconds, 0.25f));
			ceiling = Math.Max(0.5f, Math.Min(8f, ceiling));
			float num = ((enabled && (!automaticMode || LowLight)) ? 1f : 0f);
			NightBlend = Ease(NightBlend, num, dt, (num > NightBlend) ? 0.35f : 0.65f);
			float to = ((!enabled) ? 1f : (autoGain ? Math.Max(0.12f, Math.Min(ceiling, 0.18f / Meter)) : ceiling));
			Gain = Ease(Gain, to, dt, 0.5f);
		}

		private static float Ease(float from, float to, float dt, float timeConstant)
		{
			return from + (to - from) * (1f - (float)Math.Exp((0f - dt) / timeConstant));
		}
	}
	internal static class CCTVFocusControlsOverlay
	{
		private static GameObject _root;

		private static Canvas _canvas;

		private static Image _background;

		private static RectTransform _panelRect;

		private static RectTransform _textRect;

		private static TextMeshProUGUI _text;

		private static string _lastText;

		private const float PanelPaddingX = 18f;

		private const float PanelPaddingY = 12f;

		private const float PanelMinWidth = 260f;

		private const float PanelMaxWidth = 620f;

		private const float PanelMinHeight = 56f;

		private const string PlayerControlsText = "CCTV CONTROLS\nMOUSE   AIM CAMERA\nARROWS  CAMERA LIST\nSPACE   RADAR VIEW\nWHEEL   CAMERA ZOOM\nSPC+WHL RADAR ZOOM\nLMB     HACK / SQUAD PING\nV HOLD  WALKIE\nE/ESC   EXIT";

		private const string DebugControlsText = "\nH       HIDE PANEL\nF1      EDIT MENU\nF2      CAMERA EDIT";

		internal static Transform RootTransform
		{
			get
			{
				if (!((Object)(object)_root != (Object)null))
				{
					return null;
				}
				return _root.transform;
			}
		}

		private static bool ConfiguredOn
		{
			get
			{
				if (SurveillanceBootstrap.Config?.ShowOperatorControlsOverlay != null)
				{
					return SurveillanceBootstrap.Config.ShowOperatorControlsOverlay.Value;
				}
				return false;
			}
		}

		private static bool OverlayEnabled
		{
			get
			{
				if (!ConfiguredOn)
				{
					return CCTVStickyNoteItem.RegistrationFailed;
				}
				return true;
			}
		}

		internal static void Tick()
		{
			if (!OverlayEnabled)
			{
				Shutdown();
				return;
			}
			if (!MonitorFocus.IsFocused)
			{
				SetVisible(visible: false);
				return;
			}
			Ensure();
			SetVisible(visible: true);
			RefreshText();
		}

		internal static void Shutdown()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_canvas = null;
			_background = null;
			_panelRect = null;
			_textRect = null;
			_text = null;
			_lastText = null;
		}

		private static void Ensure()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root != (Object)null))
			{
				_root = new GameObject("LethalCCTV_FocusControlsOverlay", new Type[4]
				{
					typeof(RectTransform),
					typeof(Canvas),
					typeof(CanvasScaler),
					typeof(GraphicRaycaster)
				});
				Object.DontDestroyOnLoad((Object)(object)_root);
				_canvas = _root.GetComponent<Canvas>();
				_canvas.renderMode = (RenderMode)0;
				_canvas.sortingOrder = 32760;
				CanvasScaler component = _root.GetComponent<CanvasScaler>();
				component.uiScaleMode = (ScaleMode)1;
				component.referenceResolution = new Vector2(1920f, 1080f);
				component.screenMatchMode = (ScreenMatchMode)0;
				component.matchWidthOrHeight = 0.5f;
				((Behaviour)_root.GetComponent<GraphicRaycaster>()).enabled = false;
				GameObject val = new GameObject("ControlsPanel", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(Image)
				});
				val.transform.SetParent(_root.transform, false);
				_panelRect = val.GetComponent<RectTransform>();
				_panelRect.anchorMin = new Vector2(0f, 1f);
				_panelRect.anchorMax = new Vector2(0f, 1f);
				_panelRect.pivot = new Vector2(0f, 1f);
				_panelRect.anchoredPosition = new Vector2(26f, -86f);
				_panelRect.sizeDelta = new Vector2(260f, 56f);
				_background = val.GetComponent<Image>();
				((Graphic)_background).color = new Color(0f, 0f, 0f, 0.56f);
				((Graphic)_background).raycastTarget = false;
				GameObject val2 = new GameObject("ControlsText", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(TextMeshProUGUI)
				});
				val2.transform.SetParent(val.transform, false);
				_textRect = val2.GetComponent<RectTransform>();
				_textRect.anchorMin = Vector2.zero;
				_textRect.anchorMax = Vector2.one;
				_textRect.offsetMin = new Vector2(18f, 12f);
				_textRect.offsetMax = new Vector2(-18f, -12f);
				_text = val2.GetComponent<TextMeshProUGUI>();
				((Graphic)_text).raycastTarget = false;
				((TMP_Text)_text).enableWordWrapping = false;
				((TMP_Text)_text).richText = true;
				((TMP_Text)_text).alignment = (TextAlignmentOptions)257;
				((TMP_Text)_text).fontSize = 24f;
				((TMP_Text)_text).lineSpacing = -7f;
				((Graphic)_text).color = new Color(1f, 0.58f, 0.14f, 0.96f);
				TryAssignHudFont(_text);
			}
		}

		private static void RefreshText()
		{
			if ((Object)(object)_text == (Object)null)
			{
				return;
			}
			if (MonitorFocus.IsOperatorDebugToolsEnabled)
			{
				string cameraPlacementEditOverlayText = MonitorFocus.GetCameraPlacementEditOverlayText();
				if (!string.IsNullOrWhiteSpace(cameraPlacementEditOverlayText))
				{
					SetText(cameraPlacementEditOverlayText);
					return;
				}
				string stationEditMenuOverlayText = MonitorFocus.GetStationEditMenuOverlayText();
				if (!string.IsNullOrWhiteSpace(stationEditMenuOverlayText))
				{
					SetText(stationEditMenuOverlayText);
					return;
				}
				string firstPersonHandEditOverlayText = Y4NGZPlayerAnimationBridge.GetFirstPersonHandEditOverlayText();
				if (!string.IsNullOrWhiteSpace(firstPersonHandEditOverlayText))
				{
					SetText(firstPersonHandEditOverlayText);
				}
				else
				{
					SetText("CCTV CONTROLS\nMOUSE   AIM CAMERA\nARROWS  CAMERA LIST\nSPACE   RADAR VIEW\nWHEEL   CAMERA ZOOM\nSPC+WHL RADAR ZOOM\nLMB     HACK / SQUAD PING\nV HOLD  WALKIE\nE/ESC   EXIT\nH       HIDE PANEL\nF1      EDIT MENU\nF2      CAMERA EDIT");
				}
			}
			else
			{
				SetText("CCTV CONTROLS\nMOUSE   AIM CAMERA\nARROWS  CAMERA LIST\nSPACE   RADAR VIEW\nWHEEL   CAMERA ZOOM\nSPC+WHL RADAR ZOOM\nLMB     HACK / SQUAD PING\nV HOLD  WALKIE\nE/ESC   EXIT");
			}
		}

		private static void SetText(string value)
		{
			if (!(value == _lastText))
			{
				_lastText = value;
				((TMP_Text)_text).text = value;
				ResizePanelToText();
			}
		}

		private static void ResizePanelToText()
		{
			//IL_0040: Unknown result type (might be due to invalid I