Decompiled source of FactionUnitSort v1.0.1

FactionUnitSort.dll

Decompiled a day 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.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DM;
using HarmonyLib;
using Landfall.TABS;
using Landfall.TABS.Workshop;
using LevelCreator;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FactionUnitSort;

internal enum ContentKind
{
	Units,
	Factions,
	Battles,
	Campaigns,
	Maps
}
internal static class ContentSort
{
	private static readonly Dictionary<Type, MethodInfo> WriteTimeCache = new Dictionary<Type, MethodInfo>();

	private static readonly Dictionary<Type, PropertyInfo> FilePathCache = new Dictionary<Type, PropertyInfo>();

	private static readonly Dictionary<Type, MethodInfo> CostCache = new Dictionary<Type, MethodInfo>();

	internal static IEnumerable<T> Apply<T>(IEnumerable<T> source, ContentKind kind) where T : class
	{
		if (source == null)
		{
			return null;
		}
		Plugin.ContentSortMode value = Plugin.ConfigFor(kind).Value;
		if (value == Plugin.ContentSortMode.Default)
		{
			return source;
		}
		List<T> list = source.ToList();
		if (list.Count < 2)
		{
			return list;
		}
		switch (value)
		{
		case Plugin.ContentSortMode.TimeNewest:
			list = list.OrderByDescending((T item) => TimeOf(item)).ThenBy(NameOf).ToList();
			break;
		case Plugin.ContentSortMode.TimeOldest:
			list = list.OrderBy((T item) => TimeOf(item)).ThenBy(NameOf).ToList();
			break;
		case Plugin.ContentSortMode.CostHigh:
			list = list.OrderByDescending((T item) => CostOf(item)).ThenBy(NameOf).ToList();
			break;
		case Plugin.ContentSortMode.CostLow:
			list = list.OrderBy((T item) => CostOf(item)).ThenBy(NameOf).ToList();
			break;
		}
		Plugin.LogInfo("[ContentSort] " + kind.ToString() + ": " + value.ToString() + ", sorted " + list.Count + " item(s)");
		return list;
	}

	internal static DateTime TimeOf(object item)
	{
		if (item == null)
		{
			return DateTime.MinValue;
		}
		Type type = item.GetType();
		if (!WriteTimeCache.TryGetValue(type, out var value))
		{
			value = type.GetMethod("GetWriteTime", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
			WriteTimeCache[type] = value;
		}
		if (value != null && value.ReturnType == typeof(DateTime))
		{
			try
			{
				return (DateTime)value.Invoke(item, null);
			}
			catch
			{
			}
		}
		if (!FilePathCache.TryGetValue(type, out var value2))
		{
			value2 = type.GetProperty("FilePath", BindingFlags.Instance | BindingFlags.Public);
			FilePathCache[type] = value2;
		}
		if (value2 != null)
		{
			try
			{
				string text = value2.GetValue(item, null) as string;
				if (!string.IsNullOrEmpty(text) && File.Exists(text))
				{
					return File.GetLastWriteTimeUtc(text);
				}
			}
			catch
			{
			}
		}
		return DateTime.MinValue;
	}

	internal static string NameOf(object item)
	{
		if (item == null)
		{
			return string.Empty;
		}
		try
		{
			object obj = Member(item, "Entity");
			if (obj != null)
			{
				object obj2 = Member(obj, "Name");
				if (obj2 is string)
				{
					return (string)obj2;
				}
			}
			object obj3 = Member(item, "Name");
			if (obj3 is string)
			{
				return (string)obj3;
			}
		}
		catch
		{
		}
		return string.Empty;
	}

	internal static uint CostOf(object item)
	{
		if (item == null)
		{
			return 0u;
		}
		UnitBlueprint val = (UnitBlueprint)((item is UnitBlueprint) ? item : null);
		if ((Object)(object)val != (Object)null)
		{
			try
			{
				return val.GetUnitCost(true);
			}
			catch
			{
				return 0u;
			}
		}
		Faction val2 = (Faction)((item is Faction) ? item : null);
		if ((Object)(object)val2 != (Object)null)
		{
			uint num = 0u;
			try
			{
				UnitBlueprint[] units = val2.Units;
				if (units != null)
				{
					for (int i = 0; i < units.Length; i++)
					{
						if ((Object)(object)units[i] != (Object)null)
						{
							num += CostOf(units[i]);
						}
					}
				}
			}
			catch
			{
			}
			return num;
		}
		Type type = item.GetType();
		if (!CostCache.TryGetValue(type, out var value))
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public);
			for (int j = 0; j < methods.Length; j++)
			{
				if (!(methods[j].Name != "GetUnitCost") && methods[j].GetParameters().Length <= 1)
				{
					value = methods[j];
					break;
				}
			}
			CostCache[type] = value;
		}
		if (value != null)
		{
			try
			{
				object[] parameters = ((value.GetParameters().Length == 0) ? null : new object[1] { true });
				object obj3 = value.Invoke(item, parameters);
				if (obj3 != null)
				{
					return Convert.ToUInt32(obj3);
				}
			}
			catch
			{
			}
		}
		try
		{
			if (Member(item, "Units") is Array array)
			{
				uint num2 = 0u;
				for (int k = 0; k < array.Length; k++)
				{
					num2 += CostOf(array.GetValue(k));
				}
				return num2;
			}
		}
		catch
		{
		}
		return 0u;
	}

	private static object Member(object target, string name)
	{
		if (target == null)
		{
			return null;
		}
		Type type = target.GetType();
		PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
		if (property != null)
		{
			return property.GetValue(target, null);
		}
		FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public);
		if (!(field != null))
		{
			return null;
		}
		return field.GetValue(target);
	}
}
[HarmonyPatch(typeof(ContentDatabase), "GetUserUnitBlueprintsByNamePartAndType")]
internal static class UnitListSortPatch
{
	[HarmonyPostfix]
	internal static void Postfix(ref IEnumerable<UnitBlueprint> __result)
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			__result = ContentSort.Apply(__result, ContentKind.Units);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] units: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(ContentDatabase), "GetUserFactionsByNamePartAndType")]
internal static class FactionListSortPatch
{
	[HarmonyPostfix]
	internal static void Postfix(ref IEnumerable<Faction> __result)
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			__result = ContentSort.Apply(__result, ContentKind.Factions);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] factions: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(ContentDatabase), "GetUserCampaignLevelsByFilter")]
internal static class BattleListSortPatch
{
	[HarmonyPostfix]
	internal static void Postfix(ref IEnumerable<TABSCampaignLevelAsset> __result)
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			__result = ContentSort.Apply(__result, ContentKind.Battles);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] battles: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(ContentDatabase), "GetUserCampaignsByFilter")]
internal static class CampaignListSortPatch
{
	[HarmonyPostfix]
	internal static void Postfix(ref IEnumerable<TABSCampaignAsset> __result)
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			__result = ContentSort.Apply(__result, ContentKind.Campaigns);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] campaigns: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(ContentDatabase), "GetUserMapsByFilter")]
internal static class MapListSortPatch
{
	[HarmonyPostfix]
	internal static void Postfix(ref IEnumerable<CustomMap> __result)
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			__result = ContentSort.Apply(__result, ContentKind.Maps);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] maps: " + ex.Message);
		}
	}
}
internal class FactionUnitEditor : MonoBehaviour
{
	private const string ButtonName = "FactionUnitSortCostButton";

