Decompiled source of PeakObjectIdentifier v1.4.10

plugins/PeakObjectIdentifier/PeakObjectIdentifier.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakObjectIdentifier")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PeakObjectIdentifier")]
[assembly: AssemblyTitle("PeakObjectIdentifier")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PeakObjectIdentifier
{
	public enum Classification
	{
		None,
		Terrain,
		Normal,
		Luggage,
		FakeLuggage,
		HostileUninteractive,
		Special,
		Esoteric,
		HostileInteractive
	}
	public class CategoryConfig
	{
		public ConfigEntry<bool> Enabled;

		public ConfigEntry<bool> Fill;

		public ConfigEntry<string> ColorHex;
	}
	[BepInPlugin("com.josephtechnology.peak.objectidentifier", "Peak Object Identifier", "1.3.0")]
	public class PeakObjectIdentifierPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.josephtechnology.peak.objectidentifier";

		public const string PluginName = "Peak Object Identifier";

		public const string PluginVersion = "1.3.0";

		public ConfigEntry<bool> EnableMod;

		public ConfigEntry<bool> ShowCrosshairTarget;

		public ConfigEntry<bool> EnableHighlight;

		public ConfigEntry<bool> ShowBoxLabels;

		public ConfigEntry<bool> IncludeComponentNames;

		public ConfigEntry<bool> AutoInjectSettingsTab;

		public ConfigEntry<float> TargetLabelY;

		public ConfigEntry<float> MaxDistance;

		public ConfigEntry<float> ScanInterval;

		public ConfigEntry<float> BoxThickness;

		public ConfigEntry<float> HighlightDistance;

		public ConfigEntry<float> MaxColliderSize;

		public ConfigEntry<float> FillAlpha;

		public ConfigEntry<int> MaxHighlights;

		public ConfigEntry<int> MaxSettingsInjectAttempts;

		public ConfigEntry<float> SettingsInjectInterval;

		public ConfigEntry<bool> EnableMinimap;

		public ConfigEntry<bool> MinimapRotate;

		public ConfigEntry<float> MinimapSize;

		public ConfigEntry<float> MinimapRange;

		public ConfigEntry<KeyCode> OpenSettingsKey;

		public ConfigEntry<KeyCode> ToggleEspKey;

		public ConfigEntry<KeyCode> SpawnFakeKey;

		public ConfigEntry<KeyCode> SpawnHostileKey;

		public ConfigEntry<KeyCode> SpawnRockKey;

		public ConfigEntry<KeyCode> DebugLogKey;

		public Dictionary<Classification, CategoryConfig> Categories = new Dictionary<Classification, CategoryConfig>();

		public Dictionary<Classification, ConfigEntry<string>> Patterns = new Dictionary<Classification, ConfigEntry<string>>();

		public Dictionary<Classification, Regex> PatternRegexes = new Dictionary<Classification, Regex>();

		public static readonly Classification[] ClassifyPriority = new Classification[8]
		{
			Classification.FakeLuggage,
			Classification.Esoteric,
			Classification.Special,
			Classification.HostileInteractive,
			Classification.HostileUninteractive,
			Classification.Luggage,
			Classification.Normal,
			Classification.Terrain
		};

		public static readonly Classification[] UiOrder = new Classification[8]
		{
			Classification.Terrain,
			Classification.Normal,
			Classification.Luggage,
			Classification.FakeLuggage,
			Classification.HostileUninteractive,
			Classification.Special,
			Classification.Esoteric,
			Classification.HostileInteractive
		};

		public static PeakObjectIdentifierPlugin Instance { get; private set; }

		public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			Instance = this;
			BindConfig();
			RebuildRegexes();
			((Component)this).gameObject.AddComponent<HighlighterController>();
			((Component)this).gameObject.AddComponent<SettingsMenuInjector>();
			Logger.LogInfo((object)"Peak Object Identifier v1.3.0 loaded.");
			Logger.LogInfo((object)"Fallback settings hotkey: F10");
		}

		private void BindConfig()
		{
			EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Master switch.");
			ShowCrosshairTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCrosshairTarget", true, "Shows object under crosshair.");
			TargetLabelY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TargetLabelY", 90f, "Vertical position of target label.");
			MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxTargetDistance", 100f, "Crosshair raycast distance.");
			ScanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScanInterval", 1.5f, "Scan interval for highlights. Higher value = better performance.");
			EnableHighlight = ((BaseUnityPlugin)this).Config.Bind<bool>("Highlight", "EnableHighlight", true, "Enables highlight ESP.");
			MaxHighlights = ((BaseUnityPlugin)this).Config.Bind<int>("Highlight", "MaxHighlights", 48, "Maximum highlighted objects.");
			BoxThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Highlight", "BoxThickness", 2f, "ESP outline thickness.");
			HighlightDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Highlight", "HighlightDistance", 45f, "Highlight range.");
			MaxColliderSize = ((BaseUnityPlugin)this).Config.Bind<float>("Highlight", "MaxColliderSize", 12f, "Ignore large colliders. Helps skip terrain/rocks.");
			ShowBoxLabels = ((BaseUnityPlugin)this).Config.Bind<bool>("Highlight", "ShowBoxLabels", false, "Shows text labels over ESP boxes.");
			FillAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("Highlight", "FillAlpha", 0.18f, "Default fill alpha when fill is enabled.");
			IncludeComponentNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Highlight", "IncludeComponentNames", false, "Includes component names in matching. Expensive.");
			AutoInjectSettingsTab = ((BaseUnityPlugin)this).Config.Bind<bool>("SettingsMenu", "AutoInjectSettingsTab", true, "Attempts to add Mods button.");
			SettingsInjectInterval = ((BaseUnityPlugin)this).Config.Bind<float>("SettingsMenu", "SettingsInjectInterval", 5f, "Settings injection scan interval.");
			MaxSettingsInjectAttempts = ((BaseUnityPlugin)this).Config.Bind<int>("SettingsMenu", "MaxSettingsInjectAttempts", 8, "Max settings injection attempts per scene.");
			EnableMinimap = ((BaseUnityPlugin)this).Config.Bind<bool>("Minimap", "EnableMinimap", false, "Simple minimap/radar. Disabled by default.");
			MinimapRotate = ((BaseUnityPlugin)this).Config.Bind<bool>("Minimap", "RotateWithCamera", true, "Rotates minimap with camera.");
			MinimapSize = ((BaseUnityPlugin)this).Config.Bind<float>("Minimap", "Size", 200f, "Minimap size in pixels.");
			MinimapRange = ((BaseUnityPlugin)this).Config.Bind<float>("Minimap", "Range", 80f, "Minimap display range.");
			OpenSettingsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "OpenSettingsKey", (KeyCode)291, "Opens Mods panel.");
			ToggleEspKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ToggleEspKey", (KeyCode)290, "Toggle ESP.");
			SpawnFakeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnFakeKey", (KeyCode)287, "Spawn fake luggage test.");
			SpawnHostileKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnHostileKey", (KeyCode)288, "Spawn hostile test.");
			SpawnRockKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "SpawnRockKey", (KeyCode)289, "Spawn rock occluder.");
			DebugLogKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "DebugLogKey", (KeyCode)286, "Debug log.");
			BindCategory(Classification.Terrain, enabled: false, fill: false, "#808080FF", "terrain,ground,rock,stone,cliff,mountain,floor,wall,cave");
			BindCategory(Classification.Normal, enabled: true, fill: false, "#3B82F6FF", "normal,prop,crate,box,barrel,container,item,interactable,grab,carry,tool,equipment");
			BindCategory(Classification.Luggage, enabled: true, fill: false, "#00FF00FF", "luggage,suitcase,bag,case");
			BindCategory(Classification.FakeLuggage, enabled: true, fill: false, "#FF0000FF", "fake.*luggage,luggage.*fake,decoy.*bag,mimic.*bag,sus.*case,trap.*bag");
			BindCategory(Classification.HostileUninteractive, enabled: true, fill: false, "#FF7F00FF", "thorn,urchin,spike,trap,hazard,cactus,bramble,sting,poison");
			BindCategory(Classification.Special, enabled: true, fill: false, "#FFD700FF", "amulet,ancient,relic,artifact,treasure,shrine,idol,golden,sacred,altar");
			BindCategory(Classification.Esoteric, enabled: true, fill: false, "#FFD700FF", "esoteric,occult,mystic,arcane,ritual,secret,eldritch");
			BindCategory(Classification.HostileInteractive, enabled: true, fill: false, "#FF2222FF", "scoutmaster,bee,wasps,wasp,hornet,swarm,enemy,hostile,monster,creature");
		}

		private void BindCategory(Classification classification, bool enabled, bool fill, string color, string pattern)
		{
			string text = classification.ToString();
			CategoryConfig value = new CategoryConfig
			{
				Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Categories", text + "_Enabled", enabled, "Enable " + text + " highlighting."),
				Fill = ((BaseUnityPlugin)this).Config.Bind<bool>("Categories", text + "_Fill", fill, "Fill " + text + " highlight boxes."),
				ColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Categories", text + "_Color", color, "Color for " + text + ". Use #RRGGBB or #RRGGBBAA.")
			};
			Categories[classification] = value;
			Patterns[classification] = ((BaseUnityPlugin)this).Config.Bind<string>("Patterns", text + "_Patterns", pattern, "Patterns for " + text + ".");
		}

		public void RebuildRegexes()
		{
			foreach (KeyValuePair<Classification, ConfigEntry<string>> pattern in Patterns)
			{
				PatternRegexes[pattern.Key] = BuildRegex(pattern.Value.Value);
			}
			ObjectClassifier.ClearCache();
		}

		private Regex BuildRegex(string pattern)
		{
			try
			{
				if (string.IsNullOrWhiteSpace(pattern))
				{
					return null;
				}
				pattern = pattern.Replace(';', '|').Replace(',', '|');
				if (string.IsNullOrWhiteSpace(pattern.Replace("|", string.Empty)))
				{
					return null;
				}
				return new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Invalid pattern '" + pattern + "': " + ex.Message));
				return null;
			}
		}

		public bool IsCategoryEnabled(Classification classification)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (classification == Classification.None)
			{
				return false;
			}
			if (!Categories.TryGetValue(classification, out var value))
			{
				return false;
			}
			if (!value.Enabled.Value)
			{
				return false;
			}
			return GetColor(classification).a > 0.01f;
		}

		public bool AnyHighlightCategoryEnabled()
		{
			foreach (KeyValuePair<Classification, CategoryConfig> category in Categories)
			{
				if (IsCategoryEnabled(category.Key))
				{
					return true;
				}
			}
			return false;
		}

		public Color GetColor(Classification classification)
		{
			//IL_0010: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!Categories.TryGetValue(classification, out var value))
			{
				return Color.white;
			}
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString(value.ColorHex.Value ?? string.Empty, ref result))
			{
				return GetDefaultColor(classification);
			}
			return result;
		}

		public Color GetFillColor(Classification classification)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Color color = GetColor(classification);
			if (color.a > 0.95f)
			{
				color.a = Mathf.Clamp01(FillAlpha.Value);
			}
			return color;
		}

		public Color GetDefaultColor(Classification classification)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0067: 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_009b: 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_00cf: 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)
			return (Color)(classification switch
			{
				Classification.Terrain => new Color(0.5f, 0.5f, 0.5f, 1f), 
				Classification.Normal => new Color(0.23f, 0.51f, 0.96f, 1f), 
				Classification.Luggage => Color.green, 
				Classification.FakeLuggage => Color.red, 
				Classification.HostileUninteractive => new Color(1f, 0.5f, 0f, 1f), 
				Classification.Special => new Color(1f, 0.84f, 0f, 1f), 
				Classification.Esoteric => new Color(1f, 0.84f, 0f, 1f), 
				Classification.HostileInteractive => new Color(1f, 0.13f, 0.13f, 1f), 
				_ => Color.white, 
			});
		}
	}
	public static class Utils
	{
		private static Font _defaultFont;

		private static Font _gameFont;

		private static Font _creditFont;

		private static Color? _tabColor;

		public static Color TabColor
		{
			get
			{
				//IL_0045: 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 (!_tabColor.HasValue)
				{
					Color value = default(Color);
					if (!ColorUtility.TryParseHtmlString("#1c4b82", ref value))
					{
						((Color)(ref value))..ctor(0.11f, 0.29f, 0.51f, 1f);
					}
					_tabColor = value;
				}
				return _tabColor.Value;
			}
		}

		public static Font DefaultFont
		{
			get
			{
				if ((Object)(object)_defaultFont == (Object)null)
				{
					try
					{
						_defaultFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
					}
					catch
					{
						try
						{
							_defaultFont = Font.CreateDynamicFontFromOSFont("Arial", 14);
						}
						catch
						{
							_defaultFont = null;
						}
					}
				}
				return _defaultFont;
			}
		}

		public static Font GameFont
		{
			get
			{
				if ((Object)(object)_gameFont == (Object)null)
				{
					_gameFont = FindFont(new string[1] { "Darumadrop" }, new string[1] { "Darumadrop One" });
				}
				return _gameFont;
			}
		}

		public static Font CreditFont
		{
			get
			{
				if ((Object)(object)_creditFont == (Object)null)
				{
					_creditFont = FindFont(new string[1] { "Josefin" }, new string[1] { "Josefin Sans" });
				}
				return _creditFont;
			}
		}

		private static Font FindFont(string[] containsNames, string[] osNames)
		{
			try
			{
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				foreach (Font val in array)
				{
					if (!((Object)(object)val == (Object)null) && ContainsAny(((Object)val).name, containsNames))
					{
						return val;
					}
				}
			}
			catch
			{
			}
			foreach (string text in osNames)
			{
				try
				{
					Font val2 = Font.CreateDynamicFontFromOSFont(text, 16);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
				catch
				{
				}
			}
			return DefaultFont;
		}

		public static bool ContainsAny(string value, params string[] terms)
		{
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			foreach (string value2 in terms)
			{
				if (!string.IsNullOrEmpty(value2) && value.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		public static string GetClassificationName(Classification classification)
		{
			return classification switch
			{
				Classification.Terrain => "Terrain", 
				Classification.Normal => "Normal Object", 
				Classification.Luggage => "Luggage", 
				Classification.FakeLuggage => "Fake Luggage", 
				Classification.HostileUninteractive => "Hostile Uninteractive Object", 
				Classification.Special => "Special Things", 
				Classification.Esoteric => "Esoteric Object", 
				Classification.HostileInteractive => "Hostile Interactive Object", 
				_ => "None", 
			};
		}
	}
	public static class ObjectClassifier
	{
		private sealed class CachedClassification
		{
			public float Time;

			public int NameHash;

			public Classification Classification;
		}

		private static readonly Dictionary<int, CachedClassification> Cache = new Dictionary<int, CachedClassification>();

		public static void ClearCache()
		{
			Cache.Clear();
		}

		public static Classification Classify(GameObject go)
		{
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)go == (Object)null)
			{
				return Classification.None;
			}
			int instanceID = ((Object)go).GetInstanceID();
			int num;
			try
			{
				num = ((Object)go).name?.GetHashCode() ?? 0;
			}
			catch
			{
				num = 0;
			}
			if (Cache.TryGetValue(instanceID, out var value) && value.NameHash == num && Time.unscaledTime - value.Time < 5f)
			{
				return value.Classification;
			}
			Classification classification = ClassifyInternal(go, instance);
			Cache[instanceID] = new CachedClassification
			{
				Time = Time.unscaledTime,
				NameHash = num,
				Classification = classification
			};
			if (Cache.Count > 4096)
			{
				Cache.Clear();
			}
			return classification;
		}

		private static Classification ClassifyInternal(GameObject go, PeakObjectIdentifierPlugin plugin)
		{
			string input = BuildHaystack(go);
			Classification[] classifyPriority = PeakObjectIdentifierPlugin.ClassifyPriority;
			foreach (Classification classification in classifyPriority)
			{
				if (plugin.PatternRegexes.TryGetValue(classification, out var value) && value != null && value.IsMatch(input))
				{
					return classification;
				}
			}
			return Classification.None;
		}

		private static string BuildHaystack(GameObject go)
		{
			StringBuilder stringBuilder = new StringBuilder(128);
			try
			{
				AppendHierarchyNames(go.transform, stringBuilder, 5);
				try
				{
					stringBuilder.Append(go.tag).Append(' ');
				}
				catch
				{
				}
				if ((Object)(object)PeakObjectIdentifierPlugin.Instance != (Object)null && PeakObjectIdentifierPlugin.Instance.IncludeComponentNames.Value)
				{
					Component[] components = go.GetComponents<Component>();
					for (int i = 0; i < components.Length && i < 8; i++)
					{
						if ((Object)(object)components[i] != (Object)null)
						{
							stringBuilder.Append(((object)components[i]).GetType().Name).Append(' ');
						}
					}
				}
			}
			catch
			{
			}
			return stringBuilder.ToString();
		}

		private static void AppendHierarchyNames(Transform t, StringBuilder sb, int depth)
		{
			if (!((Object)(object)t == (Object)null) && depth > 0)
			{
				if ((Object)(object)t.parent != (Object)null)
				{
					AppendHierarchyNames(t.parent, sb, depth - 1);
				}
				sb.Append(((Object)t).name).Append(' ');
			}
		}
	}
	public sealed class HighlightEntry
	{
		public GameObject GameObject;

		public Classification Classification;

		public Bounds? Bounds;

		public HighlightEntry(GameObject go, Classification classification)
		{
			GameObject = go;
			Classification = classification;
			Bounds = CalculateBounds(go);
		}

		private static Bounds? CalculateBounds(GameObject go)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00a4: 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_0070: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Bounds? result = null;
				Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>();
				foreach (Collider val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null) && val.enabled && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
					{
						if (result.HasValue)
						{
							Bounds value = result.Value;
							((Bounds)(ref value)).Encapsulate(val.bounds);
							result = value;
						}
						else
						{
							result = val.bounds;
						}
					}
				}
				if (!result.HasValue)
				{
					result = new Bounds(go.transform.position, Vector3.one * 0.75f);
				}
				return result;
			}
			catch
			{
				return new Bounds(go.transform.position, Vector3.one * 0.75f);
			}
		}
	}
	public class HighlighterController : MonoBehaviour
	{
		private Camera _camera;

		private Texture2D _pixel;

		private GUIStyle _hudStyle;

		private GUIStyle _boxStyle;

		private string _targetText = string.Empty;

		private float _nextScanTime;

		private float _nextTargetTime;

		private string _lastSceneName;

		private readonly List<HighlightEntry> _highlights = new List<HighlightEntry>();

		private readonly Collider[] _overlapBuffer = (Collider[])(object)new Collider[1024];

		public static HighlighterController Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			_pixel = MakePixelTexture();
		}

		private void Update()
		{
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.EnableMod.Value)
			{
				EnsureCamera();
				HandleHotkeys();
				if (Time.unscaledTime >= _nextScanTime)
				{
					_nextScanTime = Time.unscaledTime + Mathf.Max(0.25f, instance.ScanInterval.Value);
					ScanHighlights();
				}
				if (Time.unscaledTime >= _nextTargetTime)
				{
					_nextTargetTime = Time.unscaledTime + 0.1f;
					_targetText = GetTargetText();
				}
			}
		}

		private void OnGUI()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.EnableMod.Value && Event.current != null && (int)Event.current.type == 7)
			{
				EnsureStyles();
				GUI.depth = -1000;
				DrawTargetLabel();
				DrawHighlights();
				DrawMinimap();
			}
		}

		public void ForceScan()
		{
			ScanHighlights();
		}

		public void SpawnFakeTest()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			SpawnTestObject("FakeLuggage_Test", (PrimitiveType)3, PeakObjectIdentifierPlugin.Instance.GetColor(Classification.FakeLuggage));
		}

		public void SpawnHostileTest()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			SpawnTestObject("HostileInteractive_Test", (PrimitiveType)1, PeakObjectIdentifierPlugin.Instance.GetColor(Classification.HostileInteractive));
		}

		public void SpawnRockTest()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			EnsureCamera();
			if (!((Object)(object)_camera == (Object)null))
			{
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)val).name = "Rock_Occluder";
				val.transform.localScale = new Vector3(4f, 4f, 1f);
				val.transform.position = ((Component)_camera).transform.position + ((Component)_camera).transform.forward * 1.5f;
				TrySetColor(val, new Color(0.45f, 0.45f, 0.45f));
				Object.Destroy((Object)(object)val, 120f);
			}
		}

		private void HandleHotkeys()
		{
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if (KeyDown(instance.OpenSettingsKey))
			{
				SettingsMenuInjector.Instance?.TogglePanel();
			}
			if (KeyDown(instance.ToggleEspKey))
			{
				instance.EnableHighlight.Value = !instance.EnableHighlight.Value;
			}
			if (KeyDown(instance.SpawnFakeKey))
			{
				SpawnFakeTest();
			}
			if (KeyDown(instance.SpawnHostileKey))
			{
				SpawnHostileTest();
			}
			if (KeyDown(instance.SpawnRockKey))
			{
				SpawnRockTest();
			}
			if (KeyDown(instance.DebugLogKey))
			{
				ManualLogSource logger = instance.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("Target text: " + _targetText));
				}
				ManualLogSource logger2 = instance.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)("Camera: " + (((Object)(object)_camera == (Object)null) ? "null" : ((Object)((Component)_camera).gameObject).name)));
				}
				ManualLogSource logger3 = instance.Logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)$"Highlight count: {_highlights.Count}");
				}
			}
		}

		private bool KeyDown(ConfigEntry<KeyCode> key)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (key != null && (int)key.Value != 0)
			{
				return Input.GetKeyDown(key.Value);
			}
			return false;
		}

		private void EnsureCamera()
		{
			if ((Object)(object)_camera != (Object)null && ((Behaviour)_camera).isActiveAndEnabled)
			{
				return;
			}
			_camera = Camera.main;
			if ((Object)(object)_camera == (Object)null || !((Behaviour)_camera).isActiveAndEnabled)
			{
				_camera = ((IEnumerable<Camera>)Camera.allCameras).FirstOrDefault((Func<Camera, bool>)((Camera c) => (Object)(object)c != (Object)null && ((Behaviour)c).isActiveAndEnabled && !Utils.ContainsAny(((Object)((Component)c).gameObject).name, "UI", "Canvas", "Menu", "Overlay")));
			}
		}

		private void EnsureStyles()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003e: 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_0070: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (_hudStyle == null)
			{
				_hudStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)1,
					fontSize = 18,
					fontStyle = (FontStyle)1
				};
				_hudStyle.normal.textColor = Color.white;
				_hudStyle.font = Utils.GameFont;
			}
			if (_boxStyle == null)
			{
				_boxStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)1,
					fontSize = 12,
					fontStyle = (FontStyle)1
				};
				_boxStyle.normal.textColor = Color.white;
				_boxStyle.font = Utils.GameFont;
			}
		}

		private void ScanHighlights()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			_highlights.Clear();
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHighlight.Value || !instance.AnyHighlightCategoryEnabled() || (Object)(object)_camera == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (!((Scene)(ref activeScene)).IsValid() || !((Scene)(ref activeScene)).isLoaded || Utils.ContainsAny(((Scene)(ref activeScene)).name, "MainMenu", "Title", "Loading", "UI"))
			{
				return;
			}
			if (_lastSceneName != ((Scene)(ref activeScene)).name)
			{
				_lastSceneName = ((Scene)(ref activeScene)).name;
				ObjectClassifier.ClearCache();
			}
			int num = Mathf.Min(Physics.OverlapSphereNonAlloc(((Component)_camera).transform.position, instance.HighlightDistance.Value, _overlapBuffer, -1, (QueryTriggerInteraction)2), 512);
			HashSet<int> hashSet = new HashSet<int>();
			int num2 = Mathf.Clamp(instance.MaxHighlights.Value, 1, 512);
			float num3 = instance.MaxColliderSize.Value * instance.MaxColliderSize.Value;
			for (int i = 0; i < num; i++)
			{
				if (_highlights.Count >= num2)
				{
					break;
				}
				Collider val = _overlapBuffer[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				if (((Vector3)(ref size)).sqrMagnitude > num3)
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				if (!((Object)(object)gameObject == (Object)null) && gameObject.activeInHierarchy && !IsIgnoredGameObject(gameObject) && TryClassifyAncestor(gameObject, out var target, out var classification, requireEnabled: true))
				{
					int instanceID = ((Object)target).GetInstanceID();
					if (hashSet.Add(instanceID))
					{
						_highlights.Add(new HighlightEntry(target, classification));
					}
				}
			}
		}

		private bool TryClassifyAncestor(GameObject start, out GameObject target, out Classification classification, bool requireEnabled)
		{
			target = null;
			classification = Classification.None;
			if ((Object)(object)start == (Object)null)
			{
				return false;
			}
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			Transform val = start.transform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 6)
			{
				GameObject gameObject = ((Component)val).gameObject;
				if (!((Object)(object)gameObject == (Object)null) && gameObject.activeInHierarchy && !IsIgnoredGameObject(gameObject))
				{
					Classification classification2 = ObjectClassifier.Classify(gameObject);
					if (classification2 != Classification.None && (!requireEnabled || instance.IsCategoryEnabled(classification2)))
					{
						target = gameObject;
						classification = classification2;
						return true;
					}
				}
				num++;
				val = val.parent;
			}
			return false;
		}

		private bool IsIgnoredGameObject(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return true;
			}
			if (go.layer == 5)
			{
				return true;
			}
			if ((Object)(object)go.GetComponent<Camera>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)go.GetComponent<Canvas>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)go.GetComponent<EventSystem>() != (Object)null)
			{
				return true;
			}
			if (Utils.ContainsAny(((Object)go).name, "PeakObjectIdentifier", "EventSystem", "Main Camera", "Directional Light", "PostProcess", "GlobalVolume", "Reflection Probe"))
			{
				return true;
			}
			try
			{
				Transform root = go.transform.root;
				if ((Object)(object)root != (Object)null && Utils.ContainsAny(((Object)((Component)root).gameObject).name, "HUD", "UI", "Canvas", "EventSystem"))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private string GetTargetText()
		{
			//IL_0046: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.ShowCrosshairTarget.Value || (Object)(object)_camera == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				RaycastHit[] array = Physics.RaycastAll(_camera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)), instance.MaxDistance.Value, -1, (QueryTriggerInteraction)2);
				if (array == null || array.Length == 0)
				{
					return "Target: none";
				}
				RaycastHit val = ((IEnumerable<RaycastHit>)array.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)).FirstOrDefault((Func<RaycastHit, bool>)((RaycastHit h) => (Object)(object)((RaycastHit)(ref h)).collider != (Object)null && !IsIgnoredGameObject(((Component)((RaycastHit)(ref h)).collider).gameObject)));
				if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
				{
					return "Target: none";
				}
				GameObject gameObject = ((Component)((RaycastHit)(ref val)).collider).gameObject;
				if (TryClassifyAncestor(gameObject, out var target, out var classification, requireEnabled: false))
				{
					return $"Target: {GetDisplayName(target)} [{Utils.GetClassificationName(classification)}] {((RaycastHit)(ref val)).distance:F1}m";
				}
				return $"Target: {GetDisplayName(gameObject)} [None] {((RaycastHit)(ref val)).distance:F1}m";
			}
			catch
			{
				return string.Empty;
			}
		}

		private string GetDisplayName(GameObject go)
		{
			try
			{
				Transform root = go.transform.root;
				if ((Object)(object)root != (Object)null && (Object)(object)root != (Object)(object)go.transform)
				{
					return ((Object)root).name + "/" + ((Object)go).name;
				}
				return ((Object)go).name;
			}
			catch
			{
				return "Unknown";
			}
		}

		private void DrawTargetLabel()
		{
			//IL_002b: 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)
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.ShowCrosshairTarget.Value && !string.IsNullOrWhiteSpace(_targetText))
			{
				GUI.color = Color.white;
				GUI.Label(new Rect(0f, instance.TargetLabelY.Value, (float)Screen.width, 30f), _targetText, _hudStyle);
			}
		}

		private void DrawHighlights()
		{
			//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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHighlight.Value || (Object)(object)_camera == (Object)null || (Object)(object)_pixel == (Object)null)
			{
				return;
			}
			foreach (HighlightEntry highlight in _highlights)
			{
				if ((Object)(object)highlight?.GameObject == (Object)null || !highlight.GameObject.activeInHierarchy || !instance.IsCategoryEnabled(highlight.Classification))
				{
					continue;
				}
				Color color = instance.GetColor(highlight.Classification);
				if (!(color.a <= 0.01f))
				{
					Bounds? bounds = highlight.Bounds;
					if (bounds.HasValue)
					{
						string label = (instance.ShowBoxLabels.Value ? (Utils.GetClassificationName(highlight.Classification) + ": " + ((Object)highlight.GameObject).name) : string.Empty);
						DrawBounds(bounds.Value, color, label, highlight.Classification);
					}
				}
			}
		}

		private void DrawBounds(Bounds bounds, Color color, string label, Classification classification)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006b: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_017f: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: 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_0297: 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_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)_pixel == (Object)null)
			{
				return;
			}
			Vector3 min = ((Bounds)(ref bounds)).min;
			Vector3 max = ((Bounds)(ref bounds)).max;
			Vector3[] obj = new Vector3[8]
			{
				new Vector3(min.x, min.y, min.z),
				new Vector3(min.x, min.y, max.z),
				new Vector3(min.x, max.y, min.z),
				new Vector3(min.x, max.y, max.z),
				new Vector3(max.x, min.y, min.z),
				new Vector3(max.x, min.y, max.z),
				new Vector3(max.x, max.y, min.z),
				new Vector3(max.x, max.y, max.z)
			};
			float num = float.MaxValue;
			float num2 = float.MaxValue;
			float num3 = float.MinValue;
			float num4 = float.MinValue;
			Vector3[] array = (Vector3[])(object)obj;
			foreach (Vector3 val in array)
			{
				Vector3 val2 = _camera.WorldToScreenPoint(val);
				if (val2.z <= 0f)
				{
					return;
				}
				num = Mathf.Min(num, val2.x);
				num2 = Mathf.Min(num2, val2.y);
				num3 = Mathf.Max(num3, val2.x);
				num4 = Mathf.Max(num4, val2.y);
			}
			if (num > num3 || num2 > num4)
			{
				return;
			}
			Rect val3 = Rect.MinMaxRect(num, (float)Screen.height - num4, num3, (float)Screen.height - num2);
			if (!(((Rect)(ref val3)).width < 2f) && !(((Rect)(ref val3)).height < 2f))
			{
				if (instance.Categories.TryGetValue(classification, out var value) && value.Fill.Value)
				{
					GUI.color = instance.GetFillColor(classification);
					GUI.DrawTexture(val3, (Texture)(object)_pixel);
				}
				GUI.color = color;
				float num5 = Mathf.Max(1f, instance.BoxThickness.Value);
				GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMin, ((Rect)(ref val3)).yMin, ((Rect)(ref val3)).width, num5), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMin, ((Rect)(ref val3)).yMax - num5, ((Rect)(ref val3)).width, num5), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMin, ((Rect)(ref val3)).yMin, num5, ((Rect)(ref val3)).height), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMax - num5, ((Rect)(ref val3)).yMin, num5, ((Rect)(ref val3)).height), (Texture)(object)_pixel);
				if (!string.IsNullOrWhiteSpace(label))
				{
					GUI.Label(new Rect(((Rect)(ref val3)).xMin, ((Rect)(ref val3)).yMin - 20f, ((Rect)(ref val3)).width, 20f), label, _boxStyle);
				}
			}
		}

		private void DrawMinimap()
		{
			//IL_0098: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableMinimap.Value || (Object)(object)_camera == (Object)null || (Object)(object)_pixel == (Object)null)
			{
				return;
			}
			float num = Mathf.Clamp(instance.MinimapSize.Value, 80f, 600f);
			float num2 = Mathf.Max(10f, instance.MinimapRange.Value);
			float num3 = 16f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)Screen.width - num - num3, num3, num, num);
			GUI.color = new Color(0.04f, 0.05f, 0.08f, 0.75f);
			GUI.DrawTexture(val, (Texture)(object)_pixel);
			DrawRectOutline(val, 2f, Utils.TabColor);
			float x = ((Rect)(ref val)).center.x;
			float y = ((Rect)(ref val)).center.y;
			GUI.color = Color.white;
			GUI.DrawTexture(new Rect(x - 3f, y - 3f, 6f, 6f), (Texture)(object)_pixel);
			float num4 = (instance.MinimapRotate.Value ? ((Component)_camera).transform.eulerAngles.y : 0f);
			float num5 = Mathf.Cos(num4 * (MathF.PI / 180f));
			float num6 = Mathf.Sin(num4 * (MathF.PI / 180f));
			float num7 = num * 0.5f / num2;
			foreach (HighlightEntry highlight in _highlights)
			{
				if ((Object)(object)highlight?.GameObject == (Object)null || !instance.IsCategoryEnabled(highlight.Classification))
				{
					continue;
				}
				Vector3 val2 = highlight.GameObject.transform.position - ((Component)_camera).transform.position;
				if (!(((Vector3)(ref val2)).magnitude > num2))
				{
					float num8 = val2.x;
					float num9 = val2.z;
					if (instance.MinimapRotate.Value)
					{
						float num10 = num8 * num5 - num9 * num6;
						float num11 = num8 * num6 + num9 * num5;
						num8 = num10;
						num9 = num11;
					}
					float num12 = x + num8 * num7;
					float num13 = y - num9 * num7;
					float num14 = Mathf.Clamp(num12, ((Rect)(ref val)).xMin + 3f, ((Rect)(ref val)).xMax - 6f);
					num13 = Mathf.Clamp(num13, ((Rect)(ref val)).yMin + 3f, ((Rect)(ref val)).yMax - 6f);
					GUI.color = instance.GetColor(highlight.Classification);
					GUI.DrawTexture(new Rect(num14 - 2f, num13 - 2f, 4f, 4f), (Texture)(object)_pixel);
				}
			}
			GUI.color = Color.white;
		}

		private void DrawRectOutline(Rect rect, float thickness, Color color)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_pixel == (Object)null))
			{
				GUI.color = color;
				GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin, ((Rect)(ref rect)).width, thickness), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).width, thickness), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin, thickness, ((Rect)(ref rect)).height), (Texture)(object)_pixel);
				GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).yMin, thickness, ((Rect)(ref rect)).height), (Texture)(object)_pixel);
			}
		}

		private void SpawnTestObject(string name, PrimitiveType primitive, Color color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			EnsureCamera();
			if (!((Object)(object)_camera == (Object)null))
			{
				GameObject val = GameObject.CreatePrimitive(primitive);
				((Object)val).name = name;
				val.transform.position = ((Component)_camera).transform.position + ((Component)_camera).transform.forward * 3f + Vector3.up * 0.5f;
				TrySetColor(val, color);
				Object.Destroy((Object)(object)val, 120f);
			}
		}

		private void TrySetColor(GameObject go, Color color)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Renderer component = go.GetComponent<Renderer>();
				if (!((Object)(object)component == (Object)null))
				{
					Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color");
					if (!((Object)(object)val == (Object)null))
					{
						Material val2 = new Material(val);
						val2.color = color;
						component.sharedMaterial = val2;
					}
				}
			}
			catch
			{
			}
		}

		private Texture2D MakePixelTexture()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			try
			{
				Texture2D val = new Texture2D(1, 1);
				val.SetPixel(0, 0, Color.white);
				val.Apply();
				return val;
			}
			catch
			{
				return null;
			}
		}
	}
	public class SettingsMenuInjector : MonoBehaviour
	{
		private Canvas _targetCanvas;

		private Canvas _fallbackCanvas;

		private GameObject _modsTabButton;

		private GameObject _modsPanel;

		private bool _injected;

		private int _attempts;

		private float _nextInjectAttempt;

		private bool _cursorSaved;

		private CursorLockMode _savedCursorLock;

		private bool _savedCursorVisible;

		public static SettingsMenuInjector Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

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

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ObjectClassifier.ClearCache();
			_injected = false;
			_attempts = 0;
			_targetCanvas = null;
			_modsTabButton = null;
		}

		private void Update()
		{
			UpdateCursor();
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.AutoInjectSettingsTab.Value && !_injected && _attempts < instance.MaxSettingsInjectAttempts.Value && !(Time.unscaledTime < _nextInjectAttempt))
			{
				_nextInjectAttempt = Time.unscaledTime + Mathf.Max(1f, instance.SettingsInjectInterval.Value);
				_attempts++;
				TryInject();
			}
		}

		private void UpdateCursor()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_modsPanel != (Object)null && _modsPanel.activeInHierarchy)
			{
				if (!_cursorSaved)
				{
					_savedCursorLock = Cursor.lockState;
					_savedCursorVisible = Cursor.visible;
					_cursorSaved = true;
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			else if (_cursorSaved)
			{
				Cursor.lockState = _savedCursorLock;
				Cursor.visible = _savedCursorVisible;
				_cursorSaved = false;
			}
		}

		public void TogglePanel()
		{
			if ((Object)(object)_modsPanel == (Object)null)
			{
				Transform val = null;
				if ((Object)(object)_targetCanvas != (Object)null)
				{
					val = ((Component)_targetCanvas).transform;
				}
				else
				{
					CreateFallbackCanvas();
					val = ((Component)_fallbackCanvas).transform;
				}
				CreateModsPanel(val);
			}
			if (!((Object)(object)_modsPanel == (Object)null))
			{
				_modsPanel.SetActive(!_modsPanel.activeSelf);
				if (_modsPanel.activeSelf)
				{
					_modsPanel.transform.SetAsLastSibling();
				}
			}
		}

		private void TryInject()
		{
			PeakObjectIdentifierPlugin instance = PeakObjectIdentifierPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Canvas[] array;
			try
			{
				array = Object.FindObjectsByType<Canvas>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			}
			catch
			{
				return;
			}
			if (array == null || array.Length == 0)
			{
				return;
			}
			Canvas[] array2 = array;
			foreach (Canvas val in array2)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || ((Object)((Component)val).gameObject).name.Contains("PeakObjectIdentifier") || !IsLikelySettingsCanvas(val))
				{
					continue;
				}
				Transform val2 = FindSettingsTabContainer(((Component)val).transform);
				if (!((Object)(object)val2 == (Object)null))
				{
					_targetCanvas = val;
					CreateNewTabButton(val2);
					CreateModsPanel(((Component)val).transform);
					if ((Object)(object)_modsPanel != (Object)null)
					{
						_modsPanel.SetActive(false);
					}
					_injected = true;
					ManualLogSource logger = instance.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)("Added Mods button to settings canvas: " + ((Object)((Component)val).gameObject).name));
					}
					break;
				}
			}
		}

		private bool IsLikelySettingsCanvas(Canvas canvas)
		{
			if ((Object)(object)canvas == (Object)null || (Object)(object)((Component)canvas).gameObject == (Object)null)
			{
				return false;
			}
			if (Utils.ContainsAny(((Object)((Component)canvas).gameObject).name, "Popup", "Dialog", "Error", "Message", "Disconnect", "Photon", "Loading", "HUD", "Chat", "Tooltip", "Notification"))
			{
				return false;
			}
			int nodes = 0;
			return ContainsSettingsKeyword(((Component)canvas).transform, 0, ref nodes);
		}

		private bool ContainsSettingsKeyword(Transform t, int depth, ref int nodes)
		{
			if ((Object)(object)t == (Object)null || depth > 5 || nodes > 400)
			{
				return false;
			}
			nodes++;
			if (Utils.ContainsAny(((Object)t).name, "Settings", "Options", "Video", "Audio", "Graphics", "Display", "Sound", "Controls", "Keybinds", "Gameplay", "Accessibility", "Interface", "Input"))
			{
				return true;
			}
			for (int i = 0; i < t.childCount; i++)
			{
				if (ContainsSettingsKeyword(t.GetChild(i), depth + 1, ref nodes))
				{
					return true;
				}
			}
			return false;
		}

		private Transform FindSettingsTabContainer(Transform root)
		{
			Transform best = null;
			int bestScore = 0;
			int nodes = 0;
			ScanTransformForTabContainers(root, 0, ref nodes, ref best, ref bestScore);
			if (bestScore < 6)
			{
				return null;
			}
			return best;
		}

		private void ScanTransformForTabContainers(Transform t, int depth, ref int nodes, ref Transform best, ref int bestScore)
		{
			if ((Object)(object)t == (Object)null || depth > 6 || nodes > 600)
			{
				return;
			}
			nodes++;
			if (t.childCount >= 2 && (Object)(object)((Component)t).GetComponent<LayoutGroup>() != (Object)null)
			{
				int num = EvaluateTabContainer(t);
				if (num > bestScore)
				{
					bestScore = num;
					best = t;
				}
			}
			for (int i = 0; i < t.childCount; i++)
			{
				ScanTransformForTabContainers(t.GetChild(i), depth + 1, ref nodes, ref best, ref bestScore);
			}
		}

		private int EvaluateTabContainer(Transform t)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (Utils.ContainsAny(((Object)t).name, "Tab", "Category", "Sidebar", "Pages"))
			{
				num += 3;
			}
			for (int i = 0; i < t.childCount; i++)
			{
				Transform child = t.GetChild(i);
				if ((Object)(object)((Component)child).GetComponent<Button>() == (Object)null && (Object)(object)((Component)child).GetComponent<Toggle>() == (Object)null)
				{
					continue;
				}
				string labelText = GetLabelText(child);
				if (!string.IsNullOrWhiteSpace(labelText) && !IsActionLabel(labelText))
				{
					num2++;
					if (IsTabLabel(labelText))
					{
						num3++;
						num += 3;
					}
					else if (labelText.Length <= 24)
					{
						num++;
					}
				}
			}
			if (num2 >= 2 && num3 >= 2)
			{
				num += 4;
			}
			if (num2 >= 2 && Utils.ContainsAny(((Object)t).name, "Tab", "Category", "Sidebar"))
			{
				num += 2;
			}
			return num;
		}

		private string GetLabelText(Transform selectable)
		{
			try
			{
				Text componentInChildren = ((Component)selectable).GetComponentInChildren<Text>(true);
				if ((Object)(object)componentInChildren != (Object)null && !string.IsNullOrWhiteSpace(componentInChildren.text))
				{
					return componentInChildren.text.Trim();
				}
				Component[] componentsInChildren = ((Component)selectable).GetComponentsInChildren<Component>(true);
				foreach (Component val in componentsInChildren)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Type type = ((object)val).GetType();
					if (!type.Name.Contains("TMP_Text") && !type.Name.Contains("TextMeshPro"))
					{
						continue;
					}
					try
					{
						string text = type.GetProperty("text")?.GetValue(val, null) as string;
						if (!string.IsNullOrWhiteSpace(text))
						{
							return text.Trim();
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return string.Empty;
		}

		private bool IsActionLabel(string label)
		{
			return Utils.ContainsAny(label, "Host", "Play", "Quit", "Exit", "Resume", "Start", "Join", "Disconnect", "OK", "Okay", "Cancel", "Back", "Close", "Apply", "Return", "Continue", "Respawn", "Spawn", "Test", "Mods");
		}

		private bool IsTabLabel(string label)
		{
			return Utils.ContainsAny(label, "Video", "Audio", "Graphics", "Display", "Sound", "Music", "Controls", "Keybinds", "Bindings", "Input", "Gameplay", "General", "Accessibility", "Interface", "Settings", "Options", "Network", "Game", "Misc");
		}

		private void CreateNewTabButton(Transform container)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			if (!((Object)(object)container == (Object)null))
			{
				GameObject val = CreateUIObject(container, "PeakObjectIdentifier_ModsTab", Vector2.zero);
				Image val2 = val.AddComponent<Image>();
				((Graphic)val2).color = Utils.TabColor;
				Button obj = val.AddComponent<Button>();
				((Selectable)obj).targetGraphic = (Graphic)(object)val2;
				LayoutElement obj2 = val.AddComponent<LayoutElement>();
				obj2.preferredWidth = 150f;
				obj2.preferredHeight = 36f;
				GameObject val3 = CreateUIObject(val.transform, "Text", Vector2.zero);
				StretchFull(val3.GetComponent<RectTransform>());
				Text obj3 = val3.AddComponent<Text>();
				obj3.text = "Mods";
				obj3.font = Utils.GameFont;
				obj3.fontSize = 18;
				((Graphic)obj3).color = Color.white;
				obj3.alignment = (TextAnchor)4;
				obj3.fontStyle = (FontStyle)1;
				obj3.horizontalOverflow = (HorizontalWrapMode)1;
				obj3.verticalOverflow = (VerticalWrapMode)1;
				((UnityEvent)obj.onClick).AddListener(new UnityAction(TogglePanel));
				val.transform.SetAsLastSibling();
				_modsTabButton = val;
			}
		}

		private void CreateModsPanel(Transform parent)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parent == (Object)null || (Object)(object)_modsPanel != (Object)null)
			{
				return;
			}
			PeakObjectIdentifierPlugin plugin = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)plugin == (Object)null))
			{
				_modsPanel = CreateUIObject(parent, "PeakObjectIdentifier_ModsPanel", Vector2.zero);
				RectTransform component = _modsPanel.GetComponent<RectTransform>();
				StretchFull(component, 120f, 80f, 120f, 80f);
				Image obj = _modsPanel.AddComponent<Image>();
				((Graphic)obj).color = new Color(0.05f, 0.06f, 0.09f, 0.97f);
				((Graphic)obj).raycastTarget = true;
				VerticalLayoutGroup val = _modsPanel.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)val).padding = new RectOffset(16, 16, 16, 16);
				((HorizontalOrVerticalLayoutGroup)val).spacing = 10f;
				((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
				GameObject val2 = CreateHorizontal(((Component)val).transform, "Header", 44f);
				CreateText(val2.transform, "PEAK Object Identifier", 28, Color.white, (TextAnchor)3, bold: true, 0f, 1f);
				CreateButton(val2.transform, "X", new Color(0.65f, 0.15f, 0.15f, 1f), Color.white, delegate
				{
					_modsPanel.SetActive(false);
				}, 36f, 36f);
				CreateText(((Component)val).transform, "Client-side identification, highlighting, colors, and minimap.", 14, new Color(0.75f, 0.78f, 0.85f), (TextAnchor)3);
				CreateSeparator(((Component)val).transform);
				CreateScrollArea(((Component)val).transform, out var content);
				Transform transform = content.transform;
				CreateSection(transform, "General");
				CreateToggleRow(transform, "Enable mod", plugin.EnableMod);
				CreateToggleRow(transform, "Show object under crosshair", plugin.ShowCrosshairTarget);
				CreateToggleRow(transform, "Enable highlight ESP", plugin.EnableHighlight);
				CreateToggleRow(transform, "Show ESP labels", plugin.ShowBoxLabels);
				CreateToggleRow(transform, "Auto inject settings button", plugin.AutoInjectSettingsTab);
				CreateSection(transform, "Minimap");
				CreateToggleRow(transform, "Enable minimap", plugin.EnableMinimap);
				CreateToggleRow(transform, "Rotate minimap with camera", plugin.MinimapRotate);
				CreateFloatRow(transform, "Minimap size", plugin.MinimapSize, 80f, 600f);
				CreateFloatRow(transform, "Minimap range", plugin.MinimapRange, 10f, 500f);
				CreateSection(transform, "Highlight Categories");
				CreateText(transform, "Enable/disable categories, choose fill, and change colors.", 13, new Color(0.75f, 0.78f, 0.85f), (TextAnchor)3);
				Classification[] uiOrder = PeakObjectIdentifierPlugin.UiOrder;
				foreach (Classification classification in uiOrder)
				{
					CreateCategoryRow(transform, classification);
				}
				CreateSection(transform, "Patterns");
				CreateText(transform, "Comma-separated regex-like patterns. Priority: Fake Luggage > Esoteric > Special > Hostile Interactive > Hostile Uninteractive > Luggage > Normal > Terrain.", 13, new Color(0.75f, 0.78f, 0.85f), (TextAnchor)3);
				uiOrder = PeakObjectIdentifierPlugin.UiOrder;
				foreach (Classification classification2 in uiOrder)
				{
					CreatePatternRow(transform, classification2);
				}
				CreateSection(transform, "Testing");
				CreateButton(transform, "Apply / Refresh", Utils.TabColor, Color.white, delegate
				{
					plugin.RebuildRegexes();
					HighlighterController.Instance?.ForceScan();
				}, 0f, 34f);
				CreateButton(transform, "Spawn fake luggage test object", new Color(0.25f, 0.25f, 0.3f, 1f), Color.white, delegate
				{
					HighlighterController.Instance?.SpawnFakeTest();
				}, 0f, 30f);
				CreateButton(transform, "Spawn hostile interactive test object", new Color(0.25f, 0.25f, 0.3f, 1f), Color.white, delegate
				{
					HighlighterController.Instance?.SpawnHostileTest();
				}, 0f, 30f);
				CreateButton(transform, "Spawn rock occluder", new Color(0.25f, 0.25f, 0.3f, 1f), Color.white, delegate
				{
					HighlighterController.Instance?.SpawnRockTest();
				}, 0f, 30f);
				CreateSeparator(((Component)val).transform);
				GameObject val3 = CreateHorizontal(((Component)val).transform, "Footer", 28f);
				((LayoutGroup)val3.GetComponent<HorizontalLayoutGroup>()).childAlignment = (TextAnchor)4;
				CreateText(val3.transform, "Made with \ud83d\udc9c by ", 16, Color.white, (TextAnchor)4, bold: false, 0f, 0f, Utils.GameFont);
				CreateText(val3.transform, "Joseph Technology", 16, Utils.TabColor, (TextAnchor)4, bold: true, 0f, 0f, Utils.CreditFont);
				_modsPanel.transform.SetAsLastSibling();
			}
		}

		private GameObject CreateScrollArea(Transform parent, out GameObject content)
		{
			//IL_0007: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0141: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			GameObject val = CreateUIObject(parent, "ScrollArea", Vector2.zero);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.flexibleWidth = 1f;
			obj.flexibleHeight = 1f;
			((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.15f);
			ScrollRect obj2 = val.AddComponent<ScrollRect>();
			obj2.horizontal = false;
			obj2.vertical = true;
			obj2.scrollSensitivity = 20f;
			GameObject val2 = CreateUIObject(val.transform, "Viewport", Vector2.zero);
			StretchFull(val2.GetComponent<RectTransform>());
			((Graphic)val2.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.05f);
			val2.AddComponent<Mask>().showMaskGraphic = false;
			content = CreateUIObject(val2.transform, "Content", Vector2.zero);
			RectTransform component = content.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.offsetMin = new Vector2(0f, 0f);
			component.offsetMax = new Vector2(0f, 0f);
			VerticalLayoutGroup obj3 = content.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj3).padding = new RectOffset(4, 8, 4, 4);
			((HorizontalOrVerticalLayoutGroup)obj3).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
			content.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			obj2.viewport = val2.GetComponent<RectTransform>();
			obj2.content = component;
			return val;
		}

		private void CreateSection(Transform parent, string title)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			CreateText(parent, title, 20, Utils.TabColor, (TextAnchor)3, bold: true);
			CreateSeparator(parent);
		}

		private GameObject CreateSeparator(Transform parent)
		{
			//IL_0011: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = CreateUIObject(parent, "Separator", new Vector2(0f, 2f));
			((Graphic)obj.AddComponent<Image>()).color = new Color(Utils.TabColor.r, Utils.TabColor.g, Utils.TabColor.b, 0.55f);
			obj.AddComponent<LayoutElement>().preferredHeight = 2f;
			return obj;
		}

		private void CreateCategoryRow(Transform parent, Classification classification)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin plugin = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)plugin == (Object)null) && plugin.Categories.TryGetValue(classification, out var category))
			{
				GameObject val = CreateHorizontal(parent, "Category_" + classification, 34f);
				GameObject val2 = CreateUIObject(val.transform, "Swatch", new Vector2(18f, 18f));
				Image swatchImage = val2.AddComponent<Image>();
				((Graphic)swatchImage).color = plugin.GetColor(classification);
				LayoutElement obj = val2.AddComponent<LayoutElement>();
				obj.preferredWidth = 18f;
				obj.preferredHeight = 18f;
				Text label = CreateText(val.transform, Utils.GetClassificationName(classification), 16, plugin.GetColor(classification), (TextAnchor)3, bold: true, 240f, 1f);
				CreateToggleWithLabel(val.transform, category.Enabled.Value, delegate(bool value)
				{
					category.Enabled.Value = value;
					HighlighterController.Instance?.ForceScan();
				}, "On", 80f);
				CreateToggleWithLabel(val.transform, category.Fill.Value, delegate(bool value)
				{
					category.Fill.Value = value;
					HighlighterController.Instance?.ForceScan();
				}, "Fill", 90f);
				CreateInputField(val.transform, category.ColorHex.Value, delegate(string value)
				{
					//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_0029: 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)
					category.ColorHex.Value = value;
					Color color = plugin.GetColor(classification);
					((Graphic)swatchImage).color = color;
					((Graphic)label).color = color;
					HighlighterController.Instance?.ForceScan();
				}, 140f);
			}
		}

		private void CreatePatternRow(Transform parent, Classification classification)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			PeakObjectIdentifierPlugin plugin = PeakObjectIdentifierPlugin.Instance;
			if (!((Object)(object)plugin == (Object)null) && plugin.Patterns.TryGetValue(classification, out var pattern))
			{
				GameObject val = CreateHorizontal(parent, "Pattern_" + classification, 30f);
				CreateText(val.transform, Utils.GetClassificationName(classification), 14, plugin.GetColor(classification), (TextAnchor)3, bold: true, 220f);
				CreateInputField(val.transform, pattern.Value, delegate(string value)
				{
					pattern.Value = value;
					plugin.RebuildRegexes();
					HighlighterController.Instance?.ForceScan();
				}, 0f);
			}
		}

		private void CreateFloatRow(Transform parent, string label, ConfigEntry<float> entry, float min, float max)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateHorizontal(parent, "Row_" + label, 30f);
			CreateText(val.transform, label, 15, Color.white, (TextAnchor)3, bold: false, 260f, 1f);
			CreateInputField(val.transform, entry.Value.ToString("0.##"), delegate(string value)
			{
				if (float.TryParse(value, out var result))
				{
					entry.Value = Mathf.Clamp(result, min, max);
				}
				HighlighterController.Instance?.ForceScan();
			}, 120f);
		}

		private void CreateFallbackCanvas()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_fallbackCanvas != (Object)null))
			{
				EnsureEventSystem();
				GameObject val = new GameObject("PeakObjectIdentifier_FallbackCanvas", new Type[4]
				{
					typeof(RectTransform),
					typeof(Canvas),
					typeof(CanvasScaler),
					typeof(GraphicRaycaster)
				});
				_fallbackCanvas = val.GetComponent<Canvas>();
				_fallbackCanvas.renderMode = (RenderMode)0;
				_fallbackCanvas.sortingOrder = 9999;
				CanvasScaler component = val.GetComponent<CanvasScaler>();
				component.uiScaleMode = (ScaleMode)1;
				component.referenceResolution = new Vector2(1920f, 1080f);
				Object.DontDestroyOnLoad((Object)(object)val);
			}
		}

		private void EnsureEventSystem()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			try
			{
				EventSystem[] array = Object.FindObjectsByType<EventSystem>((FindObjectsInactive)0, (FindObjectsSortMode)0);
				if (array == null || array.Length == 0)
				{
					Object.DontDestroyOnLoad((Object)new GameObject("PeakObjectIdentifier_EventSystem", new Type[2]
					{
						typeof(EventSystem),
						typeof(StandaloneInputModule)
					}));
				}
			}
			catch
			{
			}
		}

		private GameObject CreateHorizontal(Transform parent, string name, float preferredHeight)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = CreateUIObject(parent, name, new Vector2(0f, preferredHeight));
			HorizontalLayoutGroup obj2 = obj.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			obj.AddComponent<LayoutElement>().preferredHeight = preferredHeight;
			return obj;
		}

		private void CreateToggleRow(Transform parent, string label, ConfigEntry<bool> entry)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateHorizontal(parent, "Row_" + label, 30f);
			CreateText(val.transform, label, 16, Color.white, (TextAnchor)3, bold: false, 0f, 1f);
			CreateToggle(val.transform, entry.Value, delegate(bool value)
			{
				entry.Value = value;
			});
		}

		private GameObject CreateToggleWithLabel(Transform parent, bool initial, Action<bool> onChanged, string label, float width)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUIObject(parent, "Toggle_" + label, new Vector2(width, 24f));
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			val.AddComponent<LayoutElement>().preferredWidth = width;
			CreateToggle(val.transform, initial, onChanged);
			CreateText(val.transform, label, 12, Color.white, (TextAnchor)3);
			return val;
		}

		private GameObject CreateToggle(Transform parent, bool initial, Action<bool> onChanged)
		{
			//IL_001e: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUIObject(parent, "Toggle", new Vector2(26f, 26f));
			Toggle obj = val.AddComponent<Toggle>();
			GameObject val2 = CreateUIObject(val.transform, "Background", Vector2.zero);
			StretchFull(val2.GetComponent<RectTransform>());
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.15f, 0.15f, 0.15f, 1f);
			GameObject checkmark = CreateUIObject(val2.transform, "Checkmark", new Vector2(16f, 16f));
			RectTransform component = checkmark.GetComponent<RectTransform>();
			CenterRect(component, 16f, 16f);
			Image val4 = checkmark.AddComponent<Image>();
			((Graphic)val4).color = Utils.TabColor;
			checkmark.SetActive(initial);
			((Selectable)obj).targetGraphic = (Graphic)(object)val3;
			obj.graphic = (Graphic)(object)val4;
			obj.isOn = initial;
			((UnityEvent<bool>)(object)obj.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				checkmark.SetActive(value);
				onChanged?.Invoke(value);
			});
			LayoutElement obj2 = val.AddComponent<LayoutElement>();
			obj2.preferredWidth = 26f;
			obj2.preferredHeight = 26f;
			return val;
		}

		private GameObject CreateInputField(Transform parent, string initial, Action<string> onEnd, float width)
		{
			//IL_002b: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUIObject(parent, "InputField", new Vector2((width > 0f) ? width : 0f, 28f));
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			if (width > 0f)
			{
				val2.preferredWidth = width;
			}
			else
			{
				val2.flexibleWidth = 1f;
			}
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.12f, 0.12f, 0.12f, 1f);
			GameObject val4 = CreateUIObject(val.transform, "Text", Vector2.zero);
			StretchFull(val4.GetComponent<RectTransform>(), 6f, 2f, 6f, 2f);
			Text val5 = val4.AddComponent<Text>();
			val5.text = initial ?? string.Empty;
			val5.font = Utils.GameFont;
			val5.fontSize = 14;
			((Graphic)val5).color = Color.white;
			val5.alignment = (TextAnchor)3;
			val5.supportRichText = false;
			val5.horizontalOverflow = (HorizontalWrapMode)1;
			val5.verticalOverflow = (VerticalWrapMode)1;
			InputField obj = val.AddComponent<InputField>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val3;
			obj.textComponent = val5;
			obj.text = initial ?? string.Empty;
			((UnityEvent<string>)(object)obj.onEndEdit).AddListener((UnityAction<string>)delegate(string value)
			{
				onEnd?.Invoke(value);
			});
			return val;
		}

		private GameObject CreateButton(Transform parent, string label, Color backgroundColor, Color textColor, Action onClick, float width, float height)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			GameObject val = CreateUIObject(parent, "Button_" + label, new Vector2(width, height));
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = backgroundColor;
			Button obj = val.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val2;
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredHeight = height;
			if (width > 0f)
			{
				val3.preferredWidth = width;
			}
			else
			{
				val3.flexibleWidth = 1f;
			}
			GameObject val4 = CreateUIObject(val.transform, "Text", Vector2.zero);
			StretchFull(val4.GetComponent<RectTransform>());
			Text obj2 = val4.AddComponent<Text>();
			obj2.text = label;
			obj2.font = Utils.GameFont;
			obj2.fontSize = 16;
			((Graphic)obj2).color = textColor;
			obj2.alignment = (TextAnchor)4;
			obj2.horizontalOverflow = (HorizontalWrapMode)1;
			obj2.verticalOverflow = (VerticalWrapMode)1;
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				onClick?.Invoke();
			});
			return val;
		}

		private Text CreateText(Transform parent, string content, int fontSize, Color color, TextAnchor alignment, bool bold = false, float minWidth = 0f, float flexibleWidth = 0f, Font font = null)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = CreateUIObject(parent, "Text", Vector2.zero);
			LayoutElement val = obj.AddComponent<LayoutElement>();
			if (minWidth > 0f)
			{
				val.minWidth = minWidth;
			}
			if (flexibleWidth > 0f)
			{
				val.flexibleWidth = flexibleWidth;
			}
			Text obj2 = obj.AddComponent<Text>();
			obj2.text = content;
			obj2.font = (((Object)(object)font != (Object)null) ? font : Utils.GameFont);
			obj2.fontSize = fontSize;
			((Graphic)obj2).color = color;
			obj2.alignment = alignment;
			obj2.fontStyle = (FontStyle)(bold ? 1 : 0);
			obj2.horizontalOverflow = (HorizontalWrapMode)1;
			obj2.verticalOverflow = (VerticalWrapMode)1;
			return obj2;
		}

		private GameObject CreateUIObject(Transform parent, string name, Vector2 size)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			if ((Object)(object)parent != (Object)null)
			{
				((Transform)val2).SetParent(parent, false);
			}
			if (size != Vector2.zero)
			{
				val2.sizeDelta = size;
			}
			return val;
		}

		private void StretchFull(RectTransform rect, float left = 0f, float bottom = 0f, float right = 0f, float top = 0f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = new Vector2(left, bottom);
			rect.offsetMax = new Vector2(0f - right, 0f - top);
		}

		private void CenterRect(RectTransform rect, float width, float height)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			rect.anchorMin = new Vector2(0.5f, 0.5f);
			rect.anchorMax = new Vector2(0.5f, 0.5f);
			rect.sizeDelta = new Vector2(width, height);
		}
	}
}