Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalCCTV v1.3.0
LethalCCTV.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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