Decompiled source of Coilhead mod v1.2.7
Mods/CoilHead.dll
Decompiled 2 weeks 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BoneLib; using BoneLib.BoneMenu; using CoilHead; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Input; using Il2CppSLZ.Marrow.Utilities; using Il2CppSLZ.VRMK; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LabFusion.Data; using LabFusion.Entities; using LabFusion.Network; using LabFusion.Player; using LabFusion.SDK.Metadata; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(CoilHeadMod), "Coil Head", "1.2.7", "CoilHead", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("CoilHead")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.7.0")] [assembly: AssemblyInformationalVersion("1.2.7")] [assembly: AssemblyProduct("CoilHead")] [assembly: AssemblyTitle("CoilHead")] [assembly: AssemblyVersion("1.2.7.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CoilHead { public sealed class CoilHeadMod : MelonMod { private readonly WatchTimer _timer = new WatchTimer(); private readonly ModSettings _settings = new ModSettings(); private readonly PoseLock _pose = new PoseLock(null, delegate(string message) { MelonLogger.Warning(message); }); private readonly List<NetworkPlayer> _watchers = new List<NetworkPlayer>(); private readonly List<AIBrain> _npcWatchers = new List<AIBrain>(); private readonly NpcWatcherScanner _npcScanner = new NpcWatcherScanner(); private ObserverMode _mode; private readonly WatcherOutline _outline = new WatcherOutline(); private readonly WatcherScanner _scanner = new WatcherScanner(); private readonly DisableGesture _gesture = new DisableGesture(); private readonly CountdownHud _hud = new CountdownHud(); private readonly RemoteFreeze _remote = new RemoteFreeze(); private bool _showHud = true; private bool _showHighlights = true; private float _nextVisualRetry; private float _nextHudRetry; private static readonly Color Gold = new Color(1f, 0.9f, 0.08f); private static readonly Color Mint = new Color(0.2f, 1f, 0.72f); private Page? _menuRoot; private BoolElement? _toggle; private FunctionElement? _status; private RigManager? _rig; private Transform? _avatar; private bool _enabled; private readonly FusionPoseSupport _fusion = new FusionPoseSupport(); private bool _wasConnected; private float _nextStatus; private int _freezeSegmentSeconds = 20; public override void OnInitializeMelon() { _settings.Load(); _timer.Configure(_settings.FreezeSeconds, _settings.CooldownSeconds, _settings.LookSeconds, _settings.ReleaseSeconds); SightQuery.ViewAngle = _settings.ViewAngle; ((MelonBase)this).LoggerInstance.Msg("Coil Head 1.2.7 loaded [shared PC/Quest; Fusion 1.14.3 compatibility checked]. Pose-only freezing; no native rig detours."); } private void Menu() { //IL_001f: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) if (Page.Root == null || _menuRoot == Page.Root) { return; } Page val = Page.Root.CreatePage("Coil Head", Gold, 0, true); _status = val.CreateFunction("OFF / COILHEAD", Color.gray, (Action)delegate { }); ((Element)_status).SetTooltip("Gold: frozen, including the release delay after sight is lost. Mint: cooldown, free to move. White: ready."); _toggle = val.CreateBool("Enable Coil Head", Gold, _enabled, (Action<bool>)SetEnabled); ((Element)_toggle).SetTooltip("Combined look time qualifies each freeze. Brief look-aways keep the same pose for the release delay; the countdown continues. No new freeze in its final 5 seconds."); val.CreateEnum("Who can freeze you", Gold, (Enum)_mode, (Action<Enum>)delegate(Enum value) { Reset(); _mode = (ObserverMode)(object)value; }); val.CreateFunction("Emergency release / disable", Color.red, (Action)delegate { SetEnabled(value: false); }); Page obj = val.CreatePage("Settings", Mint, 0, true); ((Element)obj.CreateFloat("Release delay (seconds)", Color.white, _settings.ReleaseSeconds, 0.25f, 0f, 5f, (Action<float>)delegate(float value) { Reset(); _settings.ReleaseSeconds = value; _timer.Configure(_settings.FreezeSeconds, _settings.CooldownSeconds, _settings.LookSeconds, _settings.ReleaseSeconds); })).SetTooltip("Keep the same frozen pose after everyone looks away. Default 2s. A quick look-back keeps the hold smooth. Countdown expiry and disable always release."); ((Element)obj.CreateFloat("Look time before freezing", Color.white, _settings.LookSeconds, 0.25f, 0f, 10f, (Action<float>)delegate(float value) { Reset(); _settings.LookSeconds = value; _timer.Configure(_settings.FreezeSeconds, _settings.CooldownSeconds, _settings.LookSeconds, _settings.ReleaseSeconds); })).SetTooltip("Seconds of combined looks needed before each freeze. Pauses while unseen. Default 2.5s; 0 freezes instantly."); obj.CreateInt("Freeze duration (seconds)", Color.white, _settings.FreezeSeconds, 1, 1, 120, (Action<int>)delegate(int value) { Reset(); _settings.FreezeSeconds = value; _timer.Configure(_settings.FreezeSeconds, _settings.CooldownSeconds, _settings.LookSeconds, _settings.ReleaseSeconds); }); obj.CreateInt("Cooldown (seconds)", Color.white, _settings.CooldownSeconds, 1, 0, 120, (Action<int>)delegate(int value) { Reset(); _settings.CooldownSeconds = value; _timer.Configure(_settings.FreezeSeconds, _settings.CooldownSeconds, _settings.LookSeconds, _settings.ReleaseSeconds); }); ((Element)obj.CreateInt("View cone (degrees)", Color.white, _settings.ViewAngle, 5, 20, 100, (Action<int>)delegate(int value) { Reset(); _settings.ViewAngle = value; SightQuery.ViewAngle = _settings.ViewAngle; })).SetTooltip("Full cone around headset forward. Lower values require a more direct look. Default: 60 degrees."); obj.CreateEnum("Outline color", _settings.Color, (Enum)_settings.ColorChoice, (Action<Enum>)delegate(Enum value) { _settings.ColorChoice = (OutlineColor)(object)value; }); Page obj2 = val.CreatePage("Display & highlights", Mint, 0, true); obj2.CreateBool("VR countdown", Color.white, _showHud, (Action<bool>)delegate(bool value) { _showHud = value; if (!value) { _hud.Hide(); } }); obj2.CreateBool("Watcher outlines", Gold, _showHighlights, (Action<bool>)delegate(bool value) { _showHighlights = value; if (!value) { _outline.Clear(); } }); _menuRoot = Page.Root; } private void SetEnabled(bool value) { _enabled = false; Reset(); _enabled = value; if (_toggle != null) { _toggle.Value = value; } ((MelonBase)this).LoggerInstance.Msg(value ? $"Coil Head enabled. Look time {_settings.LookSeconds}s; release delay {_settings.ReleaseSeconds}s; freeze {_settings.FreezeSeconds}s; cooldown {_settings.CooldownSeconds}s." : "Coil Head disabled; released."); } public override void OnUpdate() { //IL_06d1: Unknown result type (might be due to invalid IL or missing references) //IL_06ca: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) string stage = "controller input"; try { if (_enabled) { XRApi xr = MarrowGame.xr; XRController val = ((xr != null) ? xr.LeftController : null); XRController val2 = ((xr != null) ? xr.RightController : null); bool flag = val != null && val2 != null && (Object)(object)Player.LeftController != (Object)null && (Object)(object)Player.RightController != (Object)null && ((Behaviour)Player.LeftController).isActiveAndEnabled && ((Behaviour)Player.RightController).isActiveAndEnabled; if (_gesture.Tick(flag, flag ? val.Trigger : 0f, flag ? val2.Trigger : 0f, flag && val.BButton, flag && val2.BButton, Time.realtimeSinceStartupAsDouble)) { SetEnabled(value: false); } } stage = "menu"; Menu(); stage = "rig setup"; RigManager rigManager = Player.RigManager; if ((Object)(object)_rig != (Object)(object)rigManager) { goto IL_0119; } if ((Object)(object)rigManager != (Object)null) { Transform? avatar = _avatar; Avatar avatar2 = rigManager.avatar; if ((Object)(object)avatar != (Object)(object)((avatar2 != null) ? ((Component)avatar2).transform : null)) { goto IL_0119; } } goto IL_0151; IL_0119: Reset(); _rig = rigManager; _avatar = (((Object)(object)rigManager != (Object)null && (Object)(object)rigManager.avatar != (Object)null) ? ((Component)rigManager.avatar).transform : null); goto IL_0151; IL_0151: bool hasServer = NetworkInfo.HasServer; if (hasServer != _wasConnected) { PlayerGaze.Clear(); _scanner.Clear(); _wasConnected = hasServer; } bool flag2 = _enabled && (_mode != ObserverMode.Players || hasServer) && (Object)(object)_rig != (Object)null && (Object)(object)_rig.physicsRig != (Object)null && (Object)(object)_avatar != (Object)null && (Object)(object)Player.Head != (Object)null && ((Object)(object)_rig.health == (Object)null || _rig.health.curr_Health > 0f); if (flag2) { stage = "Fusion setup"; if (hasServer) { _fusion.Ensure(QuestVisuals.Standalone, (Action)InstallPcOutgoingHook, (Action<string>)((MelonBase)this).LoggerInstance.Msg, (Action<string>)((MelonBase)this).LoggerInstance.Warning); } stage = "local pose tracking"; _pose.Track(_rig); } else { _pose.StopTracking(); } stage = "Fusion player observation"; if (flag2 && NetworkInfo.HasServer && _mode != ObserverMode.NPCs) { _scanner.Scan(Time.unscaledTime, _rig, _watchers); } else { _watchers.Clear(); _scanner.Clear(); } stage = "NPC observation"; if (flag2 && _mode != ObserverMode.Players) { _npcScanner.Scan(Time.unscaledTime, _rig, _npcWatchers); } else { _npcWatchers.Clear(); _npcScanner.Clear(); } stage = "freeze timing"; int num = _watchers.Count + _npcWatchers.Count; bool frozen = _timer.Frozen; bool flag3 = _timer.Tick(flag2, num > 0, Time.realtimeSinceStartupAsDouble); if (flag3) { if (!frozen) { _freezeSegmentSeconds = Math.Clamp((int)Math.Ceiling(_timer.FreezeRemaining), 1, 120); } if (!_pose.Active) { _pose.Capture(_rig, _timer.FreezeRemaining); } _pose.Renew(); } else if (frozen || _pose.Active) { _pose.StopTracking(); } else { _pose.Release(); } if (flag3 != frozen) { ((MelonBase)this).LoggerInstance.Msg(flag3 ? $"Frozen: {_watchers.Count} player(s), {_npcWatchers.Count} NPC(s)." : ("Released: " + ((num == 0) ? "unseen" : "freeze limit") + "; pose callbacks cleared.")); } stage = "Fusion freeze metadata"; _remote.Publish(flag2 && NetworkInfo.HasServer, _pose.Active, _freezeSegmentSeconds); _remote.Update(_rig); if (Time.unscaledTime >= _nextStatus) { _nextStatus = Time.unscaledTime + 0.2f; if (_status != null) { ((Element)_status).ElementName = ((!_enabled) ? "OFF / COILHEAD" : ((!flag2) ? "WAITING / PLAYER OR LOBBY" : (_pose.Active ? $"FROZEN / {_timer.FreezeRemaining:F1}s / {num} watching" : ((_timer.CooldownRemaining > 0.0) ? $"FREE TO MOVE / {_timer.CooldownRemaining:F1}s" : (_timer.CountdownActive ? $"FREE / COUNTDOWN {_timer.FreezeRemaining:F1}s" : ((_timer.LookElapsed > 0.0 || num > 0) ? $"LOOK TIME / {_timer.LookElapsed:F2} / {_timer.LookSeconds:F2}s" : "READY / UNSEEN")))))); ((Element)_status).ElementColor = ((!_enabled) ? Color.gray : (_pose.Active ? Gold : ((_timer.CooldownRemaining > 0.0) ? Mint : Color.white))); } } } catch (Exception ex) { Fail(ex, stage); } } private void InstallPcOutgoingHook() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(RigPose), "ReadSkeleton", new Type[1] { typeof(RigSkeleton) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(PoseLock), "AfterReadSkeleton", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { throw new MissingMethodException("Fusion outgoing pose signature is unavailable"); } ((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public override void OnFixedUpdate() { try { if (_enabled && _timer.Frozen) { _pose.Hold(); } else { _pose.Release(); } _remote.HoldFixed(); } catch (Exception ex) { Fail(ex); } } public override void OnLateUpdate() { //IL_0101: Unknown result type (might be due to invalid IL or missing references) try { if (_enabled && _timer.Frozen) { _pose.HoldVisual(); } else { _pose.Release(); } } catch (Exception ex) { Fail(ex); } if (Time.unscaledTime >= _nextHudRetry) { try { _hud.Tick(Time.unscaledTime, _enabled && _showHud, _timer, _watchers.Count + _npcWatchers.Count); } catch (Exception ex2) { _nextHudRetry = Time.unscaledTime + 2f; _hud.Hide(); ((MelonBase)this).LoggerInstance.Warning("Coil Head HUD retry in 2s: " + ex2.Message); } } if (Time.unscaledTime < _nextVisualRetry) { return; } try { if (_enabled && _showHighlights) { _outline.Draw(_watchers, _npcWatchers, Player.Head, _settings.Color); } } catch (Exception ex3) { _nextVisualRetry = Time.unscaledTime + 10f; ((MelonBase)this).LoggerInstance.Warning("Coil Head visual retry in 10s: " + ex3.Message); } } private void Fail(Exception ex, string stage = "physics / visual update") { _enabled = false; try { Reset(); if (_toggle != null) { _toggle.Value = false; } } catch (Exception ex2) { ((MelonBase)this).LoggerInstance.Error((object)ex2); } ((MelonBase)this).LoggerInstance.Error("Coil Head disabled and released during " + stage + ": " + ex); } private void Reset() { _pose.StopTracking(); PlayerGaze.Clear(); _timer.Reset(); _gesture.Reset(); _scanner.Clear(); _watchers.Clear(); _npcScanner.Clear(); _npcWatchers.Clear(); _outline.Clear(); _hud.Hide(); _nextVisualRetry = (_nextHudRetry = 0f); _remote.Publish(enabled: false, frozen: false); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { Reset(); PlayerGaze.Clear(); _remote.ResetPeers(); _rig = null; _avatar = null; } public override void OnDeinitializeMelon() { Reset(); PlayerGaze.Clear(); _remote.ResetPeers(); _outline.Dispose(); _hud.Dispose(); QuestVisuals.Dispose(); } } internal sealed class CountdownHud : IDisposable { private GameObject? _root; private Canvas? _canvas; private Text? _number; private Material? _material; private Font? _font; private int _layer = -1; private int _lastSecond = -1; internal void Tick(float now, bool visible, WatchTimer timer, int watchers) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_017f: Unknown result type (might be due to invalid IL or missing references) CountdownReading countdownReading = CountdownReading.Read(visible, timer); if (!countdownReading.Visible) { Hide(); return; } Camera val = HeadsetView.Camera(); if ((Object)(object)val == (Object)null) { Hide(); return; } if ((Object)(object)_root == (Object)null) { Build(); } _canvas.worldCamera = val; Transform transform = _root.transform; if ((Object)(object)transform.parent != (Object)(object)((Component)val).transform) { transform.SetParent(((Component)val).transform, false); } float num = Math.Max(1.15f, val.nearClipPlane + 0.3f); Vector3 localPosition = CornerPosition(val, num); transform.localPosition = localPosition; transform.localRotation = Quaternion.identity; float num2 = num * 0.00085f; transform.localScale = new Vector3(num2, num2, num2); int num3 = HeadsetView.VisibleLayer(val.cullingMask); if (num3 < 0) { Hide(); return; } if (_layer != num3) { foreach (Transform componentsInChild in _root.GetComponentsInChildren<Transform>(true)) { ((Component)componentsInChild).gameObject.layer = num3; } _layer = num3; } if (_lastSecond != countdownReading.Seconds) { _number.text = countdownReading.Seconds.ToString(); ((Graphic)_number).color = ((countdownReading.Seconds <= 3) ? new Color(1f, 0.78f, 0.28f, 1f) : new Color(1f, 0.96f, 0.78f, 1f)); _lastSecond = countdownReading.Seconds; } if (!_root.activeSelf) { _root.SetActive(true); } } private static Vector3 CornerPosition(Camera camera, float distance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) try { Matrix4x4 stereoProjectionMatrix = camera.GetStereoProjectionMatrix((StereoscopicEye)0); Matrix4x4 stereoProjectionMatrix2 = camera.GetStereoProjectionMatrix((StereoscopicEye)1); return CountdownPlacement.Position(distance, ((Matrix4x4)(ref stereoProjectionMatrix))[0, 0], ((Matrix4x4)(ref stereoProjectionMatrix))[0, 2], ((Matrix4x4)(ref stereoProjectionMatrix))[1, 1], ((Matrix4x4)(ref stereoProjectionMatrix))[1, 2], ((Matrix4x4)(ref stereoProjectionMatrix2))[0, 0], ((Matrix4x4)(ref stereoProjectionMatrix2))[0, 2], ((Matrix4x4)(ref stereoProjectionMatrix2))[1, 1], ((Matrix4x4)(ref stereoProjectionMatrix2))[1, 2]); } catch { return CountdownPlacement.Fallback(distance); } } private void Build() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) Dispose(); try { try { _font = Resources.GetBuiltinResource<Font>("Arial.ttf"); } catch { _font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); } if ((Object)(object)_font == (Object)null) { _font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); } if ((Object)(object)_font == (Object)null) { throw new InvalidOperationException("Countdown font unavailable"); } Shader val = (QuestVisuals.Standalone ? QuestVisuals.Find("UI/Default") : null); _material = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(Graphic.defaultGraphicMaterial)); ((Object)_material).hideFlags = (HideFlags)61; _material.renderQueue = 5000; if (_material.HasProperty("_ZTest")) { _material.SetInt("_ZTest", 8); } if (_material.HasProperty("_ZWrite")) { _material.SetInt("_ZWrite", 0); } if (_material.HasProperty("_Cull")) { _material.SetInt("_Cull", 0); } if ((Object)(object)val == (Object)null || _material.HasProperty("unity_GUIZTestMode")) { _material.SetInt("unity_GUIZTestMode", 8); } _root = new GameObject("CoilHead.VR.Countdown", (Type[])(object)new Type[1] { Il2CppType.Of<RectTransform>() }); ((Object)_root).hideFlags = (HideFlags)61; _root.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_root); _canvas = _root.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)2; _canvas.sortingOrder = 32700; _root.GetComponent<RectTransform>().sizeDelta = new Vector2(110f, 80f); GameObject val2 = new GameObject("Seconds", (Type[])(object)new Type[1] { Il2CppType.Of<RectTransform>() }); RectTransform component = val2.GetComponent<RectTransform>(); ((Transform)component).SetParent(_root.transform, false); Vector2 val3 = (component.pivot = new Vector2(0.5f, 0.5f)); Vector2 anchorMin = (component.anchorMax = val3); component.anchorMin = anchorMin; component.sizeDelta = new Vector2(110f, 80f); _number = val2.AddComponent<Text>(); _number.font = _font; _number.fontSize = 56; _number.fontStyle = (FontStyle)1; ((Graphic)_number).material = _material; _number.alignment = (TextAnchor)4; ((Graphic)_number).raycastTarget = false; _number.supportRichText = false; Shadow obj2 = val2.AddComponent<Shadow>(); obj2.effectColor = new Color(0f, 0f, 0f, 0.85f); obj2.effectDistance = new Vector2(1.5f, -1.5f); } catch { Dispose(); throw; } } internal void Hide() { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); } _lastSecond = -1; } public void Dispose() { Hide(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } _root = null; _canvas = null; _number = null; _material = null; _layer = -1; } } internal static class CountdownPlacement { internal static Vector3 Fallback(float distance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return new Vector3((0f - distance) * 0.28f, (0f - distance) * 0.22f, distance); } internal static Vector3 Position(float distance, float lx, float lcx, float ly, float lcy, float rx, float rcx, float ry, float rcy) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) float num = Math.Min((1f - lcx) / lx, (1f - rcx) / rx); float num2 = Math.Min((1f - lcy) / ly, (1f - rcy) / ry); if (!float.IsFinite(num) || !float.IsFinite(num2) || num <= 0f || num2 <= 0f || lx <= 0f || ly <= 0f || rx <= 0f || ry <= 0f) { return Fallback(distance); } return new Vector3((0f - distance) * Math.Min(num * 0.38f, 0.3f), (0f - distance) * Math.Min(num2 * 0.34f, 0.24f), distance); } } internal readonly record struct CountdownReading(bool Visible, int Seconds, float Fraction) { internal static CountdownReading Read(bool enabled, WatchTimer timer) { if (!enabled || !timer.CountdownActive || timer.FreezeRemaining <= 0.0) { return default(CountdownReading); } double freezeRemaining = timer.FreezeRemaining; return new CountdownReading(Visible: true, (int)Math.Ceiling(freezeRemaining), (float)Math.Clamp(freezeRemaining / timer.FreezeSeconds, 0.0, 1.0)); } } internal sealed class DisableGesture { private enum Phase { Neutral, Ready, Gathering, Held } private Phase _phase; private bool _leftDown; private bool _rightDown; private bool _firstTap; private double? _neutralSince; private double _pressStarted; private double _firstReleased; private double _last = double.NegativeInfinity; public bool Tick(bool available, float leftTrigger, float rightTrigger, bool y, bool b, double now) { if (!available || !double.IsFinite(now) || !float.IsFinite(leftTrigger) || !float.IsFinite(rightTrigger)) { Reset(); return false; } if (now < _last || (double.IsFinite(_last) && now - _last > 0.5)) { Reset(); } _last = now; _leftDown = leftTrigger >= (_leftDown ? 0.55f : 0.8f); _rightDown = rightTrigger >= (_rightDown ? 0.55f : 0.8f); bool flag = leftTrigger < 0.55f && rightTrigger < 0.55f && !y && !b; bool flag2 = _leftDown && _rightDown && y && b; if (_firstTap && now - _firstReleased > 0.65) { _firstTap = false; } if (_phase == Phase.Neutral) { _neutralSince = (flag ? new double?(_neutralSince ?? now) : ((double?)null)); if (_neutralSince.HasValue && now - _neutralSince.Value >= 0.04) { _phase = Phase.Ready; } return false; } if (_phase == Phase.Ready) { if (!_leftDown && !_rightDown && !y && !b) { return false; } _pressStarted = now; _phase = Phase.Gathering; } if (_phase == Phase.Gathering) { if (now - _pressStarted > 0.2 || flag) { CancelTap(); return false; } if (!flag2) { return false; } if (_firstTap) { Reset(); return true; } _phase = Phase.Held; } if (_phase == Phase.Held) { if (now - _pressStarted > 0.4) { CancelTap(); return false; } if (flag) { _firstTap = true; _firstReleased = now; _neutralSince = now; _phase = Phase.Neutral; } } return false; } private void CancelTap() { _phase = Phase.Neutral; _firstTap = false; _neutralSince = null; } public void Reset() { CancelTap(); _leftDown = (_rightDown = false); _pressStarted = (_firstReleased = 0.0); _last = double.NegativeInfinity; } } internal static class EchoMeshSpace { internal static bool TryGetDrawMatrix(Renderer renderer, SkinnedMeshRenderer? skin, Mesh snapshot, out Matrix4x4 matrix) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0197: 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) matrix = (((Object)(object)skin != (Object)null) ? Matrix4x4.TRS(((Component)skin).transform.position, ((Component)skin).transform.rotation, Vector3.one) : renderer.localToWorldMatrix); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (!float.IsFinite(((Matrix4x4)(ref matrix))[i, j])) { return false; } } } if (Math.Abs(((Matrix4x4)(ref matrix))[3, 0]) > 1E-05f || Math.Abs(((Matrix4x4)(ref matrix))[3, 1]) > 1E-05f || Math.Abs(((Matrix4x4)(ref matrix))[3, 2]) > 1E-05f || Math.Abs(((Matrix4x4)(ref matrix))[3, 3] - 1f) > 1E-05f) { return false; } Bounds bounds = snapshot.bounds; if (!Usable(bounds)) { return false; } Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3 value = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(((Bounds)(ref bounds)).center); Vector3 value2 = default(Vector3); ((Vector3)(ref value2))..ctor(Math.Abs(((Matrix4x4)(ref matrix))[0, 0]) * extents.x + Math.Abs(((Matrix4x4)(ref matrix))[0, 1]) * extents.y + Math.Abs(((Matrix4x4)(ref matrix))[0, 2]) * extents.z, Math.Abs(((Matrix4x4)(ref matrix))[1, 0]) * extents.x + Math.Abs(((Matrix4x4)(ref matrix))[1, 1]) * extents.y + Math.Abs(((Matrix4x4)(ref matrix))[1, 2]) * extents.z, Math.Abs(((Matrix4x4)(ref matrix))[2, 0]) * extents.x + Math.Abs(((Matrix4x4)(ref matrix))[2, 1]) * extents.y + Math.Abs(((Matrix4x4)(ref matrix))[2, 2]) * extents.z); if (!Finite(value) || !Finite(value2)) { return false; } return ((Vector3)(ref value2)).sqrMagnitude <= 10000f; } internal static bool SameScale(Vector3 first, Vector3 second) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Finite(first) && Finite(second) && Close(first.x, second.x) && Close(first.y, second.y)) { return Close(first.z, second.z); } return false; } private static bool Close(float first, float second) { return Math.Abs(first - second) <= 0.0001f * Math.Max(0.0001f, Math.Max(Math.Abs(first), Math.Abs(second))); } private static bool Usable(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (Finite(((Bounds)(ref bounds)).center) && Finite(((Bounds)(ref bounds)).extents) && ((Bounds)(ref bounds)).extents.x >= 0f && ((Bounds)(ref bounds)).extents.y >= 0f && ((Bounds)(ref bounds)).extents.z >= 0f) { Vector3 extents = ((Bounds)(ref bounds)).extents; return ((Vector3)(ref extents)).sqrMagnitude > 0f; } return false; } private static bool Finite(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (float.IsFinite(value.x) && float.IsFinite(value.y)) { return float.IsFinite(value.z); } return false; } } internal enum FusionPoseMode { NotStarted, HookFree, PcOutgoingHook } internal sealed class FusionPoseSupport { internal FusionPoseMode Mode { get; private set; } internal void Ensure(bool standalone, Action installPcOutgoingHook, Action<string> info, Action<string> warning) { if (Mode != FusionPoseMode.NotStarted) { return; } Mode = FusionPoseMode.HookFree; if (standalone) { info("Quest Fusion: fresh-pose polling and metadata pose holds; managed detours skipped."); return; } try { installPcOutgoingHook(); Mode = FusionPoseMode.PcOutgoingHook; info("PC Fusion: outgoing-pose hook ready; incoming gaze uses fresh-pose polling."); } catch (Exception ex) { warning("Coil Head Fusion outgoing hook unavailable; using hook-free pose holds: " + ex.GetBaseException().Message); } } } internal static class HeadsetView { internal static Camera? Camera() { //IL_0071: 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) OpenControllerRig controllerRig = Player.ControllerRig; Il2CppReferenceArray<Camera> val = ((controllerRig != null) ? controllerRig.cameras : null); if (val != null) { for (int i = 0; i < ((Il2CppArrayBase<Camera>)(object)val).Length; i++) { if ((Object)(object)((Il2CppArrayBase<Camera>)(object)val)[i] != (Object)null && ((Behaviour)((Il2CppArrayBase<Camera>)(object)val)[i]).isActiveAndEnabled && (int)((Il2CppArrayBase<Camera>)(object)val)[i].stereoTargetEye != 0) { return ((Il2CppArrayBase<Camera>)(object)val)[i]; } } } Camera main = Camera.main; if (!((Object)(object)main != (Object)null) || !((Behaviour)main).isActiveAndEnabled || (int)main.stereoTargetEye == 0) { return null; } return main; } internal static int VisibleLayer(int mask) { if ((mask & 0x20) != 0) { return 5; } for (int i = 0; i < 32; i++) { if ((mask & (1 << i)) != 0) { return i; } } return -1; } } internal enum OutlineColor { Yellow, White, Cyan, Green, Blue, Purple, Pink, Red } internal sealed class ModSettings { private MelonPreferences_Category _category; private MelonPreferences_Entry<int> _freeze; private MelonPreferences_Entry<int> _cooldown; private MelonPreferences_Entry<int> _angle; private MelonPreferences_Entry<float> _lookTime; private MelonPreferences_Entry<float> _releaseDelay; private MelonPreferences_Entry<OutlineColor> _color; internal int FreezeSeconds { get { return Math.Clamp(_freeze.Value, 1, 120); } set { _freeze.Value = Math.Clamp(value, 1, 120); Save(); } } internal int CooldownSeconds { get { return Math.Clamp(_cooldown.Value, 0, 120); } set { _cooldown.Value = Math.Clamp(value, 0, 120); Save(); } } internal int ViewAngle { get { return Math.Clamp(_angle.Value, 20, 100); } set { _angle.Value = Math.Clamp(value, 20, 100); Save(); } } internal float LookSeconds { get { return ClampLookTime(_lookTime.Value); } set { _lookTime.Value = ClampLookTime(value); Save(); } } internal float ReleaseSeconds { get { return ClampRelease(_releaseDelay.Value); } set { _releaseDelay.Value = ClampRelease(value); Save(); } } internal OutlineColor ColorChoice { get { if (!Enum.IsDefined(typeof(OutlineColor), _color.Value)) { return OutlineColor.Yellow; } return _color.Value; } set { _color.Value = value; Save(); } } internal Color Color => (Color)(ColorChoice switch { OutlineColor.White => new Color(1f, 1f, 1f), OutlineColor.Cyan => new Color(0f, 1f, 1f), OutlineColor.Green => new Color(0.2f, 1f, 0.15f), OutlineColor.Blue => new Color(0.2f, 0.45f, 1f), OutlineColor.Purple => new Color(0.65f, 0.25f, 1f), OutlineColor.Pink => new Color(1f, 0.25f, 0.65f), OutlineColor.Red => new Color(1f, 0.15f, 0.08f), _ => new Color(1f, 0.9f, 0.02f), }); private static float ClampLookTime(float value) { if (!float.IsFinite(value)) { return 2.5f; } return Math.Clamp(value, 0f, 10f); } private static float ClampRelease(float value) { if (!float.IsFinite(value)) { return 2f; } return Math.Clamp(value, 0f, 5f); } internal void Load() { _category = MelonPreferences.CreateCategory("MannequinMod"); _freeze = _category.CreateEntry<int>("FreezeSeconds", 20, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _cooldown = _category.CreateEntry<int>("CooldownSeconds", 20, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _angle = _category.CreateEntry<int>("ViewAngleDegrees", 60, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _lookTime = _category.CreateEntry<float>("LookSeconds", 2.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _releaseDelay = _category.CreateEntry<float>("ReleaseDelaySeconds", 2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _color = _category.CreateEntry<OutlineColor>("OutlineColor", OutlineColor.Yellow, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } private void Save() { _category.SaveToFile(false); } } internal enum ObserverMode { Players, NPCs, Both } internal sealed class NpcWatcherScanner { private sealed class Observer { internal AIBrain Brain; internal bool Watching; internal float NextCheck; internal float LastCheck; } private readonly List<Observer> _npcs = new List<Observer>(); private readonly Dictionary<int, Observer> _previous = new Dictionary<int, Observer>(); private readonly SightQuery _sight = new SightQuery(); private int _cursor; private float _nextRoster; internal void Scan(float now, RigManager local, List<AIBrain> watchers) { //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) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) if (now >= _nextRoster) { _nextRoster = now + 2f; _previous.Clear(); foreach (Observer npc in _npcs) { if ((Object)(object)npc.Brain != (Object)null) { _previous[((Object)npc.Brain).GetInstanceID()] = npc; } } _npcs.Clear(); foreach (AIBrain item in Object.FindObjectsOfType<AIBrain>()) { if (Alive(item)) { _npcs.Add(_previous.TryGetValue(((Object)item).GetInstanceID(), out Observer value) ? value : new Observer { Brain = item }); } } _previous.Clear(); } Vector3 position = ((Rig)local.physicsRig).m_head.position; Vector3 position2 = ((Rig)local.physicsRig).m_pelvis.position; Vector3 point = Vector3.Lerp(position, position2, 0.55f); int num = 0; for (int i = 0; i < _npcs.Count; i++) { if (num >= 4) { break; } if (_cursor >= _npcs.Count) { _cursor = 0; } Observer observer = _npcs[_cursor++]; if (!(now < observer.NextCheck)) { num++; observer.NextCheck = now + 0.05f; observer.LastCheck = now; observer.Watching = false; AIBrain brain = observer.Brain; if (Alive(brain)) { Transform eyeTran = brain.behaviour.eyeTran; Transform transform = ((Component)brain.puppetMaster).transform; Transform targetRoot = brain.puppetMaster.targetRoot; observer.Watching = _sight.Visible(eyeTran.position, eyeTran.forward, transform, ((Component)local).transform, position, targetRoot) || _sight.Visible(eyeTran.position, eyeTran.forward, transform, ((Component)local).transform, point, targetRoot) || _sight.Visible(eyeTran.position, eyeTran.forward, transform, ((Component)local).transform, position2, targetRoot); } } } watchers.Clear(); foreach (Observer npc2 in _npcs) { if (!npc2.Watching || now < npc2.LastCheck || now - npc2.LastCheck > 0.35f || !Alive(npc2.Brain)) { npc2.Watching = false; continue; } Transform eyeTran2 = npc2.Brain.behaviour.eyeTran; if (!SightQuery.InCone(eyeTran2.position, eyeTran2.forward, position) && !SightQuery.InCone(eyeTran2.position, eyeTran2.forward, point) && !SightQuery.InCone(eyeTran2.position, eyeTran2.forward, position2)) { npc2.Watching = false; } else { watchers.Add(npc2.Brain); } } } private static bool Alive(AIBrain? brain) { if ((Object)(object)brain != (Object)null && ((Component)brain).gameObject.activeInHierarchy && !brain.isDead && (Object)(object)brain.puppetMaster != (Object)null && brain.puppetMaster.isAlive && (Object)(object)brain.behaviour != (Object)null) { return (Object)(object)brain.behaviour.eyeTran != (Object)null; } return false; } internal void Clear() { _npcs.Clear(); _previous.Clear(); _cursor = 0; _nextRoster = 0f; } } internal static class PlayerGaze { private sealed class Receipt { internal double At = double.NegativeInfinity; internal RigPose? Pose; internal RigManager? Rig; } private static readonly ConditionalWeakTable<NetworkPlayer, Receipt> Receipts = new ConditionalWeakTable<NetworkPlayer, Receipt>(); internal static void Received(NetworkPlayer player, double now) { Receipt value = Receipts.GetValue(player, (NetworkPlayer _) => new Receipt()); value.Pose = player.RigPose; RigRefs rigRefs = player.RigRefs; value.Rig = ((rigRefs != null) ? rigRefs.RigManager : null); value.At = now; } internal static void Clear() { Receipts.Clear(); } private static Receipt Observe(NetworkPlayer player, RigPose pose, RigManager rig, double now) { Receipt value = Receipts.GetValue(player, (NetworkPlayer _) => new Receipt()); if (value.Pose == null || (Object)(object)value.Rig != (Object)(object)rig || now < value.At) { value.Pose = pose; value.Rig = rig; value.At = double.NegativeInfinity; } else if (value.Pose != pose) { value.Pose = pose; value.At = now; } return value; } internal static bool TryRead(NetworkPlayer player, double now, out Vector3 eye, out Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) eye = (forward = Vector3.zero); if (!double.IsFinite(now)) { return false; } RigPose rigPose = player.RigPose; RigRefs rigRefs = player.RigRefs; Transform val = ((rigRefs != null) ? rigRefs.Headset : null); RigManager val2 = ((rigRefs != null) ? rigRefs.RigManager : null); if (!player.ReceivedPose || !player.HasRig || rigPose == null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Receipts.Remove(player); return false; } Receipt receipt = Observe(player, rigPose, val2, now); if (!double.IsFinite(receipt.At) || now < receipt.At || now - receipt.At > 0.35 || rigPose.TrackedPoints == null || rigPose.TrackedPoints.Length < 1 || rigPose.TrackedPoints[0] == null) { return false; } SerializedLocalTransform val3 = rigPose.TrackedPoints[0]; Transform parent = val.parent; eye = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(val3.position) : val3.position); Quaternion val4 = (((Object)(object)parent != (Object)null) ? parent.rotation : Quaternion.identity); Transform val5 = player.RigSkeleton?.TrackedPlayspace; if ((Object)(object)val5 != (Object)null) { val4 = rigPose.TrackedPlayspaceExpanded * Quaternion.Inverse(val5.rotation) * val4; } forward = val4 * val3.rotation * Vector3.forward; return true; } } internal sealed class PlayerSilhouetteRenderer : IDisposable { private sealed class CachedMesh { internal Renderer Renderer; internal Mesh Source; internal Mesh Mesh; internal Transform AvatarRoot; internal Transform? RootBone; internal Vector3 BakedScale; internal bool HasSnapshot; internal int Vertices; internal Il2CppStructArray<Color>? White; internal float NextBake; internal float LastSeen; internal float ScanTime = float.NegativeInfinity; internal Matrix4x4 ScanMatrix; internal bool HasScanMatrix; } private const int MaxMeshVertices = 120000; private const int MaxCachedVertices = 1000000; private readonly Dictionary<int, CachedMesh> _meshes = new Dictionary<int, CachedMesh>(); private readonly List<int> _expired = new List<int>(); private readonly Action<string> _warning; private Material? _material; private MaterialPropertyBlock? _block; private Mesh? _voiceMarker; private int _bakes; private int _draws; private int _attempts; private int _bakeVertices; private int _cachedVertices; private float _now; private float _nextAttempt; private float _nextCleanup; private float _nextWarning; private bool _disposed; internal bool Ready { get { if (!_disposed) { return (Object)(object)_material != (Object)null; } return false; } } internal PlayerSilhouetteRenderer(Action<string> warning) { _warning = warning; } internal void BeginFrame(float now) { _now = now; _bakes = 1; _draws = 96; _bakeVertices = 120000; if (_disposed) { return; } EnsureMaterial(); if (now < _nextCleanup) { return; } _nextCleanup = now + 0.5f; _expired.Clear(); foreach (KeyValuePair<int, CachedMesh> mesh in _meshes) { if ((Object)(object)mesh.Value.Renderer == (Object)null || now - mesh.Value.LastSeen > 12f) { _expired.Add(mesh.Key); } } foreach (int item in _expired) { Remove(item); } } internal void Draw(float now, SilhouetteTarget target, bool visible, float alpha, int layer, Color color, bool forceRed = false, float scanTime = float.NaN, float voiceGlow = 0f) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Expected O, but got Unknown //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) if (_disposed || (Object)(object)_material == (Object)null || !target.Alive || alpha < 0.01f) { return; } Color val = color; if (voiceGlow > 0f) { float num = Mathf.Clamp01(voiceGlow); val = Color.Lerp(val, new Color(1f, 1f, 0.95f, alpha), num * 0.6f); } _block.Clear(); _block.SetColor("_Color", val); int num2 = Math.Min(target.Renderers.Length, 8); int num3 = 0; int num4 = 64; int num5 = ((num2 > 0) ? (target.NextMesh % num2) : 0); for (int i = 0; i < num2; i++) { if (num4 <= 0) { break; } if (_draws <= 0) { break; } int num6 = (num5 + i) % num2; Renderer val2 = target.Renderers[num6]; try { if ((Object)(object)val2 == (Object)null || !val2.enabled || !((Component)val2).gameObject.activeInHierarchy || ((Object)(object)((Component)val2).transform != (Object)(object)target.AvatarRoot && !((Component)val2).transform.IsChildOf(target.AvatarRoot))) { continue; } SkinnedMeshRenderer val3 = ((Il2CppObjectBase)val2).TryCast<SkinnedMeshRenderer>(); object obj; if (!((Object)(object)val3 != (Object)null)) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); obj = ((component != null) ? component.sharedMesh : null); } else { obj = val3.sharedMesh; } Mesh val4 = (Mesh)obj; if ((Object)(object)val4 == (Object)null || val4.vertexCount == 0 || val4.vertexCount > 120000) { continue; } int vertexCount = val4.vertexCount; int instanceID = ((Object)val2).GetInstanceID(); Transform val5 = (((Object)(object)val3 != (Object)null) ? val3.rootBone : null); Vector3 val6 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).transform.lossyScale : Vector3.one); if (!EchoMeshSpace.SameScale(val6, val6)) { continue; } if (_meshes.TryGetValue(instanceID, out CachedMesh value) && ((Object)(object)value.Renderer != (Object)(object)val2 || (Object)(object)value.Source != (Object)(object)val4 || (Object)(object)value.AvatarRoot != (Object)(object)target.AvatarRoot || (Object)(object)value.RootBone != (Object)(object)val5 || value.Vertices != vertexCount)) { Remove(instanceID); value = null; } if (value != null) { goto IL_02f4; } if (_bakes <= 0 || vertexCount > _bakeVertices) { continue; } while (_meshes.Count >= 128 || _cachedVertices + vertexCount > 1000000) { EvictOldest(); } value = new CachedMesh { Renderer = val2, Source = val4, AvatarRoot = target.AvatarRoot, RootBone = val5, Vertices = vertexCount, Mesh = new Mesh { name = "CoilHead.WatcherSilhouette", hideFlags = (HideFlags)61 } }; _meshes[instanceID] = value; _cachedVertices += vertexCount; goto IL_02f4; IL_02f4: value.LastSeen = now; bool flag = float.IsFinite(scanTime); bool flag2 = flag && scanTime > value.ScanTime; bool flag3 = (Object)(object)val3 != (Object)null && value.HasSnapshot && !EchoMeshSpace.SameScale(value.BakedScale, val6); if ((!flag || flag2) && (now >= value.NextBake || flag3) && _bakes > 0 && vertexCount <= _bakeVertices) { _bakes--; _bakeVertices -= vertexCount; target.NextMesh = (num6 + 1) % num2; value.HasSnapshot = false; value.NextBake = now + 0.2f; if ((Object)(object)val3 != (Object)null) { val3.BakeMesh(value.Mesh, true); } else { Object.Destroy((Object)(object)value.Mesh); value.Mesh = Object.Instantiate<Mesh>(val4); ((Object)value.Mesh).hideFlags = (HideFlags)61; } value.Mesh.RecalculateBounds(); int vertexCount2 = value.Mesh.vertexCount; if (value.White == null || ((Il2CppArrayBase<Color>)(object)value.White).Length != vertexCount2) { value.White = new Il2CppStructArray<Color>((long)vertexCount2); for (int j = 0; j < vertexCount2; j++) { ((Il2CppArrayBase<Color>)(object)value.White)[j] = Color.white; } } value.Mesh.SetColors(value.White); value.BakedScale = val6; value.HasSnapshot = true; value.NextBake = (((Object)(object)val3 != (Object)null) ? (now + ((vertexCount > 120000) ? 0.35f : 0.2f)) : float.PositiveInfinity); } Matrix4x4 matrix; if (value.HasSnapshot && value.Mesh.vertexCount != 0 && (flag || !((Object)(object)val3 != (Object)null) || EchoMeshSpace.SameScale(value.BakedScale, val6))) { if (flag && !flag2 && value.HasScanMatrix) { matrix = value.ScanMatrix; goto IL_054d; } if (EchoMeshSpace.TryGetDrawMatrix(val2, val3, value.Mesh, out matrix)) { goto IL_054d; } if (now >= _nextWarning) { _nextWarning = now + 10f; _warning("Skipped an invalid or oversized watcher mesh snapshot."); } } goto end_IL_00d2; IL_054d: if (flag2) { value.ScanTime = scanTime; value.ScanMatrix = matrix; value.HasScanMatrix = true; } int draws = _draws; for (int k = 0; k < value.Mesh.subMeshCount; k++) { if (num4 <= 0) { break; } if (_draws <= 0) { break; } Graphics.DrawMesh(value.Mesh, matrix, _material, layer, (Camera)null, k, _block, (ShadowCastingMode)0, false, (Transform)null, (LightProbeUsage)0, (LightProbeProxyVolume)null); _draws--; num4--; } if (_draws < draws) { num3++; } end_IL_00d2:; } catch (Exception ex) { if (now >= _nextWarning) { _nextWarning = now + 10f; _warning("Player echo mesh: " + ex.Message); } } } } private void EnsureMaterial() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00f2: 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_0170: Expected O, but got Unknown if ((Object)(object)_material != (Object)null || _now < _nextAttempt) { return; } _attempts++; _nextAttempt = _now + ((_attempts >= 6) ? 10f : 2f); string[] array = new string[2] { "Hidden/Internal-Colored", "GUI/Text Shader" }; foreach (string text in array) { Shader val = QuestVisuals.Find(text); if ((Object)(object)val == (Object)null || !val.isSupported) { continue; } Material val2 = new Material(val) { hideFlags = (HideFlags)61, renderQueue = 5000 }; if (text == "Hidden/Internal-Colored" && (!val2.HasProperty("_ZTest") || !val2.HasProperty("_ZWrite"))) { Object.Destroy((Object)(object)val2); continue; } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.white); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); } Set(val2, "_ZTest", 8); Set(val2, "_ZWrite", 0); Set(val2, "_Cull", 0); Set(val2, "_SrcBlend", 5); Set(val2, "_DstBlend", 10); _material = val2; _block = new MaterialPropertyBlock(); return; } if (_attempts == 1 || _attempts == 6) { _warning("Player echo highlight shader unavailable."); } } private void EvictOldest() { int key = 0; float num = float.PositiveInfinity; foreach (KeyValuePair<int, CachedMesh> mesh in _meshes) { if (mesh.Value.LastSeen < num) { num = mesh.Value.LastSeen; key = mesh.Key; } } Remove(key); } private void Remove(int key) { if (_meshes.TryGetValue(key, out CachedMesh value)) { if ((Object)(object)value.Mesh != (Object)null) { Object.Destroy((Object)(object)value.Mesh); } _cachedVertices -= value.Vertices; _meshes.Remove(key); } } internal void Reset() { foreach (CachedMesh value in _meshes.Values) { if ((Object)(object)value.Mesh != (Object)null) { Object.Destroy((Object)(object)value.Mesh); } } _meshes.Clear(); _cachedVertices = 0; _attempts = 0; _nextAttempt = 0f; _nextCleanup = 0f; if ((Object)(object)_voiceMarker != (Object)null) { Object.Destroy((Object)(object)_voiceMarker); } _voiceMarker = null; } public void Dispose() { if (!_disposed) { _disposed = true; Reset(); if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } _material = null; _block = null; } } private static void Set(Material material, string name, int value) { if (material.HasProperty(name)) { material.SetInt(name, value); } } } internal sealed class PoseLock { private record struct Body(Rigidbody Value, Vector3 Position, Quaternion Rotation); private record struct Bone(Transform Value, Vector3 Position, Quaternion Rotation, Vector3 LocalPosition, Quaternion LocalRotation); private readonly List<Body> _historyBodies = new List<Body>(); private readonly List<Body> _bodies = new List<Body>(); private readonly List<Bone> _historyBones = new List<Bone>(); private readonly List<Bone> _bones = new List<Bone>(); private readonly HashSet<int> _bodyIds = new HashSet<int>(); private readonly Func<double> _clock; private readonly Action<string>? _warning; private readonly bool _localOwner; private double _started; private double _leaseUntil; private double _hardDeadline; private double _historyTime = double.NegativeInfinity; private RigManager? _rig; private Action? _lateCallback; private UnityAction? _renderCallback; private RigSkeleton? _skeleton; private RigPose? _historyPose; private RigPose? _networkPose; internal static PoseLock? Current { get; private set; } public bool Active { get; private set; } internal PoseLock(Func<double>? clock = null, Action<string>? warning = null, bool localOwner = true) { _clock = clock ?? ((Func<double>)(() => Time.realtimeSinceStartupAsDouble)); _warning = warning; _localOwner = localOwner; } internal void Track(RigManager rig) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown if ((Object)(object)_rig == (Object)(object)rig) { return; } StopTracking(); _rig = rig; try { _bodyIds.Clear(); Enumerator<Rigidbody> enumerator = rig.physicsRig.selfRbs.GetEnumerator(); while (enumerator.MoveNext()) { Rigidbody current = enumerator.Current; AddBody(current); } AddBody(rig.physicsRig.rbFeet); AddBody(rig.physicsRig.rbKnee); foreach (Transform componentsInChild in ((Component)rig.avatar).GetComponentsInChildren<Transform>(true)) { if ((Object)(object)componentsInChild != (Object)null) { _historyBones.Add(ReadBone(componentsInChild)); } } if (_localOwner) { _skeleton = new RigSkeleton(rig); _historyPose = new RigPose(); } _lateCallback = Action.op_Implicit((Action)AfterRigLateUpdate); _renderCallback = UnityAction.op_Implicit((Action)BeforeRender); rig.OnPostLateUpdate += _lateCallback; Application.onBeforeRender += _renderCallback; Record(); } catch { StopTracking(); throw; } } private void AddBody(Rigidbody? rb) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rb != (Object)null && _bodyIds.Add(((Object)rb).GetInstanceID())) { _historyBodies.Add(new Body(rb, rb.position, rb.rotation)); } } private static Bone ReadBone(Transform bone) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) return new Bone(bone, bone.position, bone.rotation, bone.localPosition, bone.localRotation); } private void Record() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (Active || (Object)(object)_rig == (Object)null) { return; } for (int i = 0; i < _historyBodies.Count; i++) { Rigidbody value = _historyBodies[i].Value; if ((Object)(object)value != (Object)null) { _historyBodies[i] = new Body(value, value.position, value.rotation); } } for (int j = 0; j < _historyBones.Count; j++) { if ((Object)(object)_historyBones[j].Value != (Object)null) { _historyBones[j] = ReadBone(_historyBones[j].Value); } } if (_localOwner) { _historyPose.ReadSkeleton(_skeleton); } _historyTime = _clock(); } public void Capture(RigManager rig, double duration = 20.0) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_0162: 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) if (Active) { return; } Release(); Track(rig); double num = _clock(); if (!double.IsFinite(num)) { return; } try { Vector3 val; int num2; if (_historyBodies.Count > 0) { val = _historyBodies[0].Value.position - _historyBodies[0].Position; num2 = ((((Vector3)(ref val)).sqrMagnitude > 4f) ? 1 : 0); } else { num2 = 0; } bool flag = (byte)num2 != 0; if (num < _historyTime || num - _historyTime > 0.2 || flag) { Record(); } foreach (Body historyBody in _historyBodies) { if ((Object)(object)historyBody.Value != (Object)null) { _bodies.Add(historyBody); } } _bones.AddRange(_historyBones); _networkPose = _historyPose; if (_networkPose != null) { val = (_networkPose.PelvisPose.Velocity = (_networkPose.PelvisPose.AngularVelocity = Vector3.zero)); _networkPose.LeftController.ThumbstickAxis = Vector2.zero; _networkPose.RightController.ThumbstickAxis = Vector2.zero; } _started = num; _hardDeadline = num + Math.Clamp(double.IsFinite(duration) ? duration : 20.0, 1.0, 120.0); _leaseUntil = num + 0.35; Active = true; if (_localOwner) { Current = this; } HoldVisual(); } catch { Release(); throw; } } public void Renew() { double num = _clock(); if (Active) { if (!double.IsFinite(num) || num < _started || num >= _hardDeadline) { Release(); } else { _leaseUntil = Math.Min(num + 0.35, _hardDeadline); } } } private bool CanHold() { if (!Active) { return false; } double num = _clock(); if (!double.IsFinite(num) || num < _started || num >= _leaseUntil || num >= _hardDeadline) { Release(); return false; } return true; } public void Hold() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (!CanHold()) { return; } foreach (Body body in _bodies) { if (!((Object)(object)body.Value == (Object)null)) { if (!body.Value.isKinematic) { body.Value.velocity = Vector3.zero; body.Value.angularVelocity = Vector3.zero; } body.Value.position = body.Position; body.Value.rotation = body.Rotation; ((Component)body.Value).transform.SetPositionAndRotation(body.Position, body.Rotation); } } } public void HoldVisual() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!CanHold()) { return; } Hold(); if (!Active) { return; } foreach (Bone bone in _bones) { if ((Object)(object)bone.Value != (Object)null) { bone.Value.SetPositionAndRotation(bone.Position, bone.Rotation); } } } public void Release() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) bool active = Active; Active = false; if (Current == this) { Current = null; } _networkPose = null; _leaseUntil = (_hardDeadline = 0.0); int num = 0; foreach (Bone bone in _bones) { try { if ((Object)(object)bone.Value != (Object)null) { bone.Value.localPosition = bone.LocalPosition; bone.Value.localRotation = bone.LocalRotation; } } catch { num++; } } foreach (Body body in _bodies) { try { if ((Object)(object)body.Value != (Object)null && !body.Value.isKinematic) { Rigidbody value = body.Value; Vector3 velocity = (body.Value.angularVelocity = Vector3.zero); value.velocity = velocity; body.Value.WakeUp(); } } catch { num++; } } _bodies.Clear(); _bones.Clear(); if (active) { _historyTime = double.NegativeInfinity; } if (active && num > 0) { Warn($"Coil Head released; {num} unavailable rig parts skipped. No native movement locks were set."); } } internal void StopTracking() { Release(); try { if ((Object)(object)_rig != (Object)null && (Delegate)(object)_lateCallback != (Delegate)null) { RigManager? rig = _rig; rig.OnPostLateUpdate -= _lateCallback; } } catch (Exception ex) { Warn("Coil Head late callback cleanup: " + ex.Message); } try { if ((Delegate)(object)_renderCallback != (Delegate)null) { Application.onBeforeRender -= _renderCallback; } } catch (Exception ex2) { Warn("Coil Head render callback cleanup: " + ex2.Message); } _lateCallback = null; _renderCallback = null; _rig = null; _historyPose = null; _skeleton = null; _historyBodies.Clear(); _historyBones.Clear(); _historyTime = double.NegativeInfinity; } private void Warn(string message) { try { _warning?.Invoke(message); } catch { } } private void AfterRigLateUpdate() { try { if (!((Object)(object)_rig == (Object)null)) { if (CanHold()) { HoldVisual(); return; } Release(); Record(); } } catch (Exception ex) { Release(); Warn(ex.Message); } } private void BeforeRender() { try { HoldVisual(); } catch (Exception ex) { Release(); Warn(ex.Message); } } internal static void AfterReadSkeleton(RigPose __instance, RigSkeleton skeleton) { PoseLock current = Current; if (current != null && current.CanHold() && !((Object)(object)current._rig == (Object)null) && current._networkPose != null && !((Object)(object)((Component)skeleton.PhysicsPelvis).transform != (Object)(object)((Rig)current._rig.physicsRig).m_pelvis)) { RigPose networkPose = current._networkPose; for (int i = 1; i < 3; i++) { __instance.TrackedPoints[i] = networkPose.TrackedPoints[i]; } networkPose.PelvisPose.CopyTo(__instance.PelvisPose); __instance.LeftController = networkPose.LeftController; __instance.RightController = networkPose.RightController; __instance.CrouchTarget = networkPose.CrouchTarget; __instance.FeetOffset = networkPose.FeetOffset; } } } internal static class QuestVisuals { internal const string ResourceName = "CoilHead.Assets.coilhead-shaders-android.bundle"; private static AssetBundle? _bundle; private static Shader? _shader; private static bool _attempted; internal static bool Standalone => (int)Application.platform == 11; internal static string Status { get; private set; } = "Not requested"; internal static Shader? Find(string fallback) { if (!Standalone) { return Shader.Find(fallback); } if (!_attempted) { Load(); } if (!((Object)(object)_shader != (Object)null)) { return Shader.Find(fallback); } return _shader; } private static void Load() { _attempted = true; try { using Stream stream = typeof(QuestVisuals).Assembly.GetManifestResourceStream("CoilHead.Assets.coilhead-shaders-android.bundle"); if (stream == null || stream.Length <= 0 || stream.Length > 8388608) { throw new InvalidDataException("Embedded Android shader is missing or invalid"); } using MemoryStream memoryStream = new MemoryStream((int)stream.Length); stream.CopyTo(memoryStream); _bundle = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray())); _shader = (((Object)(object)_bundle != (Object)null) ? _bundle.LoadAsset<Shader>("assets/echolocation/shaders/echovertexcolor.shader") : null); if ((Object)(object)_shader == (Object)null || !_shader.isSupported) { throw new InvalidDataException("Android stereo shader is unsupported"); } Status = "Embedded Android stereo shader loaded"; } catch (Exception ex) { _shader = null; try { ReleaseBundle(); } catch { } Status = "Android shader fallback: " + ex.GetBaseException().Message; MelonLogger.Warning(Status); } } private static void ReleaseBundle() { AssetBundle bundle = _bundle; _bundle = null; if ((Object)(object)bundle != (Object)null) { bundle.Unload(true); } } internal static void Dispose() { try { ReleaseBundle(); } finally { _shader = null; _attempted = false; Status = "Not requested"; } } } internal sealed class RemoteFreeze { private sealed class Peer { internal readonly RemoteFreezeLease Lease = new RemoteFreezeLease(); internal readonly PoseLock Pose = new PoseLock(null, delegate(string message) { MelonLogger.Warning(message); }, localOwner: false); internal RigManager Rig; internal Transform Avatar; internal bool Warned; } private const string Key = "MannequinMod.Pose.v1"; private readonly Dictionary<NetworkPlayer, Peer> _peers = new Dictionary<NetworkPlayer, Peer>(); private readonly HashSet<NetworkPlayer> _seen = new HashSet<NetworkPlayer>(); private readonly List<NetworkPlayer> _remove = new List<NetworkPlayer>(); private string _token = ""; private string _sent = ""; private long _sequence; private bool _wasFrozen; private double _nextSend; internal void Publish(bool enabled, bool frozen, int duration = 20) { PlayerMetadata metadata = LocalPlayer.Metadata; NetworkMetadata val = ((metadata != null) ? metadata.Metadata : null); if (val == null) { return; } double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; if (!enabled || !NetworkInfo.HasServer) { if (_sent.Length != 0 && val.TryRemoveMetadata("MannequinMod.Pose.v1")) { _sent = ""; } _wasFrozen = false; return; } if (frozen && !_wasFrozen) { _token = Guid.NewGuid().ToString("N"); _sequence = 0L; _nextSend = 0.0; } if (!frozen || !_wasFrozen || !(realtimeSinceStartupAsDouble < _nextSend)) { string text = (frozen ? $"F|{_token}|{++_sequence}|{Math.Clamp(duration, 1, 120)}" : "R"); if (text != _sent && val.TrySetMetadata("MannequinMod.Pose.v1", text)) { _sent = text; _nextSend = realtimeSinceStartupAsDouble + 0.4; } _wasFrozen = frozen; } } internal void Update(RigManager? localRig = null) { if (!NetworkInfo.HasServer) { ResetPeers(); return; } _seen.Clear(); double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; string text = default(string); foreach (NetworkPlayer player in NetworkPlayer.Players) { try { if (player.PlayerID == null || player.PlayerID.IsMe || !player.PlayerID.IsValid || !player.HasRig || player.ForceHide) { continue; } RigRefs rigRefs = player.RigRefs; RigManager val = ((rigRefs != null) ? rigRefs.RigManager : null); if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)localRig || (Object)(object)val.avatar == (Object)null || ((Object)(object)val.health != (Object)null && val.health.curr_Health <= 0f)) { continue; } PlayerMetadata metadata = player.PlayerID.Metadata; NetworkMetadata val2 = ((metadata != null) ? metadata.Metadata : null); _seen.Add(player); if (val2 == null || !val2.TryGetMetadata("MannequinMod.Pose.v1", ref text) || (text != "R" && !text.StartsWith("F|", StringComparison.Ordinal))) { if (_peers.TryGetValue(player, out Peer value)) { value.Lease.Observe(null, realtimeSinceStartupAsDouble); value.Pose.StopTracking(); } continue; } if (!_peers.TryGetValue(player, out Peer value2)) { value2 = (_peers[player] = new Peer()); } Transform transform = ((Component)val.avatar).transform; if ((Object)(object)value2.Rig != (Object)(object)val || (Object)(object)value2.Avatar != (Object)(object)transform) { if ((Object)(object)value2.Rig != (Object)null) { value2.Lease.Observe(null, realtimeSinceStartupAsDouble); } value2.Pose.StopTracking(); value2.Rig = val; value2.Avatar = transform; } value2.Pose.Track(val); if (value2.Lease.Observe(text, realtimeSinceStartupAsDouble)) { if (!value2.Pose.Active) { value2.Pose.Capture(val, value2.Lease.Duration); } value2.Pose.Renew(); } else { value2.Pose.Release(); } } catch (Exception ex) { if (_peers.TryGetValue(player, out Peer value3)) { value3.Lease.Observe(null, realtimeSinceStartupAsDouble); value3.Pose.StopTracking(); if (!value3.Warned) { value3.Warned = true; MelonLogger.Warning("Coil Head remote pose released: " + ex.Message); } } } } _remove.Clear(); foreach (KeyValuePair<NetworkPlayer, Peer> peer2 in _peers) { if (!_seen.Contains(peer2.Key)) { _remove.Add(peer2.Key); } } foreach (NetworkPlayer item in _remove) { Retire(_peers[item].Pose); _peers.Remove(item); } } private void Retire(PoseLock pose) { pose.StopTracking(); } internal void HoldFixed() { foreach (Peer value in _peers.Values) { try { value.Pose.Hold(); } catch { value.Lease.Observe(null, Time.realtimeSinceStartupAsDouble); value.Pose.Release(); } } } internal void ResetPeers() { foreach (Peer value in _peers.Values) { Retire(value.Pose); } _peers.Clear(); } } internal sealed class RemoteFreezeLease { private string _token = ""; private long _sequence = -1L; private double _lastHeartbeat; private double _deadline; private bool _expired; private string? _wire; internal int Duration { get; private set; } = 20; internal bool Observe(string? value, double now) { if (!double.IsFinite(now) || value == null || value.Length > 90 || !value.StartsWith("F|", StringComparison.Ordinal)) { _expired = true; return false; } if (value == _wire) { if (now < _lastHeartbeat || now - _lastHeartbeat > 1.5 || now >= _deadline) { _expired = true; } return !_expired; } string[] array = value.Split('|'); int result = 20; if ((array.Length != 3 && array.Length != 4) || !Guid.TryParseExact(array[1], "N", out var _) || !long.TryParse(array[2], out var result3) || result3 < 0 || (array.Length == 4 && (!int.TryParse(array[3], out result) || result < 1 || result > 120))) { _expired = true; return false; } _wire = value; if (array[1] != _token) { _token = array[1]; _sequence = result3; _lastHeartbeat = now; Duration = result; _deadline = now + (double)result; _expired = false; } else { if (result != Duration) { _expired = true; } if (now < _lastHeartbeat || now - _lastHeartbeat > 1.5 || now >= _deadline) { _expired = true; } if (!_expired && result3 > _sequence) { _sequence = result3; _lastHeartbeat = now; } } if (now < _lastHeartbeat || now - _lastHeartbeat > 1.5 || now >= _deadline) { _expired = true; } return !_expired; } } internal sealed class SightQuery { private readonly Il2CppStructArray<RaycastHit> _hits = new Il2CppStructArray<RaycastHit>(64L); private static int _viewAngle = 60; private static float _cosine = 0.8660254f; internal static int ViewAngle { get { return _viewAngle; } set { _viewAngle = Math.Clamp(value, 20, 100); _cosine = (float)Math.Cos((double)_viewAngle * Math.PI / 360.0); } } internal static bool InCone(Vector3 eye, Vector3 forward, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Vector3 val = point - eye; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; float sqrMagnitude2 = ((Vector3)(ref forward)).sqrMagnitude; if (float.IsFinite(sqrMagnitude) && float.IsFinite(sqrMagnitude2) && sqrMagnitude2 > 1E-06f && sqrMagnitude >= 1E-06f && sqrMagnitude <= 10000f) { return Vector3.Dot(forward / Mathf.Sqrt(sqrMagnitude2), val / Mathf.Sqrt(sqrMagnitude)) >= _cosine; } return false; } internal bool Visible(Vector3 eye, Vector3 forward, Transform observer, Transform target, Vector3 point, Transform? otherObserverRoot = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!InCone(eye, forward, point)) { return false; } Vector3 val = point - eye; float num = Mathf.Sqrt(((Vector3)(ref val)).sqrMagnitude); int num2 = Physics.RaycastNonAlloc(eye, val / num, _hits, num, -1, (QueryTriggerInteraction)1); if (num2 >= ((Il2CppArrayBase<RaycastHit>)(object)_hits).Length) { return false; } for (int i = 0; i < num2; i++) { RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i]; Collider collider = ((RaycastHit)(ref val2)).collider; if (!((Object)(object)collider == (Object)null)) { Transform transform = ((Component)collider).transform; if (!Within(transform, observer) && !Within(transform, target) && !Within(transform, otherObserverRoot)) { return false; } } } return true; } private static bool Within(Transform t, Transform? root) { if ((Object)(object)root != (Object)null) { if (!((Object)(object)t == (Object)(object)root)) { return t.IsChildOf(root); } return true; } return false; } } internal sealed class SilhouetteTarget { internal Transform Root; internal Transform AvatarRoot; internal Renderer[] Renderers = Array.Empty<Renderer>(); internal int NextMesh; internal float NextRefresh; internal float LastSeen; internal bool Alive { get { if ((Object)(object)Root != (Object)null && (Object)(object)AvatarRoot != (Object)null) { return ((Component)Root).gameObject.activeInHierarchy; } return false; } } } internal sealed class WatcherOutline : IDisposable { private readonly PlayerSilhouetteRenderer _renderer = new PlayerSilhouetteRenderer(delegate(string message) { MelonLogger.Warning(message); }); private readonly Dictionary<int, SilhouetteTarget> _targets = new Dictionary<int, SilhouetteTarget>(); private readonly List<int> _expired = new List<int>(); private readonly List<Renderer> _candidates = new List<Renderer>(); private float _nextCleanup; private int _start; public void Draw(List<NetworkPlayer> watchers, List<AIBrain> npcs, Transform? eye, Color color) { //IL_02cb: Unknown result type (might be due to invalid IL or missing references) int num = watchers.Count + npcs.Count; if ((Object)(object)eye == (Object)null || num == 0) { return; } Camera val = HeadsetView.Camera(); if ((Object)(object)val == (Object)null) { return; } int num2 = HeadsetView.VisibleLayer(val.cullingMask); if (num2 < 0) { return; } float unscaledTime = Time.unscaledTime; _renderer.BeginFrame(unscaledTime); int num3 = 1; if (_start >= num) { _start = 0; } int num4 = _start++; for (int i = 0; i < num; i++) { int num5 = (num4 + i) % num; Transform transform; Transform val3; if (num5 < watchers.Count) { NetworkPlayer val2 = watchers[num5]; if (!val2.HasRig) { continue; } RigRefs rigRefs = val2.RigRefs; if ((Object)(object)((rigRefs != null) ? rigRefs.RigManager : null) == (Object)null) { continue; } RigManager rigManager = val2.RigRefs.RigManager; if ((Object)(object)rigManager.avatar == (Object)null) { continue; } transform = ((Component)rigManager).transform; val3 = ((Component)rigManager.avatar).transform; } else { AIBrain val4 = npcs[num5 - watchers.Count]; if ((Object)(object)val4 == (Object)null || val4.isDead || (Object)(object)val4.puppetMaster == (Object)null) { continue; } transform = ((Component)val4.puppetMaster).transform; val3 = val4.puppetMaster.targetRoot; if ((Object)(object)val3 == (Object)null) { continue; } } int instanceID = ((Object)val3).GetInstanceID(); if (!_targets.TryGetValue(instanceID, out SilhouetteTarget value) || (Object)(object)value.AvatarRoot != (Object)(object)val3) { if (num3 == 0) { continue; } value = new SilhouetteTarget { Root = transform, AvatarRoot = val3 }; _targets[instanceID] = value; } value.LastSeen = unscaledTime; if (unscaledTime >= value.NextRefresh && num3 > 0) { num3--; value.NextRefresh = unscaledTime + 3f; _candidates.Clear(); foreach (Renderer componentsInChild in ((Component)val3).GetComponentsInChildren<Renderer>(false)) { if ((Object)(object)componentsInChild != (Object)null && componentsInChild.enabled) { _candidates.Add(componentsInChild); } } _candidates.Sort(delegate(Renderer a, Renderer b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = b.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude; bounds = a.bounds; size = ((Bounds)(ref bounds)).size; return sqrMagnitude.CompareTo(((Vector3)(ref size)).sqrMagnitude); }); int num6 = Math.Min(8, _candidates.Count); value.Renderers = (Renderer[])(object)new Renderer[num6]; for (int num7 = 0; num7 < num6; num7++) { value.Renderers[num7] = _candidates[num7]; } } _renderer.Draw(unscaledTime, value, visible: true, 1f, num2, color); } if (!(unscaledTime >= _nextCleanup)) { return; } _nextCleanup = unscaledTime + 2f; _expired.Clear(); foreach (KeyValuePair<int, SilhouetteTarget> target in _targets) { if (!target.Value.Alive || unscaledTime - target.Value.LastSeen > 12f) { _expired.Add(target.Key); } } foreach (int item in _expired) { _targets.Remove(item); } } public void Clear() { _renderer.Reset(); _targets.Clear(); _start = 0; } public void Dispose() { Clear(); _renderer.Dispose(); } } internal sealed class WatcherScanner { private sealed class Observer { internal NetworkPlayer Player; internal bool Watching; internal float NextCheck; internal float LastCheck; } private readonly List<Observer> _players = new List<Observer>(); private readonly Dictionary<NetworkPlayer, Observer> _previous = new Dictionary<NetworkPlayer, Observer>(); private readonly SightQuery _sight = new SightQuery(); private int _cursor; private float _nextRoster; internal void Scan(float now, RigManager local, List<NetworkPlayer> watchers) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) if (now >= _nextRoster) { _nextRoster = now + 0.25f; _previous.Clear(); foreach (Observer player3 in _players) { _previous[player3.Player] = player3; } _players.Clear(); foreach (NetworkPlayer player4 in NetworkPlayer.Players) { if (player4.PlayerID != null && !player4.PlayerID.IsMe && player4.PlayerID.IsValid) { _players.Add(_previous.TryGetValue(player4, out Observer value) ? value : new Observer { Player = player4 }); } } _previous.Clear(); } Vector3 position = ((Rig)local.physicsRig).m_head.position; Vector3 position2 = ((Rig)local.physicsRig).m_pelvis.position; Vector3 point = Vector3.Lerp(position, position2, 0.55f); Transform transform = ((Component)local).transform; int num = 0; for (int i = 0; i < _players.Count; i++) { if (num >= 8) { break; } if (_cursor >= _players.Count) { _cursor = 0; } Observer observer = _players[_cursor++]; if (now < observer.NextCheck) { continue; } num++; observer.NextCheck = now + 0.05f; observer.LastCheck = now; observer.Watching = false; NetworkPlayer player = observer.Player; if (player.PlayerID != null && player.PlayerID.IsValid && player.HasRig && !player.ForceHide) { RigRefs rigRefs = player.RigRefs; RigManager val = ((rigRefs != null) ? rigRefs.RigManager : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)local) && !((Object)(object)rigRefs.Headset == (Object)null) && !(