	private FactionCreatorManager _manager;

	private GameObject _button;

	private float _nextScan;

	private bool _warnedNoSource;

	private bool _warnedNoManager;

	private Image _swatch;

	private static string ButtonLabel => Plugin.CfgSortLabel.Value;

	private void Update()
	{
		if (!Plugin.CfgEnabled.Value || !Plugin.CfgSortButton.Value || Time.unscaledTime < _nextScan)
		{
			return;
		}
		_nextScan = Time.unscaledTime + 0.5f;
		try
		{
			Scan();
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[FactionSort] " + ex.Message);
		}
	}

	private void Scan()
	{
		if (!FactionUnits.Available)
		{
			if (!_warnedNoManager)
			{
				_warnedNoManager = true;
				Plugin.LogWarn("[FactionSort] the faction editor's unit list could not be reflected - sorting and dragging are disabled");
			}
			return;
		}
		if ((Object)(object)_manager == (Object)null)
		{
			_manager = Object.FindObjectOfType<FactionCreatorManager>();
		}
		if ((Object)(object)_manager == (Object)null)
		{
			return;
		}
		bool flag;
		try
		{
			flag = _manager.isOpen;
		}
		catch
		{
			flag = false;
		}
		if ((Object)(object)_button != (Object)null && (!flag || !_button.activeInHierarchy))
		{
			Object.Destroy((Object)(object)_button);
			_button = null;
		}
		if (flag)
		{
			if ((Object)(object)_button == (Object)null)
			{
				CreateButton();
				return;
			}
			SetLabel(_button, ButtonLabel);
			UpdateSwatch();
		}
	}

