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 LethalPhonePOV v1.0.3
LethalPhonePOV/LethalPhonePOV.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using ModelReplacement; using OpenBodyCams; using OpenBodyCams.API; using Scoops.misc; using Scoops.service; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.LowLevel; using UnityEngine.PlayerLoop; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalPhonePOV")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("LethalPhonePOV")] [assembly: AssemblyTitle("LethalPhonePOV")] [assembly: AssemblyVersion("1.0.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalPhonePOV { internal static class HideAndSeekStartupGuard { private static ManualLogSource log; private static Type playerComponent; private static FieldInfo configField; private static Harmony harmony; private static bool skipReported; public static void Install(ManualLogSource logger) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown if (harmony != null || !Chainloader.PluginInfos.ContainsKey("Tibnan.LCHideAndSeekMod")) { return; } log = logger; try { playerComponent = AccessTools.TypeByName("LCHideAndSeekMod.Core.HNSPlayerComponent"); Type type = AccessTools.TypeByName("LCHideAndSeekMod.Core.Configuration.ConfigProcessor"); configField = ((type == null) ? null : AccessTools.Field(type, "Config")); if (playerComponent == null || configField == null) { throw new MissingMemberException("Hide and Seek 1.4.1 initialization members were not found."); } MethodInfo methodInfo = AccessTools.Method(typeof(BodyCamComponent).Assembly.GetType("OpenBodyCams.ShipObjects"), "LateInitialization", (Type[])null, (Type[])null); if (methodInfo == null) { throw new MissingMethodException("OpenBodyCams.ShipObjects.LateInitialization"); } harmony = new Harmony("BruhMMods.LethalPhonePOV.HideAndSeekStartup"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(HideAndSeekStartupGuard), "GuardInitialSwitch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); Application.quitting += Uninstall; log.LogInfo((object)"Guarded OpenBodyCams' initial radar switch while Hide and Seek player data is unavailable."); } catch (Exception ex) { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; log.LogWarning((object)("Hide and Seek startup guard was not installed; phone video remains independent: " + ex)); } } internal static IEnumerable<CodeInstruction> GuardInitialSwitch(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); MethodInfo original = typeof(ManualCameraRenderer).GetMethod("SwitchRadarTargetAndSync", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null); MethodInfo method = typeof(HideAndSeekStartupGuard).GetMethod("SafeInitialSwitch", BindingFlags.Static | BindingFlags.NonPublic); if (original == null || method == null) { throw new MissingMethodException("The initial radar-switch guard signature did not match."); } List<CodeInstruction> list2 = list.Where((CodeInstruction i) => (i.opcode == OpCodes.Call || i.opcode == OpCodes.Callvirt) && object.Equals(i.operand, original)).ToList(); if (list2.Count != 1) { throw new InvalidOperationException("Expected exactly one initial radar switch; found " + list2.Count + "."); } list2[0].opcode = OpCodes.Call; list2[0].operand = method; return list; } private static void SafeInitialSwitch(ManualCameraRenderer map, int index) { GameNetworkManager instance = GameNetworkManager.Instance; PlayerControllerB val = (((Object)(object)instance == (Object)null) ? null : instance.localPlayerController); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent(playerComponent) == (Object)null || configField.GetValue(null) == null) { if (!skipReported) { skipReported = true; log.LogInfo((object)"Skipped premature bodycam radar initialization: Hide and Seek player data is not ready. Normal radar switching and seeker restrictions are unchanged."); } } else { map.SwitchRadarTargetAndSync(index); } } private static void Uninstall() { Application.quitting -= Uninstall; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; } } internal static class PhoneRuntime { [CompilerGenerated] private static class <>O { public static Action <0>__Shutdown; public static UnityAction<Scene, LoadSceneMode> <1>__SceneLoaded; public static WillRenderCanvases <2>__BeforeCanvasRender; public static UpdateFunction <3>__LoopUpdate; } private static ManualLogSource log; private static IVideoSession video; private static SessionCoordinator coordinator; private static bool running; private static bool inTick; private static bool loopReported; private static bool canvasReported; private static int lastLoopFrame = -1; private static float retryAfter; private static float nextErrorLog; private static float nextLoopCheck; public static void Start(ManualLogSource logger, IVideoSession session) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown if (running) { logger.LogWarning((object)"Ignoring a duplicate phone-video bootstrap; the existing runtime remains active."); return; } log = logger; video = session; coordinator = new SessionCoordinator(session); running = true; loopReported = (canvasReported = (inTick = false)); lastLoopFrame = -1; retryAfter = (nextErrorLog = (nextLoopCheck = 0f)); Application.quitting += Shutdown; SceneManager.sceneLoaded += SceneLoaded; object obj = <>O.<2>__BeforeCanvasRender; if (obj == null) { WillRenderCanvases val = BeforeCanvasRender; <>O.<2>__BeforeCanvasRender = val; obj = (object)val; } Canvas.preWillRenderCanvases += (WillRenderCanvases)obj; EnsureLoop(); log.LogInfo((object)"Video runtime initialized; player-loop and pre-canvas callbacks registered."); } private static void EnsureLoop() { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!running) { return; } PlayerLoopSystem system = PlayerLoop.GetCurrentPlayerLoop(); if (!PlayerLoopRegistration.Contains(system)) { object obj = <>O.<3>__LoopUpdate; if (obj == null) { UpdateFunction val = LoopUpdate; <>O.<3>__LoopUpdate = val; obj = (object)val; } if (!PlayerLoopRegistration.Insert(ref system, (UpdateFunction)obj)) { log.LogWarning((object)"Unity late-update phase not found; using the pre-canvas video driver."); return; } PlayerLoop.SetPlayerLoop(system); log.LogInfo((object)"Installed phone-video callback before Unity script LateUpdate."); } } private static void SceneLoaded(Scene scene, LoadSceneMode mode) { if (!running) { return; } try { EnsureLoop(); log.LogInfo((object)("Phone-video runtime active after scene load: " + ((Scene)(ref scene)).name + ".")); } catch (Exception ex) { log.LogError((object)("Could not verify phone-video frame driver: " + ex)); } } private static void LoopUpdate() { lastLoopFrame = Time.frameCount; Tick(canvasFallback: false); } private static void BeforeCanvasRender() { if (!running || inTick || lastLoopFrame == Time.frameCount) { return; } Tick(canvasFallback: true); if (Time.realtimeSinceStartup < nextLoopCheck) { return; } nextLoopCheck = Time.realtimeSinceStartup + 5f; try { EnsureLoop(); } catch (Exception ex) { log.LogWarning((object)("Video loop check failed; pre-canvas driver remains active: " + ex)); } } private static void Tick(bool canvasFallback) { if (!running || inTick) { return; } inTick = true; try { if (canvasFallback && !canvasReported) { canvasReported = true; log.LogInfo((object)"Video runtime tick via Unity pre-canvas fallback."); } if (!canvasFallback && !loopReported) { loopReported = true; log.LogInfo((object)"Video runtime tick via Unity player loop."); } if (!(Time.realtimeSinceStartup < retryAfter)) { coordinator.Tick(Time.frameCount); } } catch (Exception ex) { retryAfter = Time.realtimeSinceStartup + 1f; if (Time.realtimeSinceStartup >= nextErrorLog) { nextErrorLog = Time.realtimeSinceStartup + 10f; log.LogError((object)("Phone video update failed; retrying in one second: " + ex)); } try { coordinator.Reset(); video.Close(); } catch (Exception ex2) { log.LogWarning((object)("Video recovery cleanup failed: " + ex2)); } } finally { inTick = false; } } public static void BootstrapDestroyed() { if (running) { log.LogWarning((object)"Phone-video bootstrap component received OnDestroy; the independent frame driver remains active. Disable General/Enabled in its config to turn video off during this process."); } } public static void Shutdown() { //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_0075: Expected O, but got Unknown //IL_007c: 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_008d: Unknown result type (might be due to invalid IL or missing references) if (!running) { return; } running = false; Application.quitting -= Shutdown; SceneManager.sceneLoaded -= SceneLoaded; object obj = <>O.<2>__BeforeCanvasRender; if (obj == null) { WillRenderCanvases val = BeforeCanvasRender; <>O.<2>__BeforeCanvasRender = val; obj = (object)val; } Canvas.preWillRenderCanvases -= (WillRenderCanvases)obj; try { PlayerLoopSystem system = PlayerLoop.GetCurrentPlayerLoop(); if (PlayerLoopRegistration.Remove(ref system)) { PlayerLoop.SetPlayerLoop(system); } } catch (Exception ex) { log.LogWarning((object)("Could not detach phone-video loop: " + ex)); } try { coordinator.Reset(); video.Close(); } catch (Exception ex2) { log.LogWarning((object)("Could not finish video cleanup: " + ex2)); } coordinator = null; video = null; log.LogInfo((object)"Phone-video runtime stopped."); } } internal static class PlayerLoopRegistration { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct PhoneVideoUpdate { } public static bool Contains(PlayerLoopSystem system) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (system.type == typeof(PhoneVideoUpdate)) { return true; } if (system.subSystemList == null) { return false; } PlayerLoopSystem[] subSystemList = system.subSystemList; foreach (PlayerLoopSystem system2 in subSystemList) { if (Contains(system2)) { return true; } } return false; } public static bool Insert(ref PlayerLoopSystem system, UpdateFunction callback) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (Contains(system)) { return true; } return InsertBefore(ref system, typeof(ScriptRunBehaviourLateUpdate), new PlayerLoopSystem { type = typeof(PhoneVideoUpdate), updateDelegate = callback }); } private static bool InsertBefore(ref PlayerLoopSystem system, Type target, PlayerLoopSystem entry) { //IL_0079: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) PlayerLoopSystem[] subSystemList = system.subSystemList; if (subSystemList == null) { return false; } for (int i = 0; i < subSystemList.Length; i++) { if (subSystemList[i].type == target) { PlayerLoopSystem[] array = (PlayerLoopSystem[])(object)new PlayerLoopSystem[subSystemList.Length + 1]; Array.Copy(subSystemList, 0, array, 0, i); array[i] = entry; Array.Copy(subSystemList, i, array, i + 1, subSystemList.Length - i); system.subSystemList = array; return true; } PlayerLoopSystem system2 = subSystemList[i]; if (InsertBefore(ref system2, target, entry)) { PlayerLoopSystem[] array2 = (PlayerLoopSystem[])subSystemList.Clone(); array2[i] = system2; system.subSystemList = array2; return true; } } return false; } public static bool Remove(ref PlayerLoopSystem system) { //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_0035: 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_0058: 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) PlayerLoopSystem[] subSystemList = system.subSystemList; if (subSystemList == null) { return false; } List<PlayerLoopSystem> list = new List<PlayerLoopSystem>(subSystemList.Length); bool flag = false; PlayerLoopSystem[] array = subSystemList; foreach (PlayerLoopSystem val in array) { if (val.type == typeof(PhoneVideoUpdate)) { flag = true; continue; } PlayerLoopSystem system2 = val; flag |= Remove(ref system2); list.Add(system2); } if (flag) { system.subSystemList = list.ToArray(); } return flag; } } [BepInPlugin("BruhMMods.LethalPhonePOV", "LethalPhonePOV", "1.0.12")] [BepInDependency("LethalPhones", "1.3.23")] [BepInDependency("Zaggy1024.OpenBodyCams", "3.0.12")] [BepInDependency("meow.ModelReplacementAPI", "2.4.20")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("rayan.LethalFaceTime")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "BruhMMods.LethalPhonePOV"; public const string Version = "1.0.12"; private void Awake() { try { Settings settings = new Settings(((BaseUnityPlugin)this).Config); FacingSync.Init(((BaseUnityPlugin)this).Logger); PhoneRuntime.Start(((BaseUnityPlugin)this).Logger, new VideoSession(((BaseUnityPlugin)this).Logger, settings)); HideAndSeekStartupGuard.Install(((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalPhonePOV 1.0.12 ready; Unity frame driver armed. Accept a call and open the phone to view the caller's POV."); } catch (Exception ex) { PhoneRuntime.Shutdown(); ((BaseUnityPlugin)this).Logger.LogError((object)("Could not start LethalPhonePOV: " + ex)); } } private void OnDestroy() { PhoneRuntime.BootstrapDestroyed(); } } internal sealed class Settings { public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<int> Width; public readonly ConfigEntry<int> Height; public readonly ConfigEntry<float> Fps; public readonly ConfigEntry<bool> ShowInterior; public readonly ConfigEntry<Key> FlipCameraKey; public readonly ConfigEntry<float> SelfieDistance; public readonly ConfigEntry<float> CameraOffsetRight; public readonly ConfigEntry<float> CameraOffsetLeft; public readonly ConfigEntry<float> CameraOffsetUp; public readonly ConfigEntry<float> CameraOffsetForward; public readonly ConfigEntry<float> CameraSmoothingSpeed; public readonly ConfigEntry<bool> UseSafeMaterial; public readonly ConfigEntry<bool> ShowSelfPreview; public readonly ConfigEntry<float> SelfPreviewSize; public readonly ConfigEntry<float> SelfPreviewAnchorX; public readonly ConfigEntry<float> SelfPreviewAnchorY; public readonly ConfigEntry<float> SelfPreviewOffsetX; public readonly ConfigEntry<float> SelfPreviewOffsetY; public readonly ConfigEntry<float> SelfPreviewMaxHeight; public readonly ConfigEntry<float> SelfiePositionX; public readonly ConfigEntry<float> SelfiePositionY; public readonly ConfigEntry<float> SelfiePositionZ; public readonly ConfigEntry<float> SelfiePitch; public readonly ConfigEntry<float> SelfieYaw; public readonly ConfigEntry<float> SelfieRoll; public readonly ConfigEntry<bool> SelfieUseHeadAnchor; public readonly ConfigEntry<bool> SelfieAutoFraming; public readonly ConfigEntry<bool> SelfieDodgeOccluders; public readonly ConfigEntry<float> SelfieFieldOfView; public Settings(ConfigFile config) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Expected O, but got Unknown //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Show the connected player's POV on the open phone."); Width = config.Bind<int>("Video", "Width", 370, new ConfigDescription("Video texture width.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(64, 1024), Array.Empty<object>())); Height = config.Bind<int>("Video", "Height", 493, new ConfigDescription("Video texture height.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(64, 1024), Array.Empty<object>())); Fps = config.Bind<float>("Video", "FramesPerSecond", 24f, new ConfigDescription("Frame rate of this phone camera.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>())); ShowInterior = config.Bind<bool>("Video", "RenderRemoteInterior", true, "Temporarily pause the vanilla interior culler while viewing a caller inside the facility. Its previous enabled state is restored when the feed is hidden or the call ends."); FlipCameraKey = config.Bind<Key>("Controls", "FlipCameraKey", (Key)20, "Flips YOUR outgoing camera and your thumbnail. The other caller sees this change. Your main feed follows THEIR choice. Host and both callers need 1.0.8; None disables the key."); SelfieDistance = config.Bind<float>("Video", "SelfieDistance", 0.6387632f, new ConfigDescription("Fallback distance in front of the caller's face for the selfie camera, only used on the rare frame their held phone model isn't available yet. Normally the camera anchors at their actual phone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>())); CameraOffsetRight = config.Bind<float>("Video", "CameraOffsetRight", 0.01f, new ConfigDescription("Local phone offset to the right (meters) for the phone camera anchor.", (AcceptableValueBase)null, Array.Empty<object>())); CameraOffsetLeft = config.Bind<float>("Video", "CameraOffsetLeft", 0.2f, new ConfigDescription("Local phone offset to the left (meters) for the phone camera anchor. Use to nudge the camera left; combined with CameraOffsetRight.", (AcceptableValueBase)null, Array.Empty<object>())); CameraOffsetUp = config.Bind<float>("Video", "CameraOffsetUp", 0.2f, new ConfigDescription("Local phone offset upward (meters) for the phone camera anchor.", (AcceptableValueBase)null, Array.Empty<object>())); CameraOffsetForward = config.Bind<float>("Video", "CameraOffsetForward", 0.06f, new ConfigDescription("Local phone offset forward (meters) for the phone camera anchor.", (AcceptableValueBase)null, Array.Empty<object>())); CameraSmoothingSpeed = config.Bind<float>("Video", "CameraSmoothingSpeed", 8f, new ConfigDescription("How quickly the phone camera FOV/distance smooths to new targets (higher is snappier).", (AcceptableValueBase)null, Array.Empty<object>())); UseSafeMaterial = config.Bind<bool>("Video", "UseSafeMaterial", true, new ConfigDescription("When enabled, the phone camera will draw meshes using a simple unlit material to avoid incompatible shaders producing purple textures.", (AcceptableValueBase)null, Array.Empty<object>())); ShowSelfPreview = config.Bind<bool>("Video", "ShowSelfPreview", true, new ConfigDescription("Show a small preview in the top-right corner of the phone screen showing your own view, so you know how you look to the other caller.", (AcceptableValueBase)null, Array.Empty<object>())); SelfPreviewSize = config.Bind<float>("Video", "SelfPreviewSize", 0.4492476f, new ConfigDescription("Size of the self-preview thumbnail, as a fraction of the phone screen width.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.5f), Array.Empty<object>())); SelfPreviewAnchorX = config.Bind<float>("SelfPreview", "AnchorX", 1f, new ConfigDescription("Horizontal anchor/pivot: 0 left, 0.5 centre, 1 right.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SelfPreviewAnchorY = config.Bind<float>("SelfPreview", "AnchorY", 1f, new ConfigDescription("Vertical anchor/pivot: 0 bottom, 0.5 centre, 1 top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SelfPreviewOffsetX = config.Bind<float>("SelfPreview", "OffsetX", -6f, "Offset in phone-canvas units: negative moves left, positive right."); SelfPreviewOffsetY = config.Bind<float>("SelfPreview", "OffsetY", 0f, "Offset in phone-canvas units: negative moves down, positive up."); SelfPreviewMaxHeight = config.Bind<float>("SelfPreview", "MaxHeightFraction", 0.28f, new ConfigDescription("Maximum fraction of fitted screen height occupied by the thumbnail.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); SelfieUseHeadAnchor = config.Bind<bool>("SelfieFraming", "UseHeadAnchor", true, "True: start in front of the head at Video/SelfieDistance. False: start at the held phone, with existing Video/CameraOffset settings."); SelfiePositionX = config.Bind<float>("SelfieFraming", "PositionX", 0f, "Extra metres along the player's view-right axis. Negative moves left."); SelfiePositionY = config.Bind<float>("SelfieFraming", "PositionY", -0.2f, "Extra metres along the player's view-up axis. Negative moves down."); SelfiePositionZ = config.Bind<float>("SelfieFraming", "PositionZ", 0.1f, "Extra metres along the player's view-forward axis. Positive moves farther in front."); SelfiePitch = config.Bind<float>("SelfieFraming", "Pitch", 1.5f, "Extra camera-local X rotation in degrees, applied after aiming at the face."); SelfieYaw = config.Bind<float>("SelfieFraming", "Yaw", 0f, "Extra camera-local Y rotation in degrees."); SelfieRoll = config.Bind<float>("SelfieFraming", "Roll", 0f, "Extra camera-local Z rotation in degrees."); SelfieAutoFraming = config.Bind<bool>("SelfieFraming", "AutoFraming", true, "Disable for manual FOV/distance. When enabled, main-feed FOV and fallback distance adapt to model size."); SelfieDodgeOccluders = config.Bind<bool>("SelfieFraming", "DodgeOccluders", false, "Disable while manually tuning: automatic obstruction avoidance can otherwise shift the main camera."); SelfieFieldOfView = config.Bind<float>("SelfieFraming", "FieldOfView", 66.68958f, new ConfigDescription("Selfie FOV for both local thumbnail and main feed when AutoFraming=false.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 110f), Array.Empty<object>())); } } internal static class SelfieTuningDefaults { public const float PreviewAnchorX = 1f; public const float PreviewAnchorY = 1f; public const float PreviewOffsetX = -6f; public const float PreviewOffsetY = 0f; public const float PreviewSize = 0.4492476f; public const float PreviewMaxHeight = 0.28f; public const bool UseHeadAnchor = true; public const float PositionX = 0f; public const float PositionY = -0.2f; public const float PositionZ = 0.1f; public const float Pitch = 1.5f; public const float Yaw = 0f; public const float Roll = 0f; public const bool AutoFraming = true; public const bool DodgeOccluders = false; public const float FieldOfView = 66.68958f; } internal struct CallKey : IEquatable<CallKey> { public ulong LocalPhone; public ulong RemotePhone; public short RemoteNumber; public bool Equals(CallKey other) { return LocalPhone == other.LocalPhone && RemotePhone == other.RemotePhone && RemoteNumber == other.RemoteNumber; } } internal struct CallState { public bool Connected; public bool Visible; public CallKey Key; } internal interface IVideoSession { CallState ReadCall(); bool TryOpen(); bool Refresh(bool visible); void Close(); } internal sealed class SessionCoordinator { private readonly IVideoSession session; private int lastFrame = -1; private bool hasCall; private bool opened; private CallKey currentCall; public SessionCoordinator(IVideoSession session) { this.session = session; } public void Tick(int frame) { if (lastFrame == frame) { return; } lastFrame = frame; CallState callState = session.ReadCall(); if (!callState.Connected) { Reset(); return; } if (!hasCall || !currentCall.Equals(callState.Key)) { Reset(); currentCall = callState.Key; hasCall = true; } if (!opened && callState.Visible) { opened = session.TryOpen(); } if (opened && !session.Refresh(callState.Visible)) { session.Close(); opened = false; } } public void Reset() { if (hasCall) { session.Close(); } hasCall = false; opened = false; } } internal static class FacingSync { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnMessageReceived; } private const string MessageName = "BruhMMods.LethalPhonePOV.Facing"; private static bool registered; private static ManualLogSource log; private static readonly Dictionary<ulong, bool> preferences = new Dictionary<ulong, bool>(); internal static void Init(ManualLogSource logger) { log = logger; } private static bool EnsureRegistered() { //IL_008a: 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_0095: Expected O, but got Unknown if (registered) { return true; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { ManualLogSource obj = log; if (obj != null) { obj.LogInfo((object)"FacingSync: NetworkManager.Singleton is not available yet."); } return false; } if (singleton.CustomMessagingManager == null) { ManualLogSource obj2 = log; if (obj2 != null) { obj2.LogInfo((object)"FacingSync: CustomMessagingManager is not available yet."); } return false; } try { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj3 = <>O.<0>__OnMessageReceived; if (obj3 == null) { HandleNamedMessageDelegate val = OnMessageReceived; <>O.<0>__OnMessageReceived = val; obj3 = (object)val; } customMessagingManager.RegisterNamedMessageHandler("BruhMMods.LethalPhonePOV.Facing", (HandleNamedMessageDelegate)obj3); registered = true; ManualLogSource obj4 = log; if (obj4 != null) { obj4.LogInfo((object)("FacingSync: registered message handler as client " + singleton.LocalClientId + ".")); } } catch (Exception ex) { ManualLogSource obj5 = log; if (obj5 != null) { obj5.LogWarning((object)("FacingSync: could not register message handler: " + ex)); } } return registered; } private static void OnMessageReceived(ulong transportSenderClientId, FastBufferReader reader) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) try { ulong num = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); preferences[num] = flag; ManualLogSource obj = log; if (obj != null) { obj.LogInfo((object)("FacingSync: received " + (flag ? "selfie" : "outside") + " for client " + num + ((transportSenderClientId != num) ? (" (via " + transportSenderClientId + ")") : "") + ".")); } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsServer && transportSenderClientId != singleton.LocalClientId) { Send(num, flag, toServerOnly: false); } } catch (Exception ex) { ManualLogSource obj2 = log; if (obj2 != null) { obj2.LogWarning((object)("FacingSync: could not read incoming message: " + ex)); } } } internal static void Broadcast(bool selfieMode) { if (EnsureRegistered()) { NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null)) { preferences[singleton.LocalClientId] = selfieMode; Send(singleton.LocalClientId, selfieMode, !singleton.IsServer); } } } private unsafe static void Send(ulong originClientId, bool selfieMode, bool toServerOnly) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { return; } try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(9, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref originClientId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref selfieMode, default(ForPrimitives)); if (toServerOnly) { singleton.CustomMessagingManager.SendNamedMessage("BruhMMods.LethalPhonePOV.Facing", 0uL, val, (NetworkDelivery)2); ManualLogSource obj = log; if (obj != null) { obj.LogInfo((object)("FacingSync: sent " + (selfieMode ? "selfie" : "outside") + " to the server for relay.")); } return; } singleton.CustomMessagingManager.SendNamedMessageToAll("BruhMMods.LethalPhonePOV.Facing", val, (NetworkDelivery)2); ManualLogSource obj2 = log; if (obj2 != null) { obj2.LogInfo((object)("FacingSync: broadcast " + (selfieMode ? "selfie" : "outside") + " for client " + originClientId + " to everyone.")); } } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } catch (Exception ex) { ManualLogSource obj3 = log; if (obj3 != null) { obj3.LogWarning((object)("FacingSync: send failed: " + ex)); } } } internal static bool GetPreference(ulong clientId, bool defaultValue = true) { EnsureRegistered(); bool value; return preferences.TryGetValue(clientId, out value) ? value : defaultValue; } } internal sealed class VideoSession : IVideoSession { private class BakedMeshMeta { public Transform root; public Matrix4x4 localToWorld; public Material safeMaterial; public Material originalMaterial; public int subMeshIndex; public Mesh bakedMesh; } public static class CameraTargetResolver { public static Transform GetHeadTransform(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return null; } BodyReplacementBase val = default(BodyReplacementBase); if (Chainloader.PluginInfos.ContainsKey("meow.ModelReplacementAPI") && ModelReplacementAPI.GetPlayerModelReplacement(player, ref val) && (Object)(object)val != (Object)null) { object obj = null; Type type = ((object)val).GetType(); PropertyInfo property = type.GetProperty("replacementAnimator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { obj = property.GetValue(val); } else { FieldInfo field = type.GetField("replacementAnimator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { obj = field.GetValue(val); } } if (obj != null) { Animator val2 = null; Animator val3 = (Animator)((obj is Animator) ? obj : null); if (val3 != null) { val2 = val3; } else { GameObject val4 = (GameObject)((obj is GameObject) ? obj : null); if (val4 != null) { val2 = val4.GetComponent<Animator>(); } else { Component val5 = (Component)((obj is Component) ? obj : null); if (val5 != null) { val2 = val5.GetComponent<Animator>(); } } } if ((Object)(object)val2 != (Object)null && (Object)(object)val2.avatar != (Object)null && val2.avatar.isValid && val2.isHuman) { Transform boneTransform = val2.GetBoneTransform((HumanBodyBones)10); if ((Object)(object)boneTransform != (Object)null) { return boneTransform; } } } } if ((Object)(object)player.playerBodyAnimator != (Object)null && (Object)(object)player.playerBodyAnimator.avatar != (Object)null && player.playerBodyAnimator.avatar.isValid) { return player.playerBodyAnimator.GetBoneTransform((HumanBodyBones)10); } return ((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform : ((Component)player).transform; } } private static readonly FieldInfo ActiveCall = AccessTools.Field(typeof(PhoneBehavior), "activeCall"); private static readonly FieldInfo ActiveCaller = AccessTools.Field(typeof(PhoneBehavior), "activeCaller"); private static readonly MethodInfo BodyCamReady = AccessTools.Method(typeof(BodyCamComponent), "HasFinishedGameStartSetup", (Type[])null, (Type[])null); private static readonly FieldInfo OcclusionCuller = AccessTools.Field(typeof(StartOfRound), "occlusionCuller"); private static readonly FieldInfo MonitorMaterial = AccessTools.Field(typeof(BodyCamComponent), "MonitorOnMaterial"); private static readonly FieldInfo CameraTransformField = AccessTools.Field(typeof(BodyCamComponent), "CameraTransform"); private readonly ManualLogSource log; private readonly Settings settings; private PlayerPhone localPhone; private PlayerPhone remotePhone; private PlayerControllerB remotePlayer; private PlayerControllerB targetPlayer; private PlayerPhone targetPhone; private Canvas canvas; private GameObject overlay; private RawImage video; private AspectRatioFitter aspect; private GameObject selfPreviewOverlay; private RawImage selfPreviewVideo; private AspectRatioFitter selfPreviewAspect; private GameObject cameraHost; private BodyCamComponent bodyCam; private Camera lens; private RenderTexture texture; private Material ownedMaterial; private GameObject selfPreviewCameraHost; private BodyCamComponent selfPreviewBodyCam; private Camera selfPreviewLens; private RenderTexture selfPreviewTexture; private Behaviour pausedCuller; private bool wasCullerEnabled; private bool renderEventSubscribed; private bool frameSeen; private readonly List<Canvas> suppressedCanvases = new List<Canvas>(); private readonly List<Renderer> suppressedRenderers = new List<Renderer>(); private readonly List<Renderer> disabledPhoneRenderers = new List<Renderer>(); private bool viewmodelHiddenForPreview; private bool cachedArmsEnabled; private int cachedArmsLayer; private bool armsAnimatorCullingModeChanged; private AnimatorCullingMode cachedArmsAnimatorCullingMode; private readonly List<Mesh> bakedMeshes = new List<Mesh>(); private readonly List<Renderer> drawnRenderers = new List<Renderer>(); private readonly Dictionary<Material, Material> persistentSafeMaterials = new Dictionary<Material, Material>(); private readonly Dictionary<int, Mesh> persistentBakedMeshes = new Dictionary<int, Mesh>(); private readonly Dictionary<int, BakedMeshMeta> bakedMeshMeta = new Dictionary<int, BakedMeshMeta>(); private float smoothedDistance = 0f; private float smoothedFov = 60f; private float cameraSmoothingSpeed = 8f; private CommandBuffer lensCommandBuffer; private readonly string lensCmdName = "POV_Lens_DrawPlayerMeshes"; private CameraEvent lensCameraEvent = (CameraEvent)20; private readonly string[] armNamePatterns = new string[6] { "arm", "hand", "glove", "sleeve", "wrist", "forearm" }; private bool occlusionDebug = false; private bool selfieMode = true; private string status; private float nextOpenAttempt; private float nextFlipAllowedTime; private float nextFrameWarning; private Renderer[] cachedSceneRenderers; private float sceneRendererCacheTime = -1f; private const float SceneRendererCacheInterval = 1f; private Renderer[] cachedPlayerRenderers; private PlayerControllerB cachedPlayerRenderersFor; private float playerRendererCacheTime = -1f; private const float PlayerRendererCacheInterval = 0.5f; private Transform cachedReplacementRoot; private PlayerControllerB cachedReplacementRootFor; private bool replacementRootResolved; private readonly Dictionary<int, bool> rendererSkipCache = new Dictionary<int, bool>(); private readonly Dictionary<int, bool> armPieceCache = new Dictionary<int, bool>(); private Canvas[] cachedSceneCanvases; private float sceneCanvasCacheTime = -1f; private const float SceneCanvasCacheInterval = 1f; private Renderer[] GetCachedSceneRenderers() { float unscaledTime = Time.unscaledTime; if (cachedSceneRenderers == null || unscaledTime - sceneRendererCacheTime >= 1f) { cachedSceneRenderers = Object.FindObjectsOfType<Renderer>(true); sceneRendererCacheTime = unscaledTime; } return cachedSceneRenderers; } private Renderer[] GetCachedPlayerRenderers() { float unscaledTime = Time.unscaledTime; if ((Object)(object)targetPlayer != (Object)(object)cachedPlayerRenderersFor) { cachedPlayerRenderers = (((Object)(object)targetPlayer != (Object)null) ? ((Component)targetPlayer).GetComponentsInChildren<Renderer>(true) : null); cachedPlayerRenderersFor = targetPlayer; playerRendererCacheTime = unscaledTime; replacementRootResolved = false; rendererSkipCache.Clear(); armPieceCache.Clear(); } else if (cachedPlayerRenderers == null || unscaledTime - playerRendererCacheTime >= 0.5f) { cachedPlayerRenderers = (((Object)(object)targetPlayer != (Object)null) ? ((Component)targetPlayer).GetComponentsInChildren<Renderer>(true) : null); playerRendererCacheTime = unscaledTime; } return cachedPlayerRenderers; } private Transform GetCachedReplacementRoot() { if (replacementRootResolved && (Object)(object)cachedReplacementRootFor == (Object)(object)targetPlayer) { return cachedReplacementRoot; } Transform val = null; try { BodyReplacementBase val2 = default(BodyReplacementBase); if (Chainloader.PluginInfos.ContainsKey("meow.ModelReplacementAPI") && ModelReplacementAPI.GetPlayerModelReplacement(targetPlayer, ref val2) && (Object)(object)val2 != (Object)null) { object obj = null; Type type = ((object)val2).GetType(); PropertyInfo property = type.GetProperty("replacementAnimator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { obj = property.GetValue(val2); } else { FieldInfo field = type.GetField("replacementAnimator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { obj = field.GetValue(val2); } } Animator val3 = (Animator)((obj is Animator) ? obj : null); if (val3 != null) { val = ((Component)val3).transform; } else { GameObject val4 = (GameObject)((obj is GameObject) ? obj : null); if (val4 != null) { val = val4.transform; } else { Component val5 = (Component)((obj is Component) ? obj : null); if (val5 != null) { val = val5.transform; } } } } } catch (Exception) { val = null; } cachedReplacementRoot = val; cachedReplacementRootFor = targetPlayer; replacementRootResolved = true; return cachedReplacementRoot; } private void UpdateTargetPlayer() { targetPlayer = remotePlayer; targetPhone = remotePhone; } public VideoSession(ManualLogSource log, Settings settings) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) this.log = log; this.settings = settings; if (ActiveCall == null || ActiveCaller == null) { throw new MissingFieldException("LethalPhones activeCall/activeCaller fields are missing."); } if (BodyCamReady == null) { throw new MissingMethodException("OpenBodyCams readiness API is missing."); } if (CameraTransformField == null) { throw new MissingFieldException("OpenBodyCams camera transform field is missing."); } } private void AttachCommandBufferToLens(Camera lens) { //IL_0018: 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_002f: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)lens == (Object)null) { return; } DetachCommandBufferFromLens(lens); lensCommandBuffer = new CommandBuffer { name = lensCmdName }; try { lens.AddCommandBuffer(lensCameraEvent, lensCommandBuffer); } catch (Exception) { try { lens.AddCommandBuffer((CameraEvent)10, lensCommandBuffer); } catch { } } } catch (Exception arg) { try { log.LogWarning((object)$"[POV] AttachCommandBufferToLens failed: {arg}"); } catch { } } } private void DetachCommandBufferFromLens(Camera lens) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)lens == (Object)null) && lensCommandBuffer != null) { try { lens.RemoveCommandBuffer(lensCameraEvent, lensCommandBuffer); } catch { } try { lens.RemoveCommandBuffer((CameraEvent)10, lensCommandBuffer); } catch { } lensCommandBuffer.Release(); lensCommandBuffer = null; } } catch (Exception arg) { try { log.LogWarning((object)$"[POV] DetachCommandBufferFromLens failed: {arg}"); } catch { } } } public CallState ReadCall() { remotePlayer = null; remotePhone = null; localPhone = (((Object)(object)PhoneNetworkHandler.Instance != (Object)null) ? PhoneNetworkHandler.Instance.localPhone : null); if (!settings.Enabled.Value || (Object)(object)localPhone == (Object)null || !((NetworkBehaviour)localPhone).IsSpawned) { return default(CallState); } short value = ((NetworkVariable<short>)ActiveCall.GetValue(localPhone)).Value; if (value == -1) { return default(CallState); } ulong value2 = ((NetworkVariable<ulong>)ActiveCaller.GetValue(localPhone)).Value; NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.SpawnManager != null && singleton.SpawnManager.SpawnedObjects.TryGetValue(value2, out var value3)) { PlayerPhone component = ((Component)value3).GetComponent<PlayerPhone>(); if ((Object)(object)component != (Object)null) { remotePlayer = component.player; remotePhone = component; } } bool visible = localPhone.toggled && (Object)(object)localPhone.player != (Object)null && !localPhone.player.isPlayerDead; return new CallState { Connected = true, Visible = visible, Key = new CallKey { LocalPhone = ((NetworkBehaviour)localPhone).NetworkObjectId, RemotePhone = value2, RemoteNumber = value } }; } public bool TryOpen() { if ((Object)(object)remotePlayer == (Object)null || Time.unscaledTime < nextOpenAttempt) { return false; } nextOpenAttempt = Time.unscaledTime + 0.25f; if (!(bool)BodyCamReady.Invoke(null, null)) { return false; } Canvas val = FindCanvas(localPhone); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)overlay == (Object)null) { AttachScreen(val); } if ((Object)(object)bodyCam == (Object)null) { CreateCamera(); } if ((Object)(object)lens == (Object)null || (Object)(object)texture == (Object)null) { return false; } UpdateTargetPlayer(); FacingSync.Broadcast(selfieMode); bodyCam.SetTargetToPlayer(targetPlayer); UpdateLensCullingMaskForPlayer(); ApplyCameraOrientation(); nextFrameWarning = Time.unscaledTime + 5f; return true; } private static Canvas FindCanvas(PlayerPhone phone) { if ((Object)(object)phone == (Object)null || (Object)(object)phone.localPhoneModel == (Object)null) { return null; } Transform transform = phone.localPhoneModel.transform; Transform val = transform.Find("LocalPhoneModel/PhoneTop/PhoneCanvas"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<Canvas>(); } Canvas[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Canvas>(true); foreach (Canvas val2 in componentsInChildren) { if (((Object)val2).name == "PhoneCanvas") { return val2; } } return null; } private void AttachScreen(Canvas phoneCanvas) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_008e: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) canvas = phoneCanvas; overlay = new GameObject("LethalPhonePOV.Screen", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); overlay.SetActive(false); overlay.layer = ((Component)canvas).gameObject.layer; RectTransform component = overlay.GetComponent<RectTransform>(); ((Transform)component).SetParent(((Component)canvas).transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; ((Transform)component).localPosition = new Vector3(((Transform)component).localPosition.x, ((Transform)component).localPosition.y, 0f); ((Transform)component).SetAsLastSibling(); RawImage component2 = overlay.GetComponent<RawImage>(); ((Graphic)component2).color = Color.black; ((Graphic)component2).raycastTarget = false; GameObject val = new GameObject("CallerPOV", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage), typeof(AspectRatioFitter) }); val.layer = ((Component)canvas).gameObject.layer; val.transform.SetParent((Transform)(object)component, false); RectTransform component3 = val.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = Vector2.zero; component3.offsetMax = Vector2.zero; component3.pivot = new Vector2(0.5f, 0.5f); video = val.GetComponent<RawImage>(); ((Graphic)video).color = Color.white; ((Graphic)video).raycastTarget = false; aspect = val.GetComponent<AspectRatioFitter>(); aspect.aspectMode = (AspectMode)3; SetTexture(texture); CreateSelfPreviewOverlay(val.GetComponent<RectTransform>()); } private void CreateSelfPreviewOverlay(RectTransform parent) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_008a: 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_00bf: Unknown result type (might be due to invalid IL or missing references) selfPreviewOverlay = new GameObject("LethalPhonePOV.SelfPreview", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage), typeof(AspectRatioFitter) }); selfPreviewOverlay.SetActive(false); selfPreviewOverlay.layer = ((Component)canvas).gameObject.layer; RectTransform component = selfPreviewOverlay.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)parent, false); ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; ((Transform)component).SetAsLastSibling(); selfPreviewVideo = selfPreviewOverlay.GetComponent<RawImage>(); ((Graphic)selfPreviewVideo).color = Color.white; ((Graphic)selfPreviewVideo).raycastTarget = false; selfPreviewAspect = selfPreviewOverlay.GetComponent<AspectRatioFitter>(); selfPreviewAspect.aspectMode = (AspectMode)0; ApplySelfPreviewLayout(); } private void ApplySelfPreviewLayout() { //IL_0067: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)selfPreviewOverlay == (Object)null) { return; } RectTransform component = selfPreviewOverlay.GetComponent<RectTransform>(); Transform parent = ((Transform)component).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } float value = settings.SelfPreviewAnchorX.Value; float value2 = settings.SelfPreviewAnchorY.Value; component.anchorMin = new Vector2(value, value2); component.anchorMax = new Vector2(value, value2); component.pivot = new Vector2(value, value2); float num = Mathf.Clamp(settings.SelfPreviewSize.Value, 0.05f, 0.5f); Rect rect = val.rect; float num2; if (!(((Rect)(ref rect)).width > 0f)) { num2 = 56f; } else { rect = val.rect; num2 = ((Rect)(ref rect)).width * num; } float num3 = num2; float num4 = num3 * 0.75f; rect = val.rect; if (((Rect)(ref rect)).height > 0f) { rect = val.rect; float num5 = ((Rect)(ref rect)).height * settings.SelfPreviewMaxHeight.Value; if (num4 > num5) { num4 = num5; num3 = num4 / 0.75f; } } component.sizeDelta = new Vector2(num3, num4); component.anchoredPosition = new Vector2(settings.SelfPreviewOffsetX.Value, settings.SelfPreviewOffsetY.Value); } private void CreateCamera() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_00b7: 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_015c: Expected O, but got Unknown cameraHost = new GameObject("LethalPhonePOV.Camera"); if ((Object)(object)StartOfRound.Instance != (Object)null) { cameraHost.transform.SetParent(((Component)StartOfRound.Instance).transform, false); } bodyCam = BodyCam.CreateBodyCam(cameraHost, (Renderer)null, -1, (ManualCameraRenderer)null); bodyCam.OnRenderTextureCreated += SetTexture; bodyCam.ForceEnableCamera = true; bodyCam.Framerate = settings.Fps.Value; bodyCam.Resolution = new Vector2Int(settings.Width.Value, settings.Height.Value); lens = bodyCam.GetCamera(); if ((Object)(object)lens != (Object)null) { try { lens.cullingMask = -1; } catch (Exception) { } } ref Material reference = ref ownedMaterial; object? obj = MonitorMaterial?.GetValue(bodyCam); reference = (Material)((obj is Material) ? obj : null); if ((Object)(object)lens != (Object)null) { SetTexture(lens.targetTexture); } if ((Object)(object)lens != (Object)null) { try { lensCommandBuffer = new CommandBuffer(); lensCommandBuffer.name = lensCmdName; lens.AddCommandBuffer((CameraEvent)10, lensCommandBuffer); } catch (Exception) { } } if ((Object)(object)lens != (Object)null) { smoothedFov = lens.fieldOfView; smoothedDistance = settings.SelfieDistance.Value; cameraSmoothingSpeed = settings.CameraSmoothingSpeed.Value; } if ((Object)(object)lens != (Object)null) { smoothedFov = lens.fieldOfView; smoothedDistance = settings.SelfieDistance.Value; } RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; RenderPipelineManager.endCameraRendering += CameraRendered; renderEventSubscribed = true; CreateSelfPreviewCamera(); } private void CreateSelfPreviewCamera() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)localPhone == (Object)null || (Object)(object)localPhone.player == (Object)null) { return; } selfPreviewCameraHost = new GameObject("LethalPhonePOV.SelfPreviewCamera"); if ((Object)(object)StartOfRound.Instance != (Object)null) { selfPreviewCameraHost.transform.SetParent(((Component)StartOfRound.Instance).transform, false); } selfPreviewBodyCam = BodyCam.CreateBodyCam(selfPreviewCameraHost, (Renderer)null, -1, (ManualCameraRenderer)null); selfPreviewBodyCam.OnRenderTextureCreated += SetSelfPreviewTexture; selfPreviewBodyCam.ForceEnableCamera = true; selfPreviewBodyCam.Framerate = settings.Fps.Value; selfPreviewBodyCam.Resolution = new Vector2Int(160, 120); selfPreviewBodyCam.SetTargetToPlayer(localPhone.player); selfPreviewLens = selfPreviewBodyCam.GetCamera(); if ((Object)(object)selfPreviewLens != (Object)null) { ApplySelfPreviewCullingMask(); SetSelfPreviewTexture(selfPreviewLens.targetTexture); } try { Animator val = (((Object)(object)localPhone?.player != (Object)null) ? localPhone.player.playerBodyAnimator : null); if ((Object)(object)val != (Object)null) { cachedArmsAnimatorCullingMode = val.cullingMode; val.cullingMode = (AnimatorCullingMode)0; armsAnimatorCullingModeChanged = true; } } catch (Exception) { } } private void ApplySelfPreviewCullingMask() { if ((Object)(object)selfPreviewLens == (Object)null) { return; } try { int num = 0; if ((Object)(object)localPhone != (Object)null && (Object)(object)localPhone.player != (Object)null) { Renderer[] componentsInChildren = ((Component)localPhone.player).GetComponentsInChildren<Renderer>(true); if (componentsInChildren != null) { Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val != (Object)null) { num |= 1 << ((Component)val).gameObject.layer; } } } } if (num == 0) { Camera main = Camera.main; num = (((Object)(object)main != (Object)null) ? main.cullingMask : (1 << LayerMask.NameToLayer("Default"))); } int num2 = LayerMask.GetMask(new string[4] { "UI", "HelmetVisor", "Ignore Raycast", "MapRadar" }); int num3 = LayerMask.NameToLayer("Triggers"); if (num3 != -1) { num2 |= 1 << num3; } selfPreviewLens.cullingMask = num & ~num2; int num4 = LayerMask.NameToLayer("Room"); if (num4 != -1) { Camera obj = selfPreviewLens; obj.cullingMask |= 1 << num4; } } catch (Exception) { } } private void ApplySelfPreviewOrientation() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00ed: 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_0179: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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_01b6: 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_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)selfPreviewBodyCam == (Object)null || (Object)(object)localPhone == (Object)null || (Object)(object)localPhone.player == (Object)null) { return; } object? value = CameraTransformField.GetValue(selfPreviewBodyCam); Transform val = (Transform)((value is Transform) ? value : null); if ((Object)(object)val == (Object)null) { return; } Transform playerHead = GetPlayerHead(localPhone.player); if ((Object)(object)playerHead == (Object)null) { return; } Transform val2 = (((Object)(object)localPhone.serverPhoneModel != (Object)null) ? localPhone.serverPhoneModel.transform : null); Vector3 val3; if (settings.SelfieUseHeadAnchor.Value || (Object)(object)val2 == (Object)null) { val3 = playerHead.position + playerHead.forward * settings.SelfieDistance.Value; } else { float num = settings.CameraOffsetRight.Value - settings.CameraOffsetLeft.Value; val3 = val2.position + val2.right * num + val2.up * settings.CameraOffsetUp.Value + val2.forward * settings.CameraOffsetForward.Value; } val3 += playerHead.right * settings.SelfiePositionX.Value + playerHead.up * settings.SelfiePositionY.Value + playerHead.forward * settings.SelfiePositionZ.Value; Vector3 val4 = playerHead.position - val3; if (((Vector3)(ref val4)).sqrMagnitude < 0.0001f) { val4 = -playerHead.forward; } Quaternion val5 = (selfieMode ? Quaternion.LookRotation(val4, Vector3.up) : Quaternion.LookRotation(playerHead.forward, Vector3.up)); Quaternion val6 = Quaternion.Euler(settings.SelfiePitch.Value, settings.SelfieYaw.Value, settings.SelfieRoll.Value); val.SetPositionAndRotation(val3, val5 * val6); if ((Object)(object)selfPreviewLens != (Object)null) { if (selfPreviewLens.nearClipPlane > 0.05f) { selfPreviewLens.nearClipPlane = 0.05f; } if (!settings.SelfieAutoFraming.Value) { selfPreviewLens.fieldOfView = settings.SelfieFieldOfView.Value; } } } public bool Refresh(bool visible) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bodyCam == (Object)null || (Object)(object)lens == (Object)null || (Object)(object)overlay == (Object)null || (Object)(object)video == (Object)null || (Object)(object)remotePlayer == (Object)null || (Object)(object)canvas != (Object)(object)FindCanvas(localPhone)) { return false; } Keyboard current = Keyboard.current; if (visible && current != null && ((ButtonControl)current[settings.FlipCameraKey.Value]).wasPressedThisFrame && Time.unscaledTime >= nextFlipAllowedTime) { nextFlipAllowedTime = Time.unscaledTime + 0.2f; selfieMode = !selfieMode; FacingSync.Broadcast(selfieMode); } UpdateTargetPlayer(); if ((Object)(object)bodyCam.CurrentPlayerTarget != (Object)(object)targetPlayer) { bodyCam.SetTargetToPlayer(targetPlayer); } bool flag = visible && ((Behaviour)canvas).enabled && ((Component)canvas).gameObject.activeInHierarchy; bodyCam.ForceEnableCamera = flag; ((Behaviour)bodyCam).enabled = flag; if (!flag) { ((Behaviour)lens).enabled = false; } Vector2Int val = default(Vector2Int); ((Vector2Int)(ref val))..ctor(settings.Width.Value, settings.Height.Value); if (bodyCam.Resolution != val) { bodyCam.Resolution = val; } bodyCam.Framerate = settings.Fps.Value; SetTexture(lens.targetTexture); bool flag2 = flag && (Object)(object)texture != (Object)null && !bodyCam.IsBlanked; if (overlay.activeSelf != flag2) { overlay.SetActive(flag2); } if (flag2) { overlay.transform.SetAsLastSibling(); } UpdateSelfPreview(flag); KeepInteriorVisible(flag && settings.ShowInterior.Value && (Object)(object)targetPlayer != (Object)null && targetPlayer.isInsideFactory); if (flag && !frameSeen && Time.unscaledTime >= nextFrameWarning) { nextFrameWarning = Time.unscaledTime + 10f; log.LogWarning((object)("Phone camera has not reported a rendered frame yet. Camera status: " + ((object)bodyCam.CameraStatus/*cast due to .constrained prefix*/).ToString() + "; handset canvas active: " + ((Component)canvas).gameObject.activeInHierarchy)); } return true; } private void SetTexture(RenderTexture next) { RenderTexture val = texture; texture = next; if ((Object)(object)video != (Object)null) { video.texture = (Texture)(object)next; } if ((Object)(object)aspect != (Object)null && (Object)(object)next != (Object)null) { aspect.aspectRatio = (float)((Texture)next).width / (float)((Texture)next).height; } if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)next) { val.Release(); Object.Destroy((Object)(object)val); } } private void SetSelfPreviewTexture(RenderTexture next) { RenderTexture val = selfPreviewTexture; selfPreviewTexture = next; if ((Object)(object)selfPreviewVideo != (Object)null) { selfPreviewVideo.texture = (Texture)(object)next; } if ((Object)(object)selfPreviewAspect != (Object)null && (Object)(object)next != (Object)null) { selfPreviewAspect.aspectRatio = (float)((Texture)next).width / (float)((Texture)next).height; } if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)next) { val.Release(); Object.Destroy((Object)(object)val); } } private void UpdateSelfPreview(bool mainFeedVisible) { if ((Object)(object)selfPreviewOverlay == (Object)null) { return; } ApplySelfPreviewLayout(); bool flag = mainFeedVisible && settings.ShowSelfPreview.Value && (Object)(object)localPhone != (Object)null && (Object)(object)localPhone.player != (Object)null && !localPhone.player.isPlayerDead; if (flag && ((Object)(object)selfPreviewBodyCam == (Object)null || (Object)(object)selfPreviewLens == (Object)null)) { CreateSelfPreviewCamera(); } if ((Object)(object)selfPreviewBodyCam != (Object)null) { if ((Object)(object)selfPreviewBodyCam.CurrentPlayerTarget != (Object)(object)localPhone?.player && (Object)(object)localPhone?.player != (Object)null) { selfPreviewBodyCam.SetTargetToPlayer(localPhone.player); } selfPreviewBodyCam.ForceEnableCamera = flag; ((Behaviour)selfPreviewBodyCam).enabled = flag; if ((Object)(object)selfPreviewLens != (Object)null) { ((Behaviour)selfPreviewLens).enabled = flag; } } bool flag2 = flag && (Object)(object)selfPreviewTexture != (Object)null; if (selfPreviewOverlay.activeSelf != flag2) { selfPreviewOverlay.SetActive(flag2); } if (flag2) { selfPreviewOverlay.transform.SetAsLastSibling(); } } private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { if ((Object)(object)camera == (Object)(object)lens) { UpdateLensCullingMaskForPlayer(); if (occlusionDebug) { LogNearbyCanvases(); } SuppressRemotePlayerCanvases(suppress: true, considerNearby: true); SuppressDebugGeometry(suppress: true); SuppressOccludingRenderers(suppress: true); DrawPlayerMeshesToCamera(); UpdateCommandBuffer(lens); ApplyCameraOrientation(); } else if ((Object)(object)camera == (Object)(object)selfPreviewLens) { ApplySelfPreviewCullingMask(); ApplySelfPreviewOrientation(); HideLocalViewmodelForSelfPreview(); } } private void HideLocalViewmodelForSelfPreview() { if (viewmodelHiddenForPreview) { return; } try { Renderer val = (Renderer)(object)(((Object)(object)localPhone?.player != (Object)null) ? localPhone.player.thisPlayerModelArms : null); if (!((Object)(object)val == (Object)null)) { cachedArmsEnabled = val.enabled; cachedArmsLayer = ((Component)val).gameObject.layer; val.enabled = false; ((Component)val).gameObject.layer = 23; viewmodelHiddenForPreview = true; } } catch (Exception) { } } private void RestoreLocalViewmodelAfterSelfPreview() { if (!viewmodelHiddenForPreview) { return; } try { Renderer val = (Renderer)(object)(((Object)(object)localPhone?.player != (Object)null) ? localPhone.player.thisPlayerModelArms : null); if ((Object)(object)val != (Object)null) { val.enabled = cachedArmsEnabled; ((Component)val).gameObject.layer = cachedArmsLayer; } } catch (Exception) { } finally { viewmodelHiddenForPreview = false; } } private void DrawPlayerMeshesToCamera() { //IL_08d2: Unknown result type (might be due to invalid IL or missing references) //IL_08d7: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Unknown result type (might be due to invalid IL or missing references) //IL_0832: Unknown result type (might be due to invalid IL or missing references) //IL_0842: Expected O, but got Unknown //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Expected O, but got Unknown if ((Object)(object)targetPlayer == (Object)null) { return; } try { if (occlusionDebug) { try { string text = (((Object)(object)targetPlayer != (Object)null) ? targetPlayer.playerUsername : "(null)"); log.LogInfo((object)("[POV-OCC] DrawPlayerMeshesToCamera start. TargetPlayer=" + text)); } catch { } } } catch { } try { drawnRenderers.Clear(); Transform val = GetCachedReplacementRoot(); Renderer[] array = GetCachedPlayerRenderers(); if (array == null || array.Length == 0) { return; } Renderer[] array2 = array; foreach (Renderer val2 in array2) { if ((Object)(object)val2 == (Object)null) { continue; } if ((Object)(object)val != (Object)null) { if (!((Component)val2).transform.IsChildOf(val) && (Object)(object)((Component)val2).transform != (Object)(object)val) { continue; } } else if (!((Component)val2).transform.IsChildOf(((Component)targetPlayer).transform) && (Object)(object)((Component)val2).transform != (Object)(object)((Component)targetPlayer).transform) { continue; } int instanceID = ((Object)val2).GetInstanceID(); if (!rendererSkipCache.TryGetValue(instanceID, out var value)) { string text2 = ((Object)((Component)val2).gameObject).name.ToLowerInvariant(); value = text2.Contains("ui") || text2.Contains("canvas") || text2.Contains("phone") || text2.Contains("visor") || text2.Contains("badge") || text2.Contains("debug") || text2.Contains("gizmo") || text2.Contains("mapdot") || text2.Contains("mapdirectionindicator") || text2.Contains("spherehelper") || text2.Contains("openbodycams_targettracker") || text2.Contains("impvis") || text2.Contains("collision") || text2.Contains("wireframe") || text2.Contains("bounds") || text2.Contains("radius") || text2 == "sphere" || text2 == "lineofsight2" || text2.Contains("lineofsightcube") || text2.Contains("lineofsight"); if (!value) { try { string text3 = LayerMask.LayerToName(((Component)val2).gameObject.layer).ToLowerInvariant(); if (text3.Contains("debug") || text3.Contains("gizmo") || text3.Contains("editor") || text3.Contains("ignore")) { value = true; } } catch (Exception) { } } if (!value) { try { Material[] sharedMaterials = val2.sharedMaterials; if (sharedMaterials != null && sharedMaterials.Length != 0) { bool flag = true; Material[] array3 = sharedMaterials; foreach (Material val3 in array3) { if (!((Object)(object)val3 == (Object)null)) { string text4 = (((Object)(object)val3.shader != (Object)null) ? ((Object)val3.shader).name.ToLowerInvariant() : ""); if (!text4.Contains("hidden") && !text4.Contains("debug") && !text4.Contains("error") && !text4.Contains("gizmo") && !text4.Contains("wireframe")) { flag = false; break; } } } if (flag) { value = true; } } } catch (Exception) { } } rendererSkipCache[instanceID] = value; bool value2 = false; try { string[] array4 = armNamePatterns; foreach (string value3 in array4) { if (text2.Contains(value3)) { value2 = true; break; } } } catch (Exception) { value2 = false; } armPieceCache[instanceID] = value2; } if (value || !val2.enabled || (armPieceCache.TryGetValue(instanceID, out var value4) && value4)) { continue; } drawnRenderers.Add(val2); Mesh val4 = null; int instanceID2 = ((Object)val2).GetInstanceID(); SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null); if (val5 != null) { Mesh value5 = null; if (!persistentBakedMeshes.TryGetValue(instanceID2, out value5) || (Object)(object)value5 == (Object)null) { value5 = new Mesh(); persistentBakedMeshes[instanceID2] = value5; } try { val5.BakeMesh(value5); val4 = value5; } catch (Exception ex4) { try { log.LogWarning((object)("[POV-OCC] SkinnedMeshRenderer.BakeMesh failed for " + ((Object)((Component)val2).gameObject).name + ": " + ex4.Message)); } catch { } val4 = null; } if ((Object)(object)val4 == (Object)null) { try { if ((Object)(object)val5.sharedMesh != (Object)null) { val4 = val5.sharedMesh; try { log.LogInfo((object)("[POV-OCC] Falling back to SkinnedMeshRenderer.sharedMesh for " + ((Object)((Component)val2).gameObject).name)); } catch { } } } catch (Exception) { val4 = null; } } } else { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { val4 = component.sharedMesh; } } if ((Object)(object)val4 == (Object)null) { if (occlusionDebug) { try { log.LogInfo((object)("[POV-OCC] Skipped renderer with no mesh: " + ((Object)((Component)val2).gameObject).name + " (root=" + ((Object)((Component)val2).transform.root).name + ")")); } catch { } } continue; } Material[] array5 = (Material[])(((object)val2.sharedMaterials) ?? ((object)new Material[0])); int num = Mathf.Max(1, val4.subMeshCount); for (int l = 0; l < num; l++) { Material val6 = ((l < array5.Length && (Object)(object)array5[l] != (Object)null) ? array5[l] : ((array5.Length != 0) ? array5[0] : null)); if ((Object)(object)val6 == (Object)null) { continue; } Material value6 = val6; try { bool flag2 = false; try { flag2 = settings.UseSafeMaterial.Value; } catch (Exception) { flag2 = true; } bool flag3 = false; try { flag3 = (Object)(object)val6.shader == (Object)null || !val6.shader.isSupported || ((Object)val6.shader).name.ToLowerInvariant().Contains("hidden") || ((Object)val6.shader).name.ToLowerInvariant().Contains("debug") || ((Object)val6.shader).name.ToLowerInvariant().Contains("hdrp"); } catch (Exception) { flag3 = true; } if ((flag2 || flag3) && (!persistentSafeMaterials.TryGetValue(val6, out value6) || (Object)(object)value6 == (Object)null)) { Shader val7 = Shader.Find("Unlit/Texture"); if ((Object)(object)val7 == (Object)null) { val7 = Shader.Find("Sprites/Default"); } Material val8 = (((Object)(object)val7 != (Object)null) ? new Material(val7) : new Material(Shader.Find("Standard"))); try { if ((Object)(object)val6.mainTexture != (Object)null) { val8.mainTexture = val6.mainTexture; } } catch (Exception) { } try { if (val6.HasProperty("_Color")) { val8.color = val6.color; } } catch (Exception) { } persistentSafeMaterials[val6] = val8; value6 = val8; } } catch (Exception) { } try { BakedMeshMeta bakedMeshMeta = new BakedMeshMeta { root = ((Component)val2).transform, localToWorld = ((Component)val2).transform.localToWorldMatrix, safeMaterial = value6, originalMaterial = val6, subMeshIndex = l }; Mesh bakedMesh = val4; bakedMeshMeta.bakedMesh = bakedMesh; this.bakedMeshMeta[instanceID2 ^ l] = bakedMeshMeta; } catch (Exception) { } } } try { if (occlusionDebug) { int num2 = ((drawnRenderers != null) ? drawnRenderers.Count : 0); log.LogInfo((object)$"[POV-OCC] Candidate renderers after filtering: {num2}; total renderers found: {((array != null) ? array.Length : 0)}"); } } catch { } } catch (Exception) { } try { if (!occlusionDebug) { return; } int num3 = ((this.bakedMeshMeta != null) ? this.bakedMeshMeta.Count : 0); int num4 = 0; if (this.bakedMeshMeta != null) { foreach (KeyValuePair<int, BakedMeshMeta> bakedMeshMetum in this.bakedMeshMeta) { if (bakedMeshMetum.Value != null && (Object)(object)bakedMeshMetum.Value.bakedMesh != (Object)null) { num4++; } } } log.LogInfo((object)$"[POV-OCC] BakedMeshMeta prepared: total={num3}, withMesh={num4}"); } catch (Exception) { } } private void UpdateCommandBuffer(Camera lens) { //IL_028e: 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_017e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lens == (Object)null) { return; } if (lensCommandBuffer == null) { AttachCommandBufferToLens(lens); if (lensCommandBuffer == null) { return; } } try { lensCommandBuffer.Clear(); if (bakedMeshMeta == null || bakedMeshMeta.Count == 0) { return; } if ((Object)(object)lens.targetTexture != (Object)null) { lensCommandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)lens.targetTexture)); } int num = 0; foreach (KeyValuePair<int, BakedMeshMeta> bakedMeshMetum in bakedMeshMeta) { BakedMeshMeta value = bakedMeshMetum.Value; if (value == null || (Object)(object)value.root == (Object)null) { continue; } try { Mesh val = value.bakedMesh; if ((Object)(object)val == (Object)null) { int instanceID = ((Object)value.root).GetInstanceID(); if (persistentBakedMeshes.TryGetValue(instanceID, out var value2) && (Object)(object)value2 != (Object)null) { val = value2; } } Material val2 = value.safeMaterial ?? value.originalMaterial ?? ownedMaterial; if (!((Object)(object)val != (Object)null) || !((Object)(object)val2 != (Object)null)) { continue; } try { lensCommandBuffer.DrawMesh(val, value.localToWorld, val2, 0, value.subMeshIndex); num++; if (occlusionDebug) { try { log.LogInfo((object)("[POV-OCC] UpdateCommandBuffer drew mesh for: " + (((Object)(object)value.root != (Object)null) ? ((Object)value.root).name : "(null)") + " sub=" + value.subMeshIndex)); } catch { } } } catch (Exception ex) { try { log.LogWarning((object)("[POV-OCC] UpdateCommandBuffer DrawMesh failed: " + ex.Message)); } catch { } } } catch (Exception ex2) { try { log.LogWarning((object)("[POV-OCC] UpdateCommandBuffer iteration failed: " + ex2.Message)); } catch { } } } if ((Object)(object)lens.targetTexture != (Object)null) { lensCommandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2)); } if (!occlusionDebug) { return; } try { log.LogInfo((object)$"[POV-OCC] UpdateCommandBuffer recorded draw calls: {num}"); } catch { } } catch (Exception) { } } private void LogNearbyCanvases() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)targetPlayer == (Object)null) { return; } try { Transform playerHead = GetPlayerHead(targetPlayer); if ((Object)(object)playerHead == (Object)null) { return; } int num = 30; int num2 = 0; Canvas[] array = Object.FindObjectsOfType<Canvas>(true); if (array == null) { return; } Canvas[] array2 = array; foreach (Canvas val in array2) { if ((Object)(object)val == (Object)null) { continue; } if (num2 >= num) { break; } Vector3 position = ((Component)val).transform.position; float num3 = Vector3.Distance(playerHead.position, position); if (num3 > 1.5f) { continue; } string text = (((Object)(object)((Component)val).transform.root != (Object)null) ? ((Object)((Component)val).transform.root).name : "(null)"); string text2 = ((object)val.renderMode/*cast due to .constrained prefix*/).ToString(); string text3 = (((Object)(object)val.worldCamera != (Object)null) ? ((Object)val.worldCamera).name : "(none)"); string text4 = (((Component)val).transform.IsChildOf(((Component)targetPlayer).transform) ? "childOfPlayer" : "notChild"); string text5 = ""; try { RectTransform component = ((Component)val).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { Rect rect = component.rect; text5 = "rect=" + ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString() + " anchoredPos=" + ((object)component.anchoredPosition/*cast due to .constrained prefix*/).ToString(); } } catch (Exception) { } log.LogInfo((object)("[POV-OCC] Nearby Canvas: " + ((Object)((Component)val).gameObject).name + " root=" + text + " dist=" + num3.ToString("F3") + " mode=" + text2 + " cam=" + text3 + " " + text4 + " " + text5)); num2++; } } catch (Exception) { } } private void UpdateLensCullingMaskForPlayer() { if ((Object)(object)lens == (Object)null) { return; } try { int num = 0; if ((Object)(object)targetPlayer != (Object)null) { Renderer[] array = GetCachedPlayerRenderers(); if (array != null && array.Length != 0) { Renderer[] array2 = array; foreach (Renderer val in array2) { if ((Object)(object)val != (Object)null) { num |= 1 << ((Component)val).gameObject.layer; } } } } if (num == 0) { Camera main = Camera.main; num = ((!((Object)(object)main != (Object)null)) ? (1 << LayerMask.NameToLayer("Default")) : main.cullingMask); } int num2 = LayerMask.GetMask(new string[4] { "UI", "HelmetVisor", "Ignore Raycast", "MapRadar" }); int num3 = LayerMask.NameToLayer("Triggers"); if (num3 != -1) { num2 |= 1 << num3; } lens.cullingMask = num & ~num2; int num4 = LayerMask.NameToLayer("Room"); if (num4 != -1) { Camera obj = lens; obj.cullingMask |= 1 << num4; } } catch (Exception) { } } private Canvas[] GetCachedSceneCanvases() { float unscaledTime = Time.unscaledTime; if (cachedSceneCanvases == null || unscaledTime - sceneCanvasCacheTime >= 1f) { cachedSceneCanvases = Object.FindObjectsOfType<Canvas>(true); sceneCanvasCacheTime = unscaledTime; } return cachedSceneCanvases; } private void SuppressRemotePlayerCanvases(bool suppress, bool considerNearby) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Invalid comparison between Unknown and I4 //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)targetPlayer == (Object)null) { return; } try { Canvas[] componentsInChildren = ((Component)targetPlayer).GetComponentsInChildren<Canvas>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return; } if (suppress) { Canvas[] array = componentsInChildren; foreach (Canvas val in array) { if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled) { continue; } ((Behaviour)val).enabled = false; suppressedCanvases.Add(val); if (occlusionDebug) { try { log.LogInfo((object)("[POV-OCC] Suppressed Canvas: " + ((Object)((Component)val).gameObject).name + " (root=" + ((Object)((Component)val).transform.root).name + ")")); } catch (Exception) { } } } if (!considerNearby) { return; } try { Transform playerHead = GetPlayerHead(targetPlayer); if (!((Object)(object)playerHead != (Object)null)) { return; } Canvas[] array2 = GetCachedSceneCanvases(); if (array2 == null) { return; } Canvas[] array3 = array2; foreach (Canvas val2 in array3) { if ((Object)(object)val2 == (Object)null || suppressedCanvases.Contains(val2) || (int)val2.renderMode != 2) { continue; } float num = Vector3.Distance(playerHead.position, ((Component)val2).transform.position); if (num > 1f) { continue; } string text = ((Object)((Component)val2).gameObject).name.ToLowerInvariant(); if ((!text.Contains("phone") && !text.Contains("playername") && !text.Contains("username") && !text.Contains("visor") && !text.Contains("helmet")) || !((Behaviour)val2).enabled) { continue; } ((Behaviour)val2).enabled = false; suppressedCanvases.Add(val2); if (occlusionDebug) { try { log.LogInfo((object)("[POV-OCC] Suppressed Nearby Canvas: " + ((Object)((Component)val2).gameObject).name + " root=" + ((Object)((Component)val2).transform.root).name + " dist=" + num.ToString("F3"))); } catch (Exception) { } } } return; } catch (Exception) { return; } } Canvas[] array4 = componentsInChildren; foreach (Canvas val3 in array4) { if (!((Object)(object)val3 == (Object)null) && !((Behaviour)val3).enabled && suppressedCanvases.Contains(val3)) { ((Behaviour)val3).enabled = true; } } suppressedCanvases.RemoveAll((Canvas x) => (Object)(object)x == (Object)null); } catch (Exception) { } } private Vector3 ComputeDodgeOffset(Vector3 anchorPosition, Transform head, float modelRadius) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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) try { if (suppressedRenderers == null || suppressedRenderers.Count == 0) { return Vector3.zero; } Vector3 val = Vector3.zero; float num = 0f; foreach (Renderer suppressedRenderer in suppressedRenderers) { if (!((Object)(object)suppressedRenderer == (Object)null)) { Bounds bounds = suppressedRenderer.bounds; Vector3 center = ((Bounds)(ref bounds)).center; float num2 = Vector3.Distance(anchorPosition, center); float num3 = 1f / (0.001f + num2); val += center * num3; num += num3; } } if (num <= 0f) { return Vector3.zero; } Vector3 val2 = val / num; Vector3 val3 = val2 - anchorPosition; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude <= 0.0001f) { return Vector3.zero; } Vector3 val4 = val3 / magnitude; float num4 = Mathf.Clamp01(1f - magnitude / 1f); float num5 = Mathf.Min(0.25f, modelRadius * 1.2f); float num6 = num5 * num4; return -val4 * num6; } catch (Exception)