using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Microsoft.CodeAnalysis; using Player; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace WeaponSafety { internal static class Anchors { internal static string _anchorInfo = "not computed"; internal static bool _loggedAnchorFallback; internal static bool _loggedClamped; internal static Vector2 _anchorTarget; internal static bool _loggedIconFail; internal static bool _loggedPosFail; internal static Rect _iconBox; internal static float _iconDepth; internal static float _iconBoxStamp = -9999f; internal static string _previousAnchorKind = ""; internal const float BaseChipPadding = 14f; internal static bool TryIconAnchor(Camera cam, out Vector2 target, out float z) { //IL_0002: 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_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_01df: Unknown result type (might be due to invalid IL or missing references) //IL_020a: 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_022e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) target = default(Vector2); z = 0f; Transform flashlightIcon = HudScan._flashlightIcon; if ((Object)(object)flashlightIcon != (Object)null && HudGeometry.ScreenRectOf(flashlightIcon, cam, out var r)) { Transform flashlightIconAlt = HudScan._flashlightIconAlt; string text = ((Object)flashlightIcon).name; if ((Object)(object)flashlightIconAlt != (Object)null && ((Component)flashlightIconAlt).gameObject.activeInHierarchy && HudGeometry.ScreenRectOf(flashlightIconAlt, cam, out var r2)) { r = Rect.MinMaxRect(Mathf.Min(((Rect)(ref r)).xMin, ((Rect)(ref r2)).xMin), Mathf.Min(((Rect)(ref r)).yMin, ((Rect)(ref r2)).yMin), Mathf.Max(((Rect)(ref r)).xMax, ((Rect)(ref r2)).xMax), Mathf.Max(((Rect)(ref r)).yMax, ((Rect)(ref r2)).yMax)); text = ((Object)flashlightIcon).name + " + " + ((Object)flashlightIconAlt).name; } if (!string.Equals(text, HudScan._previousIconName, StringComparison.Ordinal)) { HudScan._previousIconName = text; WeaponSafetyGUI.LogDebug($"[indicator] anchor icon: '{text}' box=({HudGeometry.F(((Rect)(ref r)).xMin)}, {HudGeometry.F(((Rect)(ref r)).yMin)})-({HudGeometry.F(((Rect)(ref r)).xMax)}, {HudGeometry.F(((Rect)(ref r)).yMax)})"); } if (((Rect)(ref r)).center.x >= (float)cam.pixelWidth * 0.5f && ((Rect)(ref r)).center.y >= (float)cam.pixelHeight * 0.45f) { float z2 = cam.WorldToScreenPoint(flashlightIcon.position).z; if (z2 > 0f) { _iconBox = r; _iconDepth = z2; _iconBoxStamp = Time.unscaledTime; target = new Vector2(((Rect)(ref r)).xMin - 8f, ((Rect)(ref r)).center.y); z = z2; _anchorInfo = $"flashlight-icon (sun) box=({HudGeometry.F(((Rect)(ref r)).xMin)}, {HudGeometry.F(((Rect)(ref r)).yMin)})-({HudGeometry.F(((Rect)(ref r)).xMax)}, {HudGeometry.F(((Rect)(ref r)).yMax)}) target=({HudGeometry.F(target.x)}, {HudGeometry.F(target.y)}) gap={HudGeometry.F(8f)}"; return true; } } } if (Time.unscaledTime - _iconBoxStamp > 1.5f) { return false; } target = new Vector2(((Rect)(ref _iconBox)).xMin - 8f, ((Rect)(ref _iconBox)).center.y); z = _iconDepth; _anchorInfo = $"flashlight-icon (sun, saved box {HudGeometry.F(Time.unscaledTime - _iconBoxStamp)} s) target=({HudGeometry.F(target.x)}, {HudGeometry.F(target.y)}) gap={HudGeometry.F(8f)}"; return true; } internal static void PlaceByRect(Transform clone, Camera cam, Vector2 target, float z) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) clone.position = cam.ScreenToWorldPoint(new Vector3(target.x, target.y, z)); for (int i = 0; i < 2; i++) { if (!HudGeometry.ScreenRectOf(clone, cam, out var r)) { break; } float num = target.x - ((Rect)(ref r)).xMax; float num2 = target.y - ((Rect)(ref r)).center.y; if (Mathf.Abs(num) < 0.05f && Mathf.Abs(num2) < 0.05f) { break; } Vector3 val = cam.WorldToScreenPoint(clone.position); clone.position = cam.ScreenToWorldPoint(new Vector3(val.x + num, val.y + num2, val.z)); } } internal static bool TryGetAnchorScreen(Camera cam, Transform? template, out Vector2 anchor, out float z) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_039f: 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_00b0: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) anchor = default(Vector2); z = 0f; Transform val = null; Transform val2 = null; Vector3 val3 = default(Vector3); Vector3 val4 = default(Vector3); int num = 0; int num2 = 0; float num3 = (float)cam.pixelWidth * 0.5f; float num4 = (float)cam.pixelHeight * 0.45f; for (int i = 0; i < HudScan._rows.Count; i++) { Transform val5 = HudScan._rows[i]; if ((Object)(object)val5 == (Object)null || !((Component)val5).gameObject.activeInHierarchy) { continue; } Vector3 val6 = cam.WorldToScreenPoint(val5.position); if (val6.z <= 0f) { continue; } if (val6.x < num3 || val6.y < num4) { num2++; continue; } num++; if ((Object)(object)val == (Object)null || val6.y < val3.y) { val2 = val; val4 = val3; val = val5; val3 = val6; } else if ((Object)(object)val2 == (Object)null || val6.y < val4.y) { val2 = val5; val4 = val6; } } if ((Object)(object)val != (Object)null) { float num5 = (((Object)(object)val2 != (Object)null) ? (val4.y - val3.y) : 0f); if (num5 < 6f || num5 > 300f) { num5 = 33f * (float)cam.pixelHeight / 1080f; } anchor = new Vector2(val3.x, val3.y - num5); z = val3.z; _anchorInfo = $"rows={num} (candidates={HudScan._rows.Count}, out-of-region={num2}) bottom='{((Object)val).name}' screen=({HudGeometry.F(val3.x)}, {HudGeometry.F(val3.y)}) gap={HudGeometry.F(num5)} target=({HudGeometry.F(anchor.x)}, {HudGeometry.F(anchor.y)})"; return true; } if ((Object)(object)template != (Object)null) { Vector3 val7 = cam.WorldToScreenPoint(template.position); if (val7.z > 0f) { anchor = new Vector2(val7.x, val7.y); z = val7.z; _anchorInfo = $"no HUD rows: anchor at template ({HudGeometry.F(val7.x)}, {HudGeometry.F(val7.y)})"; if (!_loggedAnchorFallback) { _loggedAnchorFallback = true; WeaponSafetyGUI.LogInfo("[WeaponSafety] No list rows visible: the indicator uses the template as an anchor (fixed position)."); } return true; } } _anchorInfo = "no anchor (no rows and no template)"; return false; } internal static void PlaceIndicator(Transform clone, Transform? template, bool log) { //IL_0024: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: 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_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: 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) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) Camera componentInParent = ((Component)clone).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return; } HudScan.RefreshRows(); bool flag = false; Vector2 target = default(Vector2); float z = 0f; try { flag = TryIconAnchor(componentInParent, out target, out z); } catch (Exception ex) { if (!_loggedIconFail) { _loggedIconFail = true; WeaponSafetyGUI.LogInfo("The flashlight icon anchor failed (" + ex.GetType().Name + "): using the weapon list."); } } if (!flag) { if (!TryGetAnchorScreen(componentInParent, template, out target, out z)) { return; } flag = false; } target.x += ModConfig.OffsetX.Value; target.y += ModConfig.OffsetY.Value; target.x -= ((Chip._marginRight >= 0f) ? Chip._marginRight : (14f * (float)componentInParent.pixelHeight / 1080f)) + HudGeometry.ExtraPadding(componentInParent); _anchorTarget = target; string text = ((!flag) ? "rows" : (_anchorInfo.StartsWith("flashlight-icon (sun, saved box", StringComparison.Ordinal) ? "icon-saved" : "flashlight-icon")); if (log && !string.Equals(text, _previousAnchorKind, StringComparison.Ordinal)) { _previousAnchorKind = text; WeaponSafetyGUI.LogDebug("[indicator] anchor -> " + text + ": " + _anchorInfo); } if (flag) { PlaceByRect(clone, componentInParent, target, z); } else { clone.position = componentInParent.ScreenToWorldPoint(new Vector3(target.x, target.y, z)); } float value = ModConfig.DepthOffset.Value; if (value > 0f) { Vector3 val = ((Component)componentInParent).transform.position - clone.position; float num = Vector3.Dot(clone.position - ((Component)componentInParent).transform.position, ((Component)componentInParent).transform.forward); float num2 = num - (componentInParent.nearClipPlane + 5f); if (num2 > 0f && ((Vector3)(ref val)).sqrMagnitude > 0.0001f) { clone.position += ((Vector3)(ref val)).normalized * Mathf.Min(value, num2); } } Vector3 val2 = componentInParent.WorldToScreenPoint(clone.position); float num3 = Mathf.Clamp(val2.x, 24f, (float)componentInParent.pixelWidth - 24f); float num4 = Mathf.Clamp(val2.y, 24f, (float)componentInParent.pixelHeight - 24f); if (!Mathf.Approximately(num3, val2.x) || !Mathf.Approximately(num4, val2.y)) { clone.position = componentInParent.ScreenToWorldPoint(new Vector3(num3, num4, val2.z)); if (log && !_loggedClamped) { _loggedClamped = true; WeaponSafetyGUI.LogInfo($"Indicator out of frame at ({HudGeometry.F(val2.x)}, {HudGeometry.F(val2.y)}): clamped to ({HudGeometry.F(num3)}, {HudGeometry.F(num4)}). anchor: {_anchorInfo}"); } } else { _loggedClamped = false; } clone.SetAsLastSibling(); Chip.ManageChip(clone, componentInParent); } } internal static class Chip { internal static float _lastCenterX; internal static float _lastTargetWidth; internal static float _previousClip = float.MinValue; internal const float IconGap = 8f; internal static GameObject? _chip; internal static Vector3 _chipStartScale; internal static float _chipStartHeight; internal static float _marginLeft = -1f; internal static float _marginRight = -1f; internal static float _rowHeightPx; internal static float _nextChipSearch = -9999f; internal static bool _chipSearchedHud; internal static bool _loggedChipFail; internal static bool _loggedChipCalled; internal static bool _loggedChipRect; internal static Texture2D? _opaqueTexture; internal static Material? _ownMaterial; internal static void ManageChip(Transform clone, Camera cam) { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_05df: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_061c: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_0519: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) if (!_loggedChipCalled) { _loggedChipCalled = true; Rect r; bool flag = HudGeometry.ScreenRectOf(clone, cam, out r); WeaponSafetyGUI.LogInfo("[chip] ManageChip running: ref=" + (((Object)(object)HudScan._referenceText != (Object)null) ? ("'" + HudScan._referenceText.text + "'") : "null") + $", rows={HudScan._rows.Count}, our-box=" + (flag ? $"{HudGeometry.F(((Rect)(ref r)).width)}x{HudGeometry.F(((Rect)(ref r)).height)} at ({HudGeometry.F(((Rect)(ref r)).center.x)}, {HudGeometry.F(((Rect)(ref r)).center.y)})" : "NO RECT") + "."); } if ((Object)(object)_chip == (Object)null && Time.unscaledTime >= _nextChipSearch) { _nextChipSearch = Time.unscaledTime + 2f; CreateChip(clone, cam); } GameObject chip = _chip; if ((Object)(object)chip == (Object)null) { return; } if (!chip.activeSelf) { chip.SetActive(true); } if (!HudGeometry.ScreenRectOf(clone, cam, out var r2) || ((Rect)(ref r2)).width < 2f || ((Rect)(ref r2)).height < 2f) { return; } float num = 14f * (float)cam.pixelHeight / 1080f; float num2 = HudGeometry.ExtraPadding(cam); float num3 = ((_marginLeft >= 0f) ? _marginLeft : num) + num2; float num4 = ((_marginRight >= 0f) ? _marginRight : num) + num2; float num5 = Mathf.Max(40f, ((Rect)(ref r2)).width + num3 + num4); float num6 = ((Rect)(ref r2)).center.x + (num4 - num3) * 0.5f; float y = ((Rect)(ref r2)).center.y; if (Time.unscaledTime - Anchors._iconBoxStamp < 2f) { float num7 = ((Rect)(ref Anchors._iconBox)).xMin - 8f; float num8 = num6 - num5 * 0.5f; if (num8 + num5 > num7 + 0.5f) { float num9 = num8 + num5 - num7; num5 = Mathf.Max(40f, num7 - num8); num6 = num8 + num5 * 0.5f; if (Mathf.Abs(num9 - _previousClip) > 1f) { _previousClip = num9; WeaponSafetyGUI.LogDebug($"[chip] chip clipped {HudGeometry.F(num9)} px on the right so it does not invade the flashlight icon (limit x={HudGeometry.F(num7)}, sun box {HudGeometry.F(((Rect)(ref Anchors._iconBox)).xMin)}-{HudGeometry.F(((Rect)(ref Anchors._iconBox)).xMax)})."); } } } _lastCenterX = num6; _lastTargetWidth = num5; float num10 = ((_chipStartHeight > 0f) ? _chipStartHeight : (((Rect)(ref r2)).height + 2f * num)); if (_rowHeightPx > 0f && _rowHeightPx < num10) { num10 = _rowHeightPx; } Transform transform = chip.transform; float z = cam.WorldToScreenPoint(clone.position).z; transform.position = cam.ScreenToWorldPoint(new Vector3(num6, y, z + 0.3f)); for (int i = 0; i < 3; i++) { if (!HudGeometry.ScreenRectOf(transform, cam, out var r3) || ((Rect)(ref r3)).width < 1f || ((Rect)(ref r3)).height < 1f) { return; } float num11 = num5 / ((Rect)(ref r3)).width; float num12 = num10 / ((Rect)(ref r3)).height; if (Mathf.Abs(num11 - 1f) < 0.004f && Mathf.Abs(num12 - 1f) < 0.004f) { break; } Vector3 localScale = transform.localScale; transform.localScale = new Vector3(localScale.x * num11, localScale.y * num12, localScale.z); } if (HudGeometry.ScreenRectOf(transform, cam, out var r4)) { float num13 = num6 - ((Rect)(ref r4)).center.x; float num14 = y - ((Rect)(ref r4)).center.y; if (Mathf.Abs(num13) > 0.4f || Mathf.Abs(num14) > 0.4f) { Vector3 val = cam.ScreenToWorldPoint(new Vector3(((Rect)(ref r4)).center.x, ((Rect)(ref r4)).center.y, z + 0.3f)); Vector3 val2 = cam.ScreenToWorldPoint(new Vector3(((Rect)(ref r4)).center.x + num13, ((Rect)(ref r4)).center.y + num14, z + 0.3f)); transform.position += val2 - val; } } Renderer component = ((Component)clone).GetComponent(); Renderer component2 = ((Component)transform).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.sortingOrder = ModConfig.SortingOrder.Value - 1; if ((Object)(object)component != (Object)null) { component2.sortingLayerID = component.sortingLayerID; if (component.sortingOrder - 1 < component2.sortingOrder) { component2.sortingOrder = component.sortingOrder - 1; } } } if ((Object)(object)transform.parent == (Object)(object)clone.parent) { transform.SetSiblingIndex(Mathf.Max(0, clone.GetSiblingIndex() - 1)); } if (HudLog.IsDebug) { ChipDiagnostics.DiagnoseChip(clone, transform, cam); } if (!_loggedChipRect) { _loggedChipRect = true; if (HudGeometry.ScreenRectOf(transform, cam, out var r5)) { WeaponSafetyGUI.LogDebug($"[chip] our chip = {HudGeometry.F(((Rect)(ref r5)).width)}x{HudGeometry.F(((Rect)(ref r5)).height)} at ({HudGeometry.F(((Rect)(ref r5)).xMin)}, {HudGeometry.F(((Rect)(ref r5)).yMin)})-({HudGeometry.F(((Rect)(ref r5)).xMax)}, {HudGeometry.F(((Rect)(ref r5)).yMax)}); text at ({HudGeometry.F(((Rect)(ref r2)).xMin)}, {HudGeometry.F(((Rect)(ref r2)).xMax)}) width {HudGeometry.F(((Rect)(ref r2)).width)}; target width={HudGeometry.F(num5)} centerX={HudGeometry.F(num6)}."); } } } internal static void ApplyAlwaysOnTop(GameObject copy) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_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_029a: 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_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Invalid comparison between Unknown and I4 //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Expected O, but got Unknown //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_063f: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer component = copy.GetComponent(); if ((Object)(object)component == (Object)null) { WeaponSafetyGUI.LogInfo("[chip] no SpriteRenderer: keeping the original material."); return; } Shader val = Shader.Find("GUI/Text Shader"); if ((Object)(object)val == (Object)null) { WeaponSafetyGUI.LogInfo("[chip] 'GUI/Text Shader' not found: keeping the original material."); return; } Material sharedMaterial = ((Renderer)component).sharedMaterial; Color color = component.color; string value = "no material"; if ((Object)(object)sharedMaterial != (Object)null) { string value2 = "none"; if ((Object)(object)sharedMaterial.mainTexture != (Object)null) { value2 = $"'{((Object)sharedMaterial.mainTexture).name}' {sharedMaterial.mainTexture.width}x{sharedMaterial.mainTexture.height}"; } string value3 = (sharedMaterial.HasProperty("_Color") ? (HudGeometry.F(sharedMaterial.GetColor("_Color").r) + "," + HudGeometry.F(sharedMaterial.GetColor("_Color").g) + "," + HudGeometry.F(sharedMaterial.GetColor("_Color").b)) : "?"); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 4); defaultInterpolatedStringHandler.AppendLiteral("'"); defaultInterpolatedStringHandler.AppendFormatted(((Object)sharedMaterial).name); defaultInterpolatedStringHandler.AppendLiteral("' shader="); Shader shader = sharedMaterial.shader; defaultInterpolatedStringHandler.AppendFormatted((shader != null) ? ((Object)shader).name : null); defaultInterpolatedStringHandler.AppendLiteral(" "); defaultInterpolatedStringHandler.AppendLiteral("tex="); defaultInterpolatedStringHandler.AppendFormatted(value2); defaultInterpolatedStringHandler.AppendLiteral(" _Color=("); defaultInterpolatedStringHandler.AppendFormatted(value3); defaultInterpolatedStringHandler.AppendLiteral(")"); value = defaultInterpolatedStringHandler.ToStringAndClear(); } Sprite sprite = component.sprite; object obj; if (!((Object)(object)sprite == (Object)null)) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(13, 3); defaultInterpolatedStringHandler2.AppendLiteral("'"); defaultInterpolatedStringHandler2.AppendFormatted(((Object)sprite).name); defaultInterpolatedStringHandler2.AppendLiteral("' "); defaultInterpolatedStringHandler2.AppendLiteral("rect="); Rect textureRect = sprite.textureRect; defaultInterpolatedStringHandler2.AppendFormatted(HudGeometry.F(((Rect)(ref textureRect)).width)); defaultInterpolatedStringHandler2.AppendLiteral("x"); textureRect = sprite.textureRect; defaultInterpolatedStringHandler2.AppendFormatted(HudGeometry.F(((Rect)(ref textureRect)).height)); defaultInterpolatedStringHandler2.AppendLiteral(" of "); obj = defaultInterpolatedStringHandler2.ToStringAndClear() + (((Object)(object)sprite.texture != (Object)null) ? $"'{((Object)sprite.texture).name}' {((Texture)sprite.texture).width}x{((Texture)sprite.texture).height} readable={((Texture)sprite.texture).isReadable}" : "null texture"); } else { obj = "NO SPRITE (no mesh: that would leave it invisible)"; } string value4 = (string)obj; string text = ((object)component.maskInteraction/*cast due to .constrained prefix*/).ToString(); if ((int)component.maskInteraction > 0) { WeaponSafetyGUI.LogDebug("[chip] the sprite had maskInteraction=" + text + " (invisible without SpriteMask): set to None."); } float avgAlpha = 1f; if (!ReadSpriteTexture(sprite, color, out Color tint, out avgAlpha, out string source)) { tint = FallbackTint(color); source = "rule (" + source + ")"; } bool value5 = ModConfig.DebugChipMagenta.Value; if (value5) { tint = Color.magenta; source = "MAGENTA-test " + source; } float num = (value5 ? 1f : Mathf.Clamp01(ModConfig.ChipAlpha.Value)); Material val2 = new Material(val); val2.mainTexture = (Texture)(object)OpaqueTexture(); val2.SetColor("_Color", new Color(tint.r, tint.g, tint.b, num)); val2.SetTextureScale("_MainTex", Vector2.one); val2.SetTextureOffset("_MainTex", Vector2.zero); ((Renderer)component).material = val2; component.maskInteraction = (SpriteMaskInteraction)0; component.color = new Color(1f, 1f, 1f, 1f); WeaponSafetyGUI.LogDebug($"[chip] own material '{((Object)val).name}' (ZTest Always, opaque 1x1 texture, white vertex) tint=({HudGeometry.F(tint.r)}, {HudGeometry.F(tint.g)}, {HudGeometry.F(tint.b)}) alpha={HudGeometry.F(num * 100f)}% source={source} avgSpriteAlpha={HudGeometry.F(avgAlpha * 100f)}% colorSprite=({HudGeometry.F(color.r)}, {HudGeometry.F(color.g)}, {HudGeometry.F(color.b)}, a={HudGeometry.F(color.a)}) mask={text}. | original: {value} | sprite: {value4}"); } internal static Color FallbackTint(Color colorSprite) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(colorSprite.r, Mathf.Max(colorSprite.g, colorSprite.b)); if (num <= 0f) { return new Color(0.13f, 0.13f, 0.13f, 1f); } return (num < 0.9f) ? new Color(colorSprite.r, colorSprite.g, colorSprite.b, 1f) : new Color(0.13f, 0.13f, 0.13f, 1f); } internal static Texture2D OpaqueTexture() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_opaqueTexture != (Object)null) { return _opaqueTexture; } _opaqueTexture = new Texture2D(1, 1, (TextureFormat)4, false) { name = "WeaponSafety_OpaqueTexture" }; _opaqueTexture.SetPixel(0, 0, Color.white); _opaqueTexture.Apply(false, false); return _opaqueTexture; } internal static bool ReadSpriteTexture(Sprite? sprite, Color colorSprite, out Color tint, out float avgAlpha, out string source) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) tint = default(Color); avgAlpha = 0f; source = ""; try { if ((Object)(object)sprite == (Object)null) { source = "null sprite"; return false; } Texture2D texture = sprite.texture; if ((Object)(object)texture == (Object)null) { source = "null texture"; return false; } Rect val; try { val = sprite.textureRect; } catch (Exception) { val = default(Rect); } if (((Rect)(ref val)).width < 1f || ((Rect)(ref val)).height < 1f) { ((Rect)(ref val))..ctor(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); } ((Rect)(ref val)).x = Mathf.Clamp(((Rect)(ref val)).x, 0f, (float)((Texture)texture).width - 1f); ((Rect)(ref val)).y = Mathf.Clamp(((Rect)(ref val)).y, 0f, (float)((Texture)texture).height - 1f); ((Rect)(ref val)).width = Mathf.Min(((Rect)(ref val)).width, (float)((Texture)texture).width - ((Rect)(ref val)).x); ((Rect)(ref val)).height = Mathf.Min(((Rect)(ref val)).height, (float)((Texture)texture).height - ((Rect)(ref val)).y); RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; Texture2D val2 = null; try { Graphics.Blit((Texture)(object)texture, temporary); RenderTexture.active = temporary; val2 = new Texture2D(Mathf.RoundToInt(((Rect)(ref val)).width), Mathf.RoundToInt(((Rect)(ref val)).height), (TextureFormat)4, false); val2.ReadPixels(val, 0, 0); val2.Apply(); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } Color[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val2.GetPixels()); Object.Destroy((Object)(object)val2); float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; for (int i = 0; i < array.Length; i++) { float a = array[i].a; if (!(a <= 0.01f)) { num += a; num2 += array[i].r * a; num3 += array[i].g * a; num4 += array[i].b * a; } } avgAlpha = ((array.Length != 0) ? (num / (float)array.Length) : 0f); if (num <= 0f) { source = $"transparent texture ({((Texture)texture).width}x{((Texture)texture).height}, rect {HudGeometry.F(((Rect)(ref val)).width)}x{HudGeometry.F(((Rect)(ref val)).height)})"; return false; } tint = new Color(Mathf.Clamp01(num2 / num * colorSprite.r), Mathf.Clamp01(num3 / num * colorSprite.g), Mathf.Clamp01(num4 / num * colorSprite.b), 1f); source = $"GPU texture {((Texture)texture).width}x{((Texture)texture).height} (rect {HudGeometry.F(((Rect)(ref val)).width)}x{HudGeometry.F(((Rect)(ref val)).height)})"; return true; } catch (Exception ex2) { source = "exception " + ex2.GetType().Name + ": " + ex2.Message; return false; } } internal static void CreateChip(Transform clone, Camera cam) { //IL_0021: 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_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0352: 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_0418: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) TMP_Text referenceText = HudScan._referenceText; Transform val = (((Object)(object)referenceText != (Object)null) ? HudScan.RowOf(referenceText.transform) : null); Rect r = default(Rect); bool flag = (Object)(object)referenceText != (Object)null && HudGeometry.ScreenRectOf(referenceText.transform, cam, out r); bool flag2 = flag; if (!flag2 && (Object)(object)val != (Object)null) { flag2 = HudGeometry.ScreenRectOf(val, cam, out r); } if (!flag2) { if (!_loggedChipFail) { _loggedChipFail = true; WeaponSafetyGUI.LogInfo("[chip] Failed attempt: no reference rect (ref=" + (((Object)(object)referenceText == (Object)null) ? "null" : ("'" + referenceText.text + "'")) + ", " + $"row={(((Object)(object)val == (Object)null) ? "null" : HudGeometry.PathOf(val))}, rows={HudScan._rows.Count}). " + "Dumping structure:"); if ((Object)(object)val != (Object)null) { HudScan.DumpStructure(val, cam); } } return; } _rowHeightPx = (((Object)(object)val != (Object)null && HudGeometry.ScreenRectOf(val, cam, out var r2)) ? ((Rect)(ref r2)).height : 0f); Transform best = null; float bestArea = float.MaxValue; if ((Object)(object)val != (Object)null) { SearchChipUnder(val, cam, r, ref best, ref bestArea); } if ((Object)(object)HudScan._inventoryRoot != (Object)null) { SearchChipUnder(HudScan._inventoryRoot, cam, r, ref best, ref bestArea); } if ((Object)(object)best == (Object)null && !_chipSearchedHud && (Object)(object)HudScan._stableHudRoot != (Object)null) { _chipSearchedHud = true; SearchChipUnder(HudScan._stableHudRoot, cam, r, ref best, ref bestArea); } if ((Object)(object)best == (Object)null) { if (!_loggedChipFail) { _loggedChipFail = true; WeaponSafetyGUI.LogInfo("[chip] List panel not found: the indicator " + $"still has no background (search at ({HudGeometry.F(((Rect)(ref r)).xMin)}, {HudGeometry.F(((Rect)(ref r)).yMin)})-" + $"{HudGeometry.F(((Rect)(ref r)).xMax)}, {HudGeometry.F(((Rect)(ref r)).yMax)}, rows={HudScan._rows.Count}). " + "Structure in case it has to be pointed at manually:"); if ((Object)(object)val != (Object)null) { HudScan.DumpStructure(val, cam); } } return; } Transform val2 = best; if (!HudGeometry.ScreenRectOf(val2, cam, out var r3)) { r3 = default(Rect); } _chipStartHeight = ((Rect)(ref r3)).height; float num = 14f; float num2 = 14f; if (flag && ((Rect)(ref r3)).width > 10f) { num = Mathf.Max(0f, ((Rect)(ref r)).xMin - ((Rect)(ref r3)).xMin); num2 = Mathf.Max(0f, ((Rect)(ref r3)).xMax - ((Rect)(ref r)).xMax); _marginLeft = num; _marginRight = num2; } else { _marginLeft = -1f; _marginRight = -1f; } GameObject val3 = Object.Instantiate(((Component)val2).gameObject, clone.parent, false); ((Object)val3).name = "WeaponSafety_Fondo"; _chipStartScale = val3.transform.localScale; foreach (MonoBehaviour componentsInChild in val3.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null) { ((Behaviour)componentsInChild).enabled = false; } } ApplyAlwaysOnTop(val3); _chip = val3; WeaponSafetyGUI.LogInfo($"[chip] Cloned from '{HudGeometry.PathOf(val2)}' (box={HudGeometry.F(((Rect)(ref r3)).width)}x{HudGeometry.F(((Rect)(ref r3)).height)}, row={HudGeometry.F(_rowHeightPx)}, margins left={HudGeometry.F(num)} right={HudGeometry.F(num2)}, startScale=({HudGeometry.F(_chipStartScale.x)}, {HudGeometry.F(_chipStartScale.y)}, {HudGeometry.F(_chipStartScale.z)})). It is fitted to the text every frame."); if (!ChipDiagnostics._loggedRowChips) { ChipDiagnostics._loggedRowChips = true; ChipDiagnostics.LogRowChips(cam, r3); } } internal static void SearchChipUnder(Transform root, Camera cam, Rect text, ref Transform? best, ref float bestArea) { //IL_012f: 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) Il2CppArrayBase componentsInChildren = ((Component)root).GetComponentsInChildren(true); if (componentsInChildren == null) { return; } float num = ((Rect)(ref text)).width * ((Rect)(ref text)).height * 0.5f; for (int i = 0; i < componentsInChildren.Length; i++) { Transform val = componentsInChildren[i]; if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy || ((Object)val).name.StartsWith("WeaponSafety", StringComparison.Ordinal) || (Object)(object)((Component)val).GetComponent() != (Object)null || (val.childCount > 0 && ((Component)val).GetComponentsInChildren(true).Length > 0) || (!(val is RectTransform) && (Object)(object)((Component)val).GetComponent() == (Object)null) || !HudGeometry.ScreenRectOf(val, cam, out var r) || ((Rect)(ref r)).width < 8f || ((Rect)(ref r)).height < 8f || ((Rect)(ref r)).center.x < (float)cam.pixelWidth * 0.5f || ((Rect)(ref r)).center.y < (float)cam.pixelHeight * 0.45f) { continue; } float num2 = Mathf.Max(0f, Mathf.Min(((Rect)(ref r)).xMax, ((Rect)(ref text)).xMax) - Mathf.Max(((Rect)(ref r)).xMin, ((Rect)(ref text)).xMin)); float num3 = Mathf.Max(0f, Mathf.Min(((Rect)(ref r)).yMax, ((Rect)(ref text)).yMax) - Mathf.Max(((Rect)(ref r)).yMin, ((Rect)(ref text)).yMin)); if (!(num2 * num3 < num)) { float num4 = ((Rect)(ref r)).width * ((Rect)(ref r)).height; if (num4 < bestArea) { bestArea = num4; best = val; } } } } internal static void HideChip() { if ((Object)(object)_chip != (Object)null && _chip.activeSelf) { _chip.SetActive(false); } } internal static void DestroyChip() { if ((Object)(object)_chip != (Object)null) { Object.Destroy((Object)(object)_chip); } _chip = null; _marginLeft = -1f; _marginRight = -1f; _chipStartHeight = 0f; _loggedChipRect = false; ChipDiagnostics._loggedRowChips = false; ChipDiagnostics._previousChipState = null; ChipDiagnostics._nextChipDiag = 0f; _nextChipSearch = 0f; ChipDiagnostics._sceneSweepCache = ""; ChipDiagnostics._nextSceneSweep = -9999f; } } internal static class ChipDiagnostics { internal static bool _loggedRowChips; internal static string? _previousChipState; internal static float _nextChipDiag; internal static string _sceneSweepCache = ""; internal static float _nextSceneSweep = -9999f; internal static void DiagnoseChip(Transform clone, Transform chip, Camera cam) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039b: 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_0748: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05bf: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextChipDiag) { return; } _nextChipDiag = Time.unscaledTime + 1f; Renderer component = ((Component)chip).GetComponent(); HudGeometry.ScreenRectOf(chip, cam, out var r); Vector3 val; Bounds bounds; if (!((Object)(object)component != (Object)null)) { val = chip.position; } else { bounds = component.bounds; val = ((Bounds)(ref bounds)).center; } float z = cam.WorldToScreenPoint(val).z; StringBuilder stringBuilder = new StringBuilder(1024); stringBuilder.Append("[chip-state] chip "); if ((Object)(object)component == (Object)null) { stringBuilder.Append("NO RENDERER"); } else { SpriteRenderer val2 = (SpriteRenderer)(object)((component is SpriteRenderer) ? component : null); stringBuilder.Append("rend=").Append(component.enabled ? "on" : "OFF").Append(" visible=") .Append(component.isVisible ? "yes" : "NO") .Append(" order=") .Append(component.sortingOrder) .Append(" sortingLayer=") .Append(component.sortingLayerName) .Append(" layer=") .Append(((Component)chip).gameObject.layer) .Append(" alpha=") .Append(((Object)(object)val2 != (Object)null) ? HudGeometry.F(val2.color.a) : "1") .Append(" shader=") .Append(((Object)(object)component.sharedMaterial != (Object)null) ? ((Object)component.sharedMaterial.shader).name : "?"); } StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(12, 4, stringBuilder2); handler.AppendLiteral(" rect=("); handler.AppendFormatted(Mathf.Round(((Rect)(ref r)).xMin)); handler.AppendLiteral("-"); handler.AppendFormatted(Mathf.Round(((Rect)(ref r)).xMax)); handler.AppendLiteral(", "); handler.AppendFormatted(Mathf.Round(((Rect)(ref r)).yMin)); handler.AppendLiteral("-"); handler.AppendFormatted(Mathf.Round(((Rect)(ref r)).yMax)); handler.AppendLiteral(")"); StringBuilder stringBuilder4 = stringBuilder3.Append(ref handler); StringBuilder stringBuilder5 = stringBuilder4; StringBuilder.AppendInterpolatedStringHandler handler2 = new StringBuilder.AppendInterpolatedStringHandler(11, 2, stringBuilder4); handler2.AppendLiteral(" z="); handler2.AppendFormatted(HudGeometry.F(z)); handler2.AppendLiteral(" active="); handler2.AppendFormatted(((Component)chip).gameObject.activeInHierarchy); stringBuilder5.Append(ref handler2); Renderer component2 = ((Component)clone).GetComponent(); if ((Object)(object)component2 != (Object)null) { bounds = component2.bounds; float z2 = cam.WorldToScreenPoint(((Bounds)(ref bounds)).center).z; StringBuilder stringBuilder6 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(14, 1, stringBuilder6); handler.AppendLiteral(" | text order="); handler.AppendFormatted(component2.sortingOrder); stringBuilder2 = stringBuilder6.Append(ref handler); StringBuilder stringBuilder7 = stringBuilder2; handler2 = new StringBuilder.AppendInterpolatedStringHandler(23, 2, stringBuilder2); handler2.AppendLiteral(" sortingLayer="); handler2.AppendFormatted(component2.sortingLayerName); handler2.AppendLiteral(" visible="); handler2.AppendFormatted(component2.isVisible); stringBuilder4 = stringBuilder7.Append(ref handler2); StringBuilder stringBuilder8 = stringBuilder4; StringBuilder.AppendInterpolatedStringHandler handler3 = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder4); handler3.AppendLiteral(" z="); handler3.AppendFormatted(HudGeometry.F(z2)); stringBuilder8.Append(ref handler3); } if (HudGeometry.ScreenRectOf(clone, cam, out var r2)) { float x = cam.WorldToScreenPoint(clone.position).x; stringBuilder4 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder4; handler = new StringBuilder.AppendInterpolatedStringHandler(69, 6, stringBuilder4); handler.AppendLiteral("\n [chip-state] text=("); handler.AppendFormatted(Mathf.Round(((Rect)(ref r2)).xMin)); handler.AppendLiteral("-"); handler.AppendFormatted(Mathf.Round(((Rect)(ref r2)).xMax)); handler.AppendLiteral(") pivot="); handler.AppendFormatted(Mathf.Round(x)); handler.AppendLiteral(" "); handler.AppendLiteral("anchor="); handler.AppendFormatted(Mathf.Round(Anchors._anchorTarget.x)); handler.AppendLiteral(" "); handler.AppendLiteral("chipTarget=(center "); handler.AppendFormatted(HudGeometry.F(Chip._lastCenterX)); handler.AppendLiteral(" width "); handler.AppendFormatted(HudGeometry.F(Chip._lastTargetWidth)); handler.AppendLiteral(")"); stringBuilder9.Append(ref handler); } bool value = ModConfig.DebugScene.Value; Transform val3 = (((Object)(object)HudScan._stableHudRoot != (Object)null) ? HudScan._stableHudRoot : HudScan._inventoryRoot); if (value && (Object)(object)val3 != (Object)null && ((Rect)(ref r)).width > 1f) { Il2CppArrayBase componentsInChildren = ((Component)val3).GetComponentsInChildren(true); int num = 0; for (int i = 0; i < componentsInChildren.Length; i++) { if (num >= 6) { break; } Renderer val4 = componentsInChildren[i]; if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)component) && ((Component)val4).gameObject.activeInHierarchy && !((Object)(object)((Component)val4).transform == (Object)(object)clone) && !((Object)((Component)val4).gameObject).name.StartsWith("WeaponSafety", StringComparison.Ordinal) && HudGeometry.ScreenRectOf(((Component)val4).transform, cam, out var r3) && HudGeometry.RectsOverlap(r3, r)) { bounds = val4.bounds; float z3 = cam.WorldToScreenPoint(((Bounds)(ref bounds)).center).z; stringBuilder.Append("\n [chip-state] occluder '").Append(((Object)((Component)val4).gameObject).name).Append("' rect=(") .Append(HudGeometry.F(((Rect)(ref r3)).xMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r3)).xMax)) .Append(", ") .Append(HudGeometry.F(((Rect)(ref r3)).yMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r3)).yMax)) .Append(") z=") .Append(HudGeometry.F(z3)) .Append(" order=") .Append(val4.sortingOrder) .Append((z3 < z - 0.05f) ? " (closer)" : " (farther)") .Append(((Object)(object)val4.sharedMaterial != (Object)null && (Object)(object)val4.sharedMaterial.shader != (Object)null) ? (" shader=" + ((Object)val4.sharedMaterial.shader).name) : ""); num++; } } if (num == 0) { stringBuilder.Append("\n [chip-state] nothing overlaps the chip (in the HUD)"); } } if (value && ((Rect)(ref r)).width > 1f) { stringBuilder.Append(SweepScene(clone, component, r, cam)); } string text = stringBuilder.ToString(); if (!string.Equals(text, _previousChipState, StringComparison.Ordinal)) { _previousChipState = text; WeaponSafetyGUI.LogDebug(text); } } internal static string SweepScene(Transform clone, Renderer? rend, Rect rc, Camera cam) { //IL_0105: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Unknown result type (might be due to invalid IL or missing references) if (_sceneSweepCache.Length > 0 && Time.unscaledTime < _nextSceneSweep) { return _sceneSweepCache; } _nextSceneSweep = Time.unscaledTime + 5f; StringBuilder stringBuilder = new StringBuilder(3072); int layer = ((Component)clone).gameObject.layer; stringBuilder.Append("\n [chip-state] scene:"); Il2CppArrayBase val = Object.FindObjectsOfType(); int num = 0; for (int i = 0; i < val.Length; i++) { if (num >= 10) { break; } Renderer val2 = val[i]; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)rend) && ((Component)val2).gameObject.activeInHierarchy && !((Object)(object)((Component)val2).transform == (Object)(object)clone) && !((Object)((Component)val2).gameObject).name.StartsWith("WeaponSafety", StringComparison.Ordinal) && HudGeometry.ScreenRectOf(((Component)val2).transform, cam, out var r) && HudGeometry.RectsOverlap(r, rc)) { Bounds bounds = val2.bounds; float z = cam.WorldToScreenPoint(((Bounds)(ref bounds)).center).z; stringBuilder.Append("\n [chip-state] scene-occluder '").Append(HudGeometry.PathOf(((Component)val2).transform)).Append("' type=") .Append(((object)val2).GetType().Name) .Append(" rect=(") .Append(HudGeometry.F(((Rect)(ref r)).xMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r)).xMax)) .Append(", ") .Append(HudGeometry.F(((Rect)(ref r)).yMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r)).yMax)) .Append(") z=") .Append(HudGeometry.F(z)) .Append(" order=") .Append(val2.sortingOrder) .Append(" sortingLayer=") .Append(val2.sortingLayerName) .Append(" queue=") .Append(((Object)(object)val2.sharedMaterial != (Object)null) ? val2.sharedMaterial.renderQueue.ToString() : "?") .Append(" shader=") .Append(((Object)(object)val2.sharedMaterial != (Object)null && (Object)(object)val2.sharedMaterial.shader != (Object)null) ? ((Object)val2.sharedMaterial.shader).name : "?"); num++; } } if (num == 0) { stringBuilder.Append(" no Renderer crossing the chip"); } Il2CppArrayBase val3 = Object.FindObjectsOfType(); int num2 = 0; for (int j = 0; j < val3.Length; j++) { if (num2 >= 8) { break; } CanvasRenderer val4 = val3[j]; if ((Object)(object)val4 == (Object)null || !((Component)val4).gameObject.activeInHierarchy || ((Object)((Component)val4).gameObject).name.StartsWith("WeaponSafety", StringComparison.Ordinal)) { continue; } Transform transform = ((Component)val4).transform; RectTransform val5 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val5 == (Object)null)) { val5.GetWorldCorners(Il2CppStructArray.op_Implicit(HudGeometry._corners)); if (HudGeometry.ProjectCorners(cam, 4, out var r2) && HudGeometry.RectsOverlap(r2, rc)) { Canvas componentInParent = ((Component)val4).GetComponentInParent(); float z2 = cam.WorldToScreenPoint(((Transform)val5).position).z; stringBuilder.Append("\n [chip-state] scene-uGUI '").Append(((Object)((Component)val4).gameObject).name).Append("' rect=(") .Append(HudGeometry.F(((Rect)(ref r2)).xMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r2)).xMax)) .Append(", ") .Append(HudGeometry.F(((Rect)(ref r2)).yMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r2)).yMax)) .Append(") z=") .Append(HudGeometry.F(z2)) .Append(" depth=") .Append(val4.absoluteDepth) .Append(((Object)(object)componentInParent != (Object)null) ? $" canvas={componentInParent.sortingLayerName}/{componentInParent.sortingOrder} override={componentInParent.overrideSorting}" : " canvas=none"); num2++; } } } if (num2 == 0) { stringBuilder.Append(" | uGUI: none crosses the chip"); } Il2CppArrayBase val6 = Object.FindObjectsOfType(); int num3 = 0; for (int k = 0; k < val6.Length; k++) { if (num3 >= 6) { break; } Camera val7 = val6[k]; if (!((Object)(object)val7 == (Object)null) && (val7.cullingMask & (1 << layer)) != 0) { float v = Vector3.Distance(((Component)val7).transform.position, ((Component)cam).transform.position); StringBuilder stringBuilder2 = stringBuilder.Append("\n [chip-state] scene-camera '").Append(((Object)((Component)val7).gameObject).name).Append("' enabled=") .Append(((Behaviour)val7).enabled) .Append(" clear=") .Append(val7.clearFlags) .Append(" rect=("); Rect pixelRect = val7.pixelRect; StringBuilder stringBuilder3 = stringBuilder2.Append(HudGeometry.F(((Rect)(ref pixelRect)).x)).Append(','); pixelRect = val7.pixelRect; StringBuilder stringBuilder4 = stringBuilder3.Append(HudGeometry.F(((Rect)(ref pixelRect)).y)).Append(','); pixelRect = val7.pixelRect; StringBuilder stringBuilder5 = stringBuilder4.Append(HudGeometry.F(((Rect)(ref pixelRect)).width)).Append(','); pixelRect = val7.pixelRect; stringBuilder5.Append(HudGeometry.F(((Rect)(ref pixelRect)).height)).Append(')').Append(" distance=") .Append(HudGeometry.F(v)) .Append(((Object)(object)val7 == (Object)(object)cam) ? " (the one we measure)" : ""); num3++; } } if (num3 == 0) { StringBuilder stringBuilder6 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(49, 1, stringBuilder6); handler.AppendLiteral("\n [chip-state] scene-camera: NONE draws layer "); handler.AppendFormatted(layer); stringBuilder6.Append(ref handler); } _sceneSweepCache = stringBuilder.ToString(); return _sceneSweepCache; } internal static void LogRowChips(Camera cam, Rect chipSource) { StringBuilder stringBuilder = new StringBuilder(2048); stringBuilder.Append("[chip] row chips (our source ").Append(HudGeometry.F(((Rect)(ref chipSource)).xMin)).Append('-') .Append(HudGeometry.F(((Rect)(ref chipSource)).xMax)) .Append(", ") .Append(HudGeometry.F(((Rect)(ref chipSource)).width)) .Append("px):"); for (int i = 0; i < HudScan._rows.Count; i++) { Transform val = HudScan._rows[i]; if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } string value = "?"; Il2CppArrayBase componentsInChildren = ((Component)val).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { TMP_Text val2 = componentsInChildren[j]; if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy && !string.IsNullOrEmpty(val2.text) && HudGeometry.ScreenRectOf(val2.transform, cam, out var r) && ((Rect)(ref r)).width > 2f) { value = $"x{HudGeometry.F(((Rect)(ref r)).xMin)}-{HudGeometry.F(((Rect)(ref r)).xMax)} y{HudGeometry.F(((Rect)(ref r)).yMin)}-{HudGeometry.F(((Rect)(ref r)).yMax)} '{val2.text}'"; break; } } Il2CppArrayBase componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren2.Length; k++) { Transform val3 = componentsInChildren2[k]; if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)val) && ((Component)val3).gameObject.activeInHierarchy && !((Object)(object)((Component)val3).GetComponent() != (Object)null) && HudGeometry.ScreenRectOf(val3, cam, out var r2) && !(((Rect)(ref r2)).width < 40f) && !(((Rect)(ref r2)).height < 10f)) { stringBuilder.Append("\n [chip] '").Append(((Object)val).name).Append("' / '") .Append(((Object)val3).name) .Append("' = x") .Append(HudGeometry.F(((Rect)(ref r2)).xMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r2)).xMax)) .Append(" y") .Append(HudGeometry.F(((Rect)(ref r2)).yMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r2)).yMax)) .Append(" (") .Append(HudGeometry.F(((Rect)(ref r2)).width)) .Append('x') .Append(HudGeometry.F(((Rect)(ref r2)).height)) .Append(") text ") .Append(value); } } } WeaponSafetyGUI.LogDebug(stringBuilder.ToString()); } } internal static class HudGeometry { internal static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[8]; internal static float ExtraPadding(Camera cam) { return Mathf.Max(0f, ModConfig.ChipPadding.Value) * (float)cam.pixelHeight / 1080f; } internal static bool ScreenRectOf(Transform t, Camera cam, out Rect r) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_00c2: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) r = default(Rect); if ((Object)(object)t == (Object)null) { return false; } RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null); if ((Object)(object)val != (Object)null) { val.GetWorldCorners(Il2CppStructArray.op_Implicit(_corners)); return ProjectCorners(cam, 4, out r); } Renderer component = ((Component)t).GetComponent(); if ((Object)(object)component != (Object)null) { Bounds bounds = component.bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; if (((Vector3)(ref extents)).sqrMagnitude > 0f) { int num = 0; for (int i = -1; i <= 1; i += 2) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { _corners[num++] = new Vector3(center.x + extents.x * (float)i, center.y + extents.y * (float)j, center.z + extents.z * (float)k); } } } return ProjectCorners(cam, 8, out r); } } Vector3 val2 = cam.WorldToScreenPoint(t.position); if (val2.z <= 0f) { return false; } r = new Rect(val2.x, val2.y, 0f, 0f); return true; } internal static bool ProjectCorners(Camera cam, int n, out Rect r) { //IL_0002: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b4: Unknown result type (might be due to invalid IL or missing references) r = default(Rect); float num = float.MaxValue; float num2 = float.MinValue; float num3 = float.MaxValue; float num4 = float.MinValue; for (int i = 0; i < n; i++) { Vector3 val = cam.WorldToScreenPoint(_corners[i]); if (val.z <= 0f) { return false; } if (val.x < num) { num = val.x; } if (val.x > num2) { num2 = val.x; } if (val.y < num3) { num3 = val.y; } if (val.y > num4) { num4 = val.y; } } if (num > num2 || num3 > num4) { return false; } r = Rect.MinMaxRect(num, num3, num2, num4); return true; } internal static bool RectsOverlap(Rect a, Rect b) { return ((Rect)(ref a)).xMin < ((Rect)(ref b)).xMax && ((Rect)(ref b)).xMin < ((Rect)(ref a)).xMax && ((Rect)(ref a)).yMin < ((Rect)(ref b)).yMax && ((Rect)(ref b)).yMin < ((Rect)(ref a)).yMax; } internal static string F(float v) { return v.ToString("0.#", CultureInfo.InvariantCulture); } internal static string PathOf(Transform t) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class HudLog { public static bool IsDebug => ModConfig.LogLevel.Value >= LogDetail.Debug; public static bool IsEnabled => ModConfig.LogLevel.Value > LogDetail.Off; public static void Info(string message) { if (ModConfig.LogLevel.Value >= LogDetail.Normal) { Write(message); } } public static void Debug(string message) { if (ModConfig.LogLevel.Value >= LogDetail.Debug) { Write(message); } } public static void Warning(string message) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(18, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DateTime.Now, "HH:mm:ss"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] [WeaponSafety] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); } logger.LogWarning(val); } public static void Error(string message) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(18, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DateTime.Now, "HH:mm:ss"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] [WeaponSafety] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); } logger.LogError(val); } private static void Write(string message) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DateTime.Now, "HH:mm:ss"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] [WeaponSafety] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); } logger.LogInfo(val); } } internal static class HudScan { internal static bool _loggedTemplates; internal static Transform? _stableHudRoot; internal static Transform? _template; internal static Transform? _inventoryRoot; internal static readonly List _rows = new List(); internal static float _nextRowRefresh; internal static Transform? _flashlightIcon; internal static Transform? _flashlightIconAlt; internal static string _previousIconName = ""; internal static bool _loggedStructure; internal static TMP_Text? _referenceText; internal static Transform? InventoryRootOf(Transform? t) { Transform val = t; while ((Object)(object)val != (Object)null) { if (((Object)val).name.StartsWith("InvItem", StringComparison.OrdinalIgnoreCase)) { return val.parent; } val = val.parent; } return null; } internal static void RefreshFlashlightIcon(Transform root) { try { _flashlightIcon = null; _flashlightIconAlt = null; Il2CppArrayBase componentsInChildren = ((Component)root).GetComponentsInChildren(true); if (componentsInChildren == null) { return; } for (int i = 0; i < componentsInChildren.Length; i++) { PUI_InventoryIconDisplay val = componentsInChildren[i]; if (!((Object)(object)val == (Object)null)) { SpriteStatusIcon flashLightIcon = val.FlashLightIcon; Transform val2 = (((Object)(object)flashLightIcon.Enabled != (Object)null) ? ((Component)flashLightIcon.Enabled).transform : null); Transform val3 = (((Object)(object)flashLightIcon.Disabled != (Object)null) ? ((Component)flashLightIcon.Disabled).transform : null); Transform val4 = (((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy) ? val2 : (((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.activeInHierarchy) ? val3 : (val2 ?? val3))); if ((Object)(object)val4 != (Object)null) { _flashlightIcon = val4; Transform val5 = ((val4 == val2) ? val3 : val2); _flashlightIconAlt = (((Object)(object)val5 != (Object)null && ((Component)val5).gameObject.activeInHierarchy) ? val5 : null); break; } } } } catch (Exception ex) { if (!Anchors._loggedIconFail) { Anchors._loggedIconFail = true; WeaponSafetyGUI.LogInfo("Could not read the flashlight icon (" + ex.GetType().Name + "): using the list as the anchor."); } } } internal static void RefreshRows() { if (Time.unscaledTime < _nextRowRefresh) { return; } _nextRowRefresh = Time.unscaledTime + 1f; _rows.Clear(); Transform val = (((Object)(object)_stableHudRoot != (Object)null) ? _stableHudRoot : _inventoryRoot); if ((Object)(object)val == (Object)null) { return; } RefreshFlashlightIcon(val); Il2CppArrayBase componentsInChildren = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { PUI_InventoryItem val2 = componentsInChildren[i]; if (!((Object)(object)val2 == (Object)null)) { Transform transform = ((Component)val2).transform; if (!_rows.Contains(transform)) { _rows.Add(transform); } } } } CollectByName(val, _rows); FindReferenceText(); } internal static void FindReferenceText() { //IL_018a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_referenceText != (Object)null && ((Behaviour)_referenceText).isActiveAndEnabled && InsideRow(_referenceText.transform)) { return; } TMP_Text referenceText = null; int num = -1; for (int i = 0; i < _rows.Count; i++) { Transform val = _rows[i]; if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } Il2CppArrayBase componentsInChildren = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren == null) { continue; } for (int j = 0; j < componentsInChildren.Length; j++) { TMP_Text val2 = componentsInChildren[j]; if ((Object)(object)val2 == (Object)null || ((Object)val2).name == "WeaponSafety_Status" || string.IsNullOrEmpty(val2.text)) { continue; } int num2 = 1; if ((Object)(object)Indicator._text != (Object)null && (Object)(object)val2.font != (Object)null && (Object)(object)val2.font == (Object)(object)Indicator._text.font) { num2 += 8; } Material fontSharedMaterial = val2.fontSharedMaterial; if ((Object)(object)fontSharedMaterial != (Object)null) { if (fontSharedMaterial.HasProperty("_OutlineWidth") && fontSharedMaterial.GetFloat("_OutlineWidth") > 0f) { num2 += 4; } if (fontSharedMaterial.HasProperty("_UnderlayColor") && fontSharedMaterial.GetColor("_UnderlayColor").a > 0f) { num2 += 2; } } if (num2 > num) { num = num2; referenceText = val2; } } } _referenceText = referenceText; } internal static bool InsideRow(Transform? t) { return (Object)(object)RowOf(t) != (Object)null; } internal static void CollectByName(Transform root, List target) { for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if (((Object)child).name.StartsWith("InvItem", StringComparison.OrdinalIgnoreCase)) { if (!target.Contains(child)) { target.Add(child); } } else { CollectByName(child, target); } } } internal static void DumpStructure(Transform row, Camera? cam) { if (_loggedStructure) { return; } _loggedStructure = true; StringBuilder stringBuilder = new StringBuilder(4096); stringBuilder.Append("[chip] ROW ").Append(HudGeometry.PathOf(row)).Append(":\n"); DumpBranch(row, stringBuilder, 0, cam); Transform inventoryRoot = _inventoryRoot; if ((Object)(object)inventoryRoot != (Object)null) { stringBuilder.Append("[chip] children of the list root ").Append(HudGeometry.PathOf(inventoryRoot)).Append(":\n"); for (int i = 0; i < inventoryRoot.childCount; i++) { stringBuilder.Append(" - ").Append(DescribeNode(inventoryRoot.GetChild(i), cam)).Append('\n'); } } WeaponSafetyGUI.LogDebug(stringBuilder.ToString()); } internal static void DumpBranch(Transform t, StringBuilder sb, int depth, Camera? cam) { if (!((Object)(object)t == (Object)null) && depth <= 5) { sb.Append(' ', depth * 2).Append(DescribeNode(t, cam)).Append('\n'); for (int i = 0; i < t.childCount; i++) { DumpBranch(t.GetChild(i), sb, depth + 1, cam); } } } internal static Transform? RowOf(Transform? t) { while ((Object)(object)t != (Object)null) { if (_rows.Contains(t)) { return t; } t = t.parent; } return null; } internal static string DescribeNode(Transform t, Camera? cam) { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: 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_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(((Object)t).name); if (!((Component)t).gameObject.activeSelf) { stringBuilder.Append(" [inactive]"); } if ((Object)(object)cam != (Object)null && HudGeometry.ScreenRectOf(t, cam, out var r) && ((Rect)(ref r)).width > 1f) { stringBuilder.Append(" screen=(").Append(HudGeometry.F(((Rect)(ref r)).xMin)).Append('-') .Append(HudGeometry.F(((Rect)(ref r)).xMax)) .Append(", ") .Append(HudGeometry.F(((Rect)(ref r)).yMin)) .Append('-') .Append(HudGeometry.F(((Rect)(ref r)).yMax)) .Append(") ") .Append(HudGeometry.F(((Rect)(ref r)).width)) .Append('x') .Append(HudGeometry.F(((Rect)(ref r)).height)); } int length = ((Component)t).GetComponentsInChildren(true).Length; if (length > 0) { stringBuilder.Append(" [tmp=").Append(length).Append(']'); } stringBuilder.Append(" pos=(").Append(HudGeometry.F(t.localPosition.x)).Append(", ") .Append(HudGeometry.F(t.localPosition.y)) .Append(", ") .Append(HudGeometry.F(t.localPosition.z)) .Append(") scale=(") .Append(HudGeometry.F(t.localScale.x)) .Append(", ") .Append(HudGeometry.F(t.localScale.y)) .Append(", ") .Append(HudGeometry.F(t.localScale.z)) .Append(')'); RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null); if (val != null) { StringBuilder stringBuilder2 = stringBuilder.Append(" [rect "); Rect rect = val.rect; StringBuilder stringBuilder3 = stringBuilder2.Append(HudGeometry.F(((Rect)(ref rect)).width)).Append('x'); rect = val.rect; stringBuilder3.Append(HudGeometry.F(((Rect)(ref rect)).height)).Append(']'); } Renderer component = ((Component)t).GetComponent(); if ((Object)(object)component != (Object)null) { stringBuilder.Append(" [").Append(((object)component).GetType().Name); SpriteRenderer val2 = (SpriteRenderer)(object)((component is SpriteRenderer) ? component : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sprite != (Object)null) { stringBuilder.Append(' ').Append(((Object)val2.sprite).name); } StringBuilder stringBuilder4 = stringBuilder.Append(" size="); Bounds bounds = component.bounds; StringBuilder stringBuilder5 = stringBuilder4.Append(HudGeometry.F(((Bounds)(ref bounds)).size.x)).Append('x'); bounds = component.bounds; stringBuilder5.Append(HudGeometry.F(((Bounds)(ref bounds)).size.y)); stringBuilder.Append(" vis=").Append(component.enabled); stringBuilder.Append(" sort=").Append(component.sortingOrder).Append(']'); } Image component2 = ((Component)t).GetComponent(); if ((Object)(object)component2 != (Object)null) { stringBuilder.Append(" [Image sprite=").Append(((Object)(object)component2.sprite != (Object)null) ? ((Object)component2.sprite).name : "null").Append(" vis=") .Append(((Behaviour)component2).enabled) .Append(']'); } TMP_Text component3 = ((Component)t).GetComponent(); if ((Object)(object)component3 != (Object)null) { stringBuilder.Append(" [TMP '").Append(component3.text).Append("' size=") .Append(HudGeometry.F(component3.fontSize)) .Append(" vis=") .Append(((Behaviour)component3).enabled) .Append(']'); } return stringBuilder.ToString(); } internal static Transform? FindStableRoot(PlayerGuiLayer layer) { try { GuiLayerComp movementRoot = layer.m_movementRoot; if ((Object)(object)movementRoot != (Object)null && (Object)(object)((Component)movementRoot).transform != (Object)null) { return ((Component)movementRoot).transform; } } catch (Exception ex) { HudLog.Debug("[WeaponSafety] m_movementRoot unavailable: " + ex.Message); } Transform canvasTrans = ((GuiLayer)layer).CanvasTrans; if ((Object)(object)canvasTrans != (Object)null) { return canvasTrans; } return ((GuiLayer)layer).Root; } internal static TMP_Text? FindTemplate(PlayerGuiLayer layer, out string report) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) string filter = ModConfig.StyleTemplate.Value; bool flag = !string.IsNullOrWhiteSpace(filter); List list = new List(); AddRoot(list, ((GuiLayer)layer).CanvasTrans); AddRoot(list, ((GuiLayer)layer).Root); if ((Object)(object)GuiManager.Current != (Object)null) { AddRoot(list, GuiManager.Current.m_root); } List list2 = new List(); foreach (Transform item in list) { Collect(item, list2); } if (!flag) { list2.RemoveAll((TMP_Text t) => (Object)(object)t == (Object)null || IsTextOutsidePlayerHud(HudGeometry.PathOf(t.transform))); } if (ModConfig.DebugTemplates.Value && !_loggedTemplates) { _loggedTemplates = true; int num = 0; foreach (TMP_Text item2 in list2) { WeaponSafetyGUI.LogDebug($"[HUD {++num}] {HudGeometry.PathOf(item2.transform)} [{((object)item2).GetType().Name}] size={item2.fontSize} color={((Graphic)item2).color} align={item2.alignment} active={((Component)item2).gameObject.activeInHierarchy} text='{item2.text}'"); } WeaponSafetyGUI.LogDebug($"[WeaponSafety] {list2.Count} TMP texts in the HUD."); } TMP_Text val = null; Indicator._templateOrigin = "none"; if (flag) { val = Pick(list2, (TMP_Text t) => HudGeometry.PathOf(t.transform).IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0); Indicator._templateOrigin = "filter '" + filter + "'"; } if ((Object)(object)val == (Object)null && !flag) { try { val = FindWeaponText(layer); Indicator._templateOrigin = (((Object)(object)val != (Object)null) ? "typed (weapon text)" : "typed, no result"); } catch (Exception ex) { Indicator._templateOrigin = "typed failed, scan"; if (!Indicator._loggedTypedFail) { Indicator._loggedTypedFail = true; HudLog.Warning($"[WeaponSafety] Typed search for the weapon text failed; using the scan. {ex.GetType().Name}: {ex.Message}"); } } } if ((Object)(object)val == (Object)null) { TMP_Text val2 = Pick(list2, (TMP_Text t) => MatchesAny(HudGeometry.PathOf(t.transform), "archetype", "weapon", "gun", "ammo", "detailed", "wielded")); if ((Object)(object)val2 != (Object)null) { val = val2; Indicator._templateOrigin = "name heuristic"; } else { TMP_Text val3 = Pick(list2, (TMP_Text t) => !string.IsNullOrEmpty(t.text)); if ((Object)(object)val3 != (Object)null) { val = val3; Indicator._templateOrigin = "first candidate with text"; } else { val = Pick(list2, (TMP_Text _) => true); Indicator._templateOrigin = "any candidate"; } } } if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeInHierarchy) { report = BuildReport(layer, list, list2, val) + " | reason: the template is not active in the hierarchy"; return null; } report = BuildReport(layer, list, list2, val); return val; } internal static bool IsTextOutsidePlayerHud(string path) { return path.IndexOf("MainMenuLayer", StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf("WatermarkLayer", StringComparison.OrdinalIgnoreCase) >= 0; } internal static void AddRoot(List roots, Transform? t) { if ((Object)(object)t == (Object)null) { return; } foreach (Transform root in roots) { if ((Object)(object)root == (Object)(object)t) { return; } } roots.Add(t); } internal static void Collect(Transform root, List into) { foreach (TextMeshPro componentsInChild in ((Component)root).GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null && !into.Contains((TMP_Text)(object)componentsInChild)) { into.Add((TMP_Text)(object)componentsInChild); } } foreach (TextMeshProUGUI componentsInChild2 in ((Component)root).GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild2 != (Object)null && !into.Contains((TMP_Text)(object)componentsInChild2)) { into.Add((TMP_Text)(object)componentsInChild2); } } } internal static TMP_Text? Pick(List candidates, Func predicate) { TMP_Text val = null; foreach (TMP_Text candidate in candidates) { if (!((Object)(object)candidate == (Object)null) && predicate(candidate)) { if (((Component)candidate).gameObject.activeInHierarchy) { return candidate; } if (val == null) { val = candidate; } } } return val; } internal static TMP_Text? FindWeaponText(PlayerGuiLayer layer) { PUI_Inventory inventory = layer.Inventory; Transform root = (((Object)(object)inventory != (Object)null) ? inventory.m_root : null); TMP_Text val = SearchWeaponText(root); if ((Object)(object)val != (Object)null) { return val; } val = SearchWeaponText(((GuiLayer)layer).Root); if ((Object)(object)val != (Object)null) { return val; } return SearchWeaponText(((GuiLayer)layer).CanvasTrans); } internal static TMP_Text? SearchWeaponText(Transform? root) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 if ((Object)(object)root == (Object)null) { return null; } foreach (PUI_InventoryItem componentsInChild in ((Component)root).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild == (Object)null) && (int)componentsInChild.CurrentState == 2) { TMP_Text val = PickItem(componentsInChild); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy) { return val; } } } foreach (PUI_InventoryItem componentsInChild2 in ((Component)root).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild2 == (Object)null)) { TMP_Text val2 = PickItem(componentsInChild2); if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy) { return val2; } } } return null; } internal static TMP_Text? PickItem(PUI_InventoryItem? item) { if ((Object)(object)item == (Object)null) { return null; } TMP_Text val = null; TMP_Text[] array = (TMP_Text[])(object)new TMP_Text[3] { (TMP_Text)item.m_selected_archetypeName, (TMP_Text)item.m_slim_archetypeName, (TMP_Text)item.m_selected_detailedName }; TMP_Text[] array2 = array; foreach (TMP_Text val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { if (((Component)val2).gameObject.activeInHierarchy) { return val2; } if (val == null) { val = val2; } } } return val; } internal static string BuildReport(PlayerGuiLayer layer, List roots, List candidates, TMP_Text? chosen) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Diagnostic: "); stringBuilder.Append("roots=[").Append(roots.Count).Append("] "); foreach (Transform root2 in roots) { int num = 0; foreach (TextMeshPro componentsInChild in ((Component)root2).GetComponentsInChildren(true)) { num++; } int num2 = 0; foreach (TextMeshProUGUI componentsInChild2 in ((Component)root2).GetComponentsInChildren(true)) { num2++; } stringBuilder.Append(HudGeometry.PathOf(root2)).Append(" tmp3d=").Append(num) .Append(" tmpUGUI=") .Append(num2) .Append("; "); } stringBuilder.Append("| candidates=").Append(candidates.Count); stringBuilder.Append(" | chosen=").Append(((Object)(object)chosen == (Object)null) ? "none" : HudGeometry.PathOf(chosen.transform)); PUI_Inventory inventory = layer.Inventory; if ((Object)(object)inventory == (Object)null) { stringBuilder.Append(" | Inventory=null"); } else { Transform root = inventory.m_root; stringBuilder.Append(" | inventoryRoot=").Append(((Object)(object)root == (Object)null) ? "null" : HudGeometry.PathOf(root)); if ((Object)(object)root != (Object)null) { int num3 = 0; foreach (PUI_InventoryItem componentsInChild3 in ((Component)root).GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild3 != (Object)null) { num3++; } } stringBuilder.Append(" items=").Append(num3); } } return stringBuilder.ToString(); } internal static bool MatchesAny(string haystack, params string[] needles) { foreach (string value in needles) { if (haystack.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } } internal static class Indicator { internal static GameObject? _root; internal static TMP_Text? _text; internal static Color _lastColor = new Color(-1f, -1f, -1f, -1f); internal static bool _loggedNoTemplate; internal static bool _loggedError; internal static bool _loggedTypedFail; internal static bool _loggedApplied; internal static float _nextRetry; internal static bool _loggedHudHidden; internal static bool _loggedParentOff; internal static string _templateOrigin = "none"; internal static bool _lastWielded = true; internal static bool _scriptsReenabled; internal static string _colorOnTxt = "\0"; internal static string _colorOffTxt = "\0"; internal static Color _colorOn = new Color(0.72f, 0.72f, 0.72f, 1f); internal static Color _colorOff = Color.white; internal static TMP_Text? _outlineFrom; internal static bool _loggedOutline; internal static Color SafetyColor(bool safetyOn) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) if (safetyOn) { string text = ModConfig.ColorOn.Value ?? ""; if (!string.Equals(text, _colorOnTxt, StringComparison.OrdinalIgnoreCase)) { _colorOnTxt = text; _colorOn = ParseHexColor(text, _colorOn, "Colours/ColorOn"); } return _colorOn; } string text2 = ModConfig.ColorOff.Value ?? ""; if (!string.Equals(text2, _colorOffTxt, StringComparison.OrdinalIgnoreCase)) { _colorOffTxt = text2; _colorOff = ParseHexColor(text2, _colorOff, "Colours/ColorOff"); } return _colorOff; } internal static Color ParseHexColor(string txt, Color previous, string which) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) string text = (txt ?? "").Trim(); if (text.Length == 0) { WeaponSafetyGUI.LogInfo($"[color] {which} empty: keeping #{ColorUtility.ToHtmlStringRGBA(previous)}."); return previous; } if (text[0] != '#') { text = "#" + text; } Color result = default(Color); if (ColorUtility.TryParseHtmlString(text, ref result)) { WeaponSafetyGUI.LogInfo($"[color] {which} = {text.ToUpperInvariant()}."); return result; } WeaponSafetyGUI.LogInfo($"[color] {which}='{txt}' is not valid hex (use RRGGBB or RRGGBBAA): keeping #{ColorUtility.ToHtmlStringRGBA(previous)}."); return previous; } internal static bool HasMesh() { if ((Object)(object)_root == (Object)null) { return false; } MeshFilter component = _root.GetComponent(); return (Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null && component.sharedMesh.vertexCount > 0; } internal static bool TryCreate() { //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Invalid comparison between Unknown and I4 //IL_03ba: 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_0447: 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) _root = null; _text = null; if ((Object)(object)GuiManager.Current == (Object)null) { return false; } PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; if (playerLayer == null) { return false; } Transform val = (HudScan._stableHudRoot = HudScan.FindStableRoot(playerLayer)); if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeInHierarchy) { if (!_loggedHudHidden) { _loggedHudHidden = true; WeaponSafetyGUI.LogInfo("[WeaponSafety] HUD hidden: indicator paused (it comes back on its own when the HUD reappears)."); } RetryLater(); return false; } string report; TMP_Text val2 = HudScan.FindTemplate(playerLayer, out report); if ((Object)(object)val2 == (Object)null) { RetryLater(); if (!_loggedNoTemplate) { _loggedNoTemplate = true; HudLog.Warning("[WeaponSafety] No HUD text found to clone. Enable Tuning/DebugTemplates and check the log to pick one with Tuning/Template.\n" + report); } return false; } Transform parent = val2.transform.parent; if ((Object)(object)parent == (Object)null && (Object)(object)val == (Object)null) { RetryLater(); return false; } HudScan._inventoryRoot = HudScan.InventoryRootOf(val2.transform); Transform val3 = (Transform)(((Object)(object)HudScan._inventoryRoot != (Object)null) ? ((object)HudScan._inventoryRoot) : ((object)val)); if ((Object)(object)val3 != (Object)null) { for (int num = val3.childCount - 1; num >= 0; num--) { Transform child = val3.GetChild(num); if (!(((Object)child).name != "WeaponSafety_Status") || !(((Object)child).name != "WeaponSafety_Fondo")) { if (((Object)child).name == "WeaponSafety_Fondo") { Chip._chip = null; Chip._nextChipSearch = 0f; } Object.Destroy((Object)(object)((Component)child).gameObject); } } } GameObject val4 = (((Object)(object)parent != (Object)null) ? Object.Instantiate(((Component)val2).gameObject, parent, false) : Object.Instantiate(((Component)val2).gameObject, val, true)); ((Object)val4).name = "WeaponSafety_Status"; if ((Object)(object)val3 != (Object)null && (Object)(object)val4.transform.parent != (Object)(object)val3) { val4.transform.SetParent(val3, true); } MeshRenderer component = val4.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sortingOrder = ModConfig.SortingOrder.Value; } TMP_Text component2 = (TMP_Text)(object)val4.GetComponent(); if ((Object)(object)component2 == (Object)null) { component2 = (TMP_Text)(object)val4.GetComponent(); } if ((Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val4); return false; } _lastColor = new Color(-1f, -1f, -1f, -1f); _scriptsReenabled = false; foreach (MonoBehaviour component3 in val4.GetComponents()) { if (!((Object)(object)component3 == (Object)null) && !(component3 is TMP_Text)) { ((Behaviour)component3).enabled = false; } } if (!((Behaviour)component2).enabled) { ((Behaviour)component2).enabled = true; WeaponSafetyGUI.LogInfo("[WeaponSafety] The clone's TextMeshPro was disabled: enabling it."); } if ((Object)(object)component != (Object)null) { ((Renderer)component).SetPropertyBlock((MaterialPropertyBlock)null); } TextMeshPro val5 = (TextMeshPro)(object)((component2 is TextMeshPro) ? component2 : null); if (val5 != null && (int)val5.maskType > 0) { WeaponSafetyGUI.LogInfo($"The clone inherits maskType={val5.maskType}: setting MaskOff " + "(the mask rect comes from a disabled script)."); val5.maskType = (MaskingTypes)0; } try { Material fontMaterial = component2.fontMaterial; if ((Object)(object)fontMaterial != (Object)null && fontMaterial.HasProperty("_ClipRect")) { Vector4 vector = fontMaterial.GetVector("_ClipRect"); fontMaterial.SetVector("_ClipRect", new Vector4(-100000f, -100000f, 100000f, 100000f)); WeaponSafetyGUI.LogInfo($"_ClipRect {vector} -> no clipping (the indicator's own material)."); } } catch (Exception ex) { WeaponSafetyGUI.LogInfo("Could not adjust the indicator's material: " + ex.Message); } val4.transform.SetAsLastSibling(); val4.SetActive(true); component2.text = ""; _root = val4; _text = component2; HudScan._template = val2.transform; _loggedApplied = false; try { Anchors.PlaceIndicator(val4.transform, val2.transform, log: true); } catch (Exception ex2) { Anchors._anchorInfo = "placement failed: " + ex2.GetType().Name + " (retried every frame)"; WeaponSafetyGUI.LogInfo($"Could not position the indicator on creation: {ex2}"); } WeaponSafetyGUI.LogDebug($"[WeaponSafety] Indicator created from '{HudGeometry.PathOf(val2.transform)}' [{((object)component2).GetType().Name}] (size={component2.fontSize}, origin={_templateOrigin}).\n" + DescribeClone(val4, component2, val2.transform) + "\n anchor: " + Anchors._anchorInfo); return true; } internal static void ApplyOutline(TMP_Text tmp) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HudScan._referenceText == (Object)null) { HudScan.RefreshRows(); if ((Object)(object)HudScan._referenceText == (Object)null) { if (!_loggedOutline) { _loggedOutline = true; WeaponSafetyGUI.LogInfo("[outline] No reference text in the list: the indicator keeps the template's material."); } return; } } TMP_Text referenceText = HudScan._referenceText; if ((Object)(object)_outlineFrom == (Object)(object)referenceText) { return; } try { if ((Object)(object)referenceText.font != (Object)null && (Object)(object)tmp.font != (Object)null && (Object)(object)referenceText.font != (Object)(object)tmp.font) { if (!_loggedOutline) { _loggedOutline = true; WeaponSafetyGUI.LogInfo("[outline] The reference '" + referenceText.text + "' uses a different font: material not copied (different atlas texture)."); } return; } Material fontSharedMaterial = referenceText.fontSharedMaterial; if (!((Object)(object)fontSharedMaterial == (Object)null) && !((Object)(object)fontSharedMaterial.shader == (Object)null)) { string value = DescribeOutline(tmp.fontSharedMaterial); Material val = new Material(fontSharedMaterial); ((Object)val).name = ((Object)fontSharedMaterial).name + " (WeaponSafety)"; if (val.HasProperty("_ClipRect")) { val.SetVector("_ClipRect", new Vector4(-100000f, -100000f, 100000f, 100000f)); } ((Graphic)tmp).material = val; tmp.havePropertiesChanged = true; Material ownMaterial = Chip._ownMaterial; Chip._ownMaterial = val; _outlineFrom = referenceText; if ((Object)(object)ownMaterial != (Object)null && (Object)(object)ownMaterial != (Object)(object)val) { Object.Destroy((Object)(object)ownMaterial); } WeaponSafetyGUI.LogInfo($"[outline] {value} -> {DescribeOutline(val)}, copied from '{referenceText.text}'."); } } catch (Exception value2) { WeaponSafetyGUI.LogInfo($"Could not copy the list's outline: {value2}"); } } internal static string DescribeOutline(Material? m) { //IL_0055: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m == (Object)null) { return "material=NULL"; } string value = (((Object)(object)m.shader != (Object)null) ? ((Object)m.shader).name : "?"); string value2 = (m.HasProperty("_FaceColor") ? ColorUtility.ToHtmlStringRGBA(m.GetColor("_FaceColor")) : "n/a"); string value3 = (m.HasProperty("_FaceDilate") ? HudGeometry.F(m.GetFloat("_FaceDilate")) : "n/a"); string value4 = (m.HasProperty("_OutlineWidth") ? HudGeometry.F(m.GetFloat("_OutlineWidth")) : "n/a"); string text = "n/a"; if (m.HasProperty("_UnderlayColor")) { text = ColorUtility.ToHtmlStringRGBA(m.GetColor("_UnderlayColor")); if (m.HasProperty("_UnderlayOffset")) { Vector4 vector = m.GetVector("_UnderlayOffset"); text += $" off=({HudGeometry.F(vector.x)}, {HudGeometry.F(vector.y)})"; } if (m.HasProperty("_UnderlayDilate")) { text = text + " dil=" + HudGeometry.F(m.GetFloat("_UnderlayDilate")); } } return $"[{value}: face={value2} dil={value3} outline={value4} underlay={text}]"; } internal static string DescribeClone(GameObject clone, TMP_Text tmp, Transform? template) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: 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_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: 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_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: 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_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_034b: 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_03ce: Expected O, but got Unknown //IL_091d: Unknown result type (might be due to invalid IL or missing references) //IL_0950: Unknown result type (might be due to invalid IL or missing references) //IL_0a59: Unknown result type (might be due to invalid IL or missing references) //IL_0a65: Unknown result type (might be due to invalid IL or missing references) //IL_0a6a: Unknown result type (might be due to invalid IL or missing references) //IL_0a76: Unknown result type (might be due to invalid IL or missing references) //IL_0a8e: Unknown result type (might be due to invalid IL or missing references) //IL_0a93: Unknown result type (might be due to invalid IL or missing references) //IL_0a98: Unknown result type (might be due to invalid IL or missing references) //IL_0a9a: Unknown result type (might be due to invalid IL or missing references) //IL_0aa8: Unknown result type (might be due to invalid IL or missing references) //IL_0b06: Unknown result type (might be due to invalid IL or missing references) //IL_0b21: Unknown result type (might be due to invalid IL or missing references) //IL_0b3c: Unknown result type (might be due to invalid IL or missing references) //IL_0ab6: Unknown result type (might be due to invalid IL or missing references) //IL_0b70: Unknown result type (might be due to invalid IL or missing references) //IL_0b75: Unknown result type (might be due to invalid IL or missing references) //IL_0b7a: Unknown result type (might be due to invalid IL or missing references) //IL_0b87: Unknown result type (might be due to invalid IL or missing references) //IL_0ba2: Unknown result type (might be due to invalid IL or missing references) //IL_0ac4: Unknown result type (might be due to invalid IL or missing references) //IL_0ad5: Unknown result type (might be due to invalid IL or missing references) //IL_084a: Unknown result type (might be due to invalid IL or missing references) //IL_087e: Unknown result type (might be due to invalid IL or missing references) //IL_08b2: Unknown result type (might be due to invalid IL or missing references) Transform transform = clone.transform; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(" [indicator] active=").Append(clone.activeInHierarchy); stringBuilder.Append(" text='").Append(tmp.text).Append('\''); stringBuilder.Append(" color=").Append(ColorUtility.ToHtmlStringRGBA(((Graphic)tmp).color)); stringBuilder.Append(" size=").Append(HudGeometry.F(tmp.fontSize)); stringBuilder.Append(" layer=").Append(clone.layer); stringBuilder.Append(" parent=").Append(((Object)(object)transform.parent == (Object)null) ? "null" : HudGeometry.PathOf(transform.parent)); stringBuilder.Append(" pos=(").Append(HudGeometry.F(transform.position.x)).Append(", ") .Append(HudGeometry.F(transform.position.y)) .Append(", ") .Append(HudGeometry.F(transform.position.z)) .Append(')'); if ((Object)(object)template == (Object)null) { stringBuilder.Append(" template=DESTROYED delta=(?)"); } else { stringBuilder.Append(" template=(").Append(HudGeometry.F(template.position.x)).Append(", ") .Append(HudGeometry.F(template.position.y)) .Append(", ") .Append(HudGeometry.F(template.position.z)) .Append(')'); stringBuilder.Append(" delta=(").Append(HudGeometry.F(transform.position.x - template.position.x)).Append(", ") .Append(HudGeometry.F(transform.position.y - template.position.y)) .Append(", ") .Append(HudGeometry.F(transform.position.z - template.position.z)) .Append(')'); } stringBuilder.Append(" scale=(").Append(HudGeometry.F(transform.lossyScale.x)).Append(", ") .Append(HudGeometry.F(transform.lossyScale.y)) .Append(", ") .Append(HudGeometry.F(transform.lossyScale.z)) .Append(')'); RectTransform component = clone.GetComponent(); if ((Object)(object)component != (Object)null) { StringBuilder stringBuilder2 = stringBuilder.Append(" rect="); Rect rect = component.rect; StringBuilder stringBuilder3 = stringBuilder2.Append(HudGeometry.F(((Rect)(ref rect)).width)).Append('x'); rect = component.rect; stringBuilder3.Append(HudGeometry.F(((Rect)(ref rect)).height)); } stringBuilder.Append(" align=").Append(tmp.alignment); if ((Object)(object)component != (Object)null) { stringBuilder.Append(" pivot=").Append(HudGeometry.F(component.pivot.x)).Append(',') .Append(HudGeometry.F(component.pivot.y)); } MeshRenderer component2 = clone.GetComponent(); if ((Object)(object)component2 != (Object)null) { stringBuilder.Append(" renderer=").Append(((Renderer)component2).enabled ? "on" : "OFF").Append(" sorting=") .Append(((Renderer)component2).sortingOrder) .Append(" isVisible=") .Append(((Renderer)component2).isVisible); MaterialPropertyBlock val = new MaterialPropertyBlock(); ((Renderer)component2).GetPropertyBlock(val); stringBuilder.Append(" mpb=").Append(val.isEmpty ? "empty" : "WITH-DATA"); MeshFilter component3 = clone.GetComponent(); if ((Object)(object)component3 == (Object)null || (Object)(object)component3.sharedMesh == (Object)null) { stringBuilder.Append(" mesh=NULL"); } else { stringBuilder.Append(" mesh=").Append(component3.sharedMesh.vertexCount).Append('v'); } if ((Object)(object)template != (Object)null) { MeshFilter component4 = ((Component)template).GetComponent(); stringBuilder.Append(" template_mesh=").Append(((Object)(object)component4 == (Object)null || (Object)(object)component4.sharedMesh == (Object)null) ? "NULL" : (component4.sharedMesh.vertexCount + "v")); } try { TMP_TextInfo textInfo = tmp.textInfo; if (textInfo != null) { int characterCount = textInfo.characterCount; Il2CppReferenceArray characterInfo = textInfo.characterInfo; int num = ((Il2CppArrayBase)(object)characterInfo)?.Length ?? 0; int num2 = 0; for (int i = 0; i < characterCount && i < num; i++) { if (((Il2CppArrayBase)(object)characterInfo)[i].isVisible) { num2++; } } stringBuilder.Append(" chars=").Append(characterCount).Append(" vis=") .Append(num2); } } catch (Exception ex) { stringBuilder.Append(" chars=?(").Append(ex.GetType().Name).Append(')'); } } else { stringBuilder.Append(" renderer=").Append(((Object)(object)clone.GetComponent() != (Object)null) ? "CanvasRenderer" : "NONE"); } stringBuilder.Append(" tmpEnabled=").Append(((Behaviour)tmp).enabled ? "true" : "FALSE"); TextMeshPro val2 = (TextMeshPro)(object)((tmp is TextMeshPro) ? tmp : null); if (val2 != null) { stringBuilder.Append(" mask=").Append(val2.maskType); } int num3 = 0; int num4 = 0; Transform val3 = transform; while ((Object)(object)val3 != (Object)null) { if ((Object)(object)((Component)val3).GetComponent() != (Object)null) { num3++; } else if ((Object)(object)((Component)val3).GetComponent() != (Object)null) { num3++; } if ((Object)(object)((Component)val3).GetComponent() != (Object)null) { num4++; } val3 = val3.parent; } stringBuilder.Append(" masks=").Append(num3).Append(" layouts=") .Append(num4); stringBuilder.Append(" comps=["); Il2CppArrayBase components = clone.GetComponents(); for (int j = 0; j < components.Length; j++) { Component val4 = components[j]; if ((Object)(object)val4 == (Object)null) { stringBuilder.Append("NULL,"); continue; } stringBuilder.Append(((object)val4).GetType().Name); Behaviour val5 = (Behaviour)(object)((val4 is Behaviour) ? val4 : null); if ((Object)(object)val5 != (Object)null && !val5.enabled) { stringBuilder.Append('*'); } stringBuilder.Append(", "); } stringBuilder.Append(']'); if ((Object)(object)component2 != (Object)null) { Material sharedMaterial = ((Renderer)component2).sharedMaterial; stringBuilder.Append(" mat=").Append(((Object)(object)sharedMaterial == (Object)null) ? "NULL" : ((Object)sharedMaterial).name); stringBuilder.Append(" shader=").Append(((Object)(object)sharedMaterial == (Object)null || (Object)(object)sharedMaterial.shader == (Object)null) ? "NULL" : ((Object)sharedMaterial.shader).name); Texture val6 = (((Object)(object)sharedMaterial == (Object)null) ? null : sharedMaterial.mainTexture); stringBuilder.Append(" atlas=").Append(((Object)(object)val6 == (Object)null) ? "NULL" : ((Object)val6).name); if ((Object)(object)sharedMaterial != (Object)null) { if (sharedMaterial.HasProperty("_Color")) { stringBuilder.Append(" matColor=").Append(ColorUtility.ToHtmlStringRGBA(sharedMaterial.GetColor("_Color"))); } if (sharedMaterial.HasProperty("_FaceColor")) { stringBuilder.Append(" faceColor=").Append(ColorUtility.ToHtmlStringRGBA(sharedMaterial.GetColor("_FaceColor"))); } if (sharedMaterial.HasProperty("_ClipRect")) { stringBuilder.Append(" clipRect=").Append(sharedMaterial.GetVector("_ClipRect")); } } } stringBuilder.Append(" font=").Append(((Object)(object)tmp.font == (Object)null) ? "NULL" : ((Object)tmp.font).name); stringBuilder.Append(" alpha=").Append(HudGeometry.F(tmp.alpha)); stringBuilder.Append(" overflow=").Append(tmp.overflowMode); Canvas componentInParent = ((Component)tmp).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { stringBuilder.Append(" canvas=").Append(componentInParent.renderMode); } Camera componentInParent2 = ((Component)transform).GetComponentInParent(); if ((Object)(object)componentInParent2 == (Object)null) { stringBuilder.Append(" camera=NULL"); } else { stringBuilder.Append(" camera=").Append(((Object)componentInParent2).name).Append(" camEnabled=") .Append(((Behaviour)componentInParent2).enabled) .Append(" goActive=") .Append(((Component)componentInParent2).gameObject.activeInHierarchy) .Append(" culling5=") .Append((componentInParent2.cullingMask & (1 << clone.layer)) != 0) .Append(" clip=(") .Append(HudGeometry.F(componentInParent2.nearClipPlane)) .Append(", ") .Append(HudGeometry.F(componentInParent2.farClipPlane)) .Append(')') .Append(componentInParent2.orthographic ? " ortho" : " persp") .Append(" dist=") .Append(HudGeometry.F(Vector3.Dot(transform.position - ((Component)componentInParent2).transform.position, ((Component)componentInParent2).transform.forward))); Vector3 val7 = componentInParent2.WorldToScreenPoint(transform.position); string value = ((val7.z <= 0f) ? "BEHIND-CAMERA" : ((val7.x < 0f || val7.y < 0f || val7.x > (float)componentInParent2.pixelWidth || val7.y > (float)componentInParent2.pixelHeight) ? "OFF-SCREEN" : "on-screen")); stringBuilder.Append(" screen=(").Append(HudGeometry.F(val7.x)).Append(", ") .Append(HudGeometry.F(val7.y)) .Append(", z=") .Append(HudGeometry.F(val7.z)) .Append(") ") .Append(value); if ((Object)(object)template != (Object)null) { Vector3 val8 = componentInParent2.WorldToScreenPoint(template.position); stringBuilder.Append(" template_screen=(").Append(HudGeometry.F(val8.x)).Append(", ") .Append(HudGeometry.F(val8.y)) .Append(')'); } } return stringBuilder.ToString(); } internal static void RetryLater() { _nextRetry = Time.unscaledTime + 1f; } } public enum LogDetail { Off, Normal, Debug } internal static class ModConfig { public static ConfigEntry SafetyEnabled { get; private set; } public static ConfigEntry ToggleKey { get; private set; } public static ConfigEntry KeyHoldTime { get; private set; } public static ConfigEntry ColorOn { get; private set; } public static ConfigEntry ColorOff { get; private set; } public static ConfigEntry ChipAlpha { get; private set; } public static ConfigEntry ChipPadding { get; private set; } public static ConfigEntry LogLevel { get; private set; } public static ConfigEntry StyleTemplate { get; private set; } public static ConfigEntry OffsetX { get; private set; } public static ConfigEntry OffsetY { get; private set; } public static ConfigEntry SortingOrder { get; private set; } public static ConfigEntry DepthOffset { get; private set; } public static ConfigEntry DebugTemplates { get; private set; } public static ConfigEntry DebugChipMagenta { get; private set; } public static ConfigEntry DebugScene { get; private set; } public static void Load(ConfigFile config) { SafetyEnabled = config.Bind("Basic", "Enabled", false, "Enable the weapon safety by default."); ToggleKey = config.Bind("Basic", "ToggleKey", (KeyCode)118, "The button to toggle the weapon safety."); KeyHoldTime = config.Bind("Basic", "KeyHoldTime", 1f, "The time in seconds the toggle key must be held to toggle the safety."); ColorOn = config.Bind("Colours", "ColorOn", "B8B8B8FF", "Text colour while the safety is ON, as hex: RRGGBB or RRGGBBAA (alpha included). Default B8B8B8FF = the HUD grey used by the weapon rows."); ColorOff = config.Bind("Colours", "ColorOff", "FFFFFFFF", "Text colour while the safety is OFF, as hex: RRGGBB or RRGGBBAA (alpha included). Default FFFFFFFF = plain white, like the weapon name in its row."); ChipAlpha = config.Bind("Colours", "ChipAlpha", 0.35f, "Opacity of the background chip behind the text, 0 = fully transparent, 1 = solid. The weapon rows themselves draw at about 0.05, so values around 0.2-0.5 read as 'like the rows' without disappearing."); ChipPadding = config.Bind("Colours", "ChipPadding", 6f, "Breathing room inside the chip around the text, in screen pixels at 1080p (0 = exactly the weapon row margins). It scales with resolution."); LogLevel = config.Bind("Log", "LogLevel", LogDetail.Off, "How much is written to the BepInEx log. Off = nothing, Normal = state changes only (created, safety toggled, warnings), Debug = every diagnostic dump (chip state, indicator state, scene sweep). Debug is noisy and costs FPS."); StyleTemplate = config.Bind("Tuning", "Template", "", "Substring of the HUD text object to clone as style source (e.g. the weapon text). Leave empty for auto-detection. Set LogLevel to Debug to list every HUD text."); OffsetX = config.Bind("Tuning", "OffsetX", 0f, "Extra horizontal offset in SCREEN pixels added on top of the anchor. The anchor is dynamic: next to the flashlight icon (the little sun in the HUD), or below the last row of the weapon list if that icon is missing. The text is right-aligned, so positive = right (closer to the sun) and negative = left."); OffsetY = config.Bind("Tuning", "OffsetY", 0f, "Extra vertical offset in SCREEN pixels added on top of the anchor (positive = up, negative = down). The anchor already sits on the same line as the flashlight icon, or below the last row of the weapon list."); SortingOrder = config.Bind("Tuning", "SortingOrder", 1000, "Sorting order of the indicator renderer. Higher values draw on top of the HUD panels."); DepthOffset = config.Bind("Tuning", "DepthOffset", 60f, "How far (world units) the indicator is pulled in front of the HUD plane so no panel background can cover it. Capped automatically to stay inside the camera frustum. Set to 0 to keep the template depth exactly."); DebugTemplates = config.Bind("Tuning", "DebugTemplates", false, "Log every TextMeshProUGUI found in the HUD (path, font, size, color) so you can pick one."); DebugChipMagenta = config.Bind("Tuning", "DebugChipMagenta", false, "Paint the safety background chip solid magenta (opaque) to check whether it is drawn at all. Set back to false once the check is done."); DebugScene = config.Bind("Tuning", "DebugScene", false, "Deep scene sweep for chip diagnostics: scans every Renderer, CanvasRenderer and Camera in the level looking for objects that overlap the indicator. Costs FPS, so leave it false unless you are investigating something."); } } [HarmonyPatch(typeof(BulletWeapon), "Fire")] internal static class BulletWeaponFirePatch { public static bool Prefix(BulletWeapon __instance) { Plugin._currentWeapon = __instance; if (!WeaponSafety.AllowFire()) { return false; } return true; } } [HarmonyPatch(typeof(Shotgun), "Fire")] internal static class ShotgunFirePatch { public static bool Prefix(Shotgun __instance) { Plugin._currentWeapon = (BulletWeapon?)(object)__instance; if (WeaponSafety.IsSafetyOn) { HudLog.Info("[BLOCKED] Shotgun: " + ((Object)__instance).name); return false; } return true; } } [HarmonyPatch(typeof(BulletWeapon), "TriggerSingleFireAudio")] internal static class SingleFireAudioPatch { public static bool Prefix(BulletWeapon __instance) { if (WeaponSafety.IsSafetyOn) { __instance.TriggerAudio(__instance.m_audioCooldownEnd); return false; } return true; } } [HarmonyPatch(typeof(BulletWeapon), "TriggerBurstFireAudio")] internal static class BurstFireAudioPatch { public static bool Prefix(BulletWeapon __instance) { if (WeaponSafety.IsSafetyOn) { __instance.TriggerAudio(__instance.m_audioCooldownEnd); return false; } return true; } } [HarmonyPatch(typeof(BulletWeapon), "TriggerSyncedAutoFirePerShotAudio")] internal static class SyncedBurstFireAudioPatch { public static bool Prefix(BulletWeapon __instance) { if (WeaponSafety.IsSafetyOn) { __instance.TriggerAudio(__instance.m_audioCooldownEnd); return false; } return true; } } [HarmonyPatch(typeof(BulletWeapon), "TriggerBurstFireOneShotAudio")] internal static class BurstOneShotAudioPatch { public static bool Prefix(BulletWeapon __instance) { if (WeaponSafety.IsSafetyOn) { __instance.TriggerAudio(__instance.m_audioCooldownEnd); return false; } return true; } } [HarmonyPatch(typeof(BulletWeapon), "TriggerAutoFireStartAudio")] internal static class AutoFireStartAudioPatch { public static bool Prefix(BulletWeapon __instance) { if (WeaponSafety.IsSafetyOn) { __instance.TriggerAudio(__instance.m_audioCooldownEnd); return false; } return true; } } [BepInPlugin("Daem0n.WeaponSafety", "WeaponSafety", "1.0.0")] public class Plugin : BasePlugin { public class WeaponSafetyBehaviour : MonoBehaviour { private static float _keyHoldTime; private static bool _keyTriggered; public WeaponSafetyBehaviour(IntPtr ptr) : base(ptr) { } public WeaponSafetyBehaviour() : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); } public void Start() { HudLog.Info("WeaponSafetyBehaviour START"); } public void Update() { //IL_002e: 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_010c: Unknown result type (might be due to invalid IL or missing references) WeaponSafetyGUI.Draw(); if (!WeaponSafetyGUI.IsInLevel()) { _keyHoldTime = 0f; _keyTriggered = false; } else if (Input.GetKey(ModConfig.ToggleKey.Value)) { if (WeaponSafety.IsSafetyOn && !_keyTriggered) { WeaponSafety.ToggleSafety(); WeaponSafetyGUI.LogSnapshot($"key {ModConfig.ToggleKey.Value} (pressed -> safety OFF)"); _keyHoldTime = 0f; _keyTriggered = false; return; } _keyHoldTime += Time.deltaTime; if (_keyHoldTime >= ModConfig.KeyHoldTime.Value && !_keyTriggered) { WeaponSafety.ToggleSafety(); WeaponSafetyGUI.LogSnapshot($"key {ModConfig.ToggleKey.Value} (held -> safety ON)"); _keyTriggered = true; _keyHoldTime = 0f; } } else { _keyHoldTime = 0f; _keyTriggered = false; } } } public static BulletWeapon? _currentWeapon; public static ManualLogSource Logger { get; private set; } public override void Load() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown ModConfig.Load(((BasePlugin)this).Config); Logger = ((BasePlugin)this).Log; WeaponSafety.Initialize(ModConfig.SafetyEnabled.Value); HudLog.Info($"WeaponSafety is loaded! (initial safety = {ModConfig.SafetyEnabled.Value})"); Harmony val = new Harmony("Daem0n.WeaponSafety"); val.PatchAll(); ClassInjector.RegisterTypeInIl2Cpp(); WeaponSafetyBehaviour weaponSafetyBehaviour = ((BasePlugin)this).AddComponent(); } } internal static class WeaponSafety { private static bool _safetyOn; public static bool IsSafetyOn => _safetyOn; internal static void Initialize(bool safetyOn) { _safetyOn = safetyOn; } public static bool AllowFire() { return !IsSafetyOn; } public static void ToggleSafety() { _safetyOn = !_safetyOn; } } internal static class WeaponSafetyGUI { public static void Draw() { try { DrawInternal(); } catch (Exception value) { Indicator.RetryLater(); if (!Indicator._loggedError) { Indicator._loggedError = true; HudLog.Error($"[WeaponSafety] Error drawing the indicator: {value}"); } } } public static void LogSnapshot(string reason) { if ((Object)(object)Indicator._root == (Object)null || (Object)(object)Indicator._text == (Object)null) { LogInfo("[snapshot] " + reason + ": NO indicator created."); return; } LogInfo($"[snapshot] {reason}: safety={(WeaponSafety.IsSafetyOn ? "ON" : "OFF")} expected='{(WeaponSafety.IsSafetyOn ? "SAFETY ON" : "SAFETY OFF")}' ([indicator] text may be 1 frame behind)\n" + Indicator.DescribeClone(Indicator._root, Indicator._text, HudScan._template) + "\n anchor: " + Anchors._anchorInfo); } internal static void DrawInternal() { //IL_0516: 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) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: 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_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: 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_02c9: Unknown result type (might be due to invalid IL or missing references) if (!IsInLevel()) { if ((Object)(object)Indicator._root != (Object)null && Indicator._root.activeSelf) { Indicator._root.SetActive(false); LogInfo("Out of a level: indicator hidden."); } Chip.HideChip(); Indicator._loggedNoTemplate = false; Indicator._loggedError = false; Indicator._loggedTypedFail = false; Indicator._loggedApplied = false; Indicator._loggedHudHidden = false; Indicator._loggedParentOff = false; HudScan._stableHudRoot = null; HudScan._inventoryRoot = null; HudScan._template = null; Indicator._lastWielded = true; Indicator._scriptsReenabled = false; Indicator._nextRetry = 0f; Chip._nextChipSearch = 0f; Chip._chipSearchedHud = false; Chip._loggedChipFail = false; Chip._loggedChipCalled = false; Chip._loggedChipRect = false; ChipDiagnostics._loggedRowChips = false; HudScan._loggedStructure = false; ChipDiagnostics._previousChipState = null; ChipDiagnostics._nextChipDiag = 0f; return; } bool flag = HasGunWielded(); if (flag != Indicator._lastWielded) { Indicator._lastWielded = flag; LogInfo(flag ? "Gun wielded: the indicator stays visible." : "No gun wielded (knife/tool/change): the indicator is NOT hidden."); } if (Time.unscaledTime < Indicator._nextRetry || (((Object)(object)Indicator._text == (Object)null || (Object)(object)Indicator._root == (Object)null) && !Indicator.TryCreate())) { return; } if (!Indicator._root.activeSelf) { Indicator._root.SetActive(true); } if (!Indicator._root.activeInHierarchy) { if (((Object)(object)HudScan._stableHudRoot != (Object)null && !((Component)HudScan._stableHudRoot).gameObject.activeInHierarchy) || ((Object)(object)HudScan._inventoryRoot != (Object)null && !((Component)HudScan._inventoryRoot).gameObject.activeInHierarchy)) { Chip.HideChip(); if (!Indicator._loggedHudHidden) { Indicator._loggedHudHidden = true; LogInfo("[WeaponSafety] HUD hidden: indicator paused (it comes back on its own when the HUD reappears)."); } return; } if (!Indicator._loggedParentOff) { Indicator._loggedParentOff = true; LogInfo("[WeaponSafety] The indicator's parent was deactivated (slot state change): recreating it next to the active text."); } Object.Destroy((Object)(object)Indicator._root); Indicator._root = null; Indicator._text = null; Chip.DestroyChip(); Indicator._nextRetry = Time.unscaledTime + 0.25f; return; } if (Indicator._loggedHudHidden) { LogInfo("HUD visible again: indicator resumed."); } if (Indicator._loggedParentOff) { LogInfo("The parent was reactivated: indicator resumed."); } Indicator._loggedHudHidden = false; Indicator._loggedParentOff = false; bool flag2 = false; Color val = Indicator.SafetyColor(WeaponSafety.IsSafetyOn); if (Indicator._lastColor != val) { ((Graphic)Indicator._text).color = val; Indicator._lastColor = val; flag2 = true; } string text = (WeaponSafety.IsSafetyOn ? "SAFETY ON" : "SAFETY OFF"); if (!string.Equals(Indicator._text.text, text, StringComparison.Ordinal)) { Indicator._text.text = text; flag2 = true; } if (flag2) { Indicator._text.havePropertiesChanged = true; Indicator._text.ForceMeshUpdate(true, true); } if (flag2 && !Indicator._scriptsReenabled && !Indicator.HasMesh()) { Indicator._scriptsReenabled = true; foreach (MonoBehaviour component in Indicator._root.GetComponents()) { if (!((Object)(object)component == (Object)null) && !(component is TMP_Text)) { ((Behaviour)component).enabled = true; } } LogInfo("TMP did not generate the mesh with the text set: reactivating the game scripts on the clone and forcing it again."); Indicator._text.ForceMeshUpdate(true, true); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(38, 2); defaultInterpolatedStringHandler.AppendLiteral("After reactivating scripts: "); defaultInterpolatedStringHandler.AppendFormatted(Indicator.HasMesh() ? "mesh exists" : "still no mesh"); defaultInterpolatedStringHandler.AppendLiteral(" (chars="); TMP_TextInfo textInfo = Indicator._text.textInfo; defaultInterpolatedStringHandler.AppendFormatted((textInfo != null) ? textInfo.characterCount : (-1)); defaultInterpolatedStringHandler.AppendLiteral(")."); LogInfo(defaultInterpolatedStringHandler.ToStringAndClear()); } Indicator.ApplyOutline(Indicator._text); try { Anchors.PlaceIndicator(Indicator._root.transform, HudScan._template, log: true); } catch (Exception value) { if (!Anchors._loggedPosFail) { Anchors._loggedPosFail = true; LogInfo($"Position failure (retried every frame): {value}"); } } if (!Indicator._loggedApplied) { Indicator._loggedApplied = true; LogInfo($"[WeaponSafety] Indicator updated: text='{Indicator._text.text}' color={ColorUtility.ToHtmlStringRGBA(((Graphic)Indicator._text).color)} active={Indicator._root.activeInHierarchy} pos=({HudGeometry.F(Indicator._root.transform.position.x)}, {HudGeometry.F(Indicator._root.transform.position.y)}, {HudGeometry.F(Indicator._root.transform.position.z)})"); } } internal static void LogInfo(string message) { HudLog.Info(message); } internal static void LogDebug(string message) { HudLog.Debug(message); } internal static bool IsInLevel() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 GameStateManager current = GameStateManager.Current; return (Object)(object)current != (Object)null && (int)current.m_currentStateName == 10; } internal static bool HasGunWielded() { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { return false; } PlayerInventoryBase inventory = localPlayerAgent.Inventory; if ((Object)(object)inventory == (Object)null) { return false; } ItemEquippable wieldedItem = inventory.WieldedItem; if ((Object)(object)wieldedItem == (Object)null) { return false; } return (Object)(object)((Component)wieldedItem).GetComponent() != (Object)null; } } }