	private static void MatchSize(RectTransform target, RectTransform source)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Rect rect = source.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			if (!(size.x < 1f) && !(size.y < 1f))
			{
				Transform parent = ((Transform)target).parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				Vector2 val2;
				if (!((Object)(object)val != (Object)null))
				{
					val2 = Vector2.zero;
				}
				else
				{
					rect = val.rect;
					val2 = ((Rect)(ref rect)).size;
				}
				Vector2 val3 = val2;
				Vector2 sizeDelta = size;
				if (target.anchorMax.x - target.anchorMin.x > 0.001f)
				{
					sizeDelta.x = size.x - val3.x;
				}
				if (target.anchorMax.y - target.anchorMin.y > 0.001f)
				{
					sizeDelta.y = size.y - val3.y;
				}
				target.sizeDelta = sizeDelta;
			}
		}
		catch
		{
		}
	}

	private static bool ExceedsScreen(RectTransform rect)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rect.GetWorldCorners(array);
			Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>();
			Camera val = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
			float num = float.MinValue;
			for (int i = 0; i < array.Length; i++)
			{
				num = Mathf.Max(num, RectTransformUtility.WorldToScreenPoint(val, array[i]).x);
			}
			return num > (float)Screen.width - 4f;
		}
		catch
		{
			return false;
		}
	}

	private static Image FindSwatch(GameObject button, RectTransform rect)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)button == (Object)null || (Object)(object)rect == (Object)null)
		{
			return null;
		}
		Image result = null;
		float num = float.MaxValue;
		Image[] componentsInChildren = button.GetComponentsInChildren<Image>(true);
		foreach (Image val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Transform transform = ((Component)val).transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Rect rect2 = val2.rect;
			float num2 = Mathf.Max(((Rect)(ref rect2)).width, ((Rect)(ref rect2)).height);
			Rect rect3 = rect.rect;
			float width = ((Rect)(ref rect3)).width;
			rect3 = rect.rect;
			float num3 = Mathf.Max(width, ((Rect)(ref rect3)).height);
			if (!(num2 <= 1f) && !(num2 > num3 * 0.45f))
			{
				float num4 = ((Rect)(ref rect2)).width * ((Rect)(ref rect2)).height;
				if (num4 < num)
				{
					num = num4;
					result = val;
				}
			}
		}
		return result;
	}

	private void UpdateSwatch()
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_swatch == (Object)null || (Object)(object)_manager == (Object)null)
		{
			return;
		}
		try
		{
			((Graphic)_swatch).color = _manager.GetFactionColor();
		}
		catch
		{
		}
	}

	private void CreateButton()
	{
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: 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_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		Button val = FindSourceButton();
		if ((Object)(object)val == (Object)null)
		{
			if (!_warnedNoSource)
			{
				_warnedNoSource = true;
				Plugin.LogWarn("[FactionSort] no game button to clone was found - the COST button is skipped");
			}
			return;
		}
		_button = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
		((Object)_button).name = "FactionUnitSortCostButton";
		_button.SetActive(true);
		try
		{
			_button.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1);
		}
		catch
		{
		}
		Transform transform = ((Component)val).transform;
		RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		Transform transform2 = _button.transform;
		RectTransform val3 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
		if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
		{
			val3.anchorMin = val2.anchorMin;
			val3.anchorMax = val2.anchorMax;
			val3.pivot = val2.pivot;
			val3.sizeDelta = val2.sizeDelta;
			((Transform)val3).localScale = ((Transform)val2).localScale;
			MatchSize(val3, val2);
			if (!((Object)(object)((Component)val).transform.parent != (Object)null) || !((Object)(object)((Component)((Component)val).transform.parent).GetComponent<LayoutGroup>() != (Object)null))
			{
				Rect rect = val2.rect;
				float num = Mathf.Max(8f, ((Rect)(ref rect)).width * 0.06f);
				Vector2 anchoredPosition = val2.anchoredPosition;
				rect = val2.rect;
				val3.anchoredPosition = anchoredPosition + new Vector2(((Rect)(ref rect)).width + num, 0f);
				if (ExceedsScreen(val3))
				{
					Vector2 anchoredPosition2 = val2.anchoredPosition;
					rect = val2.rect;
					val3.anchoredPosition = anchoredPosition2 - new Vector2(((Rect)(ref rect)).width + num, 0f);
				}
			}
		}
		Button component = _button.GetComponent<Button>();
		if ((Object)(object)component != (Object)null)
		{
			((UnityEventBase)component.onClick).RemoveAllListeners();
			((UnityEvent)component.onClick).AddListener(new UnityAction(OnSortClicked));
		}
		_swatch = FindSwatch(_button, val3);
		SetLabel(_button, ButtonLabel);
		UpdateSwatch();
		Plugin.LogInfo("[FactionSort] added the COST button (cloned from '" + Path(((Component)val).transform) + "')");
	}

	private void OnSortClicked()
	{
		if (!((Object)(object)_manager == (Object)null))
		{
			int num = ((FactionUnits.List(_manager) != null) ? FactionUnits.List(_manager).Count : 0);
			bool flag = FactionUnits.SortByCost(_manager, Plugin.CfgSortDescending.Value);
			Plugin.LogInfo("[FactionSort] sorted " + num + " unit(s) by cost (" + (Plugin.CfgSortDescending.Value ? "expensive first" : "cheapest first") + ")" + (flag ? string.Empty : " - the order was already correct"));
		}
	}

	private Button FindSourceButton()
	{
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		Button[] componentsInChildren = ((Component)((Component)_manager).transform.root).GetComponentsInChildren<Button>(true);
		Button val = null;
		Button val2 = null;
		Button val3 = null;
		foreach (Button val4 in componentsInChildren)
		{
			if (!((Object)(object)val4 == (Object)null) && !(((Object)((Component)val4).gameObject).name == "FactionUnitSortCostButton"))
			{
				if ((Object)(object)val == (Object)null && CallsColorPage(val4))
				{
					val = val4;
				}
				string text = ((Object)((Component)val4).gameObject).name.ToLowerInvariant();
				if ((Object)(object)val2 == (Object)null && text.Contains("color"))
				{
					val2 = val4;
				}
				if ((Object)(object)val3 == (Object)null && LabelContains(val4, "color"))
				{
					val3 = val4;
				}
			}
		}
		Button val5 = val ?? val2 ?? val3;
		if ((Object)(object)val5 != (Object)null)
		{
			return val5;
		}
		foreach (Button val6 in componentsInChildren)
		{
			if ((Object)(object)val6 == (Object)null || ((Object)((Component)val6).gameObject).name == "FactionUnitSortCostButton")
			{
				continue;
			}
			Transform transform = ((Component)val6).transform;
			RectTransform val7 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val7 == (Object)null)
			{
				continue;
			}
			Rect rect = val7.rect;
			if (!(((Rect)(ref rect)).height < 20f))
			{
				rect = val7.rect;
				if (!(((Rect)(ref rect)).height > 90f) && (!((Object)(object)((Transform)val7).parent != (Object)null) || !((Object)(object)((Component)((Transform)val7).parent).GetComponent<LayoutGroup>() != (Object)null)) && (Object)(object)LabelOf(val6) != (Object)null)
				{
					return val6;
				}
			}
		}
		return null;
	}

	private bool CallsColorPage(Button button)
	{
		try
		{
			int persistentEventCount = ((UnityEventBase)button.onClick).GetPersistentEventCount();
			for (int i = 0; i < persistentEventCount; i++)
			{
				string persistentMethodName = ((UnityEventBase)button.onClick).GetPersistentMethodName(i);
				if (persistentMethodName != null && persistentMethodName.ToLowerInvariant().Contains("color"))
				{
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private bool LabelContains(Button button, string text)
	{
		Component val = LabelOf(button);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		return LabelText(val)?.ToLowerInvariant().Contains(text) ?? false;
	}

	private static Component LabelOf(Button button)
	{
		if ((Object)(object)button == (Object)null)
		{
			return null;
		}
		Component[] componentsInChildren = ((Component)button).GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && (((object)val).GetType().Name == "TextMeshProUGUI" || ((object)val).GetType().Name == "Text"))
			{
				return val;
			}
		}
		return null;
	}

	private static string LabelText(Component label)
	{
		if ((Object)(object)label == (Object)null)
		{
			return null;
		}
		try
		{
			PropertyInfo property = ((object)label).GetType().GetProperty("text");
			return (property != null) ? (property.GetValue(label, null) as string) : null;
		}
		catch
		{
			return null;
		}
	}

	private static void SetLabel(GameObject target, string text)
	{
		if ((Object)(object)target == (Object)null)
		{
			return;
		}
		Component[] componentsInChildren = target.GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			string name = ((object)val).GetType().Name;
			if (name != "TextMeshProUGUI" && name != "Text")
			{
				continue;
			}
			try
			{
				PropertyInfo property = ((object)val).GetType().GetProperty("text");
				if (!(property == null) && property.CanWrite && property.GetValue(val, null) as string != text)
				{
					property.SetValue(val, text, null);
				}
			}
			catch
			{
			}
		}
	}

	private static string Path(Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "<null>";
		}
		string text = ((Object)t).name;
		Transform parent = t.parent;
		int num = 0;
		while ((Object)(object)parent != (Object)null && num++ < 6)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}
}
internal static class FactionUnits
{
	private static readonly FieldInfo AddedUnitsField;

	private static readonly FieldInfo UnitField;

	private static readonly FieldInfo ButtonField;

	internal static bool Available
	{
		get
		{
			if (AddedUnitsField != null && UnitField != null)
			{
				return ButtonField != null;
			}
			return false;
		}
	}

