Decompiled source of EchoLocation MM v2.0.0
Mods/EchoLocation.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BoneLib; using BoneLib.BoneMenu; using BoneLib.BoneMenu.UI; using Echolocation; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Audio; using Il2CppSLZ.Marrow.Input; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.Utilities; using Il2CppSLZ.Rig; using Il2CppSystem; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using UnityEngine.XR; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(EcholocationMod), "EchoLocation-MM", "2.0.0", "Echolocation", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 Echolocation { internal sealed class BlackoutView : IDisposable { internal const int BlackQueue = 4998; internal const int EchoQueue = 4999; private readonly Action<string> _warning; private Mesh? _mesh; private Material? _material; private int _attempts; private float _nextAttempt; private bool _disposed; private readonly Camera?[] _desktopCameras = (Camera?[])(object)new Camera[64]; private readonly bool[] _knownDesktopCameras = new bool[64]; private readonly Camera?[] _overlayCameras = (Camera?[])(object)new Camera[16]; private Il2CppReferenceArray<Camera>? _cameraBuffer; private int _desktopCount; private int _overlayCount; private int _lastCameraCount = -1; private float _nextCameraRefresh; private bool _cameraWarning; internal bool Active { get; private set; } internal string Status { get; private set; } = "Waiting for player"; internal BlackoutView(Action<string> warning) { _warning = warning; } internal void Tick(float now, bool enabled) { Active = false; if (_disposed) { return; } if (!enabled) { Status = "Normal vision"; return; } GUIMenu instance = GUIMenu.Instance; UIRig uIRig = Player.UIRig; if (((Object)(object)uIRig != (Object)null && (Object)(object)uIRig.popUpMenu != (Object)null && uIRig.popUpMenu.isActive) || ((Object)(object)instance != (Object)null && ((Component)instance).gameObject.activeInHierarchy)) { Status = "Normal vision while a game menu is open"; return; } EnsureAssets(now); if ((Object)(object)_mesh == (Object)null || (Object)(object)_material == (Object)null) { return; } OpenControllerRig controllerRig = Player.ControllerRig; Il2CppReferenceArray<Camera> val = (((Object)(object)controllerRig != (Object)null) ? controllerRig.cameras : null); Camera main = Camera.main; RefreshDesktopCameras(now); bool flag = false; int num = 0; while (val != null && num < ((Il2CppArrayBase<Camera>)(object)val).Length) { Camera val2 = ((Il2CppArrayBase<Camera>)(object)val)[num]; if ((Object)(object)val2 == (Object)(object)main) { flag = true; } DrawCamera(val2); num++; } if (!flag) { DrawCamera(main); } for (int i = 0; i < _desktopCount; i++) { Camera val3 = _desktopCameras[i]; if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)main || (!_knownDesktopCameras[i] && !IsDisplayCamera(val3))) { continue; } bool flag2 = false; int num2 = 0; while (val != null && num2 < ((Il2CppArrayBase<Camera>)(object)val).Length) { if ((Object)(object)((Il2CppArrayBase<Camera>)(object)val)[num2] == (Object)(object)val3) { flag2 = true; break; } num2++; } if (!flag2) { DrawCamera(val3); } } Status = (Active ? "Blackout active: echolocation only" : "Waiting for player camera"); } private void RefreshDesktopCameras(float now) { //IL_0102: Unknown result type (might be due to invalid IL or missing references) int allCamerasCount = Camera.allCamerasCount; if (now < _nextCameraRefresh && allCamerasCount == _lastCameraCount) { return; } _nextCameraRefresh = now + 0.5f; _lastCameraCount = allCamerasCount; Array.Clear(_desktopCameras, 0, _desktopCameras.Length); Array.Clear(_overlayCameras, 0, _overlayCameras.Length); _desktopCount = (_overlayCount = 0); try { Il2CppArrayBase<RigScreenOptions> val = Object.FindObjectsOfType<RigScreenOptions>(); for (int i = 0; i < val.Length && i < _overlayCameras.Length; i++) { RigScreenOptions val2 = val[i]; if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)val2.OverlayCam != (Object)null) { _overlayCameras[_overlayCount++] = val2.OverlayCam; } AddDesktopCamera(val2.cam, knownView: true); } } RigManager rigManager = Player.RigManager; PancakeControllerRig val3 = (((Object)(object)rigManager != (Object)null && (Object)(object)rigManager.controllerRig != (Object)null) ? ((Il2CppObjectBase)rigManager.controllerRig).TryCast<PancakeControllerRig>() : null); if ((Object)(object)val3 != (Object)null && (Object)(object)val3.wasdCam != (Object)null) { AddDesktopCamera(val3.wasdCam.Camera, knownView: true); } if (allCamerasCount < 1 || allCamerasCount > 1024) { return; } if (_cameraBuffer == null || ((Il2CppArrayBase<Camera>)(object)_cameraBuffer).Length < allCamerasCount) { _cameraBuffer = new Il2CppReferenceArray<Camera>((long)Math.Max(32, allCamerasCount)); } allCamerasCount = Camera.GetAllCameras(_cameraBuffer); for (int j = 0; j < allCamerasCount; j++) { Camera val4 = ((Il2CppArrayBase<Camera>)(object)_cameraBuffer)[j]; if ((Object)(object)val4 != (Object)null && IsDisplayCamera(val4)) { AddDesktopCamera(val4, knownView: false); } } } catch (Exception ex) { if (!_cameraWarning) { _cameraWarning = true; _warning("Desktop blackout camera discovery will retry: " + ex.Message); } } } private static bool IsDisplayCamera(Camera camera) { if (!camera.stereoEnabled && (Object)(object)camera.targetTexture == (Object)null) { return camera.targetDisplay >= 0; } return false; } private void AddDesktopCamera(Camera? camera, bool knownView) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)camera == (Object)null || !((Behaviour)camera).isActiveAndEnabled || (int)camera.cameraType != 1 || (camera.cullingMask & -33) == 0 || _desktopCount >= _desktopCameras.Length) { return; } for (int i = 0; i < _desktopCount; i++) { if ((Object)(object)_desktopCameras[i] == (Object)(object)camera) { return; } } _knownDesktopCameras[_desktopCount] = knownView; _desktopCameras[_desktopCount++] = camera; } private void DrawCamera(Camera? camera) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null || !((Behaviour)camera).isActiveAndEnabled || (int)camera.cameraType != 1 || (camera.cullingMask & -33) == 0) { return; } for (int i = 0; i < _overlayCount; i++) { if ((Object)(object)_overlayCameras[i] == (Object)(object)camera) { return; } } float num = Mathf.Max(2f, camera.nearClipPlane * 4f + camera.stereoSeparation); num = Mathf.Min(num, camera.farClipPlane * 0.4f); Matrix4x4 val = Matrix4x4.TRS(((Component)camera).transform.position, Quaternion.identity, Vector3.one * num); int num2 = VisibleLayer(camera.cullingMask); if (num2 >= 0) { Graphics.DrawMesh(_mesh, val, _material, num2, camera, 0, (MaterialPropertyBlock)null, (ShadowCastingMode)0, false, (Transform)null, (LightProbeUsage)0, (LightProbeProxyVolume)null); Active = true; } } internal void Reset() { Active = false; _attempts = 0; _nextAttempt = 0f; _lastCameraCount = -1; _nextCameraRefresh = 0f; _cameraWarning = false; _desktopCount = (_overlayCount = 0); Array.Clear(_desktopCameras, 0, _desktopCameras.Length); Array.Clear(_overlayCameras, 0, _overlayCameras.Length); _cameraBuffer = null; Status = "Waiting for player"; } private void EnsureAssets(float now) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (((Object)(object)_mesh != (Object)null && (Object)(object)_material != (Object)null) || now < _nextAttempt) { return; } _attempts++; _nextAttempt = now + ((_attempts >= 6) ? 10f : 2f); DestroyAssets(); string[] array = new string[2] { "Hidden/Internal-Colored", "GUI/Text Shader" }; foreach (string text in array) { Shader val = Shader.Find(text); if ((Object)(object)val == (Object)null || !val.isSupported) { continue; } Material val2 = new Material(val) { hideFlags = (HideFlags)61, renderQueue = 4998 }; if (text == "Hidden/Internal-Colored" && (!val2.HasProperty("_ZTest") || !val2.HasProperty("_ZWrite"))) { Object.Destroy((Object)(object)val2); continue; } _material = val2; if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.black); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); } SetInt(val2, "_ZTest", 8); SetInt(val2, "_ZWrite", 0); SetInt(val2, "_Cull", 0); SetInt(val2, "_SrcBlend", 1); SetInt(val2, "_DstBlend", 0); _mesh = MakeCube(); return; } Status = "Blackout shader unavailable"; if (_attempts == 1 || _attempts == 6) { _warning("Blackout could not find an always-visible shader. F6 restores normal vision; check Echolocation diagnostics."); } } private static Mesh MakeCube() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0129: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020f: 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_0230: Expected O, but got Unknown Vector3[] array = (Vector3[])(object)new Vector3[8] { new Vector3(-1f, -1f, -1f), new Vector3(1f, -1f, -1f), new Vector3(1f, 1f, -1f), new Vector3(-1f, 1f, -1f), new Vector3(-1f, -1f, 1f), new Vector3(1f, -1f, 1f), new Vector3(1f, 1f, 1f), new Vector3(-1f, 1f, 1f) }; int[] array2 = new int[36] { 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 0, 4, 7, 0, 7, 3, 1, 2, 6, 1, 6, 5, 3, 7, 6, 3, 6, 2, 0, 1, 5, 0, 5, 4 }; Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)array.Length); Il2CppStructArray<Color> val2 = new Il2CppStructArray<Color>((long)array.Length); Il2CppStructArray<Vector2> val3 = new Il2CppStructArray<Vector2>((long)array.Length); Il2CppStructArray<int> val4 = new Il2CppStructArray<int>((long)(array2.Length * 2)); for (int i = 0; i < array.Length; i++) { ((Il2CppArrayBase<Vector3>)(object)val)[i] = array[i]; ((Il2CppArrayBase<Color>)(object)val2)[i] = Color.black; ((Il2CppArrayBase<Vector2>)(object)val3)[i] = new Vector2(0.5f, 0.5f); } for (int j = 0; j < array2.Length; j += 3) { ((Il2CppArrayBase<int>)(object)val4)[j] = array2[j]; ((Il2CppArrayBase<int>)(object)val4)[j + 1] = array2[j + 1]; ((Il2CppArrayBase<int>)(object)val4)[j + 2] = array2[j + 2]; ((Il2CppArrayBase<int>)(object)val4)[array2.Length + j] = array2[j]; ((Il2CppArrayBase<int>)(object)val4)[array2.Length + j + 1] = array2[j + 2]; ((Il2CppArrayBase<int>)(object)val4)[array2.Length + j + 2] = array2[j + 1]; } Mesh val5 = new Mesh { name = "Echolocation.Blackout", hideFlags = (HideFlags)61 }; val5.SetVertices(val, 0, array.Length); val5.SetColors(val2, 0, array.Length); val5.SetUVs(0, val3, 0, array.Length); val5.SetTriangles(val4, 0, ((Il2CppArrayBase<int>)(object)val4).Length, 0, true, 0); return val5; } private static int VisibleLayer(int mask) { for (int i = 0; i < 32; i++) { if ((mask & (1 << i)) != 0) { return i; } } return -1; } private static void SetInt(Material material, string name, int value) { if (material.HasProperty(name)) { material.SetInt(name, value); } } private void DestroyAssets() { if ((Object)(object)_mesh != (Object)null) { Object.Destroy((Object)(object)_mesh); } if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } _mesh = null; _material = null; } public void Dispose() { if (!_disposed) { _disposed = true; Reset(); DestroyAssets(); } } } internal sealed class BulletTrails : IDisposable { private struct Shot { public Vector3 Start; public Vector3 End; public float Birth; public float Lifetime; public float Distance; public bool Hit; } private readonly Settings _settings; private readonly MarkerBatch _batch; private readonly TimedHistory<Shot> _shots = new TimedHistory<Shot>(128); private readonly Il2CppStructArray<RaycastHit> _hits = new Il2CppStructArray<RaycastHit>(64L); private int _frame = -1; private int _frameShots; public int AcceptedShots { get; private set; } public BulletTrails(Settings settings, Action<string> warning) { _settings = settings; _batch = new MarkerBatch(warning); } public void RecordShot(Gun gun, float now, Transform head, Transform? localRoot) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) if (!_settings.BulletTrails || (Object)(object)gun == (Object)null || (Object)(object)gun.firePointTransform == (Object)null) { return; } if (_frame != Time.frameCount) { _frame = Time.frameCount; _frameShots = 0; } if (_frameShots++ >= _settings.PlayerRayBudget * 2) { return; } Transform firePointTransform = gun.firePointTransform; Vector3 position = firePointTransform.position; Vector3 val = firePointTransform.forward; if (!PlayerTarget.Finite(position) || !PlayerTarget.Finite(val) || ((Vector3)(ref val)).sqrMagnitude < 0.01f) { return; } val = ((Vector3)(ref val)).normalized; if (Vector3.Distance(head.position, position) > _settings.PlayerRange) { return; } float num = _settings.TracerRange; bool flag = Vector3.Distance(head.position, position) < 2f; int num2 = Physics.RaycastNonAlloc(position, val, _hits, num, -5, (QueryTriggerInteraction)1); bool hit = false; for (int i = 0; i < num2; i++) { RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !(((RaycastHit)(ref val2)).distance <= 0.01f) && !(((RaycastHit)(ref val2)).distance >= num)) { Transform transform = ((Component)((RaycastHit)(ref val2)).collider).transform; if (!((Object)(object)transform == (Object)(object)((Component)gun).transform) && !transform.IsChildOf(((Component)gun).transform) && (!flag || !((Object)(object)localRoot != (Object)null) || (!((Object)(object)transform == (Object)(object)localRoot) && !transform.IsChildOf(localRoot)))) { num = ((RaycastHit)(ref val2)).distance; hit = true; } } } if (num2 < ((Il2CppArrayBase<RaycastHit>)(object)_hits).Length) { _shots.Add(new Shot { Start = position, End = position + val * num, Birth = now, Lifetime = _settings.TracerLifetime, Distance = num, Hit = hit }, now, _settings.TracerLifetime); AcceptedShots++; } } public void Tick(float now, Transform head) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_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_013e: 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_0148: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: 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) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) if (!_settings.BulletTrails) { _shots.Clear(); return; } _batch.Begin(now); Vector3 position = head.position; Vector3 right = head.right; Vector3 up = head.up; Camera main = Camera.main; float drawLimit = (((Object)(object)main != (Object)null) ? Mathf.Clamp(main.farClipPlane * 0.75f, 1f, 200f) : 200f); for (int i = 0; i < Math.Min(_shots.Count, _settings.TracerLimit); i++) { if (!_shots.TryGetNewest(i, now, out var item, out var _)) { continue; } (float, float, float, float) tuple = TracerStyle.At(now - item.Birth, item.Distance, item.Lifetime); if (!(tuple.Item3 <= 0.001f)) { float num = Vector3.Distance(position, (item.Start + item.End) * 0.5f); float num2 = LocatorMath.Projection(Math.Max(Vector3.Distance(position, item.Start), Vector3.Distance(position, item.End)), drawLimit); Vector3 val = position + (item.Start - position) * num2; Vector3 val2 = position + (item.End - position) * num2; Vector3 val3 = Vector3.Lerp(val, val2, tuple.Item1); Vector3 a = Vector3.Lerp(val, val2, tuple.Item2); float num3 = Math.Max(0.018f, num * 0.00055f) * num2; _batch.TaperedLine(a, val3, num3 * 0.2f, num3 * 3f, new Color(0.1f, 0.4f, 1f, 0f), new Color(0.15f, 0.8f, 1f, tuple.Item3 * 0.32f), position); _batch.TaperedLine(a, val3, num3 * 0.08f, num3, new Color(0.3f, 0.65f, 1f, tuple.Item3 * 0.08f), new Color(0.9f, 0.98f, 1f, tuple.Item3), position); float num4 = ((item.Hit && tuple.Item1 >= 1f) ? tuple.Item4 : tuple.Item3); if (num4 > 0.02f) { _batch.Line(val3 - right * num3 * 2f, val3 + right * num3 * 2f, num3 * 0.45f, new Color(1f, 0.97f, 0.8f, num4 * 0.8f), position); _batch.Line(val3 - up * num3 * 2f, val3 + up * num3 * 2f, num3 * 0.45f, new Color(1f, 0.97f, 0.8f, num4 * 0.8f), position); } if (item.Hit && tuple.Item4 > 0.02f) { float num5 = num3 * (2f + (1f - tuple.Item4) * 5f); _batch.Ring(val2, right * num5, up * num5, num3 * 0.4f, new Color(1f, 0.65f, 0.2f, tuple.Item4 * 0.5f), position); } } } _batch.Flush(); } public void Reset() { _shots.Clear(); _batch.Reset(); _frame = -1; _frameShots = 0; AcceptedShots = 0; } public void Dispose() { Reset(); _batch.Dispose(); } } internal sealed class DesktopVoiceMeter : IDisposable { private readonly Settings _settings; private readonly bool _vr; private Material? _uiMaterial; private readonly Image?[] _segments = (Image?[])(object)new Image[28]; private RectTransform? _peakMarker; private float _peak; private float _peakUntil; private GameObject? _root; private Canvas? _canvas; private RectTransform? _panel; private RectTransform? _casualMarker; private RectTransform? _loudMarker; private Text? _state; private Text? _values; private Text? _note; private Font? _font; private float _nextUpdate; private const float BarWidth = 340f; private static readonly Color Pink = new Color(1f, 0.39f, 0.55f, 1f); private static readonly Color Amber = new Color(1f, 0.79f, 0.2f, 1f); private static readonly Color Green = new Color(0.2f, 0.95f, 0.65f, 1f); public DesktopVoiceMeter(Settings settings, bool vr = false) { _settings = settings; _vr = vr; } public void Tick(float now, bool active, MicrophoneInput input) { //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: 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_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: 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_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) if (!active || !_settings.Enabled || !(_vr ? _settings.VrVoiceMeter : _settings.DesktopVoiceMeter)) { Hide(); } else if (!_vr && XRSettings.enabled && !XRSettings.showDeviceView) { Hide(); } else { if (!float.IsFinite(now)) { return; } Camera val = (_vr ? HeadsetCamera() : null); if (_vr && (Object)(object)val == (Object)null) { Hide(); return; } if ((Object)(object)_root == (Object)null || (Object)(object)_canvas == (Object)null) { if (now < _nextUpdate) { return; } _nextUpdate = now + 5f; Build(); _nextUpdate = now; } if (_vr) { _canvas.renderMode = (RenderMode)2; _canvas.worldCamera = val; int num = VoiceMeterPlacement.Layer(val.cullingMask); if (num < 0) { Hide(); return; } if (_root.layer != num) { Il2CppArrayBase<Transform> componentsInChildren = _root.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = num; } } RectTransform component = _root.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(380f, 142f); float num2 = Math.Max(1.25f, val.nearClipPlane + 0.2f); ((Transform)component).position = ((Component)val).transform.position + ((Component)val).transform.forward * num2 - ((Component)val).transform.up * (num2 * 0.224f); ((Transform)component).rotation = ((Component)val).transform.rotation; ((Transform)component).localScale = Vector3.one * (0.0015f * num2 / 1.25f); RectTransform? panel = _panel; RectTransform? panel2 = _panel; RectTransform? panel3 = _panel; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); panel3.pivot = val2; Vector2 anchorMin = (panel2.anchorMax = val2); panel.anchorMin = anchorMin; _panel.anchoredPosition = Vector2.zero; ((Transform)_panel).localScale = Vector3.one; } else { if ((int)_canvas.renderMode != 0) { _canvas.renderMode = (RenderMode)0; } _canvas.worldCamera = null; _canvas.targetDisplay = 0; float num3 = Mathf.Clamp(Math.Min((float)Screen.width / 1000f, (float)Screen.height / 700f), 0.5f, 1.5f); ((Transform)_panel).localScale = new Vector3(num3, num3, 1f); } if (!_root.activeSelf) { _root.SetActive(true); } if (now < _nextUpdate) { return; } _nextUpdate = now + 0.05f; bool available = VoiceMeterReading.IsFresh(now, input.SampleTime, VoiceMeterPlacement.Sample(_settings.MicrophoneEnabled, _settings.AnyVoiceMeter), input.HasLevel); VoiceMeterReading voiceMeterReading = new VoiceMeterReading(input.Level, _settings.VoiceRevealThreshold, _settings.VoiceLoudThreshold, available); Color color = (Color)((!voiceMeterReading.Available) ? new Color(0.5f, 0.58f, 0.66f, 1f) : (voiceMeterReading.Loud ? Pink : (voiceMeterReading.Detected ? Amber : Green))); for (int j = 0; j < _segments.Length; j++) { float num4 = (float)j / (float)_segments.Length; Color val4 = ((num4 >= voiceMeterReading.LoudMarker) ? Pink : ((num4 >= voiceMeterReading.CasualMarker) ? Amber : Green)); float num5 = Math.Clamp((voiceMeterReading.Fill - num4) * (float)_segments.Length, 0f, 1f); Color val5 = Color.Lerp(new Color(val4.r * 0.17f, val4.g * 0.17f, val4.b * 0.17f, 1f), val4, num5); if (((Graphic)_segments[j]).color != val5) { ((Graphic)_segments[j]).color = val5; } } if (!voiceMeterReading.Available) { _peak = 0f; } else if (voiceMeterReading.Fill >= _peak) { _peak = voiceMeterReading.Fill; _peakUntil = now + 0.6f; } else if (now > _peakUntil) { _peak = Math.Max(voiceMeterReading.Fill, _peak - 0.035f); } _peakMarker.anchoredPosition = new Vector2(20f + 340f * _peak, 60f); ((Component)_peakMarker).gameObject.SetActive(voiceMeterReading.Available && _peak > 0.01f); _casualMarker.anchoredPosition = new Vector2(20f + 340f * voiceMeterReading.CasualMarker, 57f); _loudMarker.anchoredPosition = new Vector2(20f + 340f * voiceMeterReading.LoudMarker, 57f); ((Graphic)_state).color = color; SetText(_state, (!voiceMeterReading.Available) ? "NO INPUT" : (voiceMeterReading.Loud ? "LOUD" : (voiceMeterReading.Detected ? "DETECTED" : "WHISPER"))); SetText(_values, $"LEVEL {voiceMeterReading.Level:F3} TALK {_settings.VoiceRevealThreshold:F3} LOUD {_settings.VoiceLoudThreshold:F3}"); string text = ((!voiceMeterReading.Available) ? input.Status : ((_settings.Mode == ScanMode.EchoLocation) ? "Your mic level; received chat volume can differ." : "Scan mode: voice does not reveal players.")); SetText(_note, (text.Length > 54) ? (text.Substring(0, 51) + "...") : text); } } private static Camera? HeadsetCamera() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 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 && VoiceMeterPlacement.Headset(((Behaviour)((Il2CppArrayBase<Camera>)(object)val)[i]).isActiveAndEnabled, ((Il2CppArrayBase<Camera>)(object)val)[i].stereoEnabled, XRSettings.enabled, (int)((Il2CppArrayBase<Camera>)(object)val)[i].stereoTargetEye > 0)) { return ((Il2CppArrayBase<Camera>)(object)val)[i]; } } } Camera main = Camera.main; if (!((Object)(object)main != (Object)null) || !VoiceMeterPlacement.Headset(((Behaviour)main).isActiveAndEnabled, main.stereoEnabled, XRSettings.enabled, (int)main.stereoTargetEye > 0)) { return null; } return main; } private void Build() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) Destroy(); try { _font = Resources.GetBuiltinResource<Font>("Arial.ttf"); } catch (Exception) { _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("Voice meter font unavailable."); } try { if (_vr) { _uiMaterial = new Material(Graphic.defaultGraphicMaterial) { hideFlags = (HideFlags)61, renderQueue = 5000 }; _uiMaterial.SetInt("unity_GUIZTestMode", 8); if (_uiMaterial.HasProperty("_ZWrite")) { _uiMaterial.SetInt("_ZWrite", 0); } } _root = new GameObject(_vr ? "EchoLocation.VrVoiceMeter" : "EchoLocation.DesktopVoiceMeter", (Type[])(object)new Type[1] { Il2CppType.Of<RectTransform>() }); _root.SetActive(false); ((Object)_root).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_root); _canvas = _root.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)(_vr ? 2 : 0); _canvas.worldCamera = null; _canvas.targetDisplay = 0; _canvas.sortingOrder = 32700; _panel = Rect(_root.transform, "Panel", 22f, 22f, 380f, 142f); Paint(_panel, new Color(0.17f, 0.24f, 0.31f, 0.95f)); Paint(Rect((Transform)(object)_panel, "Background", 1f, 1f, 378f, 140f), new Color(0.018f, 0.026f, 0.045f, 0.97f)); Paint(Rect((Transform)(object)_panel, "Accent", 0f, 108f, 3f, 26f), Pink); Label((Transform)(object)_panel, "Title", "VOICE LEVEL", 20f, 105f, 185f, 25f, 18, Color.white); Paint(Rect((Transform)(object)_panel, "Badge", 248f, 105f, 112f, 25f), new Color(0.07f, 0.1f, 0.14f, 1f)); _state = Label((Transform)(object)_panel, "State", "WHISPER", 252f, 105f, 104f, 25f, 14, Green); _state.alignment = (TextAnchor)4; Label((Transform)(object)_panel, "WhisperLegend", "WHISPER", 20f, 84f, 110f, 17f, 10, Green); Label((Transform)(object)_panel, "TalkLegend", "TALK", 143f, 84f, 90f, 17f, 10, Amber).alignment = (TextAnchor)4; Label((Transform)(object)_panel, "LoudLegend", "LOUD", 270f, 84f, 90f, 17f, 10, Pink).alignment = (TextAnchor)5; for (int i = 0; i < _segments.Length; i++) { _segments[i] = Paint(Rect((Transform)(object)_panel, "Segment" + i, 20f + 340f * (float)i / (float)_segments.Length, 60f, 340f / (float)_segments.Length - 3f, 20f), Green); } _casualMarker = Rect((Transform)(object)_panel, "TalkThreshold", 20f, 57f, 2f, 26f); Paint(_casualMarker, Amber); _loudMarker = Rect((Transform)(object)_panel, "LoudThreshold", 20f, 57f, 2f, 26f); Paint(_loudMarker, Pink); _peakMarker = Rect((Transform)(object)_panel, "Peak", 20f, 60f, 2f, 20f); Paint(_peakMarker, Color.white); _values = Label((Transform)(object)_panel, "Values", "", 20f, 30f, 345f, 22f, 12, new Color(0.86f, 0.91f, 0.98f, 1f)); _note = Label((Transform)(object)_panel, "InputStatus", "", 20f, 9f, 345f, 18f, 11, new Color(0.56f, 0.65f, 0.77f, 1f)); } catch { Destroy(); throw; } } private static RectTransform Rect(Transform parent, string name, float x, float y, float width, float height) { //IL_000f: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, (Type[])(object)new Type[1] { Il2CppType.Of<RectTransform>() }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = (component.pivot = Vector2.zero); Vector2 anchorMin = (component.anchorMax = val); component.anchorMin = anchorMin; component.anchoredPosition = new Vector2(x, y); component.sizeDelta = new Vector2(width, height); return component; } private Image Paint(RectTransform rect, Color color) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) Image val = ((Component)rect).gameObject.AddComponent<Image>(); ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; if ((Object)(object)_uiMaterial != (Object)null) { ((Graphic)val).material = _uiMaterial; } return val; } private Text Label(Transform parent, string name, string value, float x, float y, float width, float height, int size, Color color) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) Text val = ((Component)Rect(parent, name, x, y, width, height)).gameObject.AddComponent<Text>(); val.font = _font; val.fontSize = size; val.fontStyle = (FontStyle)(size >= 16); ((Graphic)val).color = color; val.alignment = (TextAnchor)3; ((Graphic)val).raycastTarget = false; val.supportRichText = false; val.horizontalOverflow = (HorizontalWrapMode)1; val.verticalOverflow = (VerticalWrapMode)0; if ((Object)(object)_uiMaterial != (Object)null) { ((Graphic)val).material = _uiMaterial; } val.text = value; return val; } private static void SetText(Text text, string value) { if (text.text != value) { text.text = value; } } public void Hide() { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); } _peak = 0f; _peakUntil = 0f; } public void Reset() { Hide(); Destroy(); _nextUpdate = 0f; } private void Destroy() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); Object.Destroy((Object)(object)_root); } if ((Object)(object)_uiMaterial != (Object)null) { Object.Destroy((Object)(object)_uiMaterial); } _root = null; _canvas = null; _uiMaterial = null; Array.Clear(_segments, 0, _segments.Length); } public void Dispose() { Destroy(); } } internal enum DotShape { Circle, Triangle, Square } internal enum RadarDirection { Inward, Outward } internal enum RadarTargetKind { Scenery, Player, Object, Npc } internal static class RadarPolicy { internal static RadarTargetKind Classify(bool player, bool npc, bool physicsObject) { if (!player) { if (!npc) { if (!physicsObject) { return RadarTargetKind.Scenery; } return RadarTargetKind.Object; } return RadarTargetKind.Npc; } return RadarTargetKind.Player; } internal static bool AcceptsContact(RadarTargetKind kind, bool contact, bool players, bool objects, bool npcs) { if (Allows(kind, players, objects, npcs)) { return kind == RadarTargetKind.Scenery || contact; } return false; } internal static bool Allows(RadarTargetKind kind, bool players, bool objects, bool npcs) { return kind switch { RadarTargetKind.Player => players, RadarTargetKind.Object => objects, RadarTargetKind.Npc => npcs, _ => true, }; } } internal static class DotShapes { internal static DotShape Valid(DotShape shape) { if (shape < DotShape.Circle || shape > DotShape.Square) { return DotShape.Circle; } return shape; } internal static (float X, float Y) Boundary(int index, DotShape shape) { int num; switch (shape) { case DotShape.Circle: { float x = (float)index * 2f * (float)Math.PI / 12f; return (X: MathF.Cos(x), Y: MathF.Sin(x)); } default: num = 4; break; case DotShape.Triangle: num = 3; break; } int num2 = num; int num3 = 12 / num2; int num4 = index / num3; float num5 = (float)(index % num3) / (float)num3; (float, float) tuple = Corner(num4, shape); (float, float) tuple2 = Corner((num4 + 1) % num2, shape); return (X: tuple.Item1 + (tuple2.Item1 - tuple.Item1) * num5, Y: tuple.Item2 + (tuple2.Item2 - tuple.Item2) * num5); } private static (float X, float Y) Corner(int i, DotShape shape) { (int, int) tuple = ((shape != DotShape.Triangle) ? (i switch { 0 => (-1, -1), 1 => (1, -1), 2 => (1, 1), _ => (-1, 1), }) : (i switch { 0 => (0, 1), 1 => (-1, -1), _ => (1, -1), })); (int, int) tuple2 = tuple; return (X: tuple2.Item1, Y: tuple2.Item2); } } internal static class DotTexture { public static float Alpha(float u, float v, DotShape shape = DotShape.Circle) { float num = u * 2f - 1f; float num2 = v * 2f - 1f; float num3 = Math.Clamp(1f - shape switch { DotShape.Square => Math.Max(Math.Abs(num), Math.Abs(num2)), DotShape.Triangle => Math.Max(0f - num2, Math.Max(2f * num + num2, -2f * num + num2)), _ => MathF.Sqrt(num * num + num2 * num2), }, 0f, 1f); return num3 * num3 * (3f - 2f * num3); } } internal sealed class DoubleClapGesture { private const float MinimumClapInterval = 0.12f; private const float MaximumClapInterval = 1.5f; private const float PulseCooldown = 0.6f; private const float MaximumSampleGap = 0.3f; private bool _initialized; private bool _armed; private bool _hasFirstClap; private Vector3 _lastLeft; private Vector3 _lastRight; private float _lastTime; private float _lastDistance; private float _firstClapTime; private float _nextPulseTime; private float _lastContactDistance; internal bool ContactDetected { get; private set; } public bool Tick(float now, Vector3 left, Vector3 right, bool available, float contactDistance = 0.3f) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) ContactDetected = false; if (!available || !float.IsFinite(now) || !Finite(left) || !Finite(right)) { Reset(); return false; } float num = Vector3.Distance(left, right); if (!float.IsFinite(num)) { Reset(); return false; } contactDistance = (float.IsFinite(contactDistance) ? Math.Clamp(contactDistance, 0.15f, 0.45f) : 0.3f); float num2 = contactDistance + 0.1f; float num3 = now - _lastTime; float num4 = Math.Max(0.6f, num3 * 14f); if (!_initialized || contactDistance != _lastContactDistance || num3 <= 0f || num3 > 0.3f || Vector3.Distance(left, _lastLeft) > num4 || Vector3.Distance(right, _lastRight) > num4) { BeginSample(now, left, right, num, contactDistance); return false; } bool flag = _lastDistance > contactDistance && num <= contactDistance; _lastTime = now; _lastLeft = left; _lastRight = right; _lastDistance = num; if (_hasFirstClap && now - _firstClapTime > 1.5f) { _hasFirstClap = false; } if (now < _nextPulseTime) { _armed = false; _hasFirstClap = false; return false; } if (num >= num2) { _armed = true; } if (!_armed || !flag) { return false; } _armed = false; if (!_hasFirstClap) { _hasFirstClap = true; _firstClapTime = now; ContactDetected = true; return false; } if (now - _firstClapTime < 0.12f) { return false; } _hasFirstClap = false; _nextPulseTime = now + 0.6f; ContactDetected = true; return true; } private void BeginSample(float now, Vector3 left, Vector3 right, float distance, float contactDistance) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (_initialized && now < _lastTime) { _nextPulseTime = 0f; } _initialized = true; _lastTime = now; _lastLeft = left; _lastRight = right; _lastDistance = distance; _lastContactDistance = contactDistance; _armed = distance >= contactDistance + 0.1f && now >= _nextPulseTime; _hasFirstClap = 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; } public void Reset() { ContactDetected = false; _initialized = false; _armed = false; _hasFirstClap = false; _nextPulseTime = 0f; } } internal readonly struct EchoEvent { public Vector3 Origin { get; } public float Strength { get; } public float VoiceLevel { get; } public EchoKind Kind { get; } public float Time { get; } public int PlayerId { get; } public AudioSource? Source { get; } public NpcSoundEmission? NpcEmission { get; } public SoundEmitterSurface? SurfaceEmission { get; } public EchoEvent(Vector3 origin, float strength, EchoKind kind, float time, int playerId = -1, AudioSource? source = null, NpcSoundEmission? npcEmission = null, SoundEmitterSurface? surfaceEmission = null, float voiceLevel = 0f) { //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) Origin = origin; Strength = (float.IsFinite(strength) ? Mathf.Clamp01(strength) : 0f); VoiceLevel = (float.IsFinite(voiceLevel) ? Mathf.Clamp01(voiceLevel) : 0f); Kind = kind; Time = time; PlayerId = playerId; Source = source; NpcEmission = npcEmission; SurfaceEmission = surfaceEmission ?? npcEmission; } internal EchoEvent WithTime(float time) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new EchoEvent(Origin, Strength, Kind, time, PlayerId, Source, NpcEmission, SurfaceEmission, VoiceLevel); } } internal enum EchoKind { Manual, Microphone, Footstep, World, Voice, Ambient } public sealed class EcholocationMod : MelonMod { private Settings _settings; private readonly StartupGate _startup = new StartupGate(); private bool _runtimeReady; private bool _runtimeFailed; private bool _stopping; private bool _gunHooked; private ImpactSurfaceGlow _impactGlow; private readonly ScanCoverage _coverage = new ScanCoverage(); private EchoRenderer _renderer; private MicrophoneInput _microphone; private WorldSoundInput _world; private ObjectSoundSources _objectSources; private WorldAudioMonitor _worldMonitor; private LocomotionInput _locomotion; private MenuPage _menu; private PulseAudio _audio; private BulletTrails _bulletTrails; private DesktopVoiceMeter _voiceMeter; private DesktopVoiceMeter _vrVoiceMeter; private readonly PulseShortcutInput _shortcut = new PulseShortcutInput(); private Action<EchoEvent> _emit; private Action<EchoEvent> _observeSound; private Transform? _head; private Transform? _rigRoot; private bool _active; private float _nextWarning; private float _nextPulse; private readonly int[] _counts = new int[5]; private readonly EchoEvent[] _pending = new EchoEvent[5]; private readonly bool[] _hasPending = new bool[5]; private int _inputCursor = 1; private readonly DoubleClapGesture _clap = new DoubleClapGesture(); private int _clapPulseCount; public override void OnInitializeMelon() { _settings = new Settings(); _menu = new MenuPage(_settings, this, Warn); _emit = Emit; _observeSound = ObserveSound; ((MelonBase)this).LoggerInstance.Msg("EchoLocation-MM 2.0.0 loaded. Sound-only EchoLocation by default; optional Continuous Surroundings in Performance. Optional VR/spectator voice meters in General; normal speech reveals, loud speech brightens. LiDAR: double right grip."); ((MelonBase)this).LoggerInstance.Msg("Visuals are local. Mic loudness is measured in memory only; no audio is saved or sent by this mod."); Save(); } private bool EnsureRuntime() { if (_runtimeReady) { return true; } if (_runtimeFailed || _stopping) { return false; } try { _renderer = new EchoRenderer(_settings, Warn, _coverage); _microphone = new MicrophoneInput(_settings, Warn, _coverage); _objectSources = new ObjectSoundSources(Warn); _world = new WorldSoundInput(_settings, Warn, _objectSources.Capture); _locomotion = new LocomotionInput(_settings); _audio = new PulseAudio(Warn); _bulletTrails = new BulletTrails(_settings, Warn); _impactGlow = new ImpactSurfaceGlow(_settings, () => (!_active) ? null : _head, Warn); _voiceMeter = new DesktopVoiceMeter(_settings); _vrVoiceMeter = new DesktopVoiceMeter(_settings, vr: true); Hooking.OnPostFireGun += OnGunShot; _gunHooked = true; _worldMonitor = new WorldAudioMonitor(RegisterWorldPlayback, Warn); _runtimeReady = true; ((MelonBase)this).LoggerInstance.Msg("Gameplay components ready after stable player rig."); return true; } catch (Exception ex) { DisposeRuntime(); _runtimeFailed = true; _settings.Enabled = false; Save(); Warn("Gameplay initialization stopped safely: " + ex.Message + ". Toggle On/Off to retry after loading."); return false; } } private void DisposeRuntime() { _active = (_runtimeReady = false); if (_gunHooked) { Hooking.OnPostFireGun -= OnGunShot; _gunHooked = false; } Release(_voiceMeter); Release(_vrVoiceMeter); Release(_impactGlow); Release(_bulletTrails); Release(_worldMonitor); Release(_microphone); Release(_world); Release(_renderer); Release(_audio); _voiceMeter = null; _vrVoiceMeter = null; _impactGlow = null; _bulletTrails = null; _worldMonitor = null; _microphone = null; _world = null; _renderer = null; _audio = null; _objectSources = null; _locomotion = null; void Release(IDisposable? part) { try { part?.Dispose(); } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Cleanup: " + ex.Message); } } } public override void OnUpdate() { //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (_settings == null || _stopping) { return; } _menu.EnsureBuilt(); if (_settings.DesktopHotkeys) { if (Input.GetKeyDown((KeyCode)287)) { SetEnabled(!_settings.Enabled); } if (Input.GetKeyDown((KeyCode)286)) { ManualPulse(); } } Transform val = null; Transform val2 = null; try { val = Player.Head; if ((Object)(object)Player.RigManager != (Object)null) { val2 = ((Component)Player.RigManager).transform; } } catch (Exception) { } if (!_settings.Enabled || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !((Component)val).gameObject.activeInHierarchy || !((Component)val2).gameObject.activeInHierarchy) { _clap.Reset(); _startup.Reset(); _shortcut.Reset(); if (_active) { ResetState(); } return; } if (_active && ((Object)(object)_head != (Object)(object)val || (Object)(object)_rigRoot != (Object)(object)val2)) { ResetState(); } if (!_startup.Ready(Time.unscaledTime, ((Object)val).GetInstanceID(), ((Object)val2).GetInstanceID()) || !EnsureRuntime()) { return; } _head = val; _rigRoot = val2; _active = true; float unscaledTime = Time.unscaledTime; ReadPulseShortcut(unscaledTime, val); bool flag = _settings.Mode == ScanMode.EchoLocation; try { _microphone.Tick(unscaledTime, val.position, _emit, _observeSound, !flag); } catch (Exception ex2) { Warn("Microphone/voice input: " + ex2.Message); } if (!flag) { return; } try { if (_settings.Mode == ScanMode.EchoLocation) { _locomotion.Tick(unscaledTime, val, val2, _emit); } } catch (Exception ex3) { Warn("Footstep input: " + ex3.Message); } try { if (_settings.WorldSoundEnabled) { _worldMonitor.Tick(unscaledTime); } else { _worldMonitor?.Reset(); } } catch (Exception ex4) { Warn("World playback monitoring: " + ex4.Message); } try { _world.Tick(unscaledTime, val.position, _emit, _observeSound); } catch (Exception ex5) { Warn("World sound input: " + ex5.Message); } FlushInput(unscaledTime); } public override void OnLateUpdate() { if (_stopping || !_runtimeReady) { return; } if (_voiceMeter != null && _settings != null) { try { _voiceMeter.Tick(Time.unscaledTime, _active && (Object)(object)_head != (Object)null, _microphone); } catch (Exception ex) { Warn("Desktop voice meter: " + ex.Message); } try { _vrVoiceMeter.Tick(Time.unscaledTime, _active && (Object)(object)_head != (Object)null, _microphone); } catch (Exception ex2) { Warn("VR voice meter: " + ex2.Message); } } if (!_active || !_settings.Enabled || (Object)(object)_head == (Object)null) { return; } try { _renderer.Tick(Time.unscaledTime, _head, _rigRoot); } catch (Exception ex3) { Warn("Surface renderer: " + ex3.Message); } try { _impactGlow.Tick(Time.unscaledTime); } catch (Exception ex4) { Warn("Impact glow renderer: " + ex4.Message); } try { _bulletTrails.Tick(Time.unscaledTime, _head); } catch (Exception ex5) { Warn("Bullet trail renderer: " + ex5.Message); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (_settings != null) { ResetState(); } } public override void OnDeinitializeMelon() { _stopping = true; ResetState(); DisposeRuntime(); if (_settings != null) { Save(); } } internal void SetEnabled(bool enabled) { _settings.Enabled = enabled; if (enabled) { _runtimeFailed = false; } if (!enabled) { ResetState(); } Save(); } internal void SetMode(ScanMode mode) { if (_settings.Mode != mode) { _settings.Mode = mode; ResetState(); Save(); } } internal void SetBlackout(bool enabled) { _settings.Blackout = enabled; Save(); } internal void SetDoubleClap(bool enabled) { _settings.DoubleClapEnabled = enabled; _clap.Reset(); Save(); } internal void SetClapDistance(float distance) { _settings.ClapContactDistance = distance; _clap.Reset(); Save(); } internal void SetPulseSound(bool enabled) { _settings.PulseSoundEnabled = enabled; if (!enabled) { _audio?.Stop(); } Save(); } internal void TestPulseSound() { if (_runtimeReady && _active) { _audio.PlayPulse(_settings.PulseSoundVolume); } } private void OnGunShot(Gun gun) { if (!_active || _settings == null || !_settings.Enabled || (Object)(object)_head == (Object)null) { return; } try { _bulletTrails.RecordShot(gun, Time.unscaledTime, _head, _rigRoot); } catch (Exception ex) { Warn("Bullet trail: " + ex.Message); } } private void ReadPulseShortcut(float now, Transform head) { //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) PulseShortcut activeShortcut = _settings.ActiveShortcut; if (_settings.ShortcutActive) { switch (activeShortcut) { case PulseShortcut.Disabled: break; case PulseShortcut.DoubleClap: _shortcut.Reset(); ReadClapGesture(now, head); return; default: _clap.Reset(); try { OpenControllerRig controllerRig = Player.ControllerRig; BaseController leftController = Player.LeftController; BaseController rightController = Player.RightController; UIRig uIRig = Player.UIRig; GUIMenu instance = GUIMenu.Instance; XRApi xr = MarrowGame.xr; XRController val = ((xr != null) ? xr.LeftController : null); XRController val2 = ((xr != null) ? xr.RightController : null); bool flag = (Object)(object)controllerRig != (Object)null && !((ControllerRig)controllerRig).IsPaused && (Object)(object)leftController != (Object)null && (Object)(object)rightController != (Object)null && ((Behaviour)leftController).isActiveAndEnabled && ((Behaviour)rightController).isActiveAndEnabled && val != null && val2 != null && (!((Object)(object)uIRig != (Object)null) || !((Object)(object)uIRig.popUpMenu != (Object)null) || !uIRig.popUpMenu.isActive) && (!((Object)(object)instance != (Object)null) || !((Component)instance).gameObject.activeInHierarchy); if (_shortcut.Tick(now, activeShortcut, flag, flag && val.AButton, flag && val.BButton, flag && val.TriggerButton, flag && val2.TriggerButton, flag && val2.GripButton) && ((_settings.Mode == ScanMode.LiDAR) ? _renderer.EnqueueLidar(head.position, head.rotation, now) : _renderer.EnqueueClap(head.position, now))) { _clapPulseCount++; if (_settings.PulseSoundEnabled) { _audio.PlayPulse(_settings.PulseSoundVolume); } } return; } catch (Exception ex) { _shortcut.Reset(); Warn("Pulse shortcut: " + ex.Message); return; } } } _shortcut.Reset(); _clap.Reset(); } private void ReadClapGesture(float now, Transform head) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) if (!_settings.DoubleClapEnabled) { _clap.Reset(); return; } try { OpenControllerRig controllerRig = Player.ControllerRig; BaseController leftController = Player.LeftController; BaseController rightController = Player.RightController; UIRig uIRig = Player.UIRig; GUIMenu instance = GUIMenu.Instance; if (((Object)(object)uIRig != (Object)null && (Object)(object)uIRig.popUpMenu != (Object)null && uIRig.popUpMenu.isActive) || ((Object)(object)instance != (Object)null && ((Component)instance).gameObject.activeInHierarchy) || !((Object)(object)controllerRig != (Object)null) || ((ControllerRig)controllerRig).IsPaused || !((Object)(object)leftController != (Object)null) || !((Object)(object)rightController != (Object)null) || !((Behaviour)leftController).isActiveAndEnabled || !((Behaviour)rightController).isActiveAndEnabled || !Player.HandsExist || Player.LeftHand.HasAttachedObject() || Player.RightHand.HasAttachedObject() || (Player.LeftHand._indexButton && Player.RightHand._indexButton)) { _clap.Reset(); return; } if (!_clap.Tick(now, ((Component)leftController).transform.position, ((Component)rightController).transform.position, available: true, _settings.ClapContactDistance)) { if (_clap.ContactDetected && _settings.PulseSoundEnabled) { _audio.PlayClap(_settings.PulseSoundVolume); } return; } Transform val = head; if (controllerRig.cameras != null) { foreach (Camera item in (Il2CppArrayBase<Camera>)(object)controllerRig.cameras) { if ((Object)(object)item != (Object)null && ((Behaviour)item).isActiveAndEnabled) { val = ((Component)item).transform; break; } } } if (_renderer.EnqueueClap(val.position, now)) { _clapPulseCount++; if (_settings.PulseSoundEnabled) { _audio.PlayPulse(_settings.PulseSoundVolume); } } } catch (Exception ex) { _clap.Reset(); Warn("Double-clap input: " + ex.Message); } } internal void ManualPulse() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) if (!_settings.Enabled || !_active || !_runtimeReady) { return; } try { Transform head = Player.Head; if (!((Object)(object)head != (Object)null)) { return; } if (_settings.Mode == ScanMode.Radar) { _renderer.RestartRadar(); } else if (_settings.Mode == ScanMode.Sonar) { _renderer.EnqueueSonar(head.position, Time.unscaledTime); } else if (_settings.Mode == ScanMode.LiDAR) { if (_renderer.EnqueueLidar(head.position, head.rotation, Time.unscaledTime) && _settings.PulseSoundEnabled) { _audio.PlayPulse(_settings.PulseSoundVolume); } } else if (_settings.Mode == ScanMode.EchoLocation) { Emit(new EchoEvent(head.position, 1f, EchoKind.Manual, Time.unscaledTime)); } } catch (Exception ex) { Warn("Manual pulse needs a loaded player rig: " + ex.Message); } } internal void RestartMicrophone() { _microphone?.Restart(); } internal void Diagnostics() { if (!_runtimeReady) { ((MelonBase)this).LoggerInstance.Msg("EchoLocation waiting for a stable loaded player rig; no gameplay components are running."); return; } ((MelonBase)this).LoggerInstance.Msg($"Enabled={_settings.Enabled}; mode={_settings.Mode}; rig={_active}; renderer={_renderer.Ready}; dots={_renderer.DotCount}"); ((MelonBase)this).LoggerInstance.Msg($"Vision: {_renderer.VisionStatus}; blackout setting={_settings.Blackout}"); ((MelonBase)this).LoggerInstance.Msg($"Players: {_renderer.PlayerStatus}; highlights={_settings.PlayerHighlights}"); ((MelonBase)this).LoggerInstance.Msg($"Echo player reveal: running enabled={_settings.RunningReveal}, speed >= {_settings.MovementThreshold:F1}m/s; voice level >= {_settings.VoiceRevealThreshold:F3}, brightest >= {_settings.VoiceLoudThreshold:F3}; fade={_settings.PlayerRevealLifetime:F1}s; scanners require a scan hit, fade={_settings.ScanPlayerLifetime:F1}s"); ((MelonBase)this).LoggerInstance.Msg($"Continuous surroundings={_settings.ContinuousSurroundings}; refresh={_settings.SurroundingsInterval:F1}s"); ((MelonBase)this).LoggerInstance.Msg($"Shortcut={_settings.Shortcut}; enabled={_settings.DoubleClapEnabled}; 360 pulses={_clapPulseCount}"); ((MelonBase)this).LoggerInstance.Msg($"Player/voice cap={_settings.PlayerRange:F0}m; beyond live dots={_settings.DetectionMargin:F1}m; coverage cells={_coverage.CellCount}; footprints={_settings.PlayerFootprints}"); ((MelonBase)this).LoggerInstance.Msg(_renderer.PerformanceStatus); ((MelonBase)this).LoggerInstance.Msg($"Bullet trails={_settings.BulletTrails}; captured shots={_bulletTrails.AcceptedShots}; history limit={_settings.TracerLimit}; trace range={_settings.TracerRange:F0}m"); ((MelonBase)this).LoggerInstance.Msg($"Pulse sound enabled={_settings.PulseSoundEnabled}; volume={_settings.PulseSoundVolume:F2}; {_audio.Status}"); ((MelonBase)this).LoggerInstance.Msg($"Visual limits: rays/pulse={_settings.RayCount}; rays/frame={_settings.RaysPerFrame}; max dots={_settings.MaxDots}"); ((MelonBase)this).LoggerInstance.Msg($"Optimize walking/sound echoes={_settings.OptimizeAutomaticEchoes}; caps: {_settings.AutomaticRayLimit} rays/pulse, {_settings.AutomaticFrameBudget} rays/frame, {_settings.AutomaticLifetime:F2}s lifetime"); ((MelonBase)this).LoggerInstance.Msg($"Microphone: {_microphone.Status}; level={_microphone.Level:F4}; threshold={_settings.MicThreshold:F4}"); ((MelonBase)this).LoggerInstance.Msg($"World sources={_world.SourceCount}; threshold={_settings.SoundThreshold:F4}; range={_settings.WorldRange:F0}m"); ((MelonBase)this).LoggerInstance.Msg("Impact audio: " + _worldMonitor.Status); ((MelonBase)this).LoggerInstance.Msg($"Footsteps: {_locomotion.Status}; world: {_world.Status}; peak={_world.PeakLevel:F4}"); ((MelonBase)this).LoggerInstance.Msg($"Accepted pulses: manual={_counts[0]}, microphone={_counts[1]}, footsteps={_counts[2]}, world={_counts[3]}, voice={_counts[4]}"); } internal void Save() { try { _settings.Save(); } catch (Exception ex) { Warn("Could not save settings: " + ex.Message); } } private void ObserveSound(EchoEvent echo) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (_active && _settings.Enabled && Finite(echo.Origin)) { _renderer.ObserveSound(echo, _rigRoot); } } private void RegisterWorldPlayback(AudioSource source) { if (_active && _settings.Enabled && _settings.Mode == ScanMode.EchoLocation && _settings.WorldSoundEnabled && !((Object)(object)source == (Object)null) && ((Behaviour)source).isActiveAndEnabled && !source.mute && !(source.volume <= 0f) && !(source.spatialBlend < 0.5f) && (!source.loop || _settings.IncludeLoopingAudio) && !((Object)(object)_head == (Object)null)) { float unscaledTime = Time.unscaledTime; _world.RegisterPlayingSource(source, _objectSources.Capture(unscaledTime, source)); } } private void Emit(EchoEvent echo) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (_settings.Mode != ScanMode.EchoLocation || (uint)echo.Kind >= (uint)_pending.Length || !_settings.Enabled || !float.IsFinite(echo.Time) || !Finite(echo.Origin)) { return; } if (echo.Kind != EchoKind.Manual) { int kind = (int)echo.Kind; if (!_hasPending[kind] || echo.Time - _pending[kind].Time > 0.3f || echo.Strength > _pending[kind].Strength) { _pending[kind] = echo; } _hasPending[kind] = true; } else if (!(echo.Time < _nextPulse) && _renderer.Enqueue(echo)) { _nextPulse = echo.Time + _settings.PulseInterval; _counts[(int)echo.Kind]++; } } private void FlushInput(float now) { if (_settings.Mode != ScanMode.EchoLocation || now < _nextPulse) { return; } for (int i = 0; i < 4; i++) { int inputCursor = _inputCursor; _inputCursor = _inputCursor % 4 + 1; if (_hasPending[inputCursor]) { EchoEvent echoEvent = _pending[inputCursor]; _hasPending[inputCursor] = false; if (!(now - echoEvent.Time > Math.Max(0.35f, _settings.PulseInterval + 0.1f)) && _renderer.Enqueue(echoEvent.WithTime(now))) { _nextPulse = now + _settings.PulseInterval; _counts[inputCursor]++; break; } } } } private void ResetState() { _active = false; _startup.Reset(); _voiceMeter?.Reset(); _vrVoiceMeter?.Reset(); _shortcut.Reset(); _bulletTrails?.Reset(); _impactGlow?.Reset(); _active = false; _head = (_rigRoot = null); _nextPulse = 0f; _clap.Reset(); Array.Clear(_hasPending, 0, _hasPending.Length); try { _audio?.Stop(); } catch (Exception ex) { Warn(ex.Message); } try { _microphone?.Restart(); } catch (Exception ex2) { Warn(ex2.Message); } try { _world?.Reset(); } catch (Exception ex3) { Warn(ex3.Message); } _worldMonitor?.Reset(); _objectSources?.Reset(); _locomotion?.Reset(); try { _renderer?.Reset(); } catch (Exception ex4) { Warn(ex4.Message); } } private void Warn(string message) { float unscaledTime = Time.unscaledTime; if (!(unscaledTime < _nextWarning)) { _nextWarning = unscaledTime + 5f; ((MelonBase)this).LoggerInstance.Warning(message); } } 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 static class EchoMeshSpace { internal static bool TryGetDrawMatrix(Renderer renderer, SkinnedMeshRenderer? skin, Mesh snapshot, out Matrix4x4 matrix, bool validateBounds = true) { //IL_0018: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022e: 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_0241: Unknown result type (might be due to invalid IL or missing references) matrix = (((Object)(object)skin != (Object)null) ? ((Component)skin).transform.localToWorldMatrix : 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 val = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(((Bounds)(ref bounds)).center); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..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(val) || !Finite(val2)) { return false; } if (!validateBounds) { return true; } Bounds bounds2 = renderer.bounds; if (!Usable(bounds2)) { return false; } Vector3 val3 = val - ((Bounds)(ref bounds2)).center; Vector3 val4 = ((Bounds)(ref bounds2)).extents * 1.5f + Vector3.one * 0.15f; if (Math.Abs(val3.x) + val2.x <= val4.x && Math.Abs(val3.y) + val2.y <= val4.y) { return Math.Abs(val3.z) + val2.z <= val4.z; } return false; } 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 sealed class EchoRenderer : IDisposable { private struct Pulse { internal Vector3 Origin; internal Quaternion Rotation; internal bool Clap; internal bool Lidar; internal bool Sonar; internal float SweepDuration; internal float HeadingX; internal float HeadingZ; internal bool Automatic; internal bool Deduplicate; internal EchoKind Kind; internal SoundEmitterSurface? SurfaceEmission; internal Vector3 ListenerOrigin; internal int SurfaceRays; internal float Strength; internal float Time; internal float Range; internal float Phase; internal int Total; internal int Next; internal int ShuffleBits; internal int ShuffleCursor; } private struct Dot { internal Vector3 Position; internal Vector3 Normal; internal bool Lidar; internal bool TrackedObject; internal RadarTargetKind RadarKind; internal RadarFade RadarFade; internal float Birth; internal float FadeInStart; internal float Lifetime; internal float Strength; internal bool Indexed; internal bool Clap; internal SurfaceCell Cell; } private struct ColliderFlags { internal Collider Collider; internal bool Local; internal bool Player; internal PlayerTarget? Target; internal bool Object; internal bool Npc; } private struct RecentSound { internal Vector3 Origin; internal float Time; internal Collider? Owner; internal bool Valid; } private readonly struct SurfaceCell : IEquatable<SurfaceCell> { private readonly int _collider; private readonly int _x; private readonly int _y; private readonly int _z; private readonly int _facing; private readonly bool _detail; internal SurfaceCell(int collider, Vector3 point, Vector3 normal, float spacing, bool detail) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0052: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) _collider = collider; _x = (int)MathF.Floor(point.x / spacing); _y = (int)MathF.Floor(point.y / spacing); _z = (int)MathF.Floor(point.z / spacing); float num = MathF.Abs(normal.x); float num2 = MathF.Abs(normal.y); float num3 = MathF.Abs(normal.z); _facing = ((num > num2 && num > num3) ? ((!(normal.x >= 0f)) ? 1 : 0) : ((num2 > num3) ? ((normal.y >= 0f) ? 2 : 3) : ((normal.z >= 0f) ? 4 : 5))); _detail = detail; } public bool Equals(SurfaceCell other) { if (_collider == other._collider && _x == other._x && _y == other._y && _z == other._z && _facing == other._facing) { return _detail == other._detail; } return false; } public override bool Equals(object? obj) { if (obj is SurfaceCell other) { return Equals(other); } return false; } public override int GetHashCode() { return HashCode.Combine(_collider, _x, _y, _z, _facing, _detail); } } private readonly RadarScanner _continuous; private Transform? _radarRoot; private const int QueueLimit = 4; private const int HardDotLimit = 65536; private const float QueueLifetime = 1.25f; private const float WaveSpeed = 45f; private const float MaximumWaveTravelTime = 1.25f; private const float GoldenAngle = 2.3999631f; private const int ShaderAttempts = 6; private const int AutomaticRaysPerPulse = 512; private const int AutomaticRaysPerFrame = 256; private const int EmitterSurfaceRayLimit = 128; private const float AutomaticLifetime = 0.85f; private const float AutomaticDotSpacing = 0.09f; private const int ColliderCacheLimit = 512; private static readonly string[] ShaderNames = new string[3] { "Sprites/Default", "Legacy Shaders/Particles/Alpha Blended", "Hidden/Internal-Colored" }; private readonly Settings _settings; private readonly Action<string> _warning; private readonly BlackoutView _blackout; private readonly PlayerEchoes _players; private readonly ScanCoverage _coverage; private readonly Pulse[] _pulses = new Pulse[4]; private readonly Il2CppStructArray<RaycastHit> _hits = new Il2CppStructArray<RaycastHit>(32L); private readonly Dictionary<SurfaceCell, int> _surfaceCells = new Dictionary<SurfaceCell, int>(); private readonly Dictionary<int, ColliderFlags> _colliderFlags = new Dictionary<int, ColliderFlags>(512); private readonly RecentSound[] _recentSounds = new RecentSound[8]; private int _recentSoundCursor; private Dot[] _dots = Array.Empty<Dot>(); private int _dotCount; private int _pulseCount; private int _pulseCursor; private int _overwriteCursor; private uint _sequence; private Mesh? _mesh; private Material? _material; private Texture2D? _dotTexture; private bool _texturedDots; private DotShape _textureShape; private double _peakRaysMs; private double _peakDotsMs; private double _peakPlayersMs; private Il2CppStructArray<Vector3>? _vertices; private Il2CppStructArray<Color>? _colors; private Il2CppStructArray<Vector2>? _uvs; private Il2CppStructArray<int>? _indices; private int _uploadCapacity; private int _shaderAttempts; private float _nextShaderAttempt; private float _nextSurroundings; private bool _disposed; private const int CircleSegments = 12; private static readonly Vector2[][] ShapeBoundaries = MakeShapeBoundaries(); internal string PerformanceStatus => $"Scene CPU peaks: rays={_peakRaysMs:F2}ms, dot upload={_peakDotsMs:F2}ms, player pass={_peakPlayersMs:F2}ms; effective ray cap={PulseWorkBudget.RayLimit(_settings.PerformanceLevel, _settings.RaysPerFrame, Time.unscaledDeltaTime)}, dot cap={PulseWorkBudget.DotLimit(_settings.PerformanceLevel, _settings.MaxDots)}; textured dots={_texturedDots}"; internal bool Ready { get { if (!_disposed && (Object)(object)_mesh != (Object)null) { return (Object)(object)_material != (Object)null; } return false; } } internal int DotCount => _dotCount; internal string VisionStatus => _blackout.Status; internal string PlayerStatus => _players.Status; private int VerticesPerDot { get { if (!_texturedDots) { return 13; } return 4; } } private int IndicesPerDot { get { if (!_texturedDots) { return 36; } return 6; } } internal EchoRenderer(Settings settings, Action<string> warning, ScanCoverage coverage) { _settings = settings; _coverage = coverage; _warning = warning; _blackout = new BlackoutView(warning); _players = new PlayerEchoes(settings, warning, coverage); _continuous = new RadarScanner(settings, (Collider collider) => GetColliderFlags(collider, _radarRoot).Local, AddRadarReturn, null, delegate(Collider collider) { ColliderFlags colliderFlags = GetColliderFlags(collider, _radarRoot); return !colliderFlags.Local && !colliderFlags.Player && ((colliderFlags.Npc && _settings.RadarNpcs) || (colliderFlags.Object && _settings.RadarObjects)); }); } internal void ObserveSound(EchoEvent echo, Transform? localRoot) { if (_disposed) { return; } try { _players.ObserveSound(echo, localRoot); } catch (Exception ex) { _warning("Player sound ownership: " + ex.Message); } } internal bool Enqueue(EchoEvent echo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Enqueue(echo, clap: false); } internal bool EnqueueClap(Vector3 origin, float now) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return Enqueue(new EchoEvent(origin, 1f, EchoKind.Manual, now), clap: true); } internal void RestartRadar() { _continuous.Reset(); _players.Reset(); } internal bool EnqueueLidar(Vector3 origin, Quaternion rotation, float now) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Enqueue(new EchoEvent(origin, 1f, EchoKind.Manual, now), clap: false, lidar: true, rotation); } internal bool EnqueueSonar(Vector3 origin, float now) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return Enqueue(new EchoEvent(origin, 1f, EchoKind.Manual, now), clap: false, lidar: true, default(Quaternion), sonar: true); } private bool Enqueue(EchoEvent echo, bool clap, bool lidar = false, Quaternion rotation = default(Quaternion), bool sonar = false) { //IL_001c: 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_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) if (_settings.Mode != ScanMode.EchoLocation && !lidar) { return false; } if (_disposed || !Finite(echo.Origin) || !float.IsFinite(echo.Time) || !float.IsFinite(echo.Strength) || echo.Strength <= 0f) { return false; } PrunePulses(echo.Time); if (echo.Kind == EchoKind.Manual) { for (int i = 0; i < _pulseCount; i++) { if (_pulses[i].Kind == EchoKind.Manual) { return false; } } } bool flag = echo.Kind == EchoKind.Ambient; bool flag2 = flag || (_settings.OptimizeAutomaticEchoes && !clap && echo.Kind != EchoKind.Manual); SoundEmitterSurface soundEmitterSurface = ((echo.Kind == EchoKind.World) ? echo.SurfaceEmission : null); if (soundEmitterSurface != null && soundEmitterSurface.Count == 0) { soundEmitterSurface = null; } Collider owner = ((soundEmitterSurface != null && soundEmitterSurface.Count > 0) ? soundEmitterSurface.GetCollider(0) : null); if (flag2 && !flag && HasRecentNearbySound(echo.Origin, echo.Time, owner)) { return false; } if (clap && ClapPulseIndex() >= 0) { return false; } if (_pulseCount >= 4) { bool flag3 = soundEmitterSurface != null && soundEmitterSurface.Count > 0; if (!clap && !flag3) { return false; } int num = -1; for (int j = 0; j < _pulseCount; j++) { if ((clap || (!_pulses[j].Clap && _pulses[j].Kind != EchoKind.Manual && _pulses[j].SurfaceEmission == null)