Decompiled source of PickupTabOverlay v0.1.27

PickupTabOverlay.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using HarmonyLib;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(PickupTabOverlay), "Pickup Tab Overlay", "0.1.27", "kp0hyc", null)]
[assembly: MelonGame("Valko Game Studios", "Labyrinthine")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("PickupTabOverlay")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PickupTabOverlay")]
[assembly: AssemblyTitle("PickupTabOverlay")]
[assembly: AssemblyVersion("1.0.0.0")]
public class PickupTabOverlay : MelonMod
{
	private readonly struct TmpOverlayModel
	{
		public readonly string Text;

		public readonly float Width;

		public readonly float Height;

		public readonly int StyleKey;

		public TmpOverlayModel(string text, float width, float height, int styleKey)
		{
			Text = text;
			Width = width;
			Height = height;
			StyleKey = styleKey;
		}
	}

	private readonly struct ObjectiveTextStyle
	{
		public static readonly ObjectiveTextStyle Fallback = new ObjectiveTextStyle(hasLiveStyle: false, "fallback", 30, 28, 24, null, null, null, null, null);

		public readonly bool HasLiveStyle;

		public readonly string Source;

		public readonly int HeaderFontSize;

		public readonly int RowFontSize;

		public readonly int FooterFontSize;

		public readonly object Color;

		public readonly object MutedColor;

		public readonly object Font;

		public readonly object FontSharedMaterial;

		public readonly object SourceText;

		public int StyleKey => (((((((HeaderFontSize * 397) ^ RowFontSize) * 397) ^ FooterFontSize) * 397) ^ ((Font != null) ? RuntimeHelpers.GetHashCode(Font) : 0)) * 397) ^ ((FontSharedMaterial != null) ? RuntimeHelpers.GetHashCode(FontSharedMaterial) : 0);

		public ObjectiveTextStyle(bool hasLiveStyle, string source, int headerFontSize, int rowFontSize, int footerFontSize, object color, object mutedColor, object font, object fontSharedMaterial, object sourceText)
		{
			HasLiveStyle = hasLiveStyle;
			Source = source;
			HeaderFontSize = headerFontSize;
			RowFontSize = rowFontSize;
			FooterFontSize = footerFontSize;
			Color = color;
			MutedColor = mutedColor;
			Font = font;
			FontSharedMaterial = fontSharedMaterial;
			SourceText = sourceText;
		}

		public static ObjectiveTextStyle FromConfig(int headerFontSize, int rowFontSize, int footerFontSize, object color)
		{
			return new ObjectiveTextStyle(hasLiveStyle: false, "config", headerFontSize, rowFontSize, footerFontSize, color, CopyColorWithAlpha(color, 0.82f), null, null, null);
		}
	}

	private readonly struct PickupEntry
	{
		public readonly int Id;

		public readonly string Name;

		public readonly int Count;

		public readonly bool LeftHand;

		public readonly bool RightHand;

		public PickupEntry(int id, string name, int count, bool leftHand, bool rightHand)
		{
			Id = id;
			Name = name;
			Count = count;
			LeftHand = leftHand;
			RightHand = rightHand;
		}
	}

	private readonly struct CollectibleEntry
	{
		public readonly string Label;

		public readonly int Amount;

		public CollectibleEntry(string label, int amount)
		{
			Label = label;
			Amount = amount;
		}
	}

	private readonly struct UnlockEntry
	{
		public readonly string Category;

		public readonly string Name;

		public readonly int Id;

		public readonly string ItemClass;

		public readonly int Count;

		public UnlockEntry(string category, string name, int id, string itemClass, int count)
		{
			Category = category;
			Name = name;
			Id = id;
			ItemClass = itemClass;
			Count = count;
		}

		public UnlockEntry WithCount(int count)
		{
			return new UnlockEntry(Category, Name, Id, ItemClass, count);
		}
	}

	private readonly struct ShandadaItemInfo
	{
		public readonly string Name;

		public readonly string ItemClass;

		public ShandadaItemInfo(string name, string itemClass)
		{
			Name = name;
			ItemClass = itemClass;
		}
	}

	private const string HarmonyId = "kp0hyc.pickuptaboverlay";

	private const string PrefCategoryName = "PickupTabOverlay";

	private const int MinimumReadableRowFontSize = 18;

	private const int MinimumReadableFooterFontSize = 16;

	private static readonly List<PickupEntry> s_entries = new List<PickupEntry>();

	private static readonly Dictionary<string, int> s_collectiblesFound = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

	private static readonly HashSet<int> s_countedCollectibles = new HashSet<int>();

	private static readonly List<UnlockEntry> s_unlockEntries = new List<UnlockEntry>();

	private static readonly Dictionary<string, int> s_unlockEntryIndexes = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

	private static readonly HashSet<int> s_countedUnlockPickups = new HashSet<int>();

	private static readonly HashSet<int> s_undiscoveredCosmeticItemIds = new HashSet<int>();

	private static readonly Dictionary<int, string> s_customizationNameCache = new Dictionary<int, string>();

	private static readonly Dictionary<int, string> s_customizationClassCache = new Dictionary<int, string>();

	private static readonly Dictionary<int, ShandadaItemInfo> s_shandadaItems = new Dictionary<int, ShandadaItemInfo>();

	private static MelonPreferences_Entry<bool> s_enabled;

	private static MelonPreferences_Entry<int> s_panelWidth;

	private static MelonPreferences_Entry<bool> s_showIds;

	private static MelonPreferences_Entry<bool> s_showHandLabels;

	private static MelonPreferences_Entry<bool> s_showEmptyMessage;

	private static MelonPreferences_Entry<bool> s_showCollectibles;

	private static MelonPreferences_Entry<bool> s_showUnlockPickups;

	private static MelonPreferences_Entry<bool> s_debugLogging;

	private static MelonPreferences_Entry<bool> s_legacyDebugLogging;

	private static MelonPreferences_Entry<bool> s_useTextMeshProOverlay;

	private static MelonPreferences_Entry<bool> s_useObjectiveTextStyle;

	private static MelonPreferences_Entry<int> s_objectiveTextScalePercent;

	private static MelonPreferences_Entry<int> s_headerFontSize;

	private static MelonPreferences_Entry<int> s_rowFontSize;

	private static MelonPreferences_Entry<int> s_footerFontSize;

	private static MelonPreferences_Entry<int> s_maxVisibleItems;

	private static DateTime s_nextRefreshUtc = DateTime.MinValue;

	private static DateTime s_nextWarningUtc = DateTime.MinValue;

	private static DateTime s_nextObjectiveStyleRefreshUtc = DateTime.MinValue;

	private static DateTime s_nextTmpOverlayRetryUtc = DateTime.MinValue;

	private static DateTime s_nextTmpDiagnosticsUtc = DateTime.MinValue;

	private static ObjectiveTextStyle s_objectiveTextStyle = ObjectiveTextStyle.Fallback;

	private static string s_lastLoggedObjectiveStyleSignature;

	private static string s_lastLoggedRendererSignature;

	private static string s_lastLoggedTmpSourceSignature;

	private static string s_lastLoggedTmpDiagnosticsSignature;

	private static string s_lastLoggedTmpLayoutSignature;

	private static string s_lastLoggedDirectTmpFailure;

	private static bool s_tmpOverlayReady;

	private static bool s_tmpOverlayFailed;

	private static bool s_tmpOverlayVisible;

	private static bool s_loggedTmpOverlayReady;

	private static bool s_tmpOverlayUsesDirectUi;

	private static bool s_shandadaItemsLoaded;

	private static string s_tmpLastText;

	private static int s_tmpLastStyleKey;

	private static float s_tmpLastWidth;

	private static float s_tmpLastHeight;

	private static Type s_rectType;

	private static Type s_colorType;

	private static Type s_vector2Type;

	private static Type s_guiType;

	private static Type s_screenType;

	private static Type s_inputType;

	private static Type s_keyCodeType;

	private static Type s_labyrinthineInputManagerType;

	private static Type s_inputButtonType;

	private static Type s_playerNetworkSyncType;

	private static Type s_gameManagerType;

	private static Type s_objectType;

	private static Type s_rndPlayerInventoryType;

	private static Type s_rndCollectibleType;

	private static Type s_customizationPickupType;

	private static Type s_customCaseItemUnlockType;

	private static Type s_customizationManagerType;

	private static Type s_localisationManagerType;

	private static Type s_objectiveUiType;

	private static Type s_tmpTextType;

	private static Type s_tmpFontAssetType;

	private static Type s_canvasType;

	private static Type s_componentType;

	private static Type s_gameObjectType;

	private static Type s_transformType;

	private static Type s_rectTransformType;

	private static Type s_resourcesType;

	private static Type s_textMeshProUguiType;

	private static Type s_renderModeType;

	private static Type s_textAlignmentOptionsType;

	private static Type s_textOverflowModesType;

	private static ConstructorInfo s_rectCtor;

	private static ConstructorInfo s_colorCtor;

	private static ConstructorInfo s_vector2Ctor;

	private static ConstructorInfo s_gameObjectCtor;

	private static ConstructorInfo s_gameObjectWithComponentsCtor;

	private static MethodInfo s_guiLabel;

	private static MethodInfo s_inputGetKey;

	private static MethodInfo s_gameGetButton;

	private static MethodInfo s_findObjectsOfTypeMethod;

	private static MethodInfo s_componentGetComponentInParentMethod;

	private static MethodInfo s_gameObjectGetComponentMethod;

	private static MethodInfo s_gameObjectAddComponentMethod;

	private static MethodInfo s_gameObjectSetActiveMethod;

	private static MethodInfo s_transformSetParentMethod;

	private static MethodInfo s_transformSetAsLastSiblingMethod;

	private static MethodInfo s_objectInstantiateMethod;

	private static MethodInfo s_objectDestroyMethod;

	private static MethodInfo s_objectDontDestroyOnLoadMethod;

	private static MethodInfo s_resourcesFindObjectsOfTypeAllMethod;

	private static PropertyInfo s_guiColorProperty;

	private static PropertyInfo s_screenWidthProperty;

	private static PropertyInfo s_screenHeightProperty;

	private static PropertyInfo s_guiSkinProperty;

	private static PropertyInfo s_guiSkinLabelProperty;

	private static PropertyInfo s_styleFontSizeProperty;

	private static PropertyInfo s_styleNormalProperty;

	private static PropertyInfo s_styleStateTextColorProperty;

	private static object s_keyCodeTab;

	private static object s_showTabMenuButton;

	private static object s_tmpOverlayRoot;

	private static object s_tmpOverlayTextObject;

	private static object s_tmpOverlayText;

	private static object s_tmpOverlayRectTransform;

	private static object s_larkeSansFont;

	private static bool s_reflectionReady;

	public override void OnInitializeMelon()
	{
		MelonPreferences_Category obj = MelonPreferences.CreateCategory("PickupTabOverlay");
		s_enabled = obj.CreateEntry<bool>("Enabled", true, "Show local pickup inventory while the tab menu is open.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_panelWidth = obj.CreateEntry<int>("PanelWidth", 320, "Pickup panel width in pixels.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_showIds = obj.CreateEntry<bool>("ShowItemIDs", true, "Show random-case item IDs next to pickup names.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_showHandLabels = obj.CreateEntry<bool>("ShowHandLabels", true, "Mark currently selected left/right hand pickup items.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_showEmptyMessage = obj.CreateEntry<bool>("ShowEmptyMessage", true, "Show a small message when no pickups are held.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_showCollectibles = obj.CreateEntry<bool>("ShowCollectibles", true, "Show random-case collectibles picked up during the current run.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_showUnlockPickups = obj.CreateEntry<bool>("ShowUnlockPickups", true, "Show cosmetic, blueprint, and stamp pickups during the current run.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_legacyDebugLogging = obj.CreateEntry<bool>("DebugLogging", false, "Legacy pickup overlay diagnostics flag.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_debugLogging = obj.CreateEntry<bool>("VerboseLogs", false, "Log pickup overlay diagnostics for troubleshooting.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_useTextMeshProOverlay = obj.CreateEntry<bool>("UseTextMeshProOverlay", true, "Draw the pickup panel using TextMeshPro instead of IMGUI.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_useObjectiveTextStyle = obj.CreateEntry<bool>("UseObjectiveTextStyle", true, "Use the game's live objective text size and color when available.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_objectiveTextScalePercent = obj.CreateEntry<int>("ObjectiveTextScalePercent", 100, "Multiplier for objective-derived pickup overlay text size.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_headerFontSize = obj.CreateEntry<int>("HeaderFontSize", 30, "Pickup panel header font size.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_rowFontSize = obj.CreateEntry<int>("RowFontSize", 28, "Pickup panel row font size.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_footerFontSize = obj.CreateEntry<int>("FooterFontSize", 24, "Pickup panel footer font size.", (string)null, false, false, (ValueValidator)null, (string)null);
		s_maxVisibleItems = obj.CreateEntry<int>("MaxVisibleItems", 12, "Maximum pickup rows to show before collapsing the rest.", (string)null, false, false, (ValueValidator)null, (string)null);
		TryPatchCollectiblePickup();
		TryPatchCustomizationPickup();
		TryPatchCustomCaseItemUnlock();
		LogDebug("PickupTabOverlay initialized.");
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		DestroyTmpOverlay();
		s_entries.Clear();
		s_collectiblesFound.Clear();
		s_countedCollectibles.Clear();
		s_unlockEntries.Clear();
		s_unlockEntryIndexes.Clear();
		s_countedUnlockPickups.Clear();
		s_undiscoveredCosmeticItemIds.Clear();
		s_nextRefreshUtc = DateTime.MinValue;
		s_nextObjectiveStyleRefreshUtc = DateTime.MinValue;
		s_objectiveTextStyle = ObjectiveTextStyle.Fallback;
		s_lastLoggedObjectiveStyleSignature = null;
		s_lastLoggedRendererSignature = null;
		s_lastLoggedTmpSourceSignature = null;
		s_lastLoggedTmpDiagnosticsSignature = null;
		s_lastLoggedTmpLayoutSignature = null;
		s_lastLoggedDirectTmpFailure = null;
		s_nextTmpDiagnosticsUtc = DateTime.MinValue;
	}

	private static void TryPatchCollectiblePickup()
	{
		//IL_0033: 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_005d: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = GetRndCollectibleType()?.GetMethod("Pickup", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (methodInfo == null)
			{
				MelonLogger.Warning("Could not find RndCollectible.Pickup; random collectibles will not be tracked.");
				return;
			}
			new Harmony("kp0hyc.pickuptaboverlay").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PickupTabOverlay).GetMethod("RndCollectiblePickupPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			LogDebug("Patched RndCollectible.Pickup for collectible tracking.");
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Could not patch RndCollectible.Pickup: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void TryPatchCustomizationPickup()
	{
		//IL_0033: 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_005d: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = GetCustomizationPickupType()?.GetMethod("Pickup", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (methodInfo == null)
			{
				MelonLogger.Warning("Could not find CustomizationPickup.Pickup; cosmetic pickups will not be tracked.");
				return;
			}
			new Harmony("kp0hyc.pickuptaboverlay").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PickupTabOverlay).GetMethod("CustomizationPickupPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			LogDebug("Patched CustomizationPickup.Pickup for cosmetic tracking.");
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Could not patch CustomizationPickup.Pickup: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void TryPatchCustomCaseItemUnlock()
	{
		//IL_0033: 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_005d: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = GetCustomCaseItemUnlockType()?.GetMethod("Pickup", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (methodInfo == null)
			{
				MelonLogger.Warning("Could not find CustomCaseItemUnlock.Pickup; blueprint/stamp pickups will not be tracked.");
				return;
			}
			new Harmony("kp0hyc.pickuptaboverlay").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PickupTabOverlay).GetMethod("CustomCaseItemUnlockPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			LogDebug("Patched CustomCaseItemUnlock.Pickup for blueprint/stamp tracking.");
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Could not patch CustomCaseItemUnlock.Pickup: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void RndCollectiblePickupPrefix(object __instance)
	{
		try
		{
			if (__instance == null)
			{
				return;
			}
			int hashCode = RuntimeHelpers.GetHashCode(__instance);
			if (!s_countedCollectibles.Contains(hashCode) && TryClassifyCollectible(__instance, out var label, out var amount))
			{
				s_countedCollectibles.Add(hashCode);
				if (!s_collectiblesFound.TryGetValue(label, out var value))
				{
					value = 0;
				}
				s_collectiblesFound[label] = value + amount;
			}
		}
		catch (Exception ex)
		{
			LogWarning("collectible pickup tracking failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void CustomizationPickupPrefix(object __instance)
	{
		try
		{
			if (__instance == null)
			{
				return;
			}
			int hashCode = RuntimeHelpers.GetHashCode(__instance);
			if (!s_countedUnlockPickups.Contains(hashCode) && TryConvertInt(GetFieldOrProp(__instance, "ItemID") ?? GetFieldOrProp(__instance, "itemID"), out var result))
			{
				s_countedUnlockPickups.Add(hashCode);
				bool flag = IsCustomizationItemAlreadyUnlocked(result);
				if (!flag)
				{
					s_undiscoveredCosmeticItemIds.Add(result);
				}
				string text = (s_undiscoveredCosmeticItemIds.Contains(result) ? "Undiscovered item" : ResolveCustomizationName(result));
				if (string.IsNullOrWhiteSpace(text))
				{
					text = CleanPickupObjectName(__instance, "Cosmetic");
				}
				string text2 = ResolveCustomizationClass(result);
				AddUnlockEntry("Cosmetic", text, result, text2);
				LogDebug("Cosmetic pickup itemID=" + result + " alreadyUnlocked=" + flag + " class=" + (text2 ?? "{unknown}") + " name=" + text);
			}
		}
		catch (Exception ex)
		{
			LogWarning("cosmetic pickup tracking failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void CustomCaseItemUnlockPrefix(object __instance)
	{
		try
		{
			if (__instance == null)
			{
				return;
			}
			int hashCode = RuntimeHelpers.GetHashCode(__instance);
			if (!s_countedUnlockPickups.Contains(hashCode))
			{
				bool flag = false;
				bool flag2 = false;
				if (TryConvertBool(GetFieldOrProp(__instance, "unlockMazeType"), out var result) && result)
				{
					object fieldOrProp = GetFieldOrProp(__instance, "mazeType");
					AddUnlockEntry("Map Blueprint", "Picked up", -1);
					LogDebug("Map blueprint pickup mazeType=" + FormatEnumValue(fieldOrProp, "Map"));
					flag = true;
					flag2 = true;
				}
				if (TryConvertBool(GetFieldOrProp(__instance, "unlockMonsterType"), out var result2) && result2)
				{
					object fieldOrProp2 = GetFieldOrProp(__instance, "monsterType");
					LogDebug("Unexpected monster blueprint pickup monsterType=" + FormatEnumValue(fieldOrProp2, "Monster"));
					flag = true;
				}
				if (TryConvertBool(GetFieldOrProp(__instance, "unlockContractType"), out var result3) && result3)
				{
					object fieldOrProp3 = GetFieldOrProp(__instance, "contractType");
					AddUnlockEntry("Stamps", "Collected", -1);
					LogDebug("Stamp pickup contractType=" + FormatEnumValue(fieldOrProp3, "Contract"));
					flag = true;
					flag2 = true;
				}
				if (!flag)
				{
					AddUnlockEntry("Blueprint", CleanPickupObjectName(__instance, "Custom Case Unlock"), -1);
					flag2 = true;
					LogDebug("Unknown custom-case unlock pickup name=" + CleanPickupObjectName(__instance, "Custom Case Unlock"));
				}
				else if (!flag2)
				{
					LogDebug("Custom-case unlock pickup had no visible overlay row.");
				}
				s_countedUnlockPickups.Add(hashCode);
			}
		}
		catch (Exception ex)
		{
			LogWarning("blueprint/stamp pickup tracking failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static bool TryClassifyCollectible(object collectible, out string label, out int amount)
	{
		label = null;
		if (!TryConvertInt(GetFieldOrProp(collectible, "amount"), out amount) || amount <= 0)
		{
			amount = 1;
		}
		object fieldOrProp = GetFieldOrProp(collectible, "collectibleType");
		string text = ((fieldOrProp == null) ? string.Empty : fieldOrProp.ToString());
		string collectibleObjectName = GetCollectibleObjectName(collectible);
		string text2 = (text + " " + collectibleObjectName + " " + (GetFieldOrProp(collectible, "pickupMessage") ?? string.Empty)).ToLowerInvariant();
		if (text2.Contains("ticket"))
		{
			label = "Tickets";
			return true;
		}
		if (text.IndexOf("Reroll", StringComparison.OrdinalIgnoreCase) >= 0 || text2.Contains("reroll"))
		{
			label = "Reroll Coins";
			return true;
		}
		return false;
	}

	private static string GetCollectibleObjectName(object collectible)
	{
		string text = GetFieldOrProp(GetFieldOrProp(collectible, "gameObject") ?? collectible, "name") as string;
		if (!string.IsNullOrWhiteSpace(text))
		{
			return text;
		}
		return string.Empty;
	}

	private static void AddUnlockEntry(string category, string name, int id, string itemClass = null)
	{
		if (string.IsNullOrWhiteSpace(category))
		{
			category = "Unlock";
		}
		if (string.IsNullOrWhiteSpace(name))
		{
			name = "Unknown";
		}
		name = CleanUnityName(name);
		itemClass = FormatItemClass(itemClass);
		string key = category + "|" + id + "|" + itemClass + "|" + name;
		if (s_unlockEntryIndexes.TryGetValue(key, out var value) && value >= 0 && value < s_unlockEntries.Count)
		{
			s_unlockEntries[value] = s_unlockEntries[value].WithCount(s_unlockEntries[value].Count + 1);
			return;
		}
		s_unlockEntryIndexes[key] = s_unlockEntries.Count;
		s_unlockEntries.Add(new UnlockEntry(category, name, id, itemClass, 1));
	}

	private static string ResolveCustomizationName(int itemId)
	{
		if (s_customizationNameCache.TryGetValue(itemId, out var value))
		{
			return value;
		}
		string text = null;
		if (TryGetShandadaItemInfo(itemId, out var info) && !string.IsNullOrWhiteSpace(info.Name))
		{
			text = info.Name;
		}
		object obj = TryGetCustomizationItem(itemId);
		if (obj != null && string.IsNullOrWhiteSpace(text))
		{
			text = GetFieldOrProp(obj, "Name") as string;
			if (string.IsNullOrWhiteSpace(text))
			{
				text = GetLocalisation(GetFieldOrProp(obj, "LocalisationKey") as string, null);
			}
		}
		if (!string.IsNullOrWhiteSpace(text))
		{
			s_customizationNameCache[itemId] = text;
			return text;
		}
		return null;
	}

	private static object TryGetCustomizationItem(int itemId)
	{
		try
		{
			object customizationCollection = GetCustomizationCollection();
			if (customizationCollection == null || itemId < 0 || itemId > 65535)
			{
				return null;
			}
			MethodInfo methodInfo = customizationCollection.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "TryGetItem" && m.GetParameters().Length == 2);
			if (methodInfo == null)
			{
				return null;
			}
			object[] array = new object[2]
			{
				(ushort)itemId,
				null
			};
			if (TryConvertBool(methodInfo.Invoke(customizationCollection, array), out var result) && result)
			{
				return array[1];
			}
		}
		catch
		{
		}
		return null;
	}

	private static string ResolveCustomizationClass(int itemId)
	{
		if (s_customizationClassCache.TryGetValue(itemId, out var value))
		{
			return value;
		}
		string text = null;
		if (TryGetShandadaItemInfo(itemId, out var info))
		{
			text = info.ItemClass;
		}
		if (string.IsNullOrWhiteSpace(text))
		{
			object obj = TryGetCustomizationItem(itemId);
			text = (GetFieldOrProp(obj, "ItemRarity") ?? GetFieldOrProp(obj, "itemRarity"))?.ToString();
		}
		text = FormatItemClass(text);
		if (!string.IsNullOrWhiteSpace(text))
		{
			s_customizationClassCache[itemId] = text;
		}
		return text;
	}

	private static bool TryGetShandadaItemInfo(int itemId, out ShandadaItemInfo info)
	{
		EnsureShandadaItemsLoaded();
		return s_shandadaItems.TryGetValue(itemId, out info);
	}

	private static void EnsureShandadaItemsLoaded()
	{
		if (s_shandadaItemsLoaded)
		{
			return;
		}
		s_shandadaItemsLoaded = true;
		try
		{
			Assembly assembly = typeof(PickupTabOverlay).Assembly;
			string text = assembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith("shandada_game_item_id_map.json", StringComparison.OrdinalIgnoreCase));
			if (string.IsNullOrWhiteSpace(text))
			{
				LogDebug("Embedded Shandadapanda item map was not found.");
				return;
			}
			using Stream stream = assembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				return;
			}
			using JsonDocument jsonDocument = JsonDocument.Parse(stream);
			if (!jsonDocument.RootElement.TryGetProperty("gameToWebsite", out var value) || value.ValueKind != JsonValueKind.Array)
			{
				return;
			}
			foreach (JsonElement item in value.EnumerateArray())
			{
				if (TryGetJsonInt(item, "gameItemId", out var value2) && value2 >= 0)
				{
					string jsonString = GetJsonString(item, "websiteName");
					string text2 = GetJsonString(item, "class") ?? GetJsonString(item, "websiteMapClass") ?? GetJsonString(item, "websiteEvent");
					if (!string.IsNullOrWhiteSpace(jsonString) || !string.IsNullOrWhiteSpace(text2))
					{
						s_shandadaItems[value2] = new ShandadaItemInfo(jsonString, text2);
					}
				}
			}
			LogDebug("Loaded " + s_shandadaItems.Count + " Shandadapanda item names.");
		}
		catch (Exception ex)
		{
			LogWarning("Shandadapanda item map load failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static bool TryGetJsonInt(JsonElement element, string name, out int value)
	{
		value = 0;
		if (!element.TryGetProperty(name, out var value2))
		{
			return false;
		}
		if (value2.ValueKind == JsonValueKind.Number)
		{
			return value2.TryGetInt32(out value);
		}
		if (value2.ValueKind == JsonValueKind.String)
		{
			return int.TryParse(value2.GetString(), out value);
		}
		return false;
	}

	private static string GetJsonString(JsonElement element, string name)
	{
		if (!element.TryGetProperty(name, out var value) || value.ValueKind != JsonValueKind.String)
		{
			return null;
		}
		return value.GetString();
	}

	private static string FormatItemClass(string itemClass)
	{
		if (string.IsNullOrWhiteSpace(itemClass))
		{
			return null;
		}
		itemClass = itemClass.Trim();
		int num = itemClass.LastIndexOf('.');
		if (num >= 0 && num + 1 < itemClass.Length)
		{
			itemClass = itemClass.Substring(num + 1);
		}
		itemClass = CleanUnityName(itemClass).Trim();
		if (!string.IsNullOrWhiteSpace(itemClass))
		{
			return itemClass.ToLowerInvariant();
		}
		return null;
	}

	private static object GetCustomizationCollection()
	{
		object customizationManager = GetCustomizationManager();
		return GetFieldOrProp(customizationManager, "Collection") ?? GetFieldOrProp(customizationManager, "collection");
	}

	private static object GetCustomizationManager()
	{
		Type customizationManagerType = GetCustomizationManagerType();
		return GetStaticFieldOrProp(customizationManagerType, "Instance") ?? FindFirstObjectOfType(customizationManagerType);
	}

	private static bool IsCustomizationItemAlreadyUnlocked(int itemId)
	{
		if (itemId < 0 || itemId > 65535)
		{
			return false;
		}
		if (TryIsCustomizationItemUnlocked(GetCurrentCustomizationSave(), itemId, out var unlocked))
		{
			return unlocked;
		}
		if (TryUnlockedItemsListContains(GetFieldOrProp(GetCustomizationManager(), "UnlockedItems"), itemId, out unlocked))
		{
			return unlocked;
		}
		LogDebug("Could not determine cosmetic unlock state for itemID=" + itemId + "; hiding name.");
		return false;
	}

	private static bool TryIsCustomizationItemUnlocked(object customizationSave, int itemId, out bool unlocked)
	{
		unlocked = false;
		if (customizationSave == null || itemId < 0 || itemId > 65535)
		{
			return false;
		}
		try
		{
			return TryConvertBool(customizationSave.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "IsItemUnlocked" && m.GetParameters().Length == 1)?.Invoke(customizationSave, new object[1] { (ushort)itemId }), out unlocked);
		}
		catch
		{
			unlocked = false;
			return false;
		}
	}

	private static bool TryUnlockedItemsListContains(object list, int itemId, out bool unlocked)
	{
		unlocked = false;
		if (list == null)
		{
			return false;
		}
		foreach (object item in EnumerateItems(list))
		{
			if (TryConvertInt(item, out var result) && result == itemId)
			{
				unlocked = true;
				return true;
			}
		}
		return true;
	}

	private static object GetCurrentCustomizationSave()
	{
		return GetFieldOrProp(GetCustomizationManager(), "CustomizationSave");
	}

	private static object LoadCustomizationSave()
	{
		try
		{
			return (FindType("CharacterCustomization.CustomizationSave")?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Load" && m.GetParameters().Length == 0))?.Invoke(null, Array.Empty<object>());
		}
		catch
		{
			return null;
		}
	}

	private static string GetLocalisation(string key, string defaultValue)
	{
		if (string.IsNullOrWhiteSpace(key))
		{
			return defaultValue;
		}
		try
		{
			string text = (GetLocalisationManagerType()?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GetLocalisation" && m.GetParameters().Length == 2))?.Invoke(null, new object[2] { key, defaultValue }) as string;
			return string.IsNullOrWhiteSpace(text) ? defaultValue : text;
		}
		catch
		{
			return defaultValue;
		}
	}

	private static string FormatEnumValue(object value, string fallback)
	{
		if (value == null)
		{
			return fallback;
		}
		string text = value.ToString();
		if (string.IsNullOrWhiteSpace(text))
		{
			return fallback;
		}
		return CleanUnityName(text);
	}

	private static string CleanPickupObjectName(object pickup, string fallback)
	{
		string text = GetFieldOrProp(GetFieldOrProp(pickup, "gameObject") ?? pickup, "name") as string;
		if (string.IsNullOrWhiteSpace(text))
		{
			return fallback;
		}
		string text2 = CleanUnityName(text);
		if (text2.StartsWith("CPickup - ", StringComparison.OrdinalIgnoreCase))
		{
			text2 = text2.Substring("CPickup - ".Length).Trim();
		}
		if (!string.IsNullOrWhiteSpace(text2))
		{
			return text2;
		}
		return fallback;
	}

	public override void OnUpdate()
	{
		if (s_enabled == null || !s_enabled.Value)
		{
			SetTmpOverlayVisible(visible: false);
			return;
		}
		DateTime utcNow = DateTime.UtcNow;
		if (utcNow >= s_nextRefreshUtc)
		{
			s_nextRefreshUtc = utcNow.AddMilliseconds(250.0);
			try
			{
				RefreshPickupEntries();
			}
			catch (Exception ex)
			{
				LogWarning("pickup refresh failed: " + ex.GetType().Name + " " + ex.Message);
			}
		}
		try
		{
			UpdateTmpOverlay();
		}
		catch (Exception ex2)
		{
			ResetTmpOverlayState(failed: false);
			LogWarning("TextMeshPro pickup overlay update failed: " + ex2.GetType().Name + " " + ex2.Message);
		}
	}

	public override void OnGUI()
	{
		if (s_enabled == null || !s_enabled.Value || !EnsureReflection() || !IsTabMenuPressed() || (!HasAnyDisplayedPickup() && (s_showEmptyMessage == null || !s_showEmptyMessage.Value)) || (IsTextMeshProOverlayEnabled() && s_tmpOverlayReady))
		{
			return;
		}
		try
		{
			DrawPickupPanel();
		}
		catch (Exception ex)
		{
			LogWarning("pickup overlay draw failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static void RefreshPickupEntries()
	{
		s_entries.Clear();
	}

	private static void DrawPickupPanel()
	{
		int val = Clamp((s_maxVisibleItems == null) ? 12 : s_maxVisibleItems.Value, 1, 40);
		ObjectiveTextStyle textStyle = ResolveTextStyle();
		LogOverlayRenderer("IMGUI fallback", GetFallbackRendererReason() + " " + DescribeTextStyleForLog(textStyle));
		List<CollectibleEntry> collectibleRows = GetCollectibleRows();
		List<UnlockEntry> unlockRows = GetUnlockRows();
		float width = ResolveOverlayWidth(unlockRows);
		int num = Math.Min(s_entries.Count, val);
		float singleRowHeight = GetSingleRowHeight(textStyle.RowFontSize);
		float num2 = ((s_entries.Count > num) ? Math.Max(20f, (float)textStyle.FooterFontSize + 8f) : 0f);
		float num3 = collectibleRows.Sum((CollectibleEntry row) => EstimateDisplayRowHeight(row.Label + ": " + row.Amount, textStyle.RowFontSize, width));
		float num4 = unlockRows.Sum((UnlockEntry row) => EstimateDisplayRowHeight(FormatUnlockEntry(row), textStyle.RowFontSize, width));
		float num5 = ((!HasAnyDisplayedPickup()) ? singleRowHeight : 0f);
		float num6 = num3 + num4 + (float)num * singleRowHeight + num2 + num5 + 8f;
		float num7 = 34f;
		float x = Math.Max(12f, (float)ScreenWidth() - width - num7);
		float num8 = Math.Max(12f, (float)ScreenHeight() - num6 - num7);
		foreach (CollectibleEntry item in collectibleRows)
		{
			string text = item.Label + ": " + item.Amount;
			float num9 = EstimateDisplayRowHeight(text, textStyle.RowFontSize, width);
			LabelShadowed(x, num8, width, num9, text, textStyle.RowFontSize, textStyle.Color);
			num8 += num9;
		}
		foreach (UnlockEntry item2 in unlockRows)
		{
			string text2 = FormatUnlockEntry(item2);
			float num10 = EstimateDisplayRowHeight(text2, textStyle.RowFontSize, width);
			LabelShadowed(x, num8, width, num10, text2, textStyle.RowFontSize, textStyle.Color);
			num8 += num10;
		}
		if (!HasAnyDisplayedPickup())
		{
			LabelShadowed(x, num8, width, singleRowHeight, "No pickups", textStyle.RowFontSize, textStyle.MutedColor);
			return;
		}
		for (int num11 = 0; num11 < num; num11++)
		{
			PickupEntry entry = s_entries[num11];
			LabelShadowed(x, num8, width, singleRowHeight, FormatEntry(entry), textStyle.RowFontSize, textStyle.Color);
			num8 += singleRowHeight;
		}
		if (s_entries.Count > num)
		{
			int num12 = s_entries.Count - num;
			LabelShadowed(x, num8, width, num2, "+ " + num12 + " more", textStyle.FooterFontSize, textStyle.MutedColor);
		}
	}

	private static void UpdateTmpOverlay()
	{
		if (!IsTextMeshProOverlayEnabled())
		{
			SetTmpOverlayVisible(visible: false);
		}
		else
		{
			if (!EnsureReflection())
			{
				return;
			}
			if (!IsTabMenuPressed() || (!HasAnyDisplayedPickup() && (s_showEmptyMessage == null || !s_showEmptyMessage.Value)))
			{
				SetTmpOverlayVisible(visible: false);
				return;
			}
			ObjectiveTextStyle objectiveTextStyle = ResolveTextStyle();
			TmpOverlayModel model = BuildTmpOverlayModel(objectiveTextStyle);
			if (EnsureTmpOverlay())
			{
				LogOverlayRenderer(s_tmpOverlayUsesDirectUi ? "TextMeshPro direct UI" : "TextMeshPro cloned UI", DescribeTextStyleForLog(objectiveTextStyle));
				ApplyTmpTextStyle(objectiveTextStyle);
				ApplyTmpLayout(model.Width, model.Height);
				ApplyTmpText(model.Text, model.StyleKey);
				LogTmpLayoutDiagnostics(objectiveTextStyle, model);
				SetTmpOverlayVisible(visible: true);
			}
		}
	}

	private static bool IsTextMeshProOverlayEnabled()
	{
		if (s_useTextMeshProOverlay != null)
		{
			return s_useTextMeshProOverlay.Value;
		}
		return true;
	}

	private static TmpOverlayModel BuildTmpOverlayModel(ObjectiveTextStyle textStyle)
	{
		int val = Clamp((s_maxVisibleItems == null) ? 12 : s_maxVisibleItems.Value, 1, 40);
		List<CollectibleEntry> collectibleRows = GetCollectibleRows();
		List<UnlockEntry> unlockRows = GetUnlockRows();
		float width = ResolveOverlayWidth(unlockRows);
		int num = Math.Min(s_entries.Count, val);
		float singleRowHeight = GetSingleRowHeight(textStyle.RowFontSize);
		float num2 = ((s_entries.Count > num) ? Math.Max(20f, (float)textStyle.FooterFontSize + 8f) : 0f);
		float num3 = ((!HasAnyDisplayedPickup()) ? singleRowHeight : 0f) + (float)num * singleRowHeight + num2 + 10f;
		StringBuilder stringBuilder = new StringBuilder();
		foreach (CollectibleEntry item in collectibleRows)
		{
			string text = item.Label + ": " + item.Amount;
			num3 += EstimateDisplayRowHeight(text, textStyle.RowFontSize, width);
			AppendTmpLine(stringBuilder, text, textStyle.RowFontSize, muted: false);
		}
		foreach (UnlockEntry item2 in unlockRows)
		{
			string text2 = FormatUnlockEntry(item2);
			num3 += EstimateDisplayRowHeight(text2, textStyle.RowFontSize, width);
			AppendTmpLine(stringBuilder, text2, textStyle.RowFontSize, muted: false);
		}
		if (!HasAnyDisplayedPickup())
		{
			AppendTmpLine(stringBuilder, "No pickups", textStyle.RowFontSize, muted: true);
		}
		else
		{
			for (int i = 0; i < num; i++)
			{
				AppendTmpLine(stringBuilder, FormatEntry(s_entries[i]), textStyle.RowFontSize, muted: false);
			}
		}
		if (s_entries.Count > num)
		{
			AppendTmpLine(stringBuilder, "+ " + (s_entries.Count - num) + " more", textStyle.FooterFontSize, muted: true);
		}
		return new TmpOverlayModel(stringBuilder.ToString().TrimEnd('\n'), width, num3, textStyle.StyleKey);
	}

	private static float ResolveOverlayWidth(List<UnlockEntry> unlockRows)
	{
		int num = Clamp((s_panelWidth == null) ? 320 : s_panelWidth.Value, 220, 900);
		int value = (unlockRows.Any((UnlockEntry row) => string.Equals(row.Category, "Cosmetic", StringComparison.OrdinalIgnoreCase)) ? Math.Max(num, 680) : num);
		int val = Math.Max(220, ScreenWidth() - 80);
		return Clamp(value, 220, Math.Min(900, val));
	}

	private static float GetSingleRowHeight(int fontSize)
	{
		return Math.Max(30f, (float)fontSize + 10f);
	}

	private static float EstimateDisplayRowHeight(string text, int fontSize, float width)
	{
		int num = EstimateWrappedLineCount(text, fontSize, width);
		return Math.Max(GetSingleRowHeight(fontSize), (float)num * ((float)fontSize + 8f) + 4f);
	}

	private static int EstimateWrappedLineCount(string text, int fontSize, float width)
	{
		if (string.IsNullOrWhiteSpace(text))
		{
			return 1;
		}
		float num = Math.Max(80f, width - 8f);
		float num2 = Math.Max(7f, (float)fontSize * 0.54f);
		int num3 = Math.Max(8, (int)Math.Floor(num / num2));
		int num4 = 1;
		int num5 = 0;
		string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text2 in array)
		{
			int num6 = Math.Max(1, text2.Length);
			if (num5 == 0)
			{
				num4 += Math.Max(0, (num6 - 1) / num3);
				num5 = num6 % num3;
				if (num5 == 0)
				{
					num5 = num3;
				}
				continue;
			}
			if (num5 + 1 + num6 <= num3)
			{
				num5 += 1 + num6;
				continue;
			}
			num4++;
			num4 += Math.Max(0, (num6 - 1) / num3);
			num5 = num6 % num3;
			if (num5 == 0)
			{
				num5 = num3;
			}
		}
		return Math.Max(1, num4);
	}

	private static void AppendTmpLine(StringBuilder builder, string text, int fontSize, bool muted)
	{
		if (builder.Length > 0)
		{
			builder.Append('\n');
		}
		builder.Append(text ?? string.Empty);
	}

	private static string EscapeTmpRichText(string text)
	{
		if (string.IsNullOrEmpty(text))
		{
			return string.Empty;
		}
		return text.Replace("<", "&lt;").Replace(">", "&gt;");
	}

	private static bool EnsureTmpOverlay()
	{
		if (s_tmpOverlayReady && s_tmpOverlayRoot != null && s_tmpOverlayText != null && s_tmpOverlayRectTransform != null)
		{
			return true;
		}
		if (s_tmpOverlayFailed && DateTime.UtcNow < s_nextTmpOverlayRetryUtc)
		{
			return false;
		}
		try
		{
			if (TryCreateDirectTmpOverlay(out var failureReason))
			{
				return true;
			}
			LogDirectTmpFailure(failureReason);
			if (s_gameObjectType == null || s_rectTransformType == null || s_canvasType == null || s_textMeshProUguiType == null || s_textAlignmentOptionsType == null || s_vector2Ctor == null || s_objectInstantiateMethod == null)
			{
				LogTmpOverlayDiagnostics("required Unity/TMP types or methods are missing");
				return MarkTmpOverlayFailed("required Unity/TMP types are not available");
			}
			if (!TryFindTmpOverlaySource(out var sourceText))
			{
				LogTmpOverlayDiagnostics("source search found no usable active TMP source");
				s_nextTmpOverlayRetryUtc = DateTime.UtcNow.AddMilliseconds(500.0);
				return false;
			}
			string text = DescribeTmpTextSource(sourceText);
			if (!string.Equals(s_lastLoggedTmpSourceSignature, text, StringComparison.Ordinal))
			{
				s_lastLoggedTmpSourceSignature = text;
				LogDebug("TextMeshPro pickup overlay source " + text + ".");
			}
			object fieldOrProp = GetFieldOrProp(sourceText, "gameObject");
			object fieldOrProp2 = GetFieldOrProp(GetComponentInParent(sourceText, s_canvasType), "transform");
			if (fieldOrProp == null || fieldOrProp2 == null)
			{
				return MarkTmpOverlayFailed("objective TextMeshPro source has no canvas parent");
			}
			s_tmpOverlayRoot = CloneGameObject(fieldOrProp, fieldOrProp2);
			s_tmpOverlayTextObject = s_tmpOverlayRoot;
			s_tmpOverlayText = GetComponent(s_tmpOverlayTextObject, s_textMeshProUguiType);
			s_tmpOverlayRectTransform = GetComponent(s_tmpOverlayTextObject, s_rectTransformType);
			if (s_tmpOverlayText == null || s_tmpOverlayRectTransform == null)
			{
				return MarkTmpOverlayFailed("could not clone TextMeshProUGUI component");
			}
			SetFieldOrProp(s_tmpOverlayRoot, "name", "kp0hyc PickupTabOverlay Text");
			object fieldOrProp3 = GetFieldOrProp(s_tmpOverlayTextObject, "transform");
			s_transformSetAsLastSiblingMethod?.Invoke(fieldOrProp3, Array.Empty<object>());
			SetRectTransformAnchors(s_tmpOverlayRectTransform, 1f, 0f, 1f, 0f, 1f, 0f);
			SetFieldOrProp(s_tmpOverlayText, "alignment", Enum.Parse(s_textAlignmentOptionsType, "BottomRight"));
			SetFieldOrProp(s_tmpOverlayText, "richText", false);
			SetFieldOrProp(s_tmpOverlayText, "enableAutoSizing", false);
			SetFieldOrProp(s_tmpOverlayText, "enableWordWrapping", true);
			if (s_textOverflowModesType != null)
			{
				SetFieldOrProp(s_tmpOverlayText, "overflowMode", Enum.Parse(s_textOverflowModesType, "Overflow"));
			}
			SetFieldOrProp(s_tmpOverlayText, "raycastTarget", false);
			s_tmpOverlayReady = true;
			s_tmpOverlayFailed = false;
			s_tmpOverlayVisible = true;
			s_tmpOverlayUsesDirectUi = false;
			SetTmpOverlayVisible(visible: false);
			if (!s_loggedTmpOverlayReady)
			{
				s_loggedTmpOverlayReady = true;
				LogDebug("TextMeshPro pickup overlay created by cloning source UI.");
			}
			return true;
		}
		catch (Exception ex)
		{
			ResetTmpOverlayState(failed: true);
			LogWarning("TextMeshPro pickup overlay creation failed: " + ex.GetType().Name + " " + ex.Message);
			return false;
		}
	}

	private static bool TryCreateDirectTmpOverlay(out string failureReason)
	{
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		failureReason = null;
		GameObject val = null;
		GameObject val2 = null;
		try
		{
			if ((object)s_textMeshProUguiType == null)
			{
				s_textMeshProUguiType = typeof(TextMeshProUGUI);
			}
			if ((object)s_textAlignmentOptionsType == null)
			{
				s_textAlignmentOptionsType = typeof(TextAlignmentOptions);
			}
			if ((object)s_textOverflowModesType == null)
			{
				s_textOverflowModesType = typeof(TextOverflowModes);
			}
			RectTransform val3 = ResolveTmpOverlayParentTransform(GameObject.Find("Global/Global Canvas/Player_UI/Tab Menu"));
			if ((Object)(object)val3 == (Object)null)
			{
				failureReason = "game Tab Menu/Player_UI RectTransform is not available";
				return false;
			}
			val = new GameObject("kp0hyc PickupTabOverlay Root");
			val.transform.SetParent((Transform)(object)val3, false);
			RectTransform val4 = val.GetComponent<RectTransform>() ?? val.AddComponent<RectTransform>();
			val2 = new GameObject("kp0hyc PickupTabOverlay Text");
			val2.transform.SetParent(val.transform, false);
			RectTransform val5 = val2.GetComponent<RectTransform>() ?? val2.AddComponent<RectTransform>();
			TextMeshProUGUI val6 = val2.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)val6 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null)
			{
				failureReason = "created direct GameObjects but TextMeshProUGUI/RectTransform was null";
				Object.Destroy((Object)(object)val);
				return false;
			}
			val4.anchorMin = new Vector2(1f, 0f);
			val4.anchorMax = new Vector2(1f, 0f);
			val4.pivot = new Vector2(1f, 0f);
			val4.anchoredPosition = new Vector2(-34f, 34f);
			val5.anchorMin = new Vector2(0f, 0f);
			val5.anchorMax = new Vector2(1f, 1f);
			val5.pivot = new Vector2(1f, 0f);
			val5.offsetMin = Vector2.zero;
			val5.offsetMax = Vector2.zero;
			SetFieldOrProp(val6, "alignment", (object)(TextAlignmentOptions)1028);
			SetFieldOrProp(val6, "richText", false);
			SetFieldOrProp(val6, "enableAutoSizing", false);
			SetFieldOrProp(val6, "enableWordWrapping", true);
			SetFieldOrProp(val6, "overflowMode", (object)(TextOverflowModes)0);
			SetFieldOrProp(val6, "raycastTarget", false);
			SetFieldOrProp(val6, "text", string.Empty);
			SetFieldOrProp(val6, "fontSize", (float)Clamp((s_rowFontSize == null) ? 18 : s_rowFontSize.Value, 18, 72));
			SetFieldOrProp(val6, "color", ObjectiveColor());
			object obj = FindTmpFontByName("Larke Sans Regular SDF");
			if (obj != null)
			{
				SetFieldOrProp(val6, "font", obj);
			}
			s_tmpOverlayRoot = val;
			s_tmpOverlayTextObject = val2;
			s_tmpOverlayText = val6;
			s_tmpOverlayRectTransform = val4;
			s_tmpOverlayReady = true;
			s_tmpOverlayFailed = false;
			s_tmpOverlayVisible = true;
			s_tmpOverlayUsesDirectUi = true;
			SetTmpOverlayVisible(visible: false);
			if (!s_loggedTmpOverlayReady)
			{
				s_loggedTmpOverlayReady = true;
				LogDebug("TextMeshPro pickup overlay created with TellMeCosmetics-style direct UI setup.");
			}
			return true;
		}
		catch (Exception ex)
		{
			failureReason = ex.GetType().Name + " " + ex.Message;
			try
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			catch
			{
			}
			return false;
		}
	}

	private static RectTransform ResolveTmpOverlayParentTransform(GameObject tabMenu)
	{
		RectTransform val = (((Object)(object)tabMenu == (Object)null) ? null : tabMenu.GetComponent<RectTransform>());
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		GameObject val2 = GameObject.Find("Global/Global Canvas/Player_UI");
		RectTransform val3 = (((Object)(object)val2 == (Object)null) ? null : val2.GetComponent<RectTransform>());
		if ((Object)(object)val3 != (Object)null)
		{
			return val3;
		}
		GameObject val4 = GameObject.Find("Global/Global Canvas");
		RectTransform val5 = (((Object)(object)val4 == (Object)null) ? null : val4.GetComponent<RectTransform>());
		if ((Object)(object)val5 != (Object)null)
		{
			return val5;
		}
		return null;
	}

	private static void LogDirectTmpFailure(string failureReason)
	{
		if (string.IsNullOrWhiteSpace(failureReason))
		{
			failureReason = "unknown";
		}
		if (!string.Equals(s_lastLoggedDirectTmpFailure, failureReason, StringComparison.Ordinal))
		{
			s_lastLoggedDirectTmpFailure = failureReason;
			LogDebug("Direct TextMeshPro pickup overlay failed: " + failureReason);
		}
	}

	private static bool TryFindTmpOverlaySource(out object sourceText)
	{
		sourceText = null;
		if (IsUsableTmpOverlaySource(s_objectiveTextStyle.SourceText))
		{
			sourceText = s_objectiveTextStyle.SourceText;
			return true;
		}
		if (TryGetObjectiveTextStyleFromObjectiveUi(out var style) && IsUsableTmpOverlaySource(style.SourceText))
		{
			s_objectiveTextStyle = style;
			sourceText = style.SourceText;
			return true;
		}
		if (TryGetObjectiveTextStyleFromTmpScan(out var style2) && IsUsableTmpOverlaySource(style2.SourceText))
		{
			s_objectiveTextStyle = style2;
			sourceText = style2.SourceText;
			return true;
		}
		return false;
	}

	private static void LogTmpOverlayDiagnostics(string reason)
	{
		if (!IsDebugLoggingEnabled())
		{
			return;
		}
		DateTime utcNow = DateTime.UtcNow;
		if (!(utcNow < s_nextTmpDiagnosticsUtc))
		{
			string text = BuildTmpOverlayDiagnostics(reason);
			if (string.Equals(s_lastLoggedTmpDiagnosticsSignature, text, StringComparison.Ordinal))
			{
				s_nextTmpDiagnosticsUtc = utcNow.AddSeconds(5.0);
				return;
			}
			s_lastLoggedTmpDiagnosticsSignature = text;
			s_nextTmpDiagnosticsUtc = utcNow.AddSeconds(2.0);
			LogDebug(text);
		}
	}

	private static void LogTmpLayoutDiagnostics(ObjectiveTextStyle textStyle, TmpOverlayModel model)
	{
		if (IsDebugLoggingEnabled())
		{
			object rectTransform = ((s_tmpOverlayTextObject == null) ? null : GetComponent(s_tmpOverlayTextObject, s_rectTransformType));
			object componentInParent = GetComponentInParent(s_tmpOverlayText, s_canvasType);
			string b = (s_tmpOverlayUsesDirectUi ? "direct" : "cloned") + "|" + model.Width.ToString("0.#") + "|" + model.Height.ToString("0.#") + "|" + textStyle.RowFontSize + "|" + DescribeRectTransform(s_tmpOverlayRectTransform) + "|" + DescribeRectTransform(rectTransform) + "|" + GetCanvasScaleFactor(s_tmpOverlayText).ToString("0.##");
			if (!string.Equals(s_lastLoggedTmpLayoutSignature, b, StringComparison.Ordinal))
			{
				s_lastLoggedTmpLayoutSignature = b;
				LogDebug("TMP pickup layout renderer=" + (s_tmpOverlayUsesDirectUi ? "direct" : "cloned") + " screen=" + ScreenWidth() + "x" + ScreenHeight() + " model=" + model.Width.ToString("0.#") + "x" + model.Height.ToString("0.#") + " root={" + DescribeRectTransform(s_tmpOverlayRectTransform) + "} text={" + DescribeRectTransform(rectTransform) + "} rootScale=" + DescribeVector(GetFieldOrProp(GetFieldOrProp(s_tmpOverlayRoot, "transform"), "lossyScale")) + " textScale=" + DescribeVector(GetFieldOrProp(GetFieldOrProp(s_tmpOverlayTextObject, "transform"), "lossyScale")) + " canvasScale=" + GetCanvasScaleFactor(s_tmpOverlayText).ToString("0.##") + " canvas='" + TruncateForLog(GetUnityObjectName(componentInParent), 60) + "' " + DescribeTextStyleForLog(textStyle));
			}
		}
	}

	private static string BuildTmpOverlayDiagnostics(string reason)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("TMP diagnostics reason=");
		stringBuilder.Append(reason);
		stringBuilder.Append(" types={");
		stringBuilder.Append("GameObject=").Append(TypeNameForLog(s_gameObjectType));
		stringBuilder.Append(", RectTransform=").Append(TypeNameForLog(s_rectTransformType));
		stringBuilder.Append(", Canvas=").Append(TypeNameForLog(s_canvasType));
		stringBuilder.Append(", TMP_Text=").Append(TypeNameForLog(s_tmpTextType));
		stringBuilder.Append(", TextMeshProUGUI=").Append(TypeNameForLog(s_textMeshProUguiType));
		stringBuilder.Append(", TextAlignmentOptions=").Append(TypeNameForLog(s_textAlignmentOptionsType));
		stringBuilder.Append(", TextOverflowModes=").Append(TypeNameForLog(s_textOverflowModesType));
		stringBuilder.Append("} methods={");
		stringBuilder.Append("FindObjectsOfType=").Append(s_findObjectsOfTypeMethod != null);
		stringBuilder.Append(", GetComponentInParent=").Append(s_componentGetComponentInParentMethod != null);
		stringBuilder.Append(", GetComponent=").Append(s_gameObjectGetComponentMethod != null);
		stringBuilder.Append(", AddComponent=").Append(s_gameObjectAddComponentMethod != null);
		stringBuilder.Append(", Instantiate=").Append(s_objectInstantiateMethod != null);
		stringBuilder.Append(", SetActive=").Append(s_gameObjectSetActiveMethod != null);
		stringBuilder.Append("}");
		AppendObjectiveUiDiagnostics(stringBuilder);
		AppendTmpScanDiagnostics(stringBuilder, s_textMeshProUguiType, "TextMeshProUGUI");
		if (s_tmpTextType != null && (object)s_tmpTextType != s_textMeshProUguiType)
		{
			AppendTmpScanDiagnostics(stringBuilder, s_tmpTextType, "TMP_Text");
		}
		return stringBuilder.ToString();
	}

	private static void AppendObjectiveUiDiagnostics(StringBuilder builder)
	{
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		List<string> list = new List<string>();
		try
		{
			foreach (object item in FindObjectsOfType(GetObjectiveUiType()))
			{
				num++;
				if (IsActiveInHierarchy(item))
				{
					num2++;
				}
				object fieldOrProp = GetFieldOrProp(item, "displayText");
				if (fieldOrProp != null)
				{
					num3++;
					if (list.Count < 2)
					{
						list.Add(DescribeTmpTextSource(fieldOrProp));
					}
				}
				else if (list.Count < 2)
				{
					list.Add("objectiveUi='" + TruncateForLog(GetUnityObjectName(item), 50) + "' displayText=null");
				}
			}
		}
		catch (Exception ex)
		{
			list.Add("error=" + ex.GetType().Name + ":" + ex.Message);
		}
		builder.Append(" objectiveUI={total=").Append(num).Append(", active=")
			.Append(num2)
			.Append(", withDisplayText=")
			.Append(num3)
			.Append(", samples=[")
			.Append(string.Join("; ", list))
			.Append("]}");
	}

	private static void AppendTmpScanDiagnostics(StringBuilder builder, Type type, string label)
	{
		if (type == null)
		{
			builder.Append(" ").Append(label).Append("={type=null}");
			return;
		}
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		int num4 = 0;
		int num5 = 0;
		int num6 = 0;
		List<string> list = new List<string>();
		try
		{
			foreach (object item in FindObjectsOfType(type))
			{
				num++;
				bool flag = IsActiveInHierarchy(item);
				if (flag)
				{
					num2++;
				}
				if (IsPickupTmpOverlayObject(item))
				{
					num5++;
					continue;
				}
				if (!TryConvertFloat(GetFieldOrProp(item, "fontSize"), out var result) || result <= 1f)
				{
					num4++;
					if (list.Count < 4)
					{
						list.Add("noFontSize {" + DescribeTmpTextSource(item) + "}");
					}
					continue;
				}
				if (GetComponentInParent(item, s_canvasType) == null)
				{
					num6++;
					if (list.Count < 4)
					{
						list.Add("noCanvas {" + DescribeTmpTextSource(item) + "}");
					}
					continue;
				}
				num3++;
				if (list.Count < 4)
				{
					list.Add("usable active=" + flag + " {" + DescribeTmpTextSource(item) + "}");
				}
			}
		}
		catch (Exception ex)
		{
			list.Add("error=" + ex.GetType().Name + ":" + ex.Message);
		}
		builder.Append(" ").Append(label).Append("={total=")
			.Append(num)
			.Append(", active=")
			.Append(num2)
			.Append(", usable=")
			.Append(num3)
			.Append(", ownOverlay=")
			.Append(num5)
			.Append(", noFontSize=")
			.Append(num4)
			.Append(", noCanvas=")
			.Append(num6)
			.Append(", samples=[")
			.Append(string.Join("; ", list))
			.Append("]}");
	}

	private static bool IsUsableTmpOverlaySource(object sourceText)
	{
		if (sourceText == null || !IsActiveInHierarchy(sourceText))
		{
			return false;
		}
		if (GetFieldOrProp(sourceText, "gameObject") == null)
		{
			return false;
		}
		return GetComponentInParent(sourceText, s_canvasType) != null;
	}

	private static bool MarkTmpOverlayFailed(string reason)
	{
		ResetTmpOverlayState(failed: true);
		LogWarning("TextMeshPro pickup overlay unavailable: " + reason);
		return false;
	}

	private static void ApplyTmpTextStyle(ObjectiveTextStyle textStyle)
	{
		if (s_tmpOverlayText != null)
		{
			if (textStyle.Font != null)
			{
				SetFieldOrProp(s_tmpOverlayText, "font", textStyle.Font);
			}
			if (textStyle.FontSharedMaterial != null)
			{
				SetFieldOrProp(s_tmpOverlayText, "fontSharedMaterial", textStyle.FontSharedMaterial);
			}
			SetFieldOrProp(s_tmpOverlayText, "fontSize", (float)textStyle.RowFontSize);
			SetFieldOrProp(s_tmpOverlayText, "color", textStyle.Color ?? ObjectiveColor());
		}
	}

	private static void ApplyTmpLayout(float width, float height)
	{
		if (s_tmpOverlayRectTransform != null && (!(Math.Abs(width - s_tmpLastWidth) < 0.1f) || !(Math.Abs(height - s_tmpLastHeight) < 0.1f)))
		{
			s_tmpLastWidth = width;
			s_tmpLastHeight = height;
			SetFieldOrProp(s_tmpOverlayRectTransform, "sizeDelta", Vector2(width, height));
			SetFieldOrProp(s_tmpOverlayRectTransform, "anchoredPosition", Vector2(-34f, 34f));
		}
	}

	private static void ApplyTmpText(string text, int styleKey)
	{
		if (s_tmpOverlayText != null && (!string.Equals(s_tmpLastText, text, StringComparison.Ordinal) || s_tmpLastStyleKey != styleKey))
		{
			s_tmpLastText = text;
			s_tmpLastStyleKey = styleKey;
			SetFieldOrProp(s_tmpOverlayText, "text", text);
		}
	}

	private static void SetTmpOverlayVisible(bool visible)
	{
		if (s_tmpOverlayRoot == null || s_gameObjectSetActiveMethod == null || s_tmpOverlayVisible == visible)
		{
			return;
		}
		try
		{
			s_gameObjectSetActiveMethod.Invoke(s_tmpOverlayRoot, new object[1] { visible });
			s_tmpOverlayVisible = visible;
		}
		catch
		{
			ResetTmpOverlayState(failed: false);
		}
	}

	private static void DestroyTmpOverlay()
	{
		if (s_tmpOverlayRoot != null && s_objectDestroyMethod != null)
		{
			try
			{
				s_objectDestroyMethod.Invoke(null, new object[1] { s_tmpOverlayRoot });
			}
			catch
			{
			}
		}
		ResetTmpOverlayState(failed: false);
	}

	private static void ResetTmpOverlayState(bool failed)
	{
		s_tmpOverlayRoot = null;
		s_tmpOverlayTextObject = null;
		s_tmpOverlayText = null;
		s_tmpOverlayRectTransform = null;
		s_tmpOverlayReady = false;
		s_tmpOverlayVisible = false;
		s_tmpOverlayFailed = failed;
		s_tmpOverlayUsesDirectUi = false;
		s_nextTmpOverlayRetryUtc = (failed ? DateTime.UtcNow.AddSeconds(5.0) : DateTime.MinValue);
		s_loggedTmpOverlayReady = false;
		s_tmpLastText = null;
		s_tmpLastStyleKey = 0;
		s_tmpLastWidth = 0f;
		s_tmpLastHeight = 0f;
	}

	private static object CreateGameObject(string name, params Type[] components)
	{
		if (s_gameObjectWithComponentsCtor != null)
		{
			return s_gameObjectWithComponentsCtor.Invoke(new object[2] { name, components });
		}
		object obj = s_gameObjectCtor.Invoke(new object[1] { name });
		foreach (Type type in components)
		{
			s_gameObjectAddComponentMethod?.Invoke(obj, new object[1] { type });
		}
		return obj;
	}

	private static object CloneGameObject(object sourceGameObject, object parentTransform)
	{
		if (sourceGameObject == null || parentTransform == null || s_objectInstantiateMethod == null)
		{
			return null;
		}
		return s_objectInstantiateMethod.Invoke(null, new object[3] { sourceGameObject, parentTransform, false });
	}

	private static object GetComponent(object gameObject, Type componentType)
	{
		if (gameObject == null || componentType == null || s_gameObjectGetComponentMethod == null)
		{
			return null;
		}
		try
		{
			return s_gameObjectGetComponentMethod.Invoke(gameObject, new object[1] { componentType });
		}
		catch
		{
			return null;
		}
	}

	private static void SetRectTransformAnchors(object rectTransform, float anchorMinX, float anchorMinY, float anchorMaxX, float anchorMaxY, float pivotX, float pivotY)
	{
		SetFieldOrProp(rectTransform, "anchorMin", Vector2(anchorMinX, anchorMinY));
		SetFieldOrProp(rectTransform, "anchorMax", Vector2(anchorMaxX, anchorMaxY));
		SetFieldOrProp(rectTransform, "pivot", Vector2(pivotX, pivotY));
	}

	private static ObjectiveTextStyle ResolveTextStyle()
	{
		if (s_useObjectiveTextStyle != null && s_useObjectiveTextStyle.Value)
		{
			TryRefreshObjectiveTextStyle();
		}
		if (s_objectiveTextStyle.HasLiveStyle)
		{
			return s_objectiveTextStyle;
		}
		return ObjectiveTextStyle.FromConfig(Clamp((s_headerFontSize == null) ? 20 : s_headerFontSize.Value, 20, 76), Clamp((s_rowFontSize == null) ? 18 : s_rowFontSize.Value, 18, 72), Clamp((s_footerFontSize == null) ? 16 : s_footerFontSize.Value, 16, 68), ObjectiveColor());
	}

	private static void TryRefreshObjectiveTextStyle()
	{
		DateTime utcNow = DateTime.UtcNow;
		if (utcNow < s_nextObjectiveStyleRefreshUtc)
		{
			return;
		}
		s_nextObjectiveStyleRefreshUtc = utcNow.AddSeconds((!s_objectiveTextStyle.HasLiveStyle) ? 1 : 2);
		try
		{
			if (TryGetObjectiveTextStyleFromObjectiveUi(out var style) || TryGetObjectiveTextStyleFromTmpScan(out style))
			{
				s_objectiveTextStyle = style;
				string text = DescribeTextStyleForLog(style);
				if (!string.Equals(s_lastLoggedObjectiveStyleSignature, text, StringComparison.Ordinal))
				{
					s_lastLoggedObjectiveStyleSignature = text;
					LogDebug("Objective text style " + text);
				}
			}
		}
		catch (Exception ex)
		{
			LogWarning("objective text style refresh failed: " + ex.GetType().Name + " " + ex.Message);
		}
	}

	private static bool TryGetObjectiveTextStyleFromObjectiveUi(out ObjectiveTextStyle style)
	{
		style = ObjectiveTextStyle.Fallback;
		Type objectiveUiType = GetObjectiveUiType();
		if (objectiveUiType == null)
		{
			return false;
		}
		foreach (object item in FindObjectsOfType(objectiveUiType))
		{
			if (item != null && IsActiveInHierarchy(item) && TryGetTextStyleFromTmpText(GetFieldOrProp(item, "displayText"), "ObjectiveUI", out style))
			{
				return true;
			}
		}
		return false;
	}

	private static bool TryGetObjectiveTextStyleFromTmpScan(out ObjectiveTextStyle style)
	{
		style = ObjectiveTextStyle.Fallback;
		Type type = GetTextMeshProUguiType() ?? GetTmpTextType();
		if (type == null)
		{
			return false;
		}
		ObjectiveTextStyle objectiveTextStyle = ObjectiveTextStyle.Fallback;
		int num = int.MinValue;
		foreach (object item in FindObjectsOfType(type))
		{
			if (item != null && IsActiveInHierarchy(item) && !IsPickupTmpOverlayObject(item) && TryGetTextStyleFromTmpText(item, "TMP scan", out var style2))
			{
				int num2 = ScoreTmpTextCandidate(item, style2.RowFontSize);
				if (num2 > num)
				{
					num = num2;
					objectiveTextStyle = style2;
				}
			}
		}
		if (!objectiveTextStyle.HasLiveStyle)
		{
			return false;
		}
		style = objectiveTextStyle;
		return true;
	}

	private static int ScoreTmpTextCandidate(object tmpText, int rowFontSize)
	{
		int num = rowFontSize;
		if (TryConvertFloat(GetFieldOrProp(tmpText, "fontSize"), out var result))
		{
			num += (int)Math.Round(result * 10f);
		}
		string text = GetFieldOrProp(tmpText, "text") as string;
		if (!string.IsNullOrWhiteSpace(text))
		{
			if (text.Length > 3)
			{
				num += 100;
			}
			if (text == text.ToUpperInvariant())
			{
				num += 200;
			}
			if (text.IndexOf("Pickups", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num -= 500;
			}
		}
		string text2 = (GetFieldOrProp(GetFieldOrProp(tmpText, "gameObject"), "name") as string) ?? string.Empty;
		if (text2.IndexOf("objective", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			num += 10000;
		}
		if (text2.IndexOf("mission", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("task", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("quest", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			num += 2000;
		}
		if (text2.IndexOf("map", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("seed", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("monster", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("pickup", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			num -= 1000;
		}
		return num;
	}

	private static bool TryGetTextStyleFromTmpText(object tmpText, string source, out ObjectiveTextStyle style)
	{
		style = ObjectiveTextStyle.Fallback;
		if (tmpText == null)
		{
			return false;
		}
		if (!TryConvertFloat(GetFieldOrProp(tmpText, "fontSize"), out var result) || result <= 1f)
		{
			return false;
		}
		int num = Clamp((s_objectiveTextScalePercent == null) ? 100 : s_objectiveTextScalePercent.Value, 50, 200);
		int val = Clamp((s_rowFontSize == null) ? 18 : s_rowFontSize.Value, 18, 72);
		int val2 = Clamp((s_headerFontSize == null) ? 20 : s_headerFontSize.Value, 20, 76);
		int val3 = Clamp((s_footerFontSize == null) ? 16 : s_footerFontSize.Value, 16, 68);
		int num2 = Clamp(Math.Max((int)Math.Round(result * (float)num / 100f), val), 18, 84);
		int headerFontSize = Clamp(Math.Max(num2 + 2, val2), 20, 88);
		int footerFontSize = Clamp(Math.Max(num2 - 4, val3), 16, 76);
		object color = NormalizeTextColor(GetFieldOrProp(tmpText, "color"));
		object fieldOrProp = GetFieldOrProp(tmpText, "font");
		object fieldOrProp2 = GetFieldOrProp(tmpText, "fontSharedMaterial");
		style = new ObjectiveTextStyle(hasLiveStyle: true, source, headerFontSize, num2, footerFontSize, color, CopyColorWithAlpha(color, 0.82f), fieldOrProp, fieldOrProp2, tmpText);
		return true;
	}

	private static float GetCanvasScaleFactor(object component)
	{
		try
		{
			Type canvasType = GetCanvasType();
			if (canvasType == null)
			{
				return 1f;
			}
			object componentInParent = GetComponentInParent(component, canvasType);
			if (componentInParent == null)
			{
				return 1f;
			}
			float result;
			return (TryConvertFloat(GetFieldOrProp(componentInParent, "scaleFactor"), out result) && result > 0f) ? Clamp(result, 0.5f, 4f) : 1f;
		}
		catch
		{
			return 1f;
		}
	}

	private static object GetComponentInParent(object component, Type requestedType)
	{
		if (component == null || requestedType == null || s_componentGetComponentInParentMethod == null)
		{
			return null;
		}
		try
		{
			return s_componentGetComponentInParentMethod.Invoke(component, new object[1] { requestedType });
		}
		catch
		{
			return null;
		}
	}

	private static IEnumerable<object> FindObjectsOfType(Type type)
	{
		if (type == null || s_findObjectsOfTypeMethod == null)
		{
			yield break;
		}
		object list = null;
		try
		{
			list = s_findObjectsOfTypeMethod.Invoke(null, new object[1] { type });
		}
		catch
		{
		}
		foreach (object item in EnumerateItems(list))
		{
			if (item != null)
			{
				yield return item;
			}
		}
	}

	private static IEnumerable<object> FindResourceObjectsOfType(Type type)
	{
		if (type == null || s_resourcesFindObjectsOfTypeAllMethod == null)
		{
			yield break;
		}
		object list = null;
		try
		{
			list = s_resourcesFindObjectsOfTypeAllMethod.Invoke(null, new object[1] { type });
		}
		catch
		{
		}
		foreach (object item in EnumerateItems(list))
		{
			if (item != null)
			{
				yield return item;
			}
		}
	}

	private static object FindTmpFontByName(string name)
	{
		if (string.IsNullOrWhiteSpace(name))
		{
			return null;
		}
		if (s_larkeSansFont != null && string.Equals(GetFieldOrProp(s_larkeSansFont, "name")?.ToString(), name, StringComparison.OrdinalIgnoreCase))
		{
			return s_larkeSansFont;
		}
		foreach (object item in FindResourceObjectsOfType(s_tmpFontAssetType))
		{
			if (string.Equals(GetFieldOrProp(item, "name")?.ToString(), name, StringComparison.OrdinalIgnoreCase))
			{
				s_larkeSansFont = item;
				return item;
			}
		}
		return null;
	}

	private static bool HasAnyDisplayedPickup()
	{
		if (s_entries.Count <= 0 && GetCollectibleRows().Count <= 0)
		{
			return GetUnlockRows().Count > 0;
		}
		return true;
	}

	private static List<CollectibleEntry> GetCollectibleRows()
	{
		List<CollectibleEntry> list = new List<CollectibleEntry>();
		if (s_showCollectibles == null || !s_showCollectibles.Value)
		{
			return list;
		}
		AddCollectibleRow(list, "Tickets");
		AddCollectibleRow(list, "Reroll Coins");
		return list;
	}

	private static void AddCollectibleRow(List<CollectibleEntry> rows, string label)
	{
		if (s_collectiblesFound.TryGetValue(label, out var value) && value > 0)
		{
			rows.Add(new CollectibleEntry(label, value));
		}
	}

	private static List<UnlockEntry> GetUnlockRows()
	{
		if (s_showUnlockPickups == null || !s_showUnlockPickups.Value)
		{
			return new List<UnlockEntry>();
		}
		return s_unlockEntries.ToList();
	}

	private static string FormatEntry(PickupEntry entry)
	{
		string text = entry.Name;
		if (entry.Count > 1)
		{
			text = text + " x" + entry.Count;
		}
		if (s_showIds != null && s_showIds.Value && entry.Id >= 0)
		{
			text = text + "  #" + entry.Id;
		}
		if (s_showHandLabels != null && s_showHandLabels.Value)
		{
			if (entry.LeftHand && entry.RightHand)
			{
				text += "  L/R";
			}
			else if (entry.LeftHand)
			{
				text += "  L";
			}
			else if (entry.RightHand)
			{
				text += "  R";
			}
		}
		return text;
	}

	private static string FormatUnlockEntry(UnlockEntry entry)
	{
		if (string.Equals(entry.Category, "Stamps", StringComparison.OrdinalIgnoreCase))
		{
			return "Stamps: " + entry.Count;
		}
		string text = entry.Category + ": " + entry.Name;
		if (entry.Id >= 0)
		{
			text = text + "  #" + entry.Id;
		}
		if (string.Equals(entry.Category, "Cosmetic", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(entry.ItemClass))
		{
			text = text + " (" + entry.ItemClass + ")";
		}
		if (entry.Count > 1)
		{
			text = text + " x" + entry.Count;
		}
		return text;
	}

	private static object GetLocalRndPlayerInventory()
	{
		object fieldOrProp = GetFieldOrProp(GetStaticFieldOrProp(GetPlayerNetworkSyncType(), "instance"), "RndPlayerInventory");
		if (fieldOrProp != null)
		{
			return fieldOrProp;
		}
		fieldOrProp = GetFieldOrProp(GetFieldOrProp(GetStaticFieldOrProp(GetGameManagerType(), "instance"), "mainPlayer"), "RndPlayerInventory");
		if (fieldOrProp != null)
		{
			return fieldOrProp;
		}
		return FindOwnedRndPlayerInventory();
	}

	private static object FindOwnedRndPlayerInventory()
	{
		try
		{
			if (!EnsureReflection() || s_findObjectsOfTypeMethod == null)
			{
				return null;
			}
			Type rndPlayerInventoryType = GetRndPlayerInventoryType();
			if (rndPlayerInventoryType == null)
			{
				return null;
			}
			object? list = s_findObjectsOfTypeMethod.Invoke(null, new object[1] { rndPlayerInventoryType });
			object obj = null;
			foreach (object item in EnumerateItems(list))
			{
				if (item != null)
				{
					obj = obj ?? item;
					if (TryConvertBool(GetFieldOrProp(GetFieldOrProp(item, "playerNetworkSync"), "isOwned"), out var result) && result)
					{
						return item;
					}
				}
			}
			return obj;
		}
		catch
		{
			return null;
		}
	}

	private static int GetHandItemId(string propertyName)
	{
		try
		{
			if (TryConvertInt(GetFieldOrProp(GetStaticFieldOrProp(FindType("InventoryController"), "Instance"), propertyName), out var result))
			{
				return result;
			}
		}
		catch
		{
		}
		return -1;
	}

	private static bool TryGetItemId(object item, out int id)
	{
		if (TryConvertInt(GetFieldOrProp(item, "SerializedID"), out id))
		{
			return true;
		}
		return TryConvertInt(GetFieldOrProp(item, "ID"), out id);
	}

	private static string GetItemDisplayName(object item)
	{
		try
		{
			string text = item.GetType().GetMethod("GetItemName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(item, Array.Empty<object>()) as string;
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
		}
		catch
		{
		}
		string text2 = GetFieldOrProp(item, "name") as string;
		if (!string.IsNullOrWhiteSpace(text2))
		{
			return CleanUnityName(text2);
		}
		text2 = GetFieldOrProp(item, "nameLocalisationKey") as string;
		if (!string.IsNullOrWhiteSpace(text2))
		{
			return text2;
		}
		return null;
	}

	private static string CleanUnityName(string name)
	{
		if (string.IsNullOrWhiteSpace(name))
		{
			return name;
		}
		string text = name.Trim();
		if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - 7).Trim();
		}
		if (text.StartsWith("SO_", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(3);
		}
		return text.Replace('_', ' ');
	}

	private static bool IsTabMenuPressed()
	{
		if (IsTabMenuObjectActive())
		{
			return true;
		}
		try
		{
			if (s_gameGetButton != null && s_showTabMenuButton != null && TryConvertBool(s_gameGetButton.Invoke(null, new object[1] { s_showTabMenuButton }), out var result))
			{
				return result;
			}
		}
		catch
		{
		}
		try
		{
			if (s_inputGetKey != null && s_keyCodeTab != null && TryConvertBool(s_inputGetKey.Invoke(null, new object[1] { s_keyCodeTab }), out var result2))
			{
				return result2;
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool IsTabMenuObjectActive()
	{
		try
		{
			if (IsActiveInHierarchy(GetFieldOrProp(GetStaticFieldOrProp(FindType("UI_Controller"), "instance"), "tabMenu")))
			{
				return true;
			}
			GameObject val = GameObject.Find("Global/Global Canvas/Player_UI/Tab Menu");
			return (Object)(object)val != (Object)null && val.activeInHierarchy;
		}
		catch
		{
			return false;
		}
	}

	private static bool IsActiveInHierarchy(object obj)
	{
		if (obj == null)
		{
			return false;
		}
		bool result;
		return TryConvertBool(GetFieldOrProp(GetFieldOrProp(obj, "gameObject") ?? obj, "activeInHierarchy"), out result) && result;
	}

	private static bool EnsureReflection()
	{
		if (s_reflectionReady)
		{
			return true;
		}
		try
		{
			s_rectType = FindType("UnityEngine.Rect");
			s_colorType = FindType("UnityEngine.Color");
			s_vector2Type = FindType("UnityEngine.Vector2");
			s_guiType = FindType("UnityEngine.GUI");
			s_screenType = FindType("UnityEngine.Screen");
			s_inputType = FindType("UnityEngine.Input");
			s_keyCodeType = FindType("UnityEngine.KeyCode");
			s_objectType = FindType("UnityEngine.Object");
			s_componentType = FindType("UnityEngine.Component");
			s_gameObjectType = FindType("UnityEngine.GameObject");
			s_transformType = FindType("UnityEngine.Transform");
			s_rectTransformType = FindType("UnityEngine.RectTransform");
			s_objectiveUiType = FindType("Objectives.ObjectiveUI");
			s_tmpTextType = FindTmpType("TMP_Text");
			s_tmpFontAssetType = FindTmpType("TMP_FontAsset");
			s_textMeshProUguiType = FindTmpType("TextMeshProUGUI");
			s_canvasType = FindType("UnityEngine.Canvas");
			s_renderModeType = FindType("UnityEngine.RenderMode");
			s_resourcesType = FindType("UnityEngine.Resources");
			s_textAlignmentOptionsType = FindTmpType("TextAlignmentOptions");
			s_textOverflowModesType = FindTmpType("TextOverflowModes");
			s_labyrinthineInputManagerType = FindType("LabyrinthineInputManager");
			s_inputButtonType = FindType("InputButton");
			if (s_rectType == null || s_colorType == null || s_guiType == null)
			{
				return LogReflectionNotReady();
			}
			s_rectCtor = s_rectType.GetConstructor(new Type[4]
			{
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(float)
			});
			s_colorCtor = s_colorType.GetConstructor(new Type[4]
			{
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(float)
			});
			s_vector2Ctor = s_vector2Type?.GetConstructor(new Type[2]
			{
				typeof(float),
				typeof(float)
			});
			s_gameObjectCtor = s_gameObjectType?.GetConstructor(new Type[1] { typeof(string) });
			s_gameObjectWithComponentsCtor = s_gameObjectType?.GetConstructor(new Type[2]
			{
				typeof(string),
				typeof(Type[])
			});
			s_guiColorProperty = s_guiType.GetProperty("color", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			s_screenWidthProperty = s_screenType?.GetProperty("width", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			s_screenHeightProperty = s_screenType?.GetProperty("height", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			s_guiSkinProperty = s_guiType.GetProperty("skin", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			s_guiLabel = s_guiType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Label" && m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == s_rectType && m.GetParameters()[1].ParameterType == typeof(string));
			s_inputGetKey = s_inputType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GetKey" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == s_keyCodeType);
			if (s_keyCodeType != null)
			{
				s_keyCodeTab = Enum.Parse(s_keyCodeType, "Tab");
			}
			if (s_labyrinthineInputManagerType != null && s_inputButtonType != null)
			{
				s_gameGetButton = s_labyrinthineInputManagerType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GetButton" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == s_inputButtonType);
				s_showTabMenuButton = Enum.Parse(s_inputButtonType, "ShowTabMenu");
			}
			s_findObjectsOfTypeMethod = s_objectType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "FindObjectsOfType" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));
			s_componentGetComponentInParentMethod = s_componentType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GetComponentInParent" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));
			s_gameObjectGetComponentMethod = s_gameObjectType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GetComponent" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));
			s_gameObjectAddComponentMethod = s_gameObjectType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "AddComponent" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));
			s_gameObjectSetActiveMethod = s_gameObjectType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "SetActive" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(bool));
			s_transformSetParentMethod = s_transformType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "SetParent" && m.GetParameters().Length == 2 && m.GetParameters()[1].ParameterType == typeof(bool));
			s_transformSetAsLastSiblingMethod = s_transformType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "SetAsLastSibling" && m.GetParameters().Length == 0);
			s_objectInstantiateMethod = s_objectType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Instantiate" && !m.ContainsGenericParameters && m.GetParameters().Length == 3 && m.GetParameters()[1].ParameterType == s_transformType && m.GetParameters()[2].ParameterType == typeof(bool));
			s_objectDestroyMethod = s_objectType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "Destroy" && m.GetParameters().Length == 1);
			s_objectDontDestroyOnLoadMethod = s_objectType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "DontDestroyOnLoad" && m.GetParameters().Length == 1);
			s_resourcesFindObjectsOfTypeAllMethod = s_resourcesType?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "FindObjectsOfTypeAll" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));
			if (s_rectCtor == null || s_colorCtor == null || s_guiLabel == null)
			{
				return LogReflectionNotReady();
			}
			InitLabelSkinAccessors();
			s_reflectionReady = true;
			return true;
		}
		catch (Exception ex)
		{
			LogWarning("Unity reflection init failed: " + ex.GetType().Name + " " + ex.Message);
			return false;
		}
	}

	private static void InitLabelSkinAccessors()
	{
		try
		{
			object obj = s_guiSkinProperty?.GetValue(null);
			PropertyInfo propertyInfo = ((s_guiSkinLabelProperty == null && obj != null) ? obj.GetType().GetProperty("label", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : s_guiSkinLabelProperty);
			if (propertyInfo != null)
			{
				s_guiSkinLabelProperty = propertyInfo;
			}
			object obj2 = s_guiSkinLabelProperty?.GetValue(obj);
			if (obj2 != null)
			{
				Type type = obj2.GetType();
				s_styleFontSizeProperty = type.GetProperty("fontSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				s_styleNormalProperty = type.GetProperty("normal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				s_styleStateTextColorProperty = (s_styleNormalProperty?.GetValue(obj2))?.GetType().GetProperty("textColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
		}
		catch
		{
		}
	}

	private static bool LogReflectionNotReady()
	{
		LogWarning("Unity IMGUI reflection is not ready yet.");
		return false;
	}

	private static void LabelShadowed(float x, float y, float width, float height, string text, int fontSize, object color)
	{
		Label(x + 1f, y + 1f, width, height, text, Color(0f, 0f, 0f, 0.7f), fontSize);
		Label(x, y, width, height, text, color, fontSize);
	}

	private static object ObjectiveColor()
	{
		return Color(1f, 1f, 1f, 1f);
	}

	private static object MutedObjectiveColor()
	{
		return Color(1f, 1f, 1f, 0.82f);
	}

	private static object NormalizeTextColor(object color)
	{
		if (TryReadColor(color, out var r, out var g, out var b, out var a))
		{
			return Color(Clamp01(r), Clamp01(g), Clamp01(b), Clamp01((a <= 0f) ? 1f : a));
		}
		return ObjectiveColor();
	}

	private static object CopyColorWithAlpha(object color, float alpha)
	{
		if (TryReadColor(color, out var r, out var g, out var b, out var _))
		{
			return Color(Clamp01(r), Clamp01(g), Clamp01(b), Clamp01(alpha));
		}
		return Color(1f, 1f, 1f, Clamp01(alpha));
	}

	private static bool TryReadColor(object color, out float r, out float g, out float b, out float a)
	{
		r = 1f;
		g = 1f;
		b = 1f;
		a = 1f;
		if (color == null)
		{
			return false;
		}
		if (TryConvertFloat(GetFieldOrProp(color, "r"), out r) && TryConvertFloat(GetFieldOrProp(color, "g"), out g) && TryConvertFloat(GetFieldOrProp(color, "b"), out b))
		{
			return TryConvertFloat(GetFieldOrProp(color, "a"), out a);
		}
		return false;
	}

	private static void Label(float x, float y, float width, float height, string text, object color, int fontSize)
	{
		SetGuiColor(color);
		object oldFontSize = null;
		object oldTextColor = null;
		object skinLabelStyle = GetSkinLabelStyle();
		object obj = ((skinLabelStyle == null) ? null : s_styleNormalProperty?.GetValue(skinLabelStyle));
		try
		{
			if (skinLabelStyle != null && s_styleFontSizeProperty != null)
			{
				oldFontSize = s_styleFontSizeProperty.GetValue(skinLabelStyle);
			}
			if (obj != null && s_styleStateTextColorProperty != null)
			{
				oldTextColor = s_styleStateTextColorProperty.GetValue(obj);
			}
			SetLabelFontSize(skinLabelStyle, fontSize);
			SetLabelTextColor(obj, color);
			s_guiLabel.Invoke(null, new object[2]
			{
				Rect(x, y, width, height),
				text
			});
		}
		finally
		{
			RestoreLabelStyle(skinLabelStyle, obj, oldFontSize, oldTextColor);
			SetGuiColor(Color(1f, 1f, 1f, 1f));
		}
	}

	private static object GetSkinLabelStyle()
	{
		try
		{
			object obj = s_guiSkinProperty?.GetValue(null);
			return (obj == null) ? null : s_guiSkinLabelProperty?.GetValue(obj);
		}
		catch
		{
			return null;
		}
	}

	private static void SetLabelFontSize(object style, int fontSize)
	{
		try
		{
			s_styleFontSizeProperty?.SetValue(style, fontSize);
		}
		catch
		{
		}
	}

	private static void SetLabelTextColor(object normal, object color)
	{
		try
		{
			s_styleStateTextColorProperty?.SetValue(normal, color);
		}
		catch
		{
		}
	}

	private static void RestoreLabelStyle(object style, object normal, object oldFontSize, object oldTextColor)
	{
		try
		{
			if (style != null && oldFontSize != null)
			{
				s_styleFontSizeProperty?.SetValue(style, oldFontSize);
			}
			if (normal != null && oldTextColor != null)
			{
				s_styleStateTextColorProperty?.SetValue(normal, oldTextColor);
			}
		}
		catch
		{
		}
	}

	private static object Rect(float x, float y, float width, float height)
	{
		return s_rectCtor.Invoke(new object[4] { x, y, width, height });
	}

	private static object Color(float r, float g, float b, float a)
	{
		return s_colorCtor.Invoke(new object[4] { r, g, b, a });
	}

	private static object Vector2(float x, float y)
	{
		return s_vector2Ctor.Invoke(new object[2] { x, y });
	}

	private static void SetGuiColor(object color)
	{
		try
		{
			s_guiColorProperty?.SetValue(null, color);
		}
		catch
		{
		}
	}

	private static int ScreenWidth()
	{
		try
		{
			return (s_screenWidthProperty == null) ? 1920 : Convert.ToInt32(s_screenWidthProperty.GetValue(null));
		}
		catch
		{
			return 1920;
		}
	}

	private static int ScreenHeight()
	{
		try
		{
			return (s_screenHeightProperty == null) ? 1080 : Convert.ToInt32(s_screenHeightProperty.GetValue(null));
		}
		catch
		{
			return 1080;
		}
	}

	private static Type GetPlayerNetworkSyncType()
	{
		if (s_playerNetworkSyncType == null)
		{
			s_playerNetworkSyncType = FindType("PlayerNetworkSync");
		}
		return s_playerNetworkSyncType;
	}

	private static Type GetGameManagerType()
	{
		if (s_gameManagerType == null)
		{
			s_gameManagerType = FindType("GameManager");
		}
		return s_gameManagerType;
	}

	private static Type GetRndPlayerInventoryType()
	{
		if (s_rndPlayerInventoryType == null)
		{
			s_rndPlayerInventoryType = FindType("ValkoGames.Labyrinthine.Cases.Inventory.RndPlayerInventory");
		}
		return s_rndPlayerInventoryType;
	}

	private static Type GetRndCollectibleType()
	{
		if (s_rndCollectibleType == null)
		{
			s_rndCollectibleType = FindType("ValkoGames.Labyrinthine.Cases.Interactions.RndCollectible");
		}
		return s_rndCollectibleType;
	}

	private static Type GetCustomizationPickupType()
	{
		if (s_customizationPickupType == null)
		{
			s_customizationPickupType = FindType("CharacterCustomization.CustomizationPickup");
		}
		return s_customizationPickupType;
	}

	private static Type GetCustomCaseItemUnlockType()
	{
		if (s_customCaseItemUnlockType == null)
		{
			s_customCaseItemUnlockType = FindType("ValkoGames.Labyrinthine.Cases.Custom.CustomCaseItemUnlock");
		}
		return s_customCaseItemUnlockType;
	}

	private static Type GetCustomizationManagerType()
	{
		if (s_customizationManagerType == null)
		{
			s_customizationManagerType = FindType("CharacterCustomization.CustomizationManager");
		}
		return s_customizationManagerType;
	}

	private static Type GetLocalisationManagerType()
	{
		if (s_localisationManagerType == null)
		{
			s_localisationManagerType = FindType("Localisation.LocalisationManager") ?? FindType("LocalisationManager");
		}
		return s_localisationManagerType;
	}

	private static Type GetObjectiveUiType()
	{
		if (s_objectiveUiType == null)
		{
			s_objectiveUiType = FindType("Objectives.ObjectiveUI");
		}
		return s_objectiveUiType;
	}

	private static Type GetTmpTextType()
	{
		if (s_tmpTextType == null)
		{
			s_tmpTextType = FindTmpType("TMP_Text");
		}
		return s_tmpTextType;
	}

	private static Type GetTextMeshProUguiType()
	{
		if (s_textMeshProUguiType == null)
		{
			s_textMeshProUguiType = FindTmpType("TextMeshProUGUI");
		}
		return s_textMeshProUguiType;
	}

	private static Type GetCanvasType()
	{
		if (s_canvasType == null)
		{
			s_canvasType = FindType("UnityEngine.Canvas");
		}
		return s_canvasType;
	}

	private static Type FindTmpType(string typeName)
	{
		return FindType("Il2CppTMPro." + typeName) ?? FindType("TMPro." + typeName);
	}

	private static Type FindType(string fullName)
	{
		string il2cppName = (fullName.StartsWith("Il2Cpp.", StringComparison.Ordinal) ? fullName : ("Il2Cpp." + fullName));
		string shortName = (fullName.Contains(".") ? fullName.Substring(fullName.LastIndexOf('.') + 1) : fullName);
		Type type = Type.GetType(fullName) ?? Type.GetType(il2cppName);
		if (type != null)
		{
			return type;
		}
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			Type type2 = assembly.GetType(fullName, throwOnError: false) ?? assembly.GetType(il2cppName, throwOnError: false);
			if (type2 != null)
			{
				return type2;
			}
		}
		assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly2 in assemblies)
		{
			Type[] source;
			try
			{
				source = assembly2.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				source = ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch
			{
				continue;
			}
			Type type3 = source.FirstOrDefault((Type t) => t.Name == shortName || t.FullName == fullName || t.FullName == il2cppName);
			if (type3 != null)
			{
				return type3;
			}
		}
		return null;
	}

	private static object GetStaticFieldOrProp(Type type, string name)
	{
		if (type == null)
		{
			return null;
		}
		try
		{
			PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				return property.GetValue(null);
			}
		}
		catch
		{
		}
		try
		{
			return type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
		}
		catch
		{
			return null;
		}
	}

	private static object GetFieldOrProp(object obj, string name)
	{
		if (obj == null)
		{
			return null;
		}
		Type type = obj.GetType();
		try
		{
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				return property.GetValue(obj);
			}
		}
		catch
		{
		}
		try
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
		}
		catch
		{
			return null;
		}
	}

	private static bool SetFieldOrProp(object obj, string name, object value)
	{
		if (obj == null)
		{
			return false;
		}
		Type type = obj.GetType();
		try
		{
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				property.SetValue(obj, value);
				return true;
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(obj, value);
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	private static object FindFirstObjectOfType(Type type)
	{
		if (type == null)
		{
			return null;
		}
		try
		{
			foreach (object item in EnumerateItems(((s_objectType ?? FindType("UnityEngine.Object"))?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "FindObjectsOfType" && !m.ContainsGenericParameters && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type)))?.Invoke(null, new object[1] { type })))
			{
				if (item != null)
				{
					return item;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static void ForEachListItem(object list, Action<object> action)
	{
		foreach (object item in EnumerateItems(list))
		{
			action(item);
		}
	}

	private static IEnumerable<object> EnumerateItems(object list)
	{
		if (list == null)
		{
			yield break;
		}
		if (list is Array array)
		{
			foreach (object item in array)
			{
				yield return item;
			}
			yield break;
		}
		if (list is IEnumerable enumerable)
		{
			foreach (object item2 in enumerable)
			{
				yield return item2;
			}
			yield break;
		}
		if (!TryConvertInt(GetFieldOrProp(list, "Count"), out var count))
		{
			TryConvertInt(GetFieldOrProp(list, "Length"), out count);
		}
		if (count <= 0)
		{
			yield break;
		}
		MethodInfo getItem = list.GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (getItem == null)
		{
			yield break;
		}
		for (int i = 0; i < count; i++)
		{
			object obj = null;
			try
			{
				obj = getItem.Invoke(list, new object[1] { i });
			}
			catch
			{
			}
			if (obj != null)
			{
				yield return obj;
			}
		}
	}

	private static bool TryConvertInt(object value, out int result)
	{
		try
		{
			if (value == null)
			{
				result = 0;
				return false;
			}
			result = Convert.ToInt32(value);
			return true;
		}
		catch
		{
			result = 0;
			return false;
		}
	}

	private static bool TryConvertFloat(object value, out float result)
	{
		try
		{
			if (value == null)
			{
				result = 0f;
				return false;
			}
			result = Convert.ToSingle(value);
			return true;
		}
		catch
		{
			result = 0f;
			return false;
		}
	}

	private static bool TryConvertBool(object value, out bool result)
	{
		try
		{
			if (value == null)
			{
				result = false;
				return false;
			}
			result = Convert.ToBoolean(value);
			return true;
		}
		catch
		{
			result = false;
			return false;
		}
	}

	private static void LogOverlayRenderer(string renderer, string details)
	{
		string b = renderer + "|" + details;
		if (!string.Equals(s_lastLoggedRendererSignature, b, StringComparison.Ordinal))
		{
			s_lastLoggedRendererSignature = b;
			LogDebug("Pickup overlay renderer=" + renderer + " " + details);
		}
	}

	private static string GetFallbackRendererReason()
	{
		if (!IsTextMeshProOverlayEnabled())
		{
			return "reason=TextMeshPro disabled";
		}
		if (s_tmpOverlayFailed)
		{
			return "reason=TextMeshPro unavailable/retrying";
		}
		if (!s_tmpOverlayReady)
		{
			return "reason=TextMeshPro not ready";
		}
		return "reason=TextMeshPro ready";
	}

	private static string DescribeTextStyleForLog(ObjectiveTextStyle style)
	{
		string text = (string.IsNullOrWhiteSpace(style.Source) ? "unknown" : style.Source);
		return "styleSource=" + text + " headerFont=" + style.HeaderFontSize + " rowFont=" + style.RowFontSize + " footerFont=" + style.FooterFontSize + " tmpSource={" + DescribeTmpTextSource(style.SourceText) + "}";
	}

	private static string DescribeTmpTextSource(object tmpText)
	{
		if (tmpText == null)
		{
			return "none";
		}
		try
		{
			string text = GetUnityObjectName(GetFieldOrProp(tmpText, "gameObject")) ?? GetUnityObjectName(tmpText) ?? tmpText.GetType().Name;
			string text2 = GetFieldOrProp(tmpText, "text") as string;
			float result;
			string text3 = (TryConvertFloat(GetFieldOrProp(tmpText, "fontSize"), out result) ? result.ToString("0.##") : "?");
			string text4 = GetCanvasScaleFactor(tmpText).ToString("0.##");
			return "name='" + TruncateForLog(text, 60) + "' fontSize=" + text3 + " canvasScale=" + text4 + " text='" + TruncateForLog(text2, 60) + "'";
		}
		catch
		{
			return tmpText.GetType().Name;
		}
	}

	private static string DescribeRectTransform(object rectTransform)
	{
		if (rectTransform == null)
		{
			return "none";
		}
		try
		{
			object fieldOrProp = GetFieldOrProp(rectTransform, "rect");
			return "name='" + TruncateForLog(GetUnityObjectName(rectTransform), 50) + "' anchorMin=" + DescribeVector(GetFieldOrProp(rectTransform, "anchorMin")) + " anchorMax=" + DescribeVector(GetFieldOrProp(rectTransform, "anchorMax")) + " pivot=" + DescribeVector(GetFieldOrProp(rectTransform, "pivot")) + " anchoredPosition=" + DescribeVector(GetFieldOrProp(rectTransform, "anchoredPosition")) + " sizeDelta=" + DescribeVector(GetFieldOrProp(rectTransform, "sizeDelta")) + " rect=" + DescribeRect(fieldOrProp);
		}
		catch
		{
			return rectTransform.GetType().Name;
		}
	}

	private static string DescribeRect(object rect)
	{
		if (rect == null)
		{
			return "none";
		}
		float result;
		string obj = (TryConvertFloat(GetFieldOrProp(rect, "width"), out result) ? result.ToString("0.#") : "?");
		float result2;
		string text = (TryConvertFloat(GetFieldOrProp(rect, "height"), out result2) ? result2.ToString("0.#") : "?");
		return obj + "x" + text;
	}

	private static string DescribeVector(object vector)
	{
		if (vector == null)
		{
			return "none";
		}
		float result;
		bool num = TryConvertFloat(GetFieldOrProp(vector, "x"), out result);
		float result2;
		bool flag = TryConvertFloat(GetFieldOrProp(vector, "y"), out result2);
		float result3;
		bool flag2 = TryConvertFloat(GetFieldOrProp(vector, "z"), out result3);
		if (!num && !flag && !flag2)
		{
			return vector.ToString();
		}
		if (!flag2)
		{
			return "(" + result.ToString("0.###") + "," + result2.ToString("0.###") + ")";
		}
		return "(" + result.ToString("0.###") + "," + result2.ToString("0.###") + "," + result3.ToString("0.###") + ")";
	}

	private static bool IsPickupTmpOverlayObject(object tmpText)
	{
		if (tmpText == null)
		{
			return false;
		}
		if (tmpText == s_tmpOverlayText)
		{
			return true;
		}
		object fieldOrProp = GetFieldOrProp(tmpText, "gameObject");
		if (fieldOrProp == s_tmpOverlayTextObject || fieldOrProp == s_tmpOverlayRoot)
		{
			return true;
		}
		return (GetUnityObjectName(fieldOrProp) ?? string.Empty).IndexOf("kp0hyc PickupTabOverlay", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static string GetUnityObjectName(object obj)
	{
		if (obj == null)
		{
			return null;
		}
		try
		{
			string text = GetFieldOrProp(obj, "name") as string;
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text.Trim();
			}
			object fieldOrProp = GetFieldOrProp(obj, "gameObject");
			if (fieldOrProp != null && fieldOrProp != obj)
			{
				text = GetFieldOrProp(fieldOrProp, "name") as string;
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text.Trim();
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static string TruncateForLog(string text, int maxLength)
	{
		if (string.IsNullOrWhiteSpace(text))
		{
			return string.Empty;
		}
		string text2 = text.Replace("\r", " ").Replace("\n", " ").Trim();
		if (text2.Length <= maxLength)
		{
			return text2;
		}
		return text2.Substring(0, Math.Max(0, maxLength - 3)) + "...";
	}

	private static string TypeNameForLog(Type type)
	{
		object obj;
		if (!(type == null))
		{
			obj = type.FullName;
			if (obj == null)
			{
				return type.Name;
			}
		}
		else
		{
			obj = "null";
		}
		return (string)obj;
	}

	private static int Clamp(int value, int min, int max)
	{
		if (value < min)
		{
			return min;
		}
		if (value <= max)
		{
			return value;
		}
		return max;
	}

	private static float Clamp(float value, float min, float max)
	{
		if (value < min)
		{
			return min;
		}
		if (!(value > max))
		{
			return value;
		}
		return max;
	}

	private static float Clamp01(float value)
	{
		if (value < 0f)
		{
			return 0f;
		}
		if (!(value > 1f))
		{
			return value;
		}
		return 1f;
	}

	private static void LogWarning(string message)
	{
		if (!(DateTime.UtcNow < s_nextWarningUtc))
		{
			s_nextWarningUtc = DateTime.UtcNow.AddSeconds(10.0);
			MelonLogger.Warning(message);
		}
	}

	private static void LogDebug(string message)
	{
		if (IsDebugLoggingEnabled())
		{
			MelonLogger.Msg("[Debug] " + message);
		}
	}

	private static bool IsDebugLoggingEnabled()
	{
		if (s_debugLogging == null || !s_debugLogging.Value)
		{
			if (s_legacyDebugLogging != null)
			{
				return s_legacyDebugLogging.Value;
			}
			return false;
		}
		return true;
	}
}