	static FactionUnits()
	{
		AddedUnitsField = AccessTools.Field(typeof(FactionCreatorManager), "addedUnits");
		try
		{
			if (!(AddedUnitsField == null))
			{
				Type fieldType = AddedUnitsField.FieldType;
				if (fieldType.IsGenericType)
				{
					Type obj = fieldType.GetGenericArguments()[0];
					UnitField = obj.GetField("unit", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					ButtonField = obj.GetField("spawnedButton", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[FactionSort] could not reflect the unit list: " + ex.Message);
		}
	}

	internal static IList List(FactionCreatorManager manager)
	{
		if ((Object)(object)manager == (Object)null || AddedUnitsField == null)
		{
			return null;
		}
		try
		{
			return AddedUnitsField.GetValue(manager) as IList;
		}
		catch
		{
			return null;
		}
	}

	internal static UnitBlueprint UnitOf(object wrapper)
	{
		if (wrapper == null || UnitField == null)
		{
			return null;
		}
		try
		{
			object? value = UnitField.GetValue(wrapper);
			return (UnitBlueprint)((value is UnitBlueprint) ? value : null);
		}
		catch
		{
			return null;
		}
	}

	internal static UnitButtonBase ButtonOf(object wrapper)
	{
		if (wrapper == null || ButtonField == null)
		{
			return null;
		}
		try
		{
			object? value = ButtonField.GetValue(wrapper);
			return (UnitButtonBase)((value is UnitButtonBase) ? value : null);
		}
		catch
		{
			return null;
		}
	}

	internal static int IndexOfUnit(FactionCreatorManager manager, UnitBlueprint unit)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		IList list = List(manager);
		if (list == null || (Object)(object)unit == (Object)null || unit.Entity == null)
		{
			return -1;
		}
		for (int i = 0; i < list.Count; i++)
		{
			UnitBlueprint val = UnitOf(list[i]);
			if (!((Object)(object)val == (Object)null) && val.Entity != null && val.Entity.GUID == unit.Entity.GUID)
			{
				return i;
			}
		}
		return -1;
	}

	internal static int IndexAtScreenPoint(FactionCreatorManager manager, Vector2 screenPoint, Camera camera)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		IList list = List(manager);
		if (list == null)
		{
			return -1;
		}
		int result = -1;
		float num = float.MaxValue;
		for (int i = 0; i < list.Count; i++)
		{
			UnitButtonBase val = ButtonOf(list[i]);
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Transform transform = ((Component)val).transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				if (RectTransformUtility.RectangleContainsScreenPoint(val2, screenPoint, camera))
				{
					return i;
				}
				float num2 = Vector2.Distance(RectTransformUtility.WorldToScreenPoint(camera, ((Transform)val2).position), screenPoint);
				if (num2 < num)
				{
					num = num2;
					result = i;
				}
			}
		}
		return result;
	}

	internal static bool Move(FactionCreatorManager manager, int from, int to)
	{
		IList list = List(manager);
		if (list == null)
		{
			return false;
		}
		if (from < 0 || from >= list.Count)
		{
			return false;
		}
		to = Mathf.Clamp(to, 0, list.Count - 1);
		if (from == to)
		{
			return false;
		}
		object value = list[from];
		list.RemoveAt(from);
		list.Insert(to, value);
		SyncSiblings(list);
		return true;
	}

	internal static bool SortByCost(FactionCreatorManager manager, bool descending)
	{
		IList list = List(manager);
		if (list == null || list.Count < 2)
		{
			return false;
		}
		List<object> list2 = new List<object>();
		for (int i = 0; i < list.Count; i++)
		{
			list2.Add(list[i]);
		}
		List<object> list3 = (descending ? list2.OrderByDescending((object w) => Cost(UnitOf(w))) : list2.OrderBy((object w) => Cost(UnitOf(w)))).ToList();
		bool result = false;
		for (int num = 0; num < list3.Count; num++)
		{
			if (list3[num] != list[num])
			{
				result = true;
				break;
			}
		}
		for (int num2 = 0; num2 < list3.Count; num2++)
		{
			list[num2] = list3[num2];
		}
		SyncSiblings(list);
		return result;
	}

	internal static uint Cost(UnitBlueprint unit)
	{
		if ((Object)(object)unit == (Object)null)
		{
			return 0u;
		}
		try
		{
			return unit.GetUnitCost(true);
		}
		catch
		{
			return 0u;
		}
	}

	internal static void SyncSiblings(IList list)
	{
		if (list == null || list.Count == 0)
		{
			return;
		}
		List<Transform> list2 = new List<Transform>();
		for (int i = 0; i < list.Count; i++)
		{
			UnitButtonBase val = ButtonOf(list[i]);
			if ((Object)(object)val != (Object)null)
			{
				list2.Add(((Component)val).transform);
			}
		}
		if (list2.Count == 0)
		{
			return;
		}
		Transform parent = list2[0].parent;
		if ((Object)(object)parent == (Object)null)
		{
			return;
		}
		for (int j = 1; j < list2.Count; j++)
		{
			if ((Object)(object)list2[j].parent != (Object)(object)parent)
			{
				return;
			}
		}
		List<int> list3 = new List<int>();
		for (int k = 0; k < list2.Count; k++)
		{
			list3.Add(list2[k].GetSiblingIndex());
		}
		list3.Sort();
		for (int l = 0; l < list2.Count; l++)
		{
			if (list2[l].GetSiblingIndex() != list3[l])
			{
				list2[l].SetSiblingIndex(list3[l]);
			}
		}
	}

	internal static void AttachDragToNewest(FactionCreatorManager manager)
	{
		if ((Object)(object)manager == (Object)null || (Object)(object)manager.FactionListParent == (Object)null)
		{
			return;
		}
		Transform factionListParent = manager.FactionListParent;
		for (int num = factionListParent.childCount - 1; num >= 0; num--)
		{
			Transform child = factionListParent.GetChild(num);
			if (!((Object)(object)child == (Object)null) && !((Object)(object)((Component)child).GetComponent<UnitButtonBase>() == (Object)null))
			{
				if (!((Object)(object)((Component)child).GetComponent<UnitDragReorder>() != (Object)null))
				{
					((Component)child).gameObject.AddComponent<UnitDragReorder>().Init(manager);
				}
				break;
			}
		}
	}

	internal static int AttachDragToAll(FactionCreatorManager manager)
	{
		if ((Object)(object)manager == (Object)null || (Object)(object)manager.FactionListParent == (Object)null)
		{
			return 0;
		}
		int num = 0;
		Transform factionListParent = manager.FactionListParent;
		for (int i = 0; i < factionListParent.childCount; i++)
		{
			Transform child = factionListParent.GetChild(i);
			if (!((Object)(object)child == (Object)null) && !((Object)(object)((Component)child).GetComponent<UnitButtonBase>() == (Object)null) && !((Object)(object)((Component)child).GetComponent<UnitDragReorder>() != (Object)null))
			{
				((Component)child).gameObject.AddComponent<UnitDragReorder>().Init(manager);
				num++;
			}
		}
		return num;
	}
}
[HarmonyPatch(typeof(FactionCreatorManager), "OnClickUnit")]
internal static class UnitAddedPatch
{
	[HarmonyPostfix]
	internal static void Postfix(FactionCreatorManager __instance)
	{
		if (!Plugin.CfgEnabled.Value || !Plugin.CfgDragReorder.Value)
		{
			return;
		}
		try
		{
			FactionUnits.AttachDragToNewest(__instance);
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[FactionSort] could not attach the drag handler: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(FactionCreatorManager), "LoadFaction")]
internal static class FactionLoadedPatch
{
	[HarmonyPostfix]
	internal static void Postfix(FactionCreatorManager __instance)
	{
		if (!Plugin.CfgEnabled.Value || !Plugin.CfgDragReorder.Value)
		{
			return;
		}
		try
		{
			int num = FactionUnits.AttachDragToAll(__instance);
			if (num > 0)
			{
				Plugin.LogInfo("[FactionSort] " + num + " unit(s) can be dragged");
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[FactionSort] could not attach the drag handlers: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(UnitButtonBase), "OnPointerClick")]
internal static class ClickSuppressPatch
{
	[HarmonyPrefix]
	internal static bool Prefix()
	{
		return !UnitDragReorder.SuppressClick;
	}
}
[HarmonyPatch(typeof(UnitButtonBase), "OnSubmit")]
internal static class SubmitSuppressPatch
{
	[HarmonyPrefix]
	internal static bool Prefix()
	{
		return !UnitDragReorder.SuppressClick;
	}
}
[BepInPlugin("saucein.tabs.factionunitsort", "Faction Unit Sort", "1.2.0")]
[BepInProcess("TotallyAccurateBattleSimulator.exe")]
public class Plugin : BaseUnityPlugin
{
	public enum ContentSortMode
	{
		Default,
		TimeNewest,
		TimeOldest,
		CostHigh,
		CostLow
	}

	public const string PluginGuid = "saucein.tabs.factionunitsort";

	public const string PluginName = "Faction Unit Sort";

	public const string PluginVersion = "1.2.0";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> CfgEnabled;

	internal static ConfigEntry<bool> CfgDragReorder;

	internal static ConfigEntry<bool> CfgSortButton;

	internal static ConfigEntry<bool> CfgSortDescending;

	internal static ConfigEntry<string> CfgSortLabel;

	internal static ConfigEntry<ContentSortMode> CfgSortUnits;

	internal static ConfigEntry<ContentSortMode> CfgSortFactions;

	internal static ConfigEntry<ContentSortMode> CfgSortBattles;

	internal static ConfigEntry<ContentSortMode> CfgSortCampaigns;

	internal static ConfigEntry<ContentSortMode> CfgSortMaps;

	internal static ConfigEntry<bool> CfgVerbose;

	private void Awake()
	{
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn the plugin's editor additions on or off.");
		CfgDragReorder = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DragToReorder", true, "Drag a unit in the faction row to move it to any position, instead of only ever appending to the right end.");
		CfgSortButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SortButton", true, "Add a COST button (cloned from the game's colour button) that sorts the faction's units by their cost.");
		CfgSortDescending = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SortDescending", false, "Sort direction for the COST button. false = cheapest first, true = most expensive first.");
		CfgSortLabel = ((BaseUnityPlugin)this).Config.Bind<string>("General", "SortButtonLabel", "COST", "Text shown on the added sort button. Matches the game's own short button labels (COLOR, ICON, ...), so 'COST' or e.g. a Chinese label both work.");
		CfgSortUnits = ((BaseUnityPlugin)this).Config.Bind<ContentSortMode>("Sorting", "SortUnits", ContentSortMode.Default, "Order of your own units (UNITS page). Written by the dropdown next to the search box.");
		CfgSortFactions = ((BaseUnityPlugin)this).Config.Bind<ContentSortMode>("Sorting", "SortFactions", ContentSortMode.Default, "Order of your own factions (FACTION page). Time comes from the faction file, cost is the sum of the faction's units.");
		CfgSortBattles = ((BaseUnityPlugin)this).Config.Bind<ContentSortMode>("Sorting", "SortBattles", ContentSortMode.Default, "Order of your own battles (BATTLE page), by file time.");
		CfgSortCampaigns = ((BaseUnityPlugin)this).Config.Bind<ContentSortMode>("Sorting", "SortCampaigns", ContentSortMode.Default, "Order of your own campaigns (CAMPAIGN page), by file time.");
		CfgSortMaps = ((BaseUnityPlugin)this).Config.Bind<ContentSortMode>("Sorting", "SortMaps", ContentSortMode.Default, "Order of your own maps (MAP page), by file time.");
		CfgVerbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", true, "Log details (useful when reporting a problem).");
		Harmony val = new Harmony("saucein.tabs.factionunitsort");
		try
		{
			val.PatchAll(typeof(UnitAddedPatch));
			val.PatchAll(typeof(FactionLoadedPatch));
			val.PatchAll(typeof(ClickSuppressPatch));
			val.PatchAll(typeof(SubmitSuppressPatch));
			val.PatchAll(typeof(UnitListSortPatch));
			val.PatchAll(typeof(FactionListSortPatch));
			val.PatchAll(typeof(BattleListSortPatch));
			val.PatchAll(typeof(CampaignListSortPatch));
			val.PatchAll(typeof(MapListSortPatch));
			LogInfo("Harmony patches applied (faction editor + five custom content sorters).");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Could not apply the Harmony patches: " + ex));
		}
		GameObject val2 = new GameObject("FactionUnitSort");
		Object.DontDestroyOnLoad((Object)val2);
		val2.AddComponent<FactionUnitEditor>();
		val2.AddComponent<UnitSortDropdown>();
		LogInfo("Faction Unit Sort 1.2.0 loaded.");
	}

	internal static ConfigEntry<ContentSortMode> ConfigFor(ContentKind kind)
	{
		return (ConfigEntry<ContentSortMode>)(kind switch
		{
			ContentKind.Factions => CfgSortFactions, 
			ContentKind.Battles => CfgSortBattles, 
			ContentKind.Campaigns => CfgSortCampaigns, 
			ContentKind.Maps => CfgSortMaps, 
			_ => CfgSortUnits, 
		});
	}

	internal static void LogInfo(string message)
	{
		if (Log != null)
		{
			if (CfgVerbose != null && !CfgVerbose.Value)
			{
				Log.LogDebug((object)message);
			}
			else
			{
				Log.LogInfo((object)message);
			}
		}
	}

	internal static void LogWarn(string message)
	{
		if (Log != null)
		{
			Log.LogWarning((object)message);
		}
	}
}
internal class UnitDragReorder : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
{
	private FactionCreatorManager _manager;

	private bool _dragging;

	private Vector3 _originalScale = Vector3.one;

	internal static float LastDragTime = -100f;

	private readonly Dictionary<Graphic, bool> _raycasts = new Dictionary<Graphic, bool>();

	internal static bool SuppressClick => Time.unscaledTime - LastDragTime < 0.3f;

	internal void Init(FactionCreatorManager manager)
	{
		_manager = manager;
	}

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		_originalScale = ((Component)this).transform.localScale;
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (Plugin.CfgEnabled.Value && Plugin.CfgDragReorder.Value && !((Object)(object)_manager == (Object)null))
		{
			_dragging = true;
			LastDragTime = Time.unscaledTime;
			((Component)this).transform.localScale = _originalScale * 1.15f;
			SetRaycasts(enabled: false);
		}
	}

	public void OnDrag(PointerEventData eventData)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (!_dragging || (Object)(object)_manager == (Object)null)
		{
			return;
		}
		int num = FactionUnits.IndexOfUnit(_manager, GetUnit());
		if (num >= 0)
		{
			int num2 = FactionUnits.IndexAtScreenPoint(_manager, eventData.position, eventData.pressEventCamera);
			if (num2 >= 0 && num2 != num && FactionUnits.Move(_manager, num, num2))
			{
				LastDragTime = Time.unscaledTime;
				Plugin.LogInfo("[FactionSort] moved unit from position " + num + " to " + num2);
			}
		}
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		_dragging = false;
		((Component)this).transform.localScale = _originalScale;
		LastDragTime = Time.unscaledTime;
		SetRaycasts(enabled: true);
	}

	private void OnDisable()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (_dragging)
		{
			_dragging = false;
			((Component)this).transform.localScale = _originalScale;
			SetRaycasts(enabled: true);
		}
	}

