Decompiled source of LCCrosshair v1.6.0

plugins/LCCrosshair.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Microsoft.Win32;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Syrupdesu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("CS2-style crosshair with native in-game settings menu")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: AssemblyInformationalVersion("1.6.0+78bca4d502adcab2c221f6e69b27781723f8ee84")]
[assembly: AssemblyProduct("LCCrosshair")]
[assembly: AssemblyTitle("LCCrosshair")]
[assembly: AssemblyVersion("1.6.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LCCrosshair
{
	internal static class Cfg
	{
		internal static ConfigFile File;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<CrosshairStyle> Style;

		internal static ConfigEntry<string> ColorHex;

		internal static ConfigEntry<float> Opacity;

		internal static ConfigEntry<OutlineMode> Outline;

		internal static ConfigEntry<int> Thickness;

		internal static ConfigEntry<bool> CenterDot;

		internal static ConfigEntry<int> Length;

		internal static ConfigEntry<int> Gap;

		internal static ConfigEntry<bool> TShape;

		internal static ConfigEntry<int> MoveSpread;

		internal static ConfigEntry<int> FireSpread;

		internal static ConfigEntry<float> FireDecay;

		internal static ConfigEntry<bool> CrouchReduce;

		private const string General = "1 通用 General";

		private const string StyleSec = "2 样式 Style";

		private const string LookSec = "3 外观 Appearance";

		private const string DynSec = "4 动态 Dynamic";

		internal static float LastFireTime = -999f;

		internal static ConfigEntry<bool> FontHintDismissed;

		internal static void Bind(ConfigFile file)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			File = file;
			Enabled = file.Bind<bool>("1 通用 General", "Enabled", true, "是否显示准星 / Show the crosshair");
			Style = file.Bind<CrosshairStyle>("2 样式 Style", "Style", CrosshairStyle.StaticCross, "样式预设 / Preset: StaticCross=静态十字, StaticCircle=静态圆形, StaticSquare=静态方块(Static Square), DotOnly=仅限圆点, DynamicCross=动态十字, DynamicCircle=动态圆形, DynamicCrossClassic=动态十字(经典), DynamicCrossLegacy=动态十字[旧版/射击反馈], DynamicQuad=动态四边形");
			ColorHex = file.Bind<string>("3 外观 Appearance", "ColorHex", "#00FF00", "准星颜色(十六进制 #RRGGBB) / Crosshair color in hex");
			Opacity = file.Bind<float>("3 外观 Appearance", "Opacity", 1f, new ConfigDescription("不透明度(0 = 隐藏准星) / Opacity (0 hides the crosshair)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			Outline = file.Bind<OutlineMode>("3 外观 Appearance", "Outline", OutlineMode.FullOutline, "轮廓 / Outline: None=无, Outline=外框, FullOutline=FULL OUTLINE");
			Thickness = file.Bind<int>("3 外观 Appearance", "Thickness", 3, new ConfigDescription("粗细(像素) / Line thickness in px", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			CenterDot = file.Bind<bool>("3 外观 Appearance", "CenterDot", false, "中心点 / Center dot");
			Length = file.Bind<int>("3 外观 Appearance", "Length", 7, new ConfigDescription("长度(像素) / Line length in px", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			Gap = file.Bind<int>("3 外观 Appearance", "Gap", 5, new ConfigDescription("间隙(像素) / Gap between center and lines in px", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 40), Array.Empty<object>()));
			TShape = file.Bind<bool>("3 外观 Appearance", "TShape", false, "T形准星(去掉上面那条线) / T-shape: remove the top line");
			MoveSpread = file.Bind<int>("4 动态 Dynamic", "MoveSpread", 8, new ConfigDescription("移动时最大外扩量(像素) / Extra size at full movement speed", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>()));
			FireSpread = file.Bind<int>("4 动态 Dynamic", "FireSpread", 12, new ConfigDescription("射击时外扩量(像素) / Extra size when firing", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
			FireDecay = file.Bind<float>("4 动态 Dynamic", "FireDecay", 0.5f, new ConfigDescription("射击反馈回缩时间(秒) / Fire feedback decay time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			CrouchReduce = file.Bind<bool>("4 动态 Dynamic", "CrouchReduce", true, "下蹲时减少移动外扩 / Crouching reduces movement spread");
			FontHintDismissed = file.Bind<bool>("5 提示 Hint", "FontHintDismissed", false, "不再显示中文字体安装提示 / Permanently hide the CJK font install hint");
		}

		internal static void ResetToDefaults()
		{
			((ConfigEntryBase)Enabled).BoxedValue = ((ConfigEntryBase)Enabled).DefaultValue;
			((ConfigEntryBase)Style).BoxedValue = ((ConfigEntryBase)Style).DefaultValue;
			((ConfigEntryBase)ColorHex).BoxedValue = ((ConfigEntryBase)ColorHex).DefaultValue;
			((ConfigEntryBase)Opacity).BoxedValue = ((ConfigEntryBase)Opacity).DefaultValue;
			((ConfigEntryBase)Outline).BoxedValue = ((ConfigEntryBase)Outline).DefaultValue;
			((ConfigEntryBase)Thickness).BoxedValue = ((ConfigEntryBase)Thickness).DefaultValue;
			((ConfigEntryBase)CenterDot).BoxedValue = ((ConfigEntryBase)CenterDot).DefaultValue;
			((ConfigEntryBase)Length).BoxedValue = ((ConfigEntryBase)Length).DefaultValue;
			((ConfigEntryBase)Gap).BoxedValue = ((ConfigEntryBase)Gap).DefaultValue;
			((ConfigEntryBase)TShape).BoxedValue = ((ConfigEntryBase)TShape).DefaultValue;
			((ConfigEntryBase)MoveSpread).BoxedValue = ((ConfigEntryBase)MoveSpread).DefaultValue;
			((ConfigEntryBase)FireSpread).BoxedValue = ((ConfigEntryBase)FireSpread).DefaultValue;
			((ConfigEntryBase)FireDecay).BoxedValue = ((ConfigEntryBase)FireDecay).DefaultValue;
			((ConfigEntryBase)CrouchReduce).BoxedValue = ((ConfigEntryBase)CrouchReduce).DefaultValue;
		}

		internal static void NotifyFired()
		{
			if (FireSpread.Value > 0 && !(FireDecay.Value <= 0f))
			{
				LastFireTime = Time.unscaledTime;
			}
		}

		internal static float FireBoost()
		{
			if (FireSpread.Value <= 0 || FireDecay.Value <= 0f)
			{
				return 0f;
			}
			float num = Time.unscaledTime - LastFireTime;
			if (num < 0f || num >= FireDecay.Value)
			{
				return 0f;
			}
			return (float)FireSpread.Value * (1f - num / FireDecay.Value);
		}

		internal static float MoveBoost(PlayerControllerB pbc)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (MoveSpread.Value <= 0 || (Object)(object)pbc == (Object)null)
			{
				return 0f;
			}
			Vector3 velocityLastFrame = pbc.velocityLastFrame;
			float num = Mathf.Sqrt(velocityLastFrame.x * velocityLastFrame.x + velocityLastFrame.z * velocityLastFrame.z);
			float num2 = ((pbc.movementSpeed > 0.2f) ? pbc.movementSpeed : 4.7f);
			float num3 = Mathf.Clamp01(num / num2);
			if (CrouchReduce.Value && pbc.isCrouching)
			{
				num3 *= 0.5f;
			}
			float num4 = (float)MoveSpread.Value * num3;
			if (pbc.isFallingFromJump || velocityLastFrame.y > 1.5f || velocityLastFrame.y < -5f || ((Object)(object)pbc.thisController != (Object)null && !pbc.thisController.isGrounded))
			{
				num4 = Mathf.Max(num4, (float)MoveSpread.Value);
			}
			return num4;
		}

		internal static bool TryGetColor(out Color c)
		{
			//IL_0073: 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)
			string value = ColorHex.Value;
			if (!string.IsNullOrEmpty(value))
			{
				value = value.Trim();
				if (value.Length > 0 && value[0] != '#')
				{
					value = "#" + value;
				}
				if (ColorUtility.TryParseHtmlString(value, ref c))
				{
					c.a *= Opacity.Value;
					return true;
				}
			}
			c = new Color(0f, 1f, 0f, Opacity.Value);
			return false;
		}
	}
	internal struct Prim
	{
		public Vector2 Pos;

		public float W;

		public float H;

		public float Angle;

		public bool Outline;

		public bool Circle;
	}
	internal static class CrosshairGeometry
	{
		private const float TwoPi = (float)Math.PI * 2f;

		internal static void Build(CrosshairStyle style, float gap, float len, float t, int outline, bool tShape, bool centerDot, float dyn, List<Prim> prims)
		{
			prims.Clear();
			switch (style)
			{
			case CrosshairStyle.StaticCross:
			case CrosshairStyle.DynamicCross:
			case CrosshairStyle.DynamicCrossLegacy:
				Cross(prims, gap + dyn, len, t, outline, tShape, centerDot);
				break;
			case CrosshairStyle.DynamicCrossClassic:
				Cross(prims, gap, len + dyn, t, outline, tShape, centerDot);
				break;
			case CrosshairStyle.StaticCircle:
			case CrosshairStyle.DynamicCircle:
				Ring(prims, gap + len + dyn, t, outline);
				if (centerDot)
				{
					SquareDot(prims, t, outline);
				}
				break;
			case CrosshairStyle.StaticSquare:
				Square(prims, (gap + len + dyn) * 2f, t, outline);
				if (centerDot)
				{
					SquareDot(prims, t, outline);
				}
				break;
			case CrosshairStyle.DynamicQuad:
				Diamond(prims, gap + len + dyn, t, outline);
				if (centerDot)
				{
					SquareDot(prims, t, outline);
				}
				break;
			case CrosshairStyle.DotOnly:
				Disc(prims, Mathf.Max(1f, t), outline);
				break;
			}
		}

		private static void Cross(List<Prim> prims, float gap, float len, float t, int o, bool tShape, bool centerDot)
		{
			gap = Mathf.Max(0f, gap);
			len = Mathf.Max(1f, len);
			float num = t * 0.5f;
			if (o > 0)
			{
				Bar(prims, gap - (float)o, 0f - num - (float)o, len + 2f * (float)o, t + 2f * (float)o, 0f, outline: true);
				Bar(prims, 0f - gap - len - (float)o, 0f - num - (float)o, len + 2f * (float)o, t + 2f * (float)o, 0f, outline: true);
				if (!tShape)
				{
					Bar(prims, 0f - num - (float)o, gap - (float)o, t + 2f * (float)o, len + 2f * (float)o, 0f, outline: true);
				}
				Bar(prims, 0f - num - (float)o, 0f - gap - len - (float)o, t + 2f * (float)o, len + 2f * (float)o, 0f, outline: true);
				if (centerDot)
				{
					Bar(prims, 0f - num - (float)o, 0f - num - (float)o, t + 2f * (float)o, t + 2f * (float)o, 0f, outline: true);
				}
			}
			Bar(prims, gap, 0f - num, len, t, 0f, outline: false);
			Bar(prims, 0f - gap - len, 0f - num, len, t, 0f, outline: false);
			if (!tShape)
			{
				Bar(prims, 0f - num, gap, t, len, 0f, outline: false);
			}
			Bar(prims, 0f - num, 0f - gap - len, t, len, 0f, outline: false);
			if (centerDot)
			{
				Bar(prims, 0f - num, 0f - num, t, t, 0f, outline: false);
			}
		}

		private static void Ring(List<Prim> prims, float radius, float t, int o)
		{
			float num = Mathf.Max(2f, radius);
			int num2 = Mathf.Clamp(Mathf.CeilToInt(num * 1.5f), 16, 56);
			float num3 = (float)Math.PI * 2f / (float)num2;
			float chord = 2f * num * Mathf.Sin(num3 * 0.5f) * 1.4f;
			if (o > 0)
			{
				RingRaw(prims, num, chord, t + 2f * (float)o, num3, num2, outline: true);
			}
			RingRaw(prims, num, chord, t, num3, num2, outline: false);
		}

		private static void RingRaw(List<Prim> prims, float r, float chord, float th, float arc, int seg, bool outline)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Vector2 pos = default(Vector2);
			for (int i = 0; i < seg; i++)
			{
				float num = (float)i * arc;
				((Vector2)(ref pos))..ctor(Mathf.Cos(num) * r, Mathf.Sin(num) * r);
				prims.Add(new Prim
				{
					Pos = pos,
					W = chord,
					H = th,
					Angle = num * 57.29578f + 90f,
					Outline = outline,
					Circle = false
				});
			}
		}

		private static void Square(List<Prim> prims, float side, float t, int o)
		{
			side = Mathf.Max(side, 2f * t + 2f);
			float num = side * 0.5f;
			if (o > 0)
			{
				Bar(prims, 0f - num - (float)o, 0f - num - (float)o, side + 2f * (float)o, t + 2f * (float)o, 0f, outline: true);
				Bar(prims, 0f - num - (float)o, num - t - (float)o, side + 2f * (float)o, t + 2f * (float)o, 0f, outline: true);
				Bar(prims, 0f - num - (float)o, 0f - num + t - (float)o, t + 2f * (float)o, side - 2f * t + 2f * (float)o, 0f, outline: true);
				Bar(prims, num - t - (float)o, 0f - num + t - (float)o, t + 2f * (float)o, side - 2f * t + 2f * (float)o, 0f, outline: true);
			}
			Bar(prims, 0f - num, 0f - num, side, t, 0f, outline: false);
			Bar(prims, 0f - num, num - t, side, t, 0f, outline: false);
			Bar(prims, 0f - num, 0f - num + t, t, side - 2f * t, 0f, outline: false);
			Bar(prims, num - t, 0f - num + t, t, side - 2f * t, 0f, outline: false);
		}

		private static void Diamond(List<Prim> prims, float r, float t, int o)
		{
			//IL_0049: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0122: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			r = Mathf.Max(2f, r);
			float num = r * Mathf.Sqrt(2f) * 1.06f;
			float[] array = new float[4] { 45f, 135f, 225f, 315f };
			Vector2[] array2 = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(r * 0.5f, (0f - r) * 0.5f),
				new Vector2(r * 0.5f, r * 0.5f),
				new Vector2((0f - r) * 0.5f, r * 0.5f),
				new Vector2((0f - r) * 0.5f, (0f - r) * 0.5f)
			};
			if (o > 0)
			{
				for (int i = 0; i < 4; i++)
				{
					prims.Add(new Prim
					{
						Pos = array2[i],
						W = num + 2f * (float)o,
						H = t + 2f * (float)o,
						Angle = array[i],
						Outline = true,
						Circle = false
					});
				}
			}
			for (int j = 0; j < 4; j++)
			{
				prims.Add(new Prim
				{
					Pos = array2[j],
					W = num,
					H = t,
					Angle = array[j],
					Outline = false,
					Circle = false
				});
			}
		}

		private static void Disc(List<Prim> prims, float r, int o)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			r = Mathf.Max(1f, r);
			if (o > 0)
			{
				prims.Add(new Prim
				{
					Pos = Vector2.zero,
					W = (r + (float)o) * 2f,
					H = (r + (float)o) * 2f,
					Angle = 0f,
					Outline = true,
					Circle = true
				});
			}
			prims.Add(new Prim
			{
				Pos = Vector2.zero,
				W = r * 2f,
				H = r * 2f,
				Angle = 0f,
				Outline = false,
				Circle = true
			});
		}

		private static void SquareDot(List<Prim> prims, float size, int o)
		{
			float num = Mathf.Max(1f, size);
			float num2 = num * 0.5f;
			if (o > 0)
			{
				Bar(prims, 0f - num2 - (float)o, 0f - num2 - (float)o, num + 2f * (float)o, num + 2f * (float)o, 0f, outline: true);
			}
			Bar(prims, 0f - num2, 0f - num2, num, num, 0f, outline: false);
		}

		private static void Bar(List<Prim> prims, float x, float y, float w, float h, float angle, bool outline)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!(w <= 0f) && !(h <= 0f))
			{
				prims.Add(new Prim
				{
					Pos = new Vector2(x + w * 0.5f, y + h * 0.5f),
					W = w,
					H = h,
					Angle = angle,
					Outline = outline,
					Circle = false
				});
			}
		}
	}
	internal sealed class CrosshairHud : MonoBehaviour
	{
		private static CrosshairHud _instance;

		private RectTransform _root;

		private readonly List<Image> _pool = new List<Image>();

		private readonly List<Prim> _prims = new List<Prim>();

		private bool _logged;

		internal static void EnsureAttached(HUDManager hud)
		{
			if (!((Object)(object)hud == (Object)null) && !((Object)(object)((Component)hud).GetComponent<CrosshairHud>() != (Object)null))
			{
				_instance = ((Component)hud).gameObject.AddComponent<CrosshairHud>();
				CrosshairPlugin.Log.LogInfo((object)"[LCCrosshair] 准星渲染组件已挂载到 HUDManager");
			}
		}

		internal static void TickStatic()
		{
			_instance?.Refresh();
		}

		private void Update()
		{
			Refresh();
		}

		private void Refresh()
		{
			//IL_00f6: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			if (!_logged)
			{
				_logged = true;
				CrosshairPlugin.Log.LogInfo((object)"[LCCrosshair] 准星渲染组件开始工作");
			}
			if (EnsureRoot())
			{
				PlayerControllerB pbc;
				float dyn;
				bool flag = ComputeVisibility(out pbc, out dyn);
				if (((Component)_root).gameObject.activeSelf != flag)
				{
					((Component)_root).gameObject.SetActive(flag);
				}
				if (flag)
				{
					Cfg.TryGetColor(out var c);
					CrosshairStyle value = Cfg.Style.Value;
					float gap = Cfg.Gap.Value;
					float len = Cfg.Length.Value;
					float t = Cfg.Thickness.Value;
					CrosshairGeometry.Build(value, gap, len, t, Cfg.Outline.Value switch
					{
						OutlineMode.Outline => 1, 
						OutlineMode.FullOutline => 2, 
						_ => 0, 
					}, Cfg.TShape.Value, Cfg.CenterDot.Value, dyn, _prims);
					CrosshairUi.Apply(_root, _pool, _prims, c, new Color(0f, 0f, 0f, c.a));
				}
			}
		}

		private bool ComputeVisibility(out PlayerControllerB pbc, out float dyn)
		{
			pbc = null;
			dyn = 0f;
			if (!Cfg.Enabled.Value)
			{
				return false;
			}
			StartOfRound instance = StartOfRound.Instance;
			pbc = (((Object)(object)instance == (Object)null) ? null : instance.localPlayerController);
			if ((Object)(object)pbc == (Object)null || pbc.isPlayerDead || pbc.inTerminalMenu)
			{
				return false;
			}
			if ((Object)(object)pbc.quickMenuManager != (Object)null && pbc.quickMenuManager.isMenuOpen)
			{
				return false;
			}
			CrosshairStyle value = Cfg.Style.Value;
			if ((uint)(value - 4) <= 4u)
			{
				float num = ((value == CrosshairStyle.DynamicCrossLegacy) ? 0f : Cfg.MoveBoost(pbc));
				dyn = num + Cfg.FireBoost();
			}
			return true;
		}

		private bool EnsureRoot()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null)
			{
				return true;
			}
			HUDManager instance = HUDManager.Instance;
			GameObject val = (((Object)(object)instance != (Object)null) ? instance.HUDContainer : null);
			if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null)
			{
				return false;
			}
			_root = new GameObject("LCCrosshairRoot", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)_root).SetParent(val.transform, false);
			RectTransform root = _root;
			RectTransform root2 = _root;
			RectTransform root3 = _root;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			root3.pivot = val2;
			Vector2 anchorMin = (root2.anchorMax = val2);
			root.anchorMin = anchorMin;
			_root.anchoredPosition = Vector2.zero;
			_root.sizeDelta = new Vector2(240f, 240f);
			((Transform)_root).localScale = Vector3.one;
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Start")]
	internal static class HudStartPatch
	{
		private static void Postfix(HUDManager __instance)
		{
			CrosshairHud.EnsureAttached(__instance);
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Update")]
	internal static class HudUpdatePatch
	{
		private static void Postfix()
		{
			CrosshairHud.TickStatic();
		}
	}
	internal sealed class CrosshairPreview : MonoBehaviour
	{
		private static readonly List<CrosshairPreview> All = new List<CrosshairPreview>();

		private RectTransform _root;

		private readonly List<Image> _pool = new List<Image>();

		private readonly List<Prim> _prims = new List<Prim>();

		internal static void Create(GameObject page)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)page.GetComponentInChildren<CrosshairPreview>(true) != (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("CrosshairPreview", new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(page.transform, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			float num = 0f;
			float num2 = 0f;
			Transform obj = page.transform.Find("Controls (1)");
			RectTransform val5 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if ((Object)(object)val5 != (Object)null)
			{
				TMP_Text component = ((Component)val5).GetComponent<TMP_Text>();
				float num3;
				if (!((Object)(object)component != (Object)null))
				{
					Rect rect = val5.rect;
					num3 = ((Rect)(ref rect)).width * 0.5f;
				}
				else
				{
					num3 = component.GetPreferredValues(component.text).x * 0.5f;
				}
				float num4 = num3;
				num = val5.anchoredPosition.x + num4 + 14f;
				num2 = val5.anchoredPosition.y;
			}
			val2.anchoredPosition = new Vector2(num, num2);
			val2.sizeDelta = new Vector2(130f, 130f);
			All.Add(val.AddComponent<CrosshairPreview>());
		}

		internal static void RefreshAll()
		{
			for (int num = All.Count - 1; num >= 0; num--)
			{
				CrosshairPreview crosshairPreview = All[num];
				if ((Object)(object)crosshairPreview == (Object)null)
				{
					All.RemoveAt(num);
				}
				else
				{
					crosshairPreview.Refresh();
				}
			}
		}

		private void Update()
		{
			Refresh();
		}

		private void Refresh()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)this).gameObject.activeInHierarchy)
			{
				if ((Object)(object)_root == (Object)null)
				{
					_root = (RectTransform)((Component)this).transform;
				}
				Cfg.TryGetColor(out var c);
				CrosshairStyle value = Cfg.Style.Value;
				float gap = Cfg.Gap.Value;
				float len = Cfg.Length.Value;
				float t = Cfg.Thickness.Value;
				CrosshairGeometry.Build(value, gap, len, t, Cfg.Outline.Value switch
				{
					OutlineMode.Outline => 1, 
					OutlineMode.FullOutline => 2, 
					_ => 0, 
				}, Cfg.TShape.Value, Cfg.CenterDot.Value, 0f, _prims);
				CrosshairUi.Apply(_root, _pool, _prims, c, new Color(0f, 0f, 0f, c.a));
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}
	}
	public enum CrosshairStyle
	{
		StaticCross,
		StaticCircle,
		StaticSquare,
		DotOnly,
		DynamicCross,
		DynamicCircle,
		DynamicCrossClassic,
		DynamicCrossLegacy,
		DynamicQuad
	}
	public enum OutlineMode
	{
		None,
		Outline,
		FullOutline
	}
	internal static class CrosshairUi
	{
		private static Sprite _circle;

		internal static Sprite CircleSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_circle != (Object)null)
			{
				return _circle;
			}
			Texture2D val = new Texture2D(96, 96, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			float num = 46.5f;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(48f, 48f);
			Color32[] array = (Color32[])(object)new Color32[9216];
			for (int i = 0; i < 96; i++)
			{
				for (int j = 0; j < 96; j++)
				{
					float num2 = Mathf.Clamp01(num - Vector2.Distance(new Vector2((float)j, (float)i), val2) + 0.5f);
					array[i * 96 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num2 * 255f));
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			_circle = Sprite.Create(val, new Rect(0f, 0f, 96f, 96f), new Vector2(0.5f, 0.5f), 100f);
			((Object)_circle).hideFlags = (HideFlags)61;
			return _circle;
		}

		internal static void Apply(RectTransform root, List<Image> pool, List<Prim> prims, Color main, Color outline)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			int count = prims.Count;
			Vector2 val3 = default(Vector2);
			while (pool.Count < count)
			{
				GameObject val = new GameObject("p" + pool.Count, new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				RectTransform val2 = (RectTransform)val.transform;
				((Transform)val2).SetParent((Transform)(object)root, false);
				((Vector2)(ref val3))..ctor(0.5f, 0.5f);
				val2.pivot = val3;
				Vector2 anchorMin = (val2.anchorMax = val3);
				val2.anchorMin = anchorMin;
				Image component = val.GetComponent<Image>();
				((Graphic)component).raycastTarget = false;
				pool.Add(component);
			}
			for (int i = 0; i < pool.Count; i++)
			{
				bool flag = i < count;
				if (((Component)pool[i]).gameObject.activeSelf != flag)
				{
					((Component)pool[i]).gameObject.SetActive(flag);
				}
				if (flag)
				{
					Prim prim = prims[i];
					RectTransform rectTransform = ((Graphic)pool[i]).rectTransform;
					rectTransform.anchoredPosition = prim.Pos;
					rectTransform.sizeDelta = new Vector2(prim.W, prim.H);
					((Transform)rectTransform).localRotation = Quaternion.Euler(0f, 0f, prim.Angle);
					((Transform)rectTransform).localScale = Vector3.one;
					pool[i].sprite = (prim.Circle ? CircleSprite() : null);
					((Graphic)pool[i]).color = (prim.Outline ? outline : main);
				}
			}
		}
	}
	[HarmonyPatch(typeof(IngamePlayerSettings), "Update")]
	internal static class IngameSettingsTickPatch
	{
		private static float _nextHealthCheck;

		private static readonly HashSet<string> LoggedStates = new HashSet<string>();

		private static void Postfix()
		{
			SettingsUI.Tick();
			CrosshairPreview.RefreshAll();
			HealthCheck();
		}

		private static void HealthCheck()
		{
			if (Time.unscaledTime < _nextHealthCheck)
			{
				return;
			}
			_nextHealthCheck = Time.unscaledTime + 5f;
			try
			{
				CrosshairPlugin instance = CrosshairPlugin.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					LogState("plugin-destroyed", "插件组件已被销毁(无法自愈,周期性功能依赖游戏钩子继续工作)");
					return;
				}
				if (!((Component)instance).gameObject.activeSelf)
				{
					((Component)instance).gameObject.SetActive(true);
					LogState("go-inactive", "插件 GameObject 处于停用状态,已自动重新激活");
				}
				if (!((Behaviour)instance).enabled)
				{
					((Behaviour)instance).enabled = true;
					LogState("plugin-disabled", "插件组件被禁用,已自动重新启用");
				}
				SettingsUI.RepairComponents();
			}
			catch
			{
			}
		}

		private static void LogState(string key, string message)
		{
			if (LoggedStates.Add(key))
			{
				CrosshairPlugin.Log.LogWarning((object)("[LCCrosshair] " + message));
			}
		}
	}
	[HarmonyPatch]
	internal static class FirePatches
	{
		private static readonly string[] GunHints = new string[8] { "gun", "shotgun", "rifle", "pistol", "revolver", "blaster", "launcher", "musket" };

		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type grabbable = typeof(GrabbableObject);
			HashSet<MethodBase> seen = new HashSet<MethodBase>();
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (!type.IsGenericType && grabbable.IsAssignableFrom(type))
					{
						MethodInfo methodInfo = AccessTools.Method(type, "ItemActivate", (Type[])null, (Type[])null);
						if (!(methodInfo == null) && !methodInfo.IsAbstract && seen.Add(methodInfo))
						{
							yield return methodInfo;
						}
					}
				}
			}
		}

		private static void Postfix(GrabbableObject __instance, object[] __args)
		{
			try
			{
				if (__args == null || __args.Length < 2)
				{
					return;
				}
				object obj = __args[1];
				if (!(obj is bool) || !(bool)obj)
				{
					return;
				}
				PlayerControllerB playerHeldBy = __instance.playerHeldBy;
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)playerHeldBy == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)playerHeldBy != (Object)(object)instance.localPlayerController)
				{
					return;
				}
				string name = ((object)__instance).GetType().Name;
				string[] gunHints = GunHints;
				foreach (string value in gunHints)
				{
					if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						Cfg.NotifyFired();
						break;
					}
				}
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("syrupdesu.lccrosshair", "LCCrosshair", "1.6.0")]
	public sealed class CrosshairPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "syrupdesu.lccrosshair";

		public const string PluginName = "LCCrosshair";

		public const string PluginVersion = "1.6.0";

		internal static CrosshairPlugin Instance;

		internal static ManualLogSource Log;

		private bool _loggedUpdateTick;

		private void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg.Bind(((BaseUnityPlugin)this).Config);
			try
			{
				new Harmony("syrupdesu.lccrosshair").PatchAll();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Harmony patch failed: {arg}");
			}
			SettingsUI.Attach(this);
			Log.LogInfo((object)"LCCrosshair 1.6.0 loaded.");
		}

		private void Update()
		{
			if (!_loggedUpdateTick)
			{
				_loggedUpdateTick = true;
				Log.LogInfo((object)"[LCCrosshair] 插件 Update 心跳");
			}
			SettingsUI.Tick();
		}
	}
	internal sealed class SettingsUI : MonoBehaviour
	{
		private sealed class AutoCloseWhenParentHidden : MonoBehaviour
		{
			internal GameObject Panel;

			private void Update()
			{
				if (!((Object)(object)Panel == (Object)null) && Panel.activeSelf && !((Component)((Component)this).transform.parent).gameObject.activeInHierarchy)
				{
					Panel.SetActive(false);
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action<int> <>9__22_0;

			public static Func<int> <>9__22_1;

			public static Action<int> <>9__22_2;

			public static Func<int, bool> <>9__22_3;

			public static Action<float> <>9__22_4;

			public static Func<float> <>9__22_5;

			public static Action<int> <>9__22_7;

			public static Func<int> <>9__22_8;

			public static Action<float> <>9__22_9;

			public static Func<float> <>9__22_10;

			public static Action<bool> <>9__22_12;

			public static Func<bool> <>9__22_13;

			public static Action<float> <>9__22_14;

			public static Func<float> <>9__22_15;

			public static Action<float> <>9__22_17;

			public static Func<float> <>9__22_18;

			public static Action<bool> <>9__22_20;

			public static Func<bool> <>9__22_21;

			public static Action<float> <>9__22_22;

			public static Func<float> <>9__22_23;

			public static Action<float> <>9__22_25;

			public static Func<float> <>9__22_26;

			public static Action<float> <>9__22_28;

			public static Func<float> <>9__22_29;

			public static Action<bool> <>9__22_31;

			public static Func<bool> <>9__22_32;

			public static UnityAction <>9__26_0;

			internal void <BuildUI>b__22_0(int i)
			{
				Cfg.Style.Value = (CrosshairStyle)i;
			}

			internal int <BuildUI>b__22_1()
			{
				return (int)Cfg.Style.Value;
			}

			internal void <BuildUI>b__22_2(int i)
			{
				Cfg.ColorHex.Value = ColorPresets[Mathf.Clamp(i, 0, ColorPresets.Length - 1)].Hex;
			}

			internal bool <BuildUI>b__22_3(int i)
			{
				return i < 0;
			}

			internal void <BuildUI>b__22_4(float v)
			{
				Cfg.Opacity.Value = v;
			}

			internal float <BuildUI>b__22_5()
			{
				return Cfg.Opacity.Value;
			}

			internal void <BuildUI>b__22_7(int i)
			{
				Cfg.Outline.Value = (OutlineMode)i;
			}

			internal int <BuildUI>b__22_8()
			{
				return (int)Cfg.Outline.Value;
			}

			internal void <BuildUI>b__22_9(float v)
			{
				Cfg.Thickness.Value = (int)v;
			}

			internal float <BuildUI>b__22_10()
			{
				return Cfg.Thickness.Value;
			}

			internal void <BuildUI>b__22_12(bool v)
			{
				Cfg.CenterDot.Value = v;
			}

			internal bool <BuildUI>b__22_13()
			{
				return Cfg.CenterDot.Value;
			}

			internal void <BuildUI>b__22_14(float v)
			{
				Cfg.Length.Value = (int)v;
			}

			internal float <BuildUI>b__22_15()
			{
				return Cfg.Length.Value;
			}

			internal void <BuildUI>b__22_17(float v)
			{
				Cfg.Gap.Value = (int)v;
			}

			internal float <BuildUI>b__22_18()
			{
				return Cfg.Gap.Value;
			}

			internal void <BuildUI>b__22_20(bool v)
			{
				Cfg.TShape.Value = v;
			}

			internal bool <BuildUI>b__22_21()
			{
				return Cfg.TShape.Value;
			}

			internal void <BuildUI>b__22_22(float v)
			{
				Cfg.MoveSpread.Value = (int)v;
			}

			internal float <BuildUI>b__22_23()
			{
				return Cfg.MoveSpread.Value;
			}

			internal void <BuildUI>b__22_25(float v)
			{
				Cfg.FireSpread.Value = (int)v;
			}

			internal float <BuildUI>b__22_26()
			{
				return Cfg.FireSpread.Value;
			}

			internal void <BuildUI>b__22_28(float v)
			{
				Cfg.FireDecay.Value = v;
			}

			internal float <BuildUI>b__22_29()
			{
				return Cfg.FireDecay.Value;
			}

			internal void <BuildUI>b__22_31(bool v)
			{
				Cfg.CrouchReduce.Value = v;
			}

			internal bool <BuildUI>b__22_32()
			{
				return Cfg.CrouchReduce.Value;
			}

			internal void <AddFontHint>b__26_0()
			{
				try
				{
					Application.OpenURL("https://thunderstore.io/c/lethal-company/p/Syrupdesu/LCChineseFont/");
				}
				catch
				{
				}
			}
		}

		private static SettingsUI _instance;

		private CrosshairPlugin _plugin;

		private bool _cjk;

		private bool _zhButNoFont;

		private bool _loggedFontHint;

		private float _nextScanTime;

		private bool _loggedFirstTick;

		private string _lastScanSummary;

		private readonly HashSet<int> _settledPanels = new HashSet<int>();

		private readonly HashSet<string> _seenScenes = new HashSet<string>();

		private const string LcChineseFontUrl = "https://thunderstore.io/c/lethal-company/p/Syrupdesu/LCChineseFont/";

		private static readonly (string Cn, string En, string Hex)[] ColorPresets = new(string, string, string)[10]
		{
			("绿色", "Green", "#00FF00"),
			("白色", "White", "#FFFFFF"),
			("红色", "Red", "#FF3232"),
			("黄色", "Yellow", "#FFFF00"),
			("青色", "Cyan", "#00FFFF"),
			("粉色", "Pink", "#FF66FF"),
			("紫色", "Purple", "#AA33FF"),
			("橙色", "Orange", "#FF9500"),
			("蓝色", "Blue", "#3399FF"),
			("黑色", "Black", "#141414")
		};

		internal static void Attach(CrosshairPlugin plugin)
		{
			SettingsUI settingsUI = ((Component)plugin).gameObject.AddComponent<SettingsUI>();
			settingsUI._plugin = plugin;
			_instance = settingsUI;
		}

		internal static void Tick()
		{
			_instance?.DriveScan();
		}

		internal static void RepairComponents()
		{
			if (!((Object)(object)_instance == (Object)null) && !((Behaviour)_instance).enabled)
			{
				((Behaviour)_instance).enabled = true;
				CrosshairPlugin.Log.LogWarning((object)"[LCCrosshair] SettingsUI 组件被禁用,已自动重新启用");
			}
		}

		private void OnEnable()
		{
			CrosshairPlugin.Log.LogInfo((object)"[LCCrosshair] SettingsUI 组件已启用");
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (_seenScenes.Add(((Scene)(ref scene)).name))
			{
				CrosshairPlugin.Log.LogInfo((object)("[LCCrosshair] 场景加载: " + ((Scene)(ref scene)).name));
			}
			_nextScanTime = 0f;
		}

		private void Update()
		{
			DriveScan();
		}

		private void DriveScan()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < _nextScanTime)
			{
				return;
			}
			_nextScanTime = Time.unscaledTime + 3f;
			if (!_loggedFirstTick)
			{
				_loggedFirstTick = true;
				try
				{
					if (!((Component)this).gameObject.activeSelf)
					{
						((Component)this).gameObject.SetActive(true);
						CrosshairPlugin.Log.LogWarning((object)"[LCCrosshair] 插件 GameObject 处于停用状态,已自动重新激活");
					}
				}
				catch
				{
				}
				ManualLogSource log = CrosshairPlugin.Log;
				Scene activeScene = SceneManager.GetActiveScene();
				log.LogInfo((object)("[LCCrosshair] 首次扫描: 活动场景=" + ((Scene)(ref activeScene)).name + ", " + $"已加载场景数={SceneManager.sceneCount}"));
			}
			TryInjectAll();
		}

		private void TryInjectAll()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SettingsOption[] array = Object.FindObjectsOfType<SettingsOption>(true);
				Dictionary<Transform, List<SettingsOption>> dictionary = new Dictionary<Transform, List<SettingsOption>>();
				SortedSet<string> sortedSet = new SortedSet<string>();
				SettingsOption[] array2 = array;
				foreach (SettingsOption val in array2)
				{
					Transform val2 = FindSettingsPanel(((Component)val).transform);
					if ((Object)(object)val2 == (Object)null)
					{
						Scene scene = ((Component)val).gameObject.scene;
						sortedSet.Add(((Scene)(ref scene)).name);
						continue;
					}
					if (!dictionary.TryGetValue(val2, out var value))
					{
						value = (dictionary[val2] = new List<SettingsOption>());
					}
					value.Add(val);
				}
				string text = $"SOs={array.Length} panels={dictionary.Count}";
				if (text != _lastScanSummary)
				{
					_lastScanSummary = text;
					string text2 = ((sortedSet.Count > 0) ? (" (无面板的场景: " + string.Join("/", sortedSet) + ")") : "");
					CrosshairPlugin.Log.LogInfo((object)("[LCCrosshair] 扫描结果: " + text + text2));
				}
				if (array.Length == 0)
				{
					return;
				}
				foreach (KeyValuePair<Transform, List<SettingsOption>> item in dictionary)
				{
					InjectPanel(item.Key, item.Value);
				}
			}
			catch (Exception arg)
			{
				CrosshairPlugin.Log.LogWarning((object)$"[LCCrosshair] 设置界面扫描失败(不影响准星本身): {arg}");
			}
		}

		private void InjectPanel(Transform panel, List<SettingsOption> opts)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00be: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Invalid comparison between Unknown and I4
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: 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)
			int instanceID = ((Object)((Component)panel).gameObject).GetInstanceID();
			if (_settledPanels.Contains(instanceID))
			{
				return;
			}
			GameObject val = null;
			GameObject val2 = null;
			GameObject val3 = null;
			StringBuilder stringBuilder = new StringBuilder();
			foreach (SettingsOption opt in opts)
			{
				GameObject gameObject = ((Component)opt).gameObject;
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(opt.optionType);
				GameObject val4 = ((((Object)gameObject).name == "Slider" && (Object)(object)gameObject.transform.parent != (Object)null) ? ((Component)gameObject.transform.parent).gameObject : gameObject);
				SettingsOptionType optionType = opt.optionType;
				if ((int)optionType != 0)
				{
					if ((int)optionType != 10)
					{
						if ((int)optionType == 11 && (Object)(object)val2 == (Object)null)
						{
							val2 = gameObject;
						}
					}
					else if ((Object)(object)val3 == (Object)null)
					{
						val3 = gameObject;
					}
				}
				else if ((Object)(object)val == (Object)null)
				{
					val = val4;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Transform obj = FindDeep(panel, "LookSensitivity");
				val = ((obj != null) ? ((Component)obj).gameObject : null);
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Transform obj2 = FindDeep(panel, "InvertYAxis");
				val2 = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			}
			if ((Object)(object)val3 == (Object)null)
			{
				Transform obj3 = FindDeep(panel, "FullscreenMode");
				val3 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				_settledPanels.Add(instanceID);
				CrosshairPlugin.Log.LogWarning((object)($"[LCCrosshair] 设置面板缺少模板行,放弃注入。slider={(Object)(object)val != (Object)null} toggle={(Object)(object)val2 != (Object)null} " + $"dropdown={(Object)(object)val3 != (Object)null} optionTypes=[{stringBuilder}]"));
				return;
			}
			_cjk = DetectCjk(val3);
			Transform val5 = panel.Find("CrosshairSettingsPanel");
			Scene scene;
			if ((Object)(object)val5 == (Object)null)
			{
				ManualLogSource log = CrosshairPlugin.Log;
				string[] obj4 = new string[5]
				{
					"[LCCrosshair] 发现设置面板 '",
					((Object)panel).name,
					"' (场景 ",
					null,
					null
				};
				scene = ((Component)panel).gameObject.scene;
				obj4[3] = ((Scene)(ref scene)).name;
				obj4[4] = "),尝试注入";
				log.LogInfo((object)string.Concat(obj4));
			}
			if ((Object)(object)val5 != (Object)null)
			{
				CrosshairPageTag component = ((Component)val5).GetComponent<CrosshairPageTag>();
				if ((Object)(object)component != (Object)null && component.BuiltChinese == _cjk)
				{
					_settledPanels.Add(instanceID);
					return;
				}
				CrosshairPlugin.Log.LogInfo((object)"[LCCrosshair] 界面语言环境变化,重建准星设置页");
				Object.Destroy((Object)(object)((Component)val5).gameObject);
				_settledPanels.Remove(instanceID);
			}
			Transform val6 = panel.Find("CrosshairOpenButton");
			if ((Object)(object)val6 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val6).gameObject);
			}
			Sprite onSprite = null;
			Sprite offSprite = null;
			SettingsOption component2 = val2.GetComponent<SettingsOption>();
			if ((Object)(object)component2 != (Object)null)
			{
				onSprite = component2.enabledImage;
				offSprite = component2.disabledImage;
			}
			Transform val7 = panel.Find("KeybindingsButton");
			Transform val8 = panel.Find("KeybindsPanel");
			if ((Object)(object)val7 == (Object)null || (Object)(object)val8 == (Object)null)
			{
				_settledPanels.Add(instanceID);
				CrosshairPlugin.Log.LogWarning((object)"[LCCrosshair] 未找到 KeybindingsButton/KeybindsPanel,放弃注入");
				return;
			}
			try
			{
				BuildUI(panel, val7, val8, val, val2, val3, onSprite, offSprite);
				_settledPanels.Add(instanceID);
				ManualLogSource log2 = CrosshairPlugin.Log;
				string[] obj5 = new string[5] { "[LCCrosshair] 已注入原生设置界面: ", null, null, null, null };
				scene = ((Component)panel).gameObject.scene;
				obj5[1] = ((Scene)(ref scene)).name;
				obj5[2] = " (语言: ";
				obj5[3] = (_cjk ? "中文" : "English");
				obj5[4] = ")";
				log2.LogInfo((object)string.Concat(obj5));
			}
			catch (Exception arg)
			{
				_settledPanels.Add(instanceID);
				CrosshairPlugin.Log.LogWarning((object)$"[LCCrosshair] 注入面板 '{((Object)panel).name}' 失败(不影响准星本身): {arg}");
			}
		}

		private List<Action> BuildUI(Transform panel, Transform kbButton, Transform kbPanel, GameObject sliderRow, GameObject toggleRow, GameObject dropdownRow, Sprite onSprite, Sprite offSprite)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			//IL_02af: 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_08e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ee: Expected O, but got Unknown
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f6: Expected O, but got Unknown
			//IL_08fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0906: Unknown result type (might be due to invalid IL or missing references)
			//IL_0912: Unknown result type (might be due to invalid IL or missing references)
			//IL_0929: Unknown result type (might be due to invalid IL or missing references)
			//IL_092e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0958: Unknown result type (might be due to invalid IL or missing references)
			//IL_0962: Expected O, but got Unknown
			List<Action> refresh = new List<Action>();
			GameObject page = Object.Instantiate<GameObject>(((Component)kbPanel).gameObject, panel, false);
			((Object)page).name = "CrosshairSettingsPanel";
			StripGameScripts(page);
			page.SetActive(false);
			page.AddComponent<AutoCloseWhenParentHidden>().Panel = page;
			SetText(page.transform.Find("Controls (1)"), T("准星设置", "Crosshair Settings"));
			Transform obj = page.transform.Find("Back");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val != (Object)null)
			{
				PrepareClone(val);
				Button component = val.GetComponent<Button>();
				if ((Object)(object)component != (Object)null)
				{
					((UnityEvent)component.onClick).AddListener((UnityAction)delegate
					{
						page.SetActive(false);
					});
				}
				SetText(val.transform, T("返回", "Back"));
			}
			Transform obj2 = page.transform.Find("SetDefault");
			GameObject val2 = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if ((Object)(object)val2 != (Object)null)
			{
				PrepareClone(val2);
				Button component2 = val2.GetComponent<Button>();
				if ((Object)(object)component2 != (Object)null)
				{
					((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
					{
						ResetToDefaults(refresh);
					});
				}
				SetText(val2.transform, T("恢复默认", "Reset"));
			}
			Transform obj3 = page.transform.Find("Scroll View/Viewport/Content");
			RectTransform val3 = (RectTransform)(object)((obj3 is RectTransform) ? obj3 : null);
			if ((Object)(object)val3 == (Object)null)
			{
				Object.Destroy((Object)(object)page);
				throw new InvalidOperationException("未找到设置页滚动容器 Scroll View/Viewport/Content");
			}
			Transform val4 = ((Transform)val3).Find("RemapKeysContainer");
			if ((Object)(object)val4 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
			val3.anchorMin = new Vector2(0f, 1f);
			val3.anchorMax = new Vector2(1f, 1f);
			val3.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup obj4 = ((Component)val3).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj4).spacing = 16f;
			((LayoutGroup)obj4).padding = new RectOffset(18, 18, 8, 8);
			((Component)val3).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			ScrollRect componentInChildren = page.GetComponentInChildren<ScrollRect>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.horizontal = false;
				if ((Object)(object)componentInChildren.content != (Object)null)
				{
					componentInChildren.content.anchoredPosition = new Vector2(0f, componentInChildren.content.anchoredPosition.y);
				}
			}
			if (_zhButNoFont && !ReadFontHintDismissedFromDisk())
			{
				AddFontHint(val3, dropdownRow);
			}
			_ = _plugin;
			AddDropdown(val3, dropdownRow, T("样式", "Style"), StyleLabels(), delegate(int i)
			{
				Cfg.Style.Value = (CrosshairStyle)i;
			}, () => (int)Cfg.Style.Value, refresh);
			AddDropdown(val3, dropdownRow, T("颜色", "Color"), ColorLabels(), delegate(int i)
			{
				Cfg.ColorHex.Value = ColorPresets[Mathf.Clamp(i, 0, ColorPresets.Length - 1)].Hex;
			}, ColorIndex, refresh, (int i) => i < 0, T("自定义", "Custom"));
			AddSlider(val3, sliderRow, 0.05f, 1f, whole: false, T("不透明度", "Opacity"), delegate(float v)
			{
				Cfg.Opacity.Value = v;
			}, () => Cfg.Opacity.Value, (float v) => string.Format(T("不透明度 {0:P0}", "Opacity {0:P0}"), v), refresh);
			AddDropdown(val3, dropdownRow, T("轮廓", "Outline"), new string[3]
			{
				T("无", "None"),
				T("外框", "Outline"),
				"FULL OUTLINE"
			}, delegate(int i)
			{
				Cfg.Outline.Value = (OutlineMode)i;
			}, () => (int)Cfg.Outline.Value, refresh);
			AddSlider(val3, sliderRow, 1f, 10f, whole: true, T("粗细", "Thickness"), delegate(float v)
			{
				Cfg.Thickness.Value = (int)v;
			}, () => Cfg.Thickness.Value, (float v) => string.Format("{0} {1}", T("粗细", "Thickness"), (int)v), refresh);
			AddToggle(val3, toggleRow, T("中心点", "Center dot"), delegate(bool v)
			{
				Cfg.CenterDot.Value = v;
			}, () => Cfg.CenterDot.Value, onSprite, offSprite, refresh);
			AddSlider(val3, sliderRow, 1f, 30f, whole: true, T("长度", "Length"), delegate(float v)
			{
				Cfg.Length.Value = (int)v;
			}, () => Cfg.Length.Value, (float v) => string.Format("{0} {1}", T("长度", "Length"), (int)v), refresh);
			AddSlider(val3, sliderRow, 0f, 40f, whole: true, T("间隙", "Gap"), delegate(float v)
			{
				Cfg.Gap.Value = (int)v;
			}, () => Cfg.Gap.Value, (float v) => string.Format("{0} {1}", T("间隙", "Gap"), (int)v), refresh);
			AddToggle(val3, toggleRow, T("T形准星", "T-shape"), delegate(bool v)
			{
				Cfg.TShape.Value = v;
			}, () => Cfg.TShape.Value, onSprite, offSprite, refresh);
			AddSlider(val3, sliderRow, 0f, 30f, whole: true, T("动态·移动外扩", "Move spread"), delegate(float v)
			{
				Cfg.MoveSpread.Value = (int)v;
			}, () => Cfg.MoveSpread.Value, (float v) => string.Format("{0} {1}", T("移动外扩", "Move spread"), (int)v), refresh);
			AddSlider(val3, sliderRow, 0f, 50f, whole: true, T("动态·射击外扩", "Fire spread"), delegate(float v)
			{
				Cfg.FireSpread.Value = (int)v;
			}, () => Cfg.FireSpread.Value, (float v) => string.Format("{0} {1}", T("射击外扩", "Fire spread"), (int)v), refresh);
			AddSlider(val3, sliderRow, 0.1f, 2f, whole: false, T("动态·射击回缩(秒)", "Fire decay (s)"), delegate(float v)
			{
				Cfg.FireDecay.Value = v;
			}, () => Cfg.FireDecay.Value, (float v) => string.Format("{0} {1:0.00}s", T("射击回缩", "Fire decay"), v), refresh);
			AddToggle(val3, toggleRow, T("动态·下蹲减扩", "Crouch reduces spread"), delegate(bool v)
			{
				Cfg.CrouchReduce.Value = v;
			}, () => Cfg.CrouchReduce.Value, onSprite, offSprite, refresh);
			GameObject obj5 = Object.Instantiate<GameObject>(((Component)kbButton).gameObject, panel, false);
			((Object)obj5).name = "CrosshairOpenButton";
			PrepareClone(obj5);
			SetText(obj5.transform, T("> 准星设置 Crosshair", "> Crosshair Settings"));
			RectTransform val5 = (RectTransform)obj5.transform;
			RectTransform val6 = (RectTransform)kbButton;
			val5.anchoredPosition = val6.anchoredPosition - new Vector2(0f, (val6.sizeDelta.y + val5.sizeDelta.y) * 0.5f + 1f);
			Button component3 = obj5.GetComponent<Button>();
			if ((Object)(object)component3 != (Object)null)
			{
				((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
				{
					page.SetActive(true);
				});
			}
			obj5.transform.SetSiblingIndex(kbPanel.GetSiblingIndex());
			page.transform.SetAsLastSibling();
			CrosshairPreview.Create(page);
			page.AddComponent<CrosshairPageTag>().BuiltChinese = _cjk;
			return refresh;
		}

		private void AddSlider(RectTransform parent, GameObject template, float min, float max, bool whole, string label, Action<float> set, Func<float> get, Func<float, string> fmt, List<Action> refresh)
		{
			GameObject val = Object.Instantiate<GameObject>(template, (Transform)(object)parent, false);
			((Object)val).name = "CrosshairRow_" + label;
			PrepareClone(val);
			Slider slider = val.GetComponentInChildren<Slider>(true);
			if ((Object)(object)slider == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Neutralize(slider.onValueChanged);
			slider.minValue = min;
			slider.maxValue = max;
			slider.wholeNumbers = whole;
			TMP_Text text = val.GetComponentInChildren<TMP_Text>(true);
			((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v)
			{
				set(v);
				Cfg.File.Save();
				if ((Object)(object)text != (Object)null)
				{
					text.text = fmt(v);
				}
			});
			Sync();
			refresh.Add(Sync);
			void Sync()
			{
				slider.SetValueWithoutNotify(Mathf.Clamp(get(), min, max));
				if ((Object)(object)text != (Object)null)
				{
					text.text = fmt(get());
				}
			}
		}

		private void AddToggle(RectTransform parent, GameObject template, string label, Action<bool> set, Func<bool> get, Sprite onSprite, Sprite offSprite, List<Action> refresh)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(template, (Transform)(object)parent, false);
			((Object)val).name = "CrosshairRow_" + label;
			PrepareClone(val);
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Neutralize(component.onClick);
			Transform obj = val.transform.Find("Background/Checkmark");
			Image check = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			TMP_Text text = val.GetComponentInChildren<TMP_Text>(true);
			bool useSprites = (Object)(object)check != (Object)null && (Object)(object)onSprite != (Object)null && (Object)(object)offSprite != (Object)null;
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				set(!get());
				Cfg.File.Save();
				Sync();
			});
			Sync();
			refresh.Add(Sync);
			void Sync()
			{
				if (useSprites)
				{
					check.sprite = (get() ? onSprite : offSprite);
				}
				else if ((Object)(object)check != (Object)null)
				{
					((Component)check).gameObject.SetActive(get());
				}
				if ((Object)(object)text != (Object)null)
				{
					text.text = label;
				}
			}
		}

		private void AddDropdown(RectTransform parent, GameObject template, string label, string[] options, Action<int> set, Func<int> get, List<Action> refresh, Func<int, bool> customWhen = null, string customText = null)
		{
			GameObject val = Object.Instantiate<GameObject>(template, (Transform)(object)parent, false);
			((Object)val).name = "CrosshairRow_" + label;
			PrepareClone(val);
			TMP_Dropdown dd = val.GetComponent<TMP_Dropdown>();
			if ((Object)(object)dd == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Neutralize(dd.onValueChanged);
			dd.ClearOptions();
			dd.AddOptions(new List<string>(options));
			if ((Object)(object)dd.captionText == (Object)null)
			{
				TMP_Dropdown obj = dd;
				Transform obj2 = val.transform.Find("Label");
				obj.captionText = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
			}
			Transform obj3 = val.transform.Find("Label2");
			TMP_Text val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = label;
			}
			((UnityEvent<int>)(object)dd.onValueChanged).AddListener((UnityAction<int>)delegate(int i)
			{
				set(i);
				Cfg.File.Save();
			});
			Sync();
			refresh.Add(Sync);
			void Sync()
			{
				int num = get();
				dd.SetValueWithoutNotify(Mathf.Clamp(num, 0, options.Length - 1));
				dd.RefreshShownValue();
				if (customWhen != null && customWhen(num) && (Object)(object)dd.captionText != (Object)null && customText != null)
				{
					dd.captionText.text = customText;
				}
			}
		}

		private void AddFontHint(RectTransform content, GameObject templateRow)
		{
			//IL_003a: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00e7: Expected O, but got Unknown
			TMP_Text componentInChildren = templateRow.GetComponentInChildren<TMP_Text>(true);
			GameObject val = new GameObject("CrosshairFontHint", new Type[3]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI),
				typeof(Button)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)content, false);
			val2.sizeDelta = new Vector2(0f, 72f);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)component).font = componentInChildren.font;
			}
			((TMP_Text)component).fontSize = 13f;
			((Graphic)component).color = new Color(1f, 0.72f, 0.15f, 0.95f);
			((TMP_Text)component).text = "Steam language is Chinese, but the current font cannot render Chinese (and no FontPatcher / LCChineseFont is installed), so this page falls back to English.\nInstall LCChineseFont to enable Chinese — click this text to open its Thunderstore page.\nTo hide this hint, set FontHintDismissed = true in BepInEx/config/syrupdesu.lccrosshair.cfg, then reopen this page.";
			Button component2 = val.GetComponent<Button>();
			((Selectable)component2).targetGraphic = null;
			ButtonClickedEvent onClick = component2.onClick;
			object obj = <>c.<>9__26_0;
			if (obj == null)
			{
				UnityAction val3 = delegate
				{
					try
					{
						Application.OpenURL("https://thunderstore.io/c/lethal-company/p/Syrupdesu/LCChineseFont/");
					}
					catch
					{
					}
				};
				<>c.<>9__26_0 = val3;
				obj = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private static bool ReadFontHintDismissedFromDisk()
		{
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "syrupdesu.lccrosshair.cfg");
				if (!File.Exists(path))
				{
					return false;
				}
				string[] array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (!text.StartsWith("FontHintDismissed", StringComparison.OrdinalIgnoreCase))
					{
						continue;
					}
					int num = text.IndexOf('=');
					if (num >= 0)
					{
						bool num2 = text.Substring(num + 1).Trim().Equals("true", StringComparison.OrdinalIgnoreCase);
						if (num2 && !Cfg.FontHintDismissed.Value)
						{
							Cfg.FontHintDismissed.Value = true;
						}
						return num2;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private int ColorIndex()
		{
			string b = (Cfg.ColorHex.Value ?? "").Trim();
			for (int i = 0; i < ColorPresets.Length; i++)
			{
				if (string.Equals(ColorPresets[i].Hex, b, StringComparison.OrdinalIgnoreCase))
				{
					return i;
				}
			}
			return -1;
		}

		private string[] StyleLabels()
		{
			return new string[9]
			{
				T("静态十字", "Static Cross"),
				T("静态圆形", "Static Circle"),
				T("静态方块", "Static Square"),
				T("仅限圆点", "Dot Only"),
				T("动态十字", "Dynamic Cross"),
				T("动态圆形", "Dynamic Circle"),
				T("动态十字(经典)", "Dynamic Cross (Classic)"),
				T("动态十字[旧版/射击反馈]", "Dynamic Cross (Legacy)"),
				T("动态四边形", "Dynamic Quad")
			};
		}

		private string[] ColorLabels()
		{
			string[] array = new string[ColorPresets.Length];
			for (int i = 0; i < ColorPresets.Length; i++)
			{
				array[i] = T(ColorPresets[i].Cn, ColorPresets[i].En);
			}
			return array;
		}

		private void ResetToDefaults(List<Action> refresh)
		{
			Cfg.ResetToDefaults();
			Cfg.File.Save();
			foreach (Action item in refresh)
			{
				item();
			}
		}

		private string T(string cn, string en)
		{
			if (!_cjk)
			{
				return en;
			}
			return cn;
		}

		private static bool SteamChinese()
		{
			string text = SteamLang.Detect();
			switch (text)
			{
			default:
				return text.StartsWith("zh");
			case "schinese":
			case "tchinese":
				return true;
			case null:
				return false;
			}
		}

		private static bool FontModInstalled()
		{
			try
			{
				string[] files = Directory.GetFiles(Paths.PluginPath, "*.dll", SearchOption.TopDirectoryOnly);
				for (int i = 0; i < files.Length; i++)
				{
					string text = Path.GetFileName(files[i]).ToLowerInvariant();
					if (text.Contains("fontpatcher") || text.Contains("lcchinesefont"))
					{
						return true;
					}
				}
				files = Directory.GetDirectories(Paths.PluginPath, "*", SearchOption.TopDirectoryOnly);
				for (int i = 0; i < files.Length; i++)
				{
					string text2 = Path.GetFileName(files[i].TrimEnd('/', '\\')).ToLowerInvariant();
					if (text2.Contains("fontpatcher") || text2.Contains("lcchinesefont"))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private bool DetectCjk(GameObject fontSourceRow)
		{
			bool flag = FontRendersCjk(GetRowFont(fontSourceRow)) || FontModInstalled();
			bool flag2 = SteamChinese();
			_zhButNoFont = flag2 && !flag;
			if (_zhButNoFont && !_loggedFontHint)
			{
				_loggedFontHint = true;
				CrosshairPlugin.Log.LogWarning((object)"[LCCrosshair] Steam 语言为中文,但当前字体无法渲染中文(也未检测到 FontPatcher/LCChineseFont),设置界面回退为英文。推荐安装 LCChineseFont: https://thunderstore.io/c/lethal-company/p/Syrupdesu/LCChineseFont/");
			}
			return flag;
		}

		private static TMP_FontAsset GetRowFont(GameObject row)
		{
			if (!((Object)(object)row == (Object)null))
			{
				TMP_Text componentInChildren = row.GetComponentInChildren<TMP_Text>(true);
				if (componentInChildren == null)
				{
					return null;
				}
				return componentInChildren.font;
			}
			return null;
		}

		private static bool FontRendersCjk(TMP_FontAsset font, int depth = 0)
		{
			if ((Object)(object)font == (Object)null || depth > 3)
			{
				return false;
			}
			try
			{
				if (font.HasCharacter('中', true, true))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				List<TMP_FontAsset> fallbackFontAssetTable = font.fallbackFontAssetTable;
				if (fallbackFontAssetTable != null)
				{
					foreach (TMP_FontAsset item in fallbackFontAssetTable)
					{
						if ((Object)(object)item != (Object)null && FontRendersCjk(item, depth + 1))
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				List<TMP_FontAsset> fallbackFontAssets = TMP_Settings.fallbackFontAssets;
				if (fallbackFontAssets != null)
				{
					foreach (TMP_FontAsset item2 in fallbackFontAssets)
					{
						if ((Object)(object)item2 != (Object)null && FontRendersCjk(item2, depth + 1))
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static Transform FindSettingsPanel(Transform from)
		{
			Transform val = from;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val.Find("KeybindsPanel") != (Object)null && (Object)(object)val.Find("Confirm") != (Object)null)
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		private static Transform FindDeep(Transform root, string name)
		{
			if (((Object)root).name == name)
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindDeep(root.GetChild(i), name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static void PrepareClone(GameObject row)
		{
			StripGameScripts(row);
			Button component = row.GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				Neutralize(component.onClick);
			}
			Slider componentInChildren = row.GetComponentInChildren<Slider>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Neutralize(componentInChildren.onValueChanged);
			}
			TMP_Dropdown component2 = row.GetComponent<TMP_Dropdown>();
			if ((Object)(object)component2 != (Object)null)
			{
				Neutralize(component2.onValueChanged);
			}
		}

		private static void StripGameScripts(GameObject root)
		{
			Assembly assembly = typeof(GrabbableObject).Assembly;
			Behaviour[] componentsInChildren = root.GetComponentsInChildren<Behaviour>(true);
			foreach (Behaviour val in componentsInChildren)
			{
				if (((object)val).GetType().Assembly == assembly)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static void Neutralize(ButtonClickedEvent ev)
		{
			if (ev != null)
			{
				for (int i = 0; i < ((UnityEventBase)ev).GetPersistentEventCount(); i++)
				{
					((UnityEventBase)ev).SetPersistentListenerState(i, (UnityEventCallState)0);
				}
			}
		}

		private static void Neutralize(SliderEvent ev)
		{
			if (ev != null)
			{
				for (int i = 0; i < ((UnityEventBase)ev).GetPersistentEventCount(); i++)
				{
					((UnityEventBase)ev).SetPersistentListenerState(i, (UnityEventCallState)0);
				}
			}
		}

		private static void Neutralize(DropdownEvent ev)
		{
			if (ev != null)
			{
				for (int i = 0; i < ((UnityEventBase)ev).GetPersistentEventCount(); i++)
				{
					((UnityEventBase)ev).SetPersistentListenerState(i, (UnityEventCallState)0);
				}
			}
		}

		private static void SetText(Transform root, string text)
		{
			TMP_Text val = ((root != null) ? ((Component)root).GetComponentInChildren<TMP_Text>(true) : null);
			if ((Object)(object)val != (Object)null)
			{
				val.text = text;
			}
		}
	}
	internal sealed class CrosshairPageTag : MonoBehaviour
	{
		internal bool BuiltChinese;
	}
	internal static class SteamLang
	{
		private static bool _tried;

		private static string _cached;

		internal static string Detect()
		{
			if (_tried)
			{
				return _cached;
			}
			_tried = true;
			try
			{
				string gameLanguage = SteamApps.GameLanguage;
				if (!string.IsNullOrEmpty(gameLanguage))
				{
					return _cached = gameLanguage.ToLowerInvariant();
				}
			}
			catch
			{
			}
			RegistryView[] array = new RegistryView[3]
			{
				RegistryView.Default,
				RegistryView.Registry64,
				RegistryView.Registry32
			};
			foreach (RegistryView view in array)
			{
				try
				{
					using RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, view);
					using RegistryKey registryKey2 = registryKey.OpenSubKey("Software\\Valve\\Steam");
					string text = registryKey2?.GetValue("Language") as string;
					if (!string.IsNullOrEmpty(text))
					{
						return _cached = text.ToLowerInvariant();
					}
				}
				catch
				{
				}
			}
			return _cached = null;
		}
	}
}