	private void SetRaycasts(bool enabled)
	{
		try
		{
			Graphic[] componentsInChildren = ((Component)this).GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] == (Object)null)
				{
					continue;
				}
				if (enabled)
				{
					if (_raycasts.TryGetValue(componentsInChildren[i], out var value))
					{
						componentsInChildren[i].raycastTarget = value;
					}
				}
				else
				{
					_raycasts[componentsInChildren[i]] = componentsInChildren[i].raycastTarget;
					componentsInChildren[i].raycastTarget = false;
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[FactionSort] could not toggle the button raycasts: " + ex.Message);
		}
	}

	private UnitBlueprint GetUnit()
	{
		UnitButtonBase component = ((Component)this).GetComponent<UnitButtonBase>();
		if (!((Object)(object)component != (Object)null))
		{
			return null;
		}
		return component.GetUnit();
	}
}
internal class UnitSortDropdown : MonoBehaviour
{
	private const float RowHeight = 30f;

	private const float Width = 210f;

	private CustomContentGridBrowser _browser;

	private RectTransform _anchor;

	private ContentKind _kind;

	private GameObject _blocker;

	private bool _open;

	private bool _logged;

	private float _nextScan;

	private GUIStyle _style;

	private Texture2D _white;

	private float _styleHeight = -1f;

	private Rect _buttonRect;

	private readonly List<Rect> _itemRects = new List<Rect>();

	private static Font _font;

	private static bool _fontTried;

	private static readonly Plugin.ContentSortMode[] FullModes = new Plugin.ContentSortMode[5]
	{
		Plugin.ContentSortMode.Default,
		Plugin.ContentSortMode.TimeNewest,
		Plugin.ContentSortMode.TimeOldest,
		Plugin.ContentSortMode.CostHigh,
		Plugin.ContentSortMode.CostLow
	};

	private static readonly Plugin.ContentSortMode[] TimeModes = new Plugin.ContentSortMode[3]
	{
		Plugin.ContentSortMode.Default,
		Plugin.ContentSortMode.TimeNewest,
		Plugin.ContentSortMode.TimeOldest
	};

	private static float _languageChecked = -100f;

	private static string _languageReason;

	private static bool Chinese => ChineseReason() != null;

	private static string ButtonWord
	{
		get
		{
			if (!Chinese)
			{
				return "Sort";
			}
			return "排序";
		}
	}

	private static Color Background => new Color(0f, 0f, 0f, 1f);

	private static Color Hover => new Color(0.16f, 0.16f, 0.16f, 1f);

	private static Color Selected => new Color(0.32f, 0.32f, 0.32f, 1f);

	private void Update()
	{
		if (!Plugin.CfgEnabled.Value || Time.unscaledTime < _nextScan)
		{
			return;
		}
		_nextScan = Time.unscaledTime + 0.5f;
		try
		{
			Scan();
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] " + ex.Message);
			Hide();
		}
	}

	private void Scan()
	{
		CustomContentGridBrowser bestBrowser = null;
		TMP_InputField bestField = null;
		string text = "page state";
		try
		{
			CustomContetnManager val = Object.FindObjectOfType<CustomContetnManager>();
			object obj = (((Object)(object)val != (Object)null) ? Member(val, "currentPage") : null);
			GameObject val2 = (GameObject)((obj != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val2 != (Object)null)
			{
				bestBrowser = val2.GetComponentInChildren<CustomContentGridBrowser>(true);
				if ((Object)(object)bestBrowser != (Object)null)
				{
					bestField = FieldOf(bestBrowser);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] could not read the current page: " + ex.Message);
		}
		if ((Object)(object)bestBrowser == (Object)null || (Object)(object)bestField == (Object)null)
		{
			text = "visibility";
			bestBrowser = null;
			bestField = null;
			PickByVisibility(ref bestBrowser, ref bestField);
		}
		_browser = bestBrowser;
		_anchor = (RectTransform)(((Object)(object)bestField != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
		_kind = KindOf(bestBrowser);
		if ((Object)(object)_anchor == (Object)null)
		{
			Hide();
			_logged = false;
		}
		else if (!_logged)
		{
			_logged = true;
			string text2 = ChineseReason();
			Plugin.LogInfo("[ContentSort] dropdown on the " + _kind.ToString() + " page via " + text + " (" + PathOf((Transform)(object)_anchor) + "), labels: " + ((text2 != null) ? ("Chinese (" + text2 + ")") : "English"));
		}
	}

	private void PickByVisibility(ref CustomContentGridBrowser bestBrowser, ref TMP_InputField bestField)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		float num = -1f;
		StringBuilder stringBuilder = new StringBuilder();
		CustomContentGridBrowser[] array = Resources.FindObjectsOfTypeAll<CustomContentGridBrowser>();
		foreach (CustomContentGridBrowser val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Scene scene = ((Component)val).gameObject.scene;
			if (!((Scene)(ref scene)).IsValid())
			{
				continue;
			}
			TMP_InputField val2 = FieldOf(val);
			if (!((Object)(object)val2 == (Object)null) && IsVisible((RectTransform)/*isinst with value type is only supported in some contexts*/, out var area))
			{
				int num2 = VisibleEntries(val);
				float num3 = area * (1f + (float)Mathf.Min(num2, 60) * 0.05f);
				stringBuilder.Append(' ').Append(KindOf(val)).Append('(')
					.Append(Mathf.RoundToInt(area))
					.Append("px/")
					.Append(num2)
					.Append(')');
				if (!(num3 <= num))
				{
					num = num3;
					bestBrowser = val;
					bestField = val2;
				}
			}
		}
		if (stringBuilder.Length > 0)
		{
			Plugin.LogInfo("[ContentSort] page candidates:" + stringBuilder);
		}
	}

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

	private static string PathOf(Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "<null>";
		}
		string text = ((Object)t).name;
		Transform parent = t.parent;
		int num = 0;
		while ((Object)(object)parent != (Object)null && num++ < 5)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}

	private static int VisibleEntries(CustomContentGridBrowser browser)
	{
		try
		{
			GridLayoutGroup currentLayoutGroup = browser.CurrentLayoutGroup;
			if ((Object)(object)currentLayoutGroup == (Object)null)
			{
				return 0;
			}
			int num = 0;
			Transform transform = ((Component)currentLayoutGroup).transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
				{
					num++;
				}
			}
			return num;
		}
		catch
		{
			return 0;
		}
	}

	private void Hide()
	{
		_open = false;
		if ((Object)(object)_blocker != (Object)null)
		{
			_blocker.SetActive(false);
		}
	}

	private static TMP_InputField FieldOf(object browser)
	{
		try
		{
			Type type = browser.GetType();
			FieldInfo field = type.GetField("filterInputField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(browser);
				return (TMP_InputField)((value is TMP_InputField) ? value : null);
			}
			PropertyInfo property = type.GetProperty("filterInputField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (TMP_InputField)((property != null) ? /*isinst with value type is only supported in some contexts*/: null);
		}
		catch
		{
			return null;
		}
	}

	private static ContentKind KindOf(object browser)
	{
		if (browser == null)
		{
			return ContentKind.Units;
		}
		string name = browser.GetType().Name;
		if (name.IndexOf("Unit", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Units;
		}
		if (name.IndexOf("Faction", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Factions;
		}
		if (name.IndexOf("Battle", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Battles;
		}
		if (name.IndexOf("Campaign", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Campaigns;
		}
		if (name.IndexOf("Level", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Maps;
		}
		if (name.IndexOf("Map", StringComparison.Ordinal) >= 0)
		{
			return ContentKind.Maps;
		}
		return ContentKind.Units;
	}

	private static Plugin.ContentSortMode[] ModesFor(ContentKind kind)
	{
		if (kind != ContentKind.Units && kind != ContentKind.Factions)
		{
			return TimeModes;
		}
		return FullModes;
	}

	private static string LabelFor(Plugin.ContentSortMode mode)
	{
		bool chinese = Chinese;
		switch (mode)
		{
		case Plugin.ContentSortMode.TimeNewest:
			if (!chinese)
			{
				return "Newest first";
			}
			return "时间:新 → 旧";
		case Plugin.ContentSortMode.TimeOldest:
			if (!chinese)
			{
				return "Oldest first";
			}
			return "时间:旧 → 新";
		case Plugin.ContentSortMode.CostHigh:
			if (!chinese)
			{
				return "Cost: high to low";
			}
			return "价格:高 → 低";
		case Plugin.ContentSortMode.CostLow:
			if (!chinese)
			{
				return "Cost: low to high";
			}
			return "价格:低 → 高";
		default:
			if (!chinese)
			{
				return "Default order";
			}
			return "默认顺序";
		}
	}

	private static string ShortFor(Plugin.ContentSortMode mode)
	{
		bool chinese = Chinese;
		switch (mode)
		{
		case Plugin.ContentSortMode.TimeNewest:
			if (!chinese)
			{
				return "Newest";
			}
			return "时间 ↓";
		case Plugin.ContentSortMode.TimeOldest:
			if (!chinese)
			{
				return "Oldest";
			}
			return "时间 ↑";
		case Plugin.ContentSortMode.CostHigh:
			if (!chinese)
			{
				return "Cost high";
			}
			return "价格 ↓";
		case Plugin.ContentSortMode.CostLow:
			if (!chinese)
			{
				return "Cost low";
			}
			return "价格 ↑";
		default:
			if (!chinese)
			{
				return "Default";
			}
			return "默认";
		}
	}

	private static string ChineseReason()
	{
		if (Time.unscaledTime - _languageChecked < 2f)
		{
			return _languageReason;
		}
		_languageChecked = Time.unscaledTime;
		_languageReason = DetectChineseReason();
		return _languageReason;
	}

	private static string DetectChineseReason()
	{
		try
		{
			string text = Localizer.ActiveCultureInfo?.Name;
			if (!string.IsNullOrEmpty(text) && text.StartsWith("zh", StringComparison.OrdinalIgnoreCase))
			{
				return "game language";
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Localizer), "m_locale");
			object obj2 = ((fieldInfo != null) ? fieldInfo.GetValue(null) : null);
			if (obj2 != null && obj2.ToString().IndexOf("CH", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "game language";
			}
		}
		catch
		{
		}
		try
		{
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			if (pluginInfos != null)
			{
				foreach (KeyValuePair<string, PluginInfo> item in pluginInfos)
				{
					if (LooksChinese(item.Key))
					{
						return "translation mod";
					}
					PluginInfo value = item.Value;
					if (value != null && value.Metadata != null && LooksChinese(value.Metadata.Name))
					{
						return "translation mod";
					}
				}
			}
		}
		catch
		{
		}
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				if (LooksChinese(assemblies[i].GetName().Name))
				{
					return "translation mod";
				}
				Type[] types;
				try
				{
					types = assemblies[i].GetTypes();
				}
				catch
				{
					continue;
				}
				for (int j = 0; j < types.Length; j++)
				{
					string fullName = types[j].FullName;
					if (fullName != null && (fullName.IndexOf("AllInOnePatch", StringComparison.OrdinalIgnoreCase) >= 0 || fullName.IndexOf("CN_AllInOne", StringComparison.OrdinalIgnoreCase) >= 0))
					{
						return "translation mod";
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static bool LooksChinese(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return false;
		}
		string text = value.ToLowerInvariant();
		if (text.Contains("chinese") || text.Contains("allinone") || text.Contains("cn_all"))
		{
			return true;
		}
		if (text.Contains("汉化") || text.Contains("中文"))
		{
			return true;
		}
		if (text.Contains("translation"))
		{
			return text.Contains("cn");
		}
		return false;
	}

	private void OnGUI()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.CfgEnabled.Value || (Object)(object)_anchor == (Object)null)
		{
			return;
		}
		try
		{
			Plugin.ContentSortMode[] array = ModesFor(_kind);
			Plugin.ContentSortMode contentSortMode = Plugin.ConfigFor(_kind).Value;
			if (Array.IndexOf(array, contentSortMode) < 0)
			{
				contentSortMode = array[0];
			}
			EnsureResources();
			GUI.depth = -10000;
			ComputeRects(array.Length);
			Vector2 val = GuiMouse();
			bool flag = ((Rect)(ref _buttonRect)).Contains(val);
			bool flag2 = false;
			Rect val2;
			if (_open)
			{
				for (int i = 0; i < _itemRects.Count; i++)
				{
					val2 = _itemRects[i];
					if (((Rect)(ref val2)).Contains(val))
					{
						flag2 = true;
						break;
					}
				}
			}
			UpdateBlocker(flag || flag2 || _open);
			Event current = Event.current;
			if (current != null && (int)current.type == 0 && current.button == 0)
			{
				if (flag)
				{
					_open = !_open;
					current.Use();
				}
				else if (_open)
				{
					bool flag3 = false;
					for (int j = 0; j < _itemRects.Count && j < array.Length; j++)
					{
						val2 = _itemRects[j];
						if (((Rect)(ref val2)).Contains(val))
						{
							Choose(array[j]);
							flag3 = true;
							break;
						}
					}
					if (flag3)
					{
						current.Use();
					}
					else
					{
						_open = false;
					}
				}
			}
			DrawPill(_buttonRect, flag ? Hover : Background);
			DrawLabel(_buttonRect, ButtonWord + ": " + ShortFor(contentSortMode) + (_open ? "  ^" : "  v"));
			if (!_open)
			{
				return;
			}
			for (int k = 0; k < _itemRects.Count && k < array.Length; k++)
			{
				bool num = array[k] == contentSortMode;
				val2 = _itemRects[k];
				Color color = (((Rect)(ref val2)).Contains(val) ? Hover : Background);
				if (num)
				{
					val2 = _itemRects[k];
					if (!((Rect)(ref val2)).Contains(val))
					{
						color = Selected;
					}
				}
				DrawPill(_itemRects[k], color);
				DrawLabel(_itemRects[k], LabelFor(array[k]));
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] dropdown draw failed: " + ex.Message);
		}
	}

	private void Choose(Plugin.ContentSortMode mode)
	{
		_open = false;
		try
		{
			Plugin.ConfigFor(_kind).Value = mode;
			Plugin.LogInfo("[ContentSort] " + _kind.ToString() + " order set to " + mode);
			if ((Object)(object)_browser != (Object)null)
			{
				_browser.Refresh();
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[ContentSort] could not refresh the browser: " + ex.Message);
		}
	}

	private void ComputeRects(int count)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		_anchor.GetWorldCorners(array);
		Canvas componentInParent = ((Component)_anchor).GetComponentInParent<Canvas>();
		Camera obj = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
		Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, array[0]);
		Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[2]);
		float num = Mathf.Abs(val2.x - val.x);
		Rect rect = _anchor.rect;
		float num2;
		if (!(((Rect)(ref rect)).width > 1f))
		{
			num2 = 1f;
		}
		else
		{
			rect = _anchor.rect;
			num2 = num / ((Rect)(ref rect)).width;
		}
		float num3 = num2;
		if (num3 <= 0.01f)
		{
			num3 = 1f;
		}
		float num4 = Mathf.Clamp(30f * num3, 20f, 44f);
		float num5 = Mathf.Clamp(210f * num3, 140f, 320f);
		float num6 = Mathf.Min(val.x, val2.x);
		float num7 = (float)Screen.height - Mathf.Min(val.y, val2.y) + 6f;
		_buttonRect = new Rect(num6, num7, num5, num4);
		_itemRects.Clear();
		for (int i = 0; i < count; i++)
		{
			_itemRects.Add(new Rect(num6, ((Rect)(ref _buttonRect)).yMax + (float)i * (num4 + 2f), num5, num4));
		}
	}

	private void UpdateBlocker(bool active)
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_blocker == (Object)null)
		{
			Canvas val = (((Object)(object)_anchor != (Object)null) ? ((Component)_anchor).GetComponentInParent<Canvas>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			_blocker = new GameObject("ContentSortClickBlocker", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			_blocker.transform.SetParent(((Component)val).transform, false);
			Transform transform = _blocker.transform;
			Transform obj = ((transform is RectTransform) ? transform : null);
			((RectTransform)obj).anchorMin = Vector2.zero;
			((RectTransform)obj).anchorMax = Vector2.one;
			((RectTransform)obj).pivot = new Vector2(0.5f, 0.5f);
			((RectTransform)obj).offsetMin = Vector2.zero;
			((RectTransform)obj).offsetMax = Vector2.zero;
			Image component = _blocker.GetComponent<Image>();
			((Graphic)component).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)component).raycastTarget = true;
			_blocker.SetActive(false);
		}
		if (_blocker.activeSelf == active)
		{
			return;
		}
		_blocker.SetActive(active);
		if (active)
		{
			try
			{
				_blocker.transform.SetAsLastSibling();
			}
			catch
			{
			}
		}
	}

	private void DrawPill(Rect rect, Color color)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp(((Rect)(ref rect)).height * 0.28f, 3f, 12f);
		GUI.DrawTexture(rect, (Texture)(object)_white, (ScaleMode)0, true, 0f, color, 0f, num);
	}

	private void DrawLabel(Rect rect, string text)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		_style.normal.textColor = new Color(0f, 0f, 0f, 0.35f);
		GUI.Label(new Rect(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).y + 1f, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, _style);
		_style.normal.textColor = Color.white;
		GUI.Label(rect, text, _style);
	}

	private void EnsureResources()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_white == (Object)null)
		{
			_white = new Texture2D(4, 4, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[16];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Color.white;
			}
			_white.SetPixels(array);
			_white.Apply();
			((Object)_white).hideFlags = (HideFlags)61;
		}
		if (_style == null)
		{
			_style = new GUIStyle(GUI.skin.label);
			_style.alignment = (TextAnchor)4;
			_style.richText = false;
			_style.clipping = (TextClipping)1;
			Font font = GetFont();
			if ((Object)(object)font != (Object)null)
			{
				_style.font = font;
			}
		}
		if (!Mathf.Approximately(_styleHeight, ((Rect)(ref _buttonRect)).height))
		{
			_styleHeight = ((Rect)(ref _buttonRect)).height;
			_style.fontSize = Mathf.RoundToInt(Mathf.Clamp(((Rect)(ref _buttonRect)).height * 0.55f, 11f, 20f));
		}
	}

	private static Font GetFont()
	{
		if (_fontTried)
		{
			return _font;
		}
		_fontTried = true;
		try
		{
			_font = Font.CreateDynamicFontFromOSFont(new string[5] { "Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Segoe UI", "Arial" }, 16);
		}
		catch
		{
			_font = null;
		}
		return _font;
	}

	private static Vector2 GuiMouse()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = Vector2.op_Implicit(Input.mousePosition);
		return new Vector2(val.x, (float)Screen.height - val.y);
	}

	private static bool IsVisible(RectTransform rect, out float area)
	{
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		area = 0f;
		if ((Object)(object)rect == (Object)null || !((Component)rect).gameObject.activeInHierarchy)
		{
			return false;
		}
		Transform val = (Transform)(object)rect;
		int num = 0;
		while ((Object)(object)val != (Object)null && num++ < 10)
		{
			Canvas component = ((Component)val).GetComponent<Canvas>();
			if ((Object)(object)component != (Object)null && !((Behaviour)component).enabled)
			{
				return false;
			}
			CanvasGroup component2 = ((Component)val).GetComponent<CanvasGroup>();
			if ((Object)(object)component2 != (Object)null && component2.alpha <= 0.01f)
			{
				return false;
			}
			val = val.parent;
		}
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		rect.GetWorldCorners(array);
		Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>();
		Camera obj = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
		Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[0]);
		Vector2 val3 = RectTransformUtility.WorldToScreenPoint(obj, array[2]);
		float num2 = Mathf.Max(0f, Mathf.Min(val2.x, val3.x));
		float num3 = Mathf.Min((float)Screen.width, Mathf.Max(val2.x, val3.x));
		float num4 = Mathf.Max(0f, Mathf.Min(val2.y, val3.y));
		float num5 = Mathf.Min((float)Screen.height, Mathf.Max(val2.y, val3.y));
		if (num3 - num2 < 30f || num5 - num4 < 8f)
		{
			return false;
		}
		area = (num3 - num2) * (num5 - num4);
		return true;
	}
}