Decompiled source of InLobbyConfig v1.5.0

plugins/InLobbyConfig/InLobbyConfig.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using InLobbyConfig.Components;
using InLobbyConfig.Components.TMP;
using InLobbyConfig.FieldControllers;
using InLobbyConfig.Fields;
using MonoMod.RuntimeDetour;
using RoR2;
using RoR2.UI;
using RoR2.UI.SkinControllers;
using ScrollableLobbyUI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace InLobbyConfig
{
	internal static class AssetBundleHelper
	{
		public static AssetBundle MainAssetBundle { get; private set; }

		internal static void LoadAssetBundle()
		{
			MainAssetBundle = AssetBundle.LoadFromFile(GetBundlePath("kingenderbrine_inlobbyconfig"));
		}

		internal static void UnloadAssetBundle()
		{
			if (Object.op_Implicit((Object)(object)MainAssetBundle))
			{
				MainAssetBundle.Unload(true);
			}
		}

		private static string GetBundlePath(string bundleName)
		{
			return Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)InLobbyConfigPlugin.Instance).Info.Location), bundleName);
		}

		internal static GameObject LoadPrefab(string name)
		{
			AssetBundle mainAssetBundle = MainAssetBundle;
			if (mainAssetBundle == null)
			{
				return null;
			}
			return mainAssetBundle.LoadAsset<GameObject>("Assets/Resources/Prefabs/" + name + ".prefab");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.KingEnderBrine.InLobbyConfig", "In Lobby Config", "1.5.0")]
	public class InLobbyConfigPlugin : BaseUnityPlugin
	{
		internal static InLobbyConfigPlugin Instance { get; private set; }

		internal static ManualLogSource InstanceLogger
		{
			get
			{
				InLobbyConfigPlugin instance = Instance;
				if (instance == null)
				{
					return null;
				}
				return ((BaseUnityPlugin)instance).Logger;
			}
		}

		internal static bool IsScrollableLobbyUILoaded { get; private set; }

		private void Start()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			IsScrollableLobbyUILoaded = Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ScrollableLobbyUI");
			AssetBundleHelper.LoadAssetBundle();
			new Hook((MethodBase)typeof(CharacterSelectController).GetMethod("Awake", (BindingFlags)(-1)), typeof(ConfigPanelController).GetMethod("CharacterSelectControllerAwake", (BindingFlags)(-1)));
			Language.collectLanguageRootFolders += CollectLanguageRootFolders;
		}

		private static void CollectLanguageRootFolders(List<string> folders)
		{
			folders.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "Language"));
		}
	}
	internal static class LanguageTokens
	{
		public const string IN_LOBBY_CONFIG_POPOUT_PANEL_NAME = "IN_LOBBY_CONFIG_POPOUT_PANEL_NAME";
	}
	public static class ModConfigCatalog
	{
		private static readonly HashSet<ModConfigEntry> entries = new HashSet<ModConfigEntry>();

		public static ReadOnlyCollection<ModConfigEntry> ReadonlyList => new ReadOnlyCollection<ModConfigEntry>(entries.ToList());

		public static void Add(ModConfigEntry entry)
		{
			if (entry != null)
			{
				entries.Add(entry);
			}
		}

		public static void Remove(ModConfigEntry entry)
		{
			entries.Remove(entry);
		}
	}
	public class ModConfigEntry
	{
		public string DisplayName { get; set; }

		public BooleanConfigField EnableField { get; set; }

		public Dictionary<string, IEnumerable<IConfigField>> SectionFields { get; } = new Dictionary<string, IEnumerable<IConfigField>>();


		public Dictionary<string, BooleanConfigField> SectionEnableFields { get; } = new Dictionary<string, BooleanConfigField>();

	}
}
namespace InLobbyConfig.Fields
{
	public abstract class BaseConfigField<T> : IConfigField
	{
		public abstract GameObject FieldPrefab { get; }

		public string DisplayName { get; }

		public TooltipContent Tooltip { get; }

		protected Func<T> ValueAccessor { get; }

		protected Action<T> OnValueChangedCallback { get; }

		public BaseConfigField(string displayName, Func<T> valueAccessor, Action<T> onValueChanged)
		{
			DisplayName = displayName;
			ValueAccessor = valueAccessor;
			OnValueChangedCallback = onValueChanged;
		}

		public BaseConfigField(string displayName, string tooltip, Func<T> valueAccessor, Action<T> onValueChanged)
			: this(displayName, valueAccessor, onValueChanged)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(tooltip))
			{
				Tooltip = new TooltipContent
				{
					titleColor = Color.black,
					overrideTitleText = displayName,
					bodyColor = Color.black,
					overrideBodyText = tooltip
				};
			}
		}

		public BaseConfigField(string displayName, TooltipContent tooltip, Func<T> valueAccessor, Action<T> onValueChanged)
			: this(displayName, valueAccessor, onValueChanged)
		{
			//IL_000b: 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)
			Tooltip = tooltip;
		}

		object IConfigField.GetValue()
		{
			return GetValue();
		}

		public virtual T GetValue()
		{
			return ValueAccessor();
		}

		public virtual void OnValueChanged(T newValue)
		{
			OnValueChangedCallback?.Invoke(newValue);
		}
	}
	public abstract class BaseInputConfigField<T> : BaseConfigField<T>
	{
		protected Action<T> OnEndEditCallback { get; }

		public BaseInputConfigField(string displayName, Func<T> valueAccessor, Action<T> onValueChanged = null, Action<T> onEndEdit = null)
			: base(displayName, valueAccessor, onValueChanged)
		{
			OnEndEditCallback = onEndEdit;
		}

		public BaseInputConfigField(string displayName, string tooltip, Func<T> valueAccessor, Action<T> onValueChanged = null, Action<T> onEndEdit = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
			OnEndEditCallback = onEndEdit;
		}

		public BaseInputConfigField(string displayName, TooltipContent tooltip, Func<T> valueAccessor, Action<T> onValueChanged, Action<T> onEndEdit = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			OnEndEditCallback = onEndEdit;
		}

		public virtual void OnEndEdit(T newValue)
		{
			OnEndEditCallback?.Invoke(newValue);
		}
	}
	public abstract class BaseNumberInputConfigField<T> : BaseInputConfigField<T> where T : struct
	{
		public T? Minimum { get; }

		public T? Maximum { get; }

		public BaseNumberInputConfigField(string displayName, Func<T> valueAccessor, Action<T> onValueChanged = null, Action<T> onEndEdit = null, T? minimum = null, T? maximum = null)
			: base(displayName, valueAccessor, onValueChanged, onEndEdit)
		{
			Minimum = minimum;
			Maximum = maximum;
		}

		public BaseNumberInputConfigField(string displayName, string tooltip, Func<T> valueAccessor, Action<T> onValueChanged = null, Action<T> onEndEdit = null, T? minimum = null, T? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
			Minimum = minimum;
			Maximum = maximum;
		}

		public BaseNumberInputConfigField(string displayName, TooltipContent tooltip, Func<T> valueAccessor, Action<T> onValueChanged = null, Action<T> onEndEdit = null, T? minimum = null, T? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Minimum = minimum;
			Maximum = maximum;
		}
	}
	public class BooleanConfigField : BaseConfigField<bool>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("BooleanFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public BooleanConfigField(string displayName, Func<bool> valueAccessor, Action<bool> onValueChanged = null)
			: base(displayName, valueAccessor, onValueChanged)
		{
		}

		public BooleanConfigField(string displayName, string tooltip, Func<bool> valueAccessor, Action<bool> onValueChanged = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
		}

		public BooleanConfigField(string displayName, TooltipContent tooltip, Func<bool> valueAccessor, Action<bool> onValueChanged)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)

	}
	public class ColorConfigField : BaseInputConfigField<Color>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("ColorFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public bool ShowAlpha { get; set; }

		public ColorConfigField(string displayName, Func<Color> valueAccessor, Action<Color> onValueChanged = null, Action<Color> onEndEdit = null, bool showAlpha = true)
			: base(displayName, valueAccessor, onValueChanged, onEndEdit)
		{
			ShowAlpha = showAlpha;
		}

		public ColorConfigField(string displayName, string tooltip, Func<Color> valueAccessor, Action<Color> onValueChanged = null, Action<Color> onEndEdit = null, bool showAlpha = true)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
			ShowAlpha = showAlpha;
		}

		public ColorConfigField(string displayName, TooltipContent tooltip, Func<Color> valueAccessor, Action<Color> onValueChanged = null, Action<Color> onEndEdit = null, bool showAlpha = true)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ShowAlpha = showAlpha;
		}
	}
	public static class ConfigFieldUtilities
	{
		public static ModConfigEntry CreateFromBepInExConfigFile(ConfigFile file, string displayName)
		{
			return CreateFromBepInExConfigFile(file, displayName, tryToFindEnabledField: true, tryToFindSectionEnabledField: true);
		}

		public static ModConfigEntry CreateFromBepInExConfigFile(ConfigFile file, string displayName, bool tryToFindEnabledField)
		{
			return CreateFromBepInExConfigFile(file, displayName, tryToFindEnabledField, tryToFindSectionEnabledField: true);
		}

		public static ModConfigEntry CreateFromBepInExConfigFile(ConfigFile file, string displayName, bool tryToFindEnabledField, bool tryToFindSectionEnabledField)
		{
			ModConfigEntry modConfigEntry = new ModConfigEntry
			{
				DisplayName = displayName
			};
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in file)
			{
				if (tryToFindEnabledField && modConfigEntry.EnableField == null && item.Key.Key.Equals("enabled", StringComparison.InvariantCultureIgnoreCase) && item.Value.BoxedValue is bool)
				{
					modConfigEntry.EnableField = CreateBooleanConfigField(item.Value as ConfigEntry<bool>);
					continue;
				}
				if (tryToFindSectionEnabledField && !modConfigEntry.SectionEnableFields.ContainsKey(item.Key.Section) && item.Key.Key.Equals("sectionEnabled", StringComparison.InvariantCultureIgnoreCase) && item.Value.BoxedValue is bool)
				{
					modConfigEntry.SectionEnableFields[item.Key.Section] = CreateBooleanConfigField(item.Value as ConfigEntry<bool>);
				}
				IConfigField configField = ProcessConfigRow(item.Value);
				if (configField == null)
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)("Config [" + displayName + "]. Not found prefab that can be associated with `" + item.Key.Key + "` field."));
				}
				else
				{
					if (!modConfigEntry.SectionFields.TryGetValue(item.Key.Section, out var value))
					{
						IEnumerable<IConfigField> enumerable2 = (modConfigEntry.SectionFields[item.Key.Section] = new List<IConfigField>());
						value = enumerable2;
					}
					(value as List<IConfigField>).Add(configField);
				}
			}
			return modConfigEntry;
		}

		public static IConfigField CreateFromBepInExConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			return ProcessConfigRow((ConfigEntryBase)(object)configEntry);
		}

		private static IConfigField ProcessConfigRow(ConfigEntryBase configEntry)
		{
			if (configEntry.BoxedValue is bool)
			{
				return CreateBooleanConfigField(configEntry as ConfigEntry<bool>);
			}
			if (configEntry.BoxedValue is Enum)
			{
				return CreateEnumConfigField(configEntry);
			}
			if (configEntry.BoxedValue is int)
			{
				return CreateIntConfigField(configEntry as ConfigEntry<int>);
			}
			if (configEntry.BoxedValue is float)
			{
				return CreateFloatConfigField(configEntry as ConfigEntry<float>);
			}
			if (configEntry.BoxedValue is string)
			{
				return CreateStringConfigField(configEntry as ConfigEntry<string>);
			}
			if (configEntry.BoxedValue is Color)
			{
				return CreateColorConfigField(configEntry as ConfigEntry<Color>);
			}
			return null;
		}

		private static BooleanConfigField CreateBooleanConfigField(ConfigEntry<bool> configEntry)
		{
			return new BooleanConfigField(((ConfigEntryBase)configEntry).Definition.Key, ((ConfigEntryBase)configEntry).Description.Description, ValueAccessor, OnValueChanged);
			void OnValueChanged(bool newValue)
			{
				configEntry.Value = newValue;
			}
			bool ValueAccessor()
			{
				return configEntry.Value;
			}
		}

		private static StringConfigField CreateStringConfigField(ConfigEntry<string> configEntry)
		{
			return new StringConfigField(((ConfigEntryBase)configEntry).Definition.Key, ((ConfigEntryBase)configEntry).Description.Description, ValueAccessor, null, OnEndEdit);
			void OnEndEdit(string newValue)
			{
				configEntry.Value = newValue;
			}
			string ValueAccessor()
			{
				return configEntry.Value;
			}
		}

		private static ColorConfigField CreateColorConfigField(ConfigEntry<Color> configEntry)
		{
			return new ColorConfigField(((ConfigEntryBase)configEntry).Definition.Key, ((ConfigEntryBase)configEntry).Description.Description, ValueAccessor, null, OnEndEdit);
			void OnEndEdit(Color newValue)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				configEntry.Value = newValue;
			}
			Color ValueAccessor()
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return configEntry.Value;
			}
		}

		private static IntConfigField CreateIntConfigField(ConfigEntry<int> configEntry)
		{
			return new IntConfigField(((ConfigEntryBase)configEntry).Definition.Key, ((ConfigEntryBase)configEntry).Description.Description, ValueAccessor, null, OnEndEdit);
			void OnEndEdit(int newValue)
			{
				configEntry.Value = newValue;
			}
			int ValueAccessor()
			{
				return configEntry.Value;
			}
		}

		private static FloatConfigField CreateFloatConfigField(ConfigEntry<float> configEntry)
		{
			return new FloatConfigField(((ConfigEntryBase)configEntry).Definition.Key, ((ConfigEntryBase)configEntry).Description.Description, ValueAccessor, null, OnEndEdit);
			void OnEndEdit(float newValue)
			{
				configEntry.Value = newValue;
			}
			float ValueAccessor()
			{
				return configEntry.Value;
			}
		}

		private static EnumConfigField CreateEnumConfigField(ConfigEntryBase configEntry)
		{
			return new EnumConfigField(configEntry.SettingType, configEntry.Definition.Key, configEntry.Description.Description, ValueAccessor, OnEndEdit);
			void OnEndEdit(Enum newValue)
			{
				configEntry.BoxedValue = newValue;
			}
			Enum ValueAccessor()
			{
				return (Enum)configEntry.BoxedValue;
			}
		}
	}
	public class EnumConfigField : BaseConfigField<Enum>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("EnumFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public ReadOnlyCollection<string> Options { get; }

		public ReadOnlyCollection<Enum> Values { get; }

		public Type EnumType { get; }

		public EnumConfigField(Type enumType, string displayName, Func<Enum> valueAccessor, Action<Enum> onValueChanged = null)
			: base(displayName, valueAccessor, onValueChanged)
		{
			EnumType = enumType;
			Options = new ReadOnlyCollection<string>(Enum.GetNames(enumType));
			Values = new ReadOnlyCollection<Enum>(Enum.GetValues(enumType).Cast<Enum>().ToList());
		}

		public EnumConfigField(Type enumType, string displayName, string tooltip, Func<Enum> valueAccessor, Action<Enum> onValueChanged = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
			EnumType = enumType;
			Options = new ReadOnlyCollection<string>(Enum.GetNames(enumType));
			Values = new ReadOnlyCollection<Enum>(Enum.GetValues(enumType).Cast<Enum>().ToList());
		}

		public EnumConfigField(Type enumType, string displayName, TooltipContent tooltip, Func<Enum> valueAccessor, Action<Enum> onValueChanged = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			EnumType = enumType;
			Options = new ReadOnlyCollection<string>(Enum.GetNames(enumType));
			Values = new ReadOnlyCollection<Enum>(Enum.GetValues(enumType).Cast<Enum>().ToList());
		}
	}
	public class EnumConfigField<T> : EnumConfigField where T : Enum
	{
		public new IEnumerable<T> Values { get; }

		protected new Action<T> OnValueChangedCallback { get; }

		protected new Func<T> ValueAccessor { get; }

		public EnumConfigField(string displayName, Func<T> valueAccessor, Action<T> onValueChanged = null)
			: base(typeof(T), displayName, () => valueAccessor())
		{
			ValueAccessor = valueAccessor;
			OnValueChangedCallback = onValueChanged;
		}

		public EnumConfigField(string displayName, string tooltip, Func<T> valueAccessor, Action<T> onValueChanged = null)
			: base(typeof(T), displayName, tooltip, () => valueAccessor())
		{
			ValueAccessor = valueAccessor;
			OnValueChangedCallback = onValueChanged;
		}

		public EnumConfigField(string displayName, TooltipContent tooltip, Func<T> valueAccessor, Action<T> onValueChanged = null)
			: base(typeof(T), displayName, tooltip, () => valueAccessor())
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			ValueAccessor = valueAccessor;
			OnValueChangedCallback = onValueChanged;
		}

		public void OnValueChanged(T newValue)
		{
			OnValueChangedCallback?.Invoke(newValue);
		}

		public override void OnValueChanged(Enum newValue)
		{
			OnValueChangedCallback?.Invoke((T)newValue);
		}

		public new T GetValue()
		{
			return ValueAccessor();
		}
	}
	public class FloatConfigField : BaseNumberInputConfigField<float>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("FloatFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public FloatConfigField(string displayName, Func<float> valueAccessor, Action<float> onValueChanged = null, Action<float> onEndEdit = null, float? minimum = null, float? maximum = null)
			: base(displayName, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}

		public FloatConfigField(string displayName, string tooltip, Func<float> valueAccessor, Action<float> onValueChanged = null, Action<float> onEndEdit = null, float? minimum = null, float? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}

		public FloatConfigField(string displayName, TooltipContent tooltip, Func<float> valueAccessor, Action<float> onValueChanged = null, Action<float> onEndEdit = null, float? minimum = null, float? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)

	}
	public interface IConfigField
	{
		GameObject FieldPrefab { get; }

		string DisplayName { get; }

		TooltipContent Tooltip { get; }

		object GetValue();
	}
	public class IntConfigField : BaseNumberInputConfigField<int>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("IntFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public IntConfigField(string displayName, Func<int> valueAccessor, Action<int> onValueChanged = null, Action<int> onEndEdit = null, int? minimum = null, int? maximum = null)
			: base(displayName, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}

		public IntConfigField(string displayName, string tooltip, Func<int> valueAccessor, Action<int> onValueChanged = null, Action<int> onEndEdit = null, int? minimum = null, int? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}

		public IntConfigField(string displayName, TooltipContent tooltip, Func<int> valueAccessor, Action<int> onValueChanged = null, Action<int> onEndEdit = null, int? minimum = null, int? maximum = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit, minimum, maximum)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)

	}
	public class SelectListField : BaseConfigField<IEnumerable<object>>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("SelectListFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		protected Func<IDictionary<object, string>> OptionsAccessor { get; }

		protected Action<object, int> OnItemAddedCallback { get; }

		protected Action<int> OnItemRemovedCallback { get; }

		public SelectListField(string displayName, Func<IEnumerable<object>> valueAccessor, Action<object, int> onItemAdded, Action<int> onItemRemoved, Func<IDictionary<object, string>> optionsAccessor)
			: base(displayName, valueAccessor, (Action<IEnumerable<object>>)null)
		{
			OnItemAddedCallback = onItemAdded;
			OnItemRemovedCallback = onItemRemoved;
			OptionsAccessor = optionsAccessor;
		}

		public SelectListField(string displayName, string tooltip, Func<IEnumerable<object>> valueAccessor, Action<object, int> onItemAdded, Action<int> onItemRemoved, Func<IDictionary<object, string>> optionsAccessor)
			: base(displayName, tooltip, valueAccessor, (Action<IEnumerable<object>>)null)
		{
			OnItemAddedCallback = onItemAdded;
			OnItemRemovedCallback = onItemRemoved;
			OptionsAccessor = optionsAccessor;
		}

		public void OnItemAdded(object value, int index)
		{
			OnItemAddedCallback?.Invoke(value, index);
		}

		public void OnItemRemoved(int index)
		{
			OnItemRemovedCallback?.Invoke(index);
		}

		public IDictionary<object, string> GetOptions()
		{
			return OptionsAccessor?.Invoke();
		}
	}
	public class SelectListField<T> : SelectListField
	{
		protected new Func<IDictionary<T, string>> OptionsAccessor { get; }

		protected new Action<T, int> OnItemAddedCallback { get; }

		protected new Action<int> OnItemRemovedCallback { get; }

		public SelectListField(string displayName, Func<ICollection<T>> valueAccessor, Action<T, int> onItemAdded, Action<int> onItemRemoved, Func<IDictionary<T, string>> optionsAccessor)
			: base(displayName, () => valueAccessor().Cast<object>(), delegate(object value, int index)
			{
				onItemAdded?.Invoke((T)value, index);
			}, onItemRemoved, () => ((IEnumerable<KeyValuePair<T, string>>)optionsAccessor?.Invoke()).ToDictionary((Func<KeyValuePair<T, string>, object>)((KeyValuePair<T, string> row) => row.Key), (Func<KeyValuePair<T, string>, string>)((KeyValuePair<T, string> row) => row.Value)))
		{
			OnItemAddedCallback = onItemAdded;
			OnItemRemovedCallback = onItemRemoved;
			OptionsAccessor = optionsAccessor;
		}

		public SelectListField(string displayName, string tooltip, Func<ICollection<T>> valueAccessor, Action<T, int> onItemAdded, Action<int> onItemRemoved, Func<IDictionary<T, string>> optionsAccessor)
			: base(displayName, tooltip, () => valueAccessor().Cast<object>(), delegate(object value, int index)
			{
				onItemAdded?.Invoke((T)value, index);
			}, onItemRemoved, () => ((IEnumerable<KeyValuePair<T, string>>)optionsAccessor?.Invoke()).ToDictionary((Func<KeyValuePair<T, string>, object>)((KeyValuePair<T, string> row) => row.Key), (Func<KeyValuePair<T, string>, string>)((KeyValuePair<T, string> row) => row.Value)))
		{
			OnItemAddedCallback = onItemAdded;
			OnItemRemovedCallback = onItemRemoved;
			OptionsAccessor = optionsAccessor;
		}

		public void OnItemAdded(T value, int index)
		{
			OnItemAddedCallback?.Invoke(value, index);
		}

		public new IDictionary<T, string> GetOptions()
		{
			return OptionsAccessor?.Invoke();
		}
	}
	public class StringConfigField : BaseInputConfigField<string>
	{
		private static GameObject fieldPrefab;

		public override GameObject FieldPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)fieldPrefab))
				{
					return fieldPrefab = AssetBundleHelper.LoadPrefab("StringFieldPrefab");
				}
				return fieldPrefab;
			}
		}

		public StringConfigField(string displayName, Func<string> valueAccessor, Action<string> onValueChanged = null, Action<string> onEndEdit = null)
			: base(displayName, valueAccessor, onValueChanged, onEndEdit)
		{
		}

		public StringConfigField(string displayName, string tooltip, Func<string> valueAccessor, Action<string> onValueChanged = null, Action<string> onEndEdit = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
		}

		public StringConfigField(string displayName, TooltipContent tooltip, Func<string> valueAccessor, Action<string> onValueChanged, Action<string> onEndEdit = null)
			: base(displayName, tooltip, valueAccessor, onValueChanged, onEndEdit)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)

	}
}
namespace InLobbyConfig.FieldControllers
{
	public class BooleanFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public Toggle toggle;

		private bool skipValueChange;

		private BooleanConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as BooleanConfigField;
			if (ConfigField != null)
			{
				if (Object.op_Implicit((Object)(object)tooltipProvider))
				{
					tooltipProvider.SetContent(ConfigField.Tooltip);
				}
				if (Object.op_Implicit((Object)(object)fieldText))
				{
					((TMP_Text)fieldText).text = ConfigField.DisplayName;
				}
				bool value = ConfigField.GetValue();
				if (value != toggle.isOn)
				{
					skipValueChange = true;
					toggle.isOn = value;
				}
			}
		}

		public void OnValueChanged(bool newValue)
		{
			if (ConfigField != null)
			{
				if (skipValueChange)
				{
					skipValueChange = false;
				}
				else
				{
					ConfigField.OnValueChanged(newValue);
				}
			}
		}
	}
	public class ColorFieldController : ConfigFieldController
	{
		public enum ColorPart
		{
			R,
			G,
			B,
			A
		}

		public TextMeshProUGUI fieldText;

		public Image preview;

		public TMP_InputField colorR;

		public TMP_InputField colorG;

		public TMP_InputField colorB;

		public TMP_InputField colorA;

		private Color32 currentColor;

		private ColorConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as ColorConfigField;
			if (ConfigField != null)
			{
				if (Object.op_Implicit((Object)(object)fieldText))
				{
					((TMP_Text)fieldText).text = ConfigField.DisplayName;
				}
				if (Object.op_Implicit((Object)(object)tooltipProvider))
				{
					tooltipProvider.SetContent(ConfigField.Tooltip);
				}
				if (!ConfigField.ShowAlpha)
				{
					((Component)((Component)colorA).transform.parent).gameObject.SetActive(false);
				}
				((MonoBehaviour)this).StartCoroutine(DelayedStartCoroutine());
			}
		}

		private IEnumerator DelayedStartCoroutine()
		{
			yield return (object)new WaitForSeconds(0.01f);
			currentColor = Color32.op_Implicit(ConfigField.GetValue());
			ProcessColor(currentColor.r, colorR);
			ProcessColor(currentColor.g, colorG);
			ProcessColor(currentColor.b, colorB);
			ProcessColor(currentColor.a, colorA);
			((Graphic)preview).color = Color32.op_Implicit(currentColor);
			static void ProcessColor(byte color, TMP_InputField inputField)
			{
				string text = color.ToString();
				if (text != inputField.text)
				{
					inputField.SetTextWithoutNotify(text);
				}
			}
		}

		public void OnValueChangedR(string newValue)
		{
			OnValueChanged(newValue, ColorPart.R);
		}

		public void OnValueChangedG(string newValue)
		{
			OnValueChanged(newValue, ColorPart.G);
		}

		public void OnValueChangedB(string newValue)
		{
			OnValueChanged(newValue, ColorPart.B);
		}

		public void OnValueChangedA(string newValue)
		{
			OnValueChanged(newValue, ColorPart.A);
		}

		private void OnValueChanged(string newValue, ColorPart colorPart)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigField == null || !int.TryParse(newValue, out var result))
			{
				return;
			}
			switch (colorPart)
			{
			case ColorPart.R:
				if (ProcessColorPart(result, colorR))
				{
					return;
				}
				currentColor.r = (byte)result;
				break;
			case ColorPart.G:
				if (ProcessColorPart(result, colorG))
				{
					return;
				}
				currentColor.g = (byte)result;
				break;
			case ColorPart.B:
				if (ProcessColorPart(result, colorB))
				{
					return;
				}
				currentColor.b = (byte)result;
				break;
			case ColorPart.A:
				if (ProcessColorPart(result, colorA))
				{
					return;
				}
				currentColor.a = (byte)result;
				break;
			}
			((Graphic)preview).color = Color32.op_Implicit(currentColor);
			ConfigField.OnValueChanged(new Color((float)(int)currentColor.r, (float)(int)currentColor.g, (float)(int)currentColor.b, (float)(int)currentColor.a));
		}

		public void OnEndEditR(string newValue)
		{
			OnEndEdit(newValue, ColorPart.R);
		}

		public void OnEndEditG(string newValue)
		{
			OnEndEdit(newValue, ColorPart.G);
		}

		public void OnEndEditB(string newValue)
		{
			OnEndEdit(newValue, ColorPart.B);
		}

		public void OnEndEditA(string newValue)
		{
			OnEndEdit(newValue, ColorPart.A);
		}

		private void OnEndEdit(string newValue, ColorPart colorPart)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigField == null)
			{
				return;
			}
			if (!int.TryParse(newValue, out var _))
			{
				bool flag = string.IsNullOrEmpty(newValue);
				switch (colorPart)
				{
				case ColorPart.R:
					colorR.text = (flag ? "0" : currentColor.r.ToString());
					break;
				case ColorPart.G:
					colorG.text = (flag ? "0" : currentColor.g.ToString());
					break;
				case ColorPart.B:
					colorB.text = (flag ? "0" : currentColor.b.ToString());
					break;
				case ColorPart.A:
					colorA.text = (flag ? "0" : currentColor.a.ToString());
					break;
				}
			}
			if (!(ConfigField.GetValue() == Color32.op_Implicit(currentColor)))
			{
				ConfigField.OnEndEdit(new Color((float)(int)currentColor.r, (float)(int)currentColor.g, (float)(int)currentColor.b, (float)(int)currentColor.a));
			}
		}

		private bool ProcessColorPart(int newValue, TMP_InputField inputField)
		{
			if (newValue > 255)
			{
				inputField.text = "255";
				return true;
			}
			if (newValue < 0)
			{
				inputField.text = "0";
				return true;
			}
			return false;
		}
	}
	public abstract class ConfigFieldController : MonoBehaviour
	{
		public TooltipProvider tooltipProvider;

		[HideInInspector]
		public IConfigField configField;
	}
	public class EnumFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public TMP_Dropdown dropdown;

		private EnumConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			ConfigField = configField as EnumConfigField;
			if (ConfigField == null)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)fieldText))
			{
				((TMP_Text)fieldText).text = ConfigField.DisplayName;
			}
			if (Object.op_Implicit((Object)(object)tooltipProvider))
			{
				tooltipProvider.SetContent(ConfigField.Tooltip);
			}
			foreach (string option in ConfigField.Options)
			{
				dropdown.options.Add(new OptionData(option));
			}
			int num = ConfigField.Values.IndexOf(ConfigField.GetValue());
			if (num != dropdown.value)
			{
				dropdown.SetValueWithoutNotify(num);
			}
		}

		public void OnValueChanged(int index)
		{
			if (ConfigField != null)
			{
				ConfigField.OnValueChanged(ConfigField.Values.ElementAt(index));
			}
		}
	}
	public class FloatFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public TMP_InputField inputField;

		private FloatConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as FloatConfigField;
			if (ConfigField != null)
			{
				if (Object.op_Implicit((Object)(object)fieldText))
				{
					((TMP_Text)fieldText).text = ConfigField.DisplayName;
				}
				if (Object.op_Implicit((Object)(object)tooltipProvider))
				{
					tooltipProvider.SetContent(ConfigField.Tooltip);
				}
				((MonoBehaviour)this).StartCoroutine(DelayedStartCoroutine());
			}
		}

		private IEnumerator DelayedStartCoroutine()
		{
			yield return (object)new WaitForSeconds(0.01f);
			string text = ConfigField.GetValue().ToString();
			if (!(text == inputField.text))
			{
				inputField.SetTextWithoutNotify(text);
			}
		}

		public void OnValueChanged(string newValue)
		{
			if (ConfigField != null && float.TryParse(newValue, out var result))
			{
				if (ConfigField.Minimum.HasValue && ConfigField.Minimum > result)
				{
					inputField.text = ConfigField.Minimum.Value.ToString(NumberFormatInfo.InvariantInfo);
				}
				else if (ConfigField.Maximum.HasValue && ConfigField.Maximum < result)
				{
					inputField.text = ConfigField.Maximum.Value.ToString(NumberFormatInfo.InvariantInfo);
				}
				else
				{
					ConfigField.OnValueChanged(result);
				}
			}
		}

		public void OnEndEdit(string newValue)
		{
			if (ConfigField != null)
			{
				float value = ConfigField.GetValue();
				if (!float.TryParse(newValue, out var result))
				{
					inputField.text = value.ToString();
				}
				if (value != result)
				{
					ConfigField.OnEndEdit(result);
				}
			}
		}
	}
	public class IntFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public TMP_InputField inputField;

		private IntConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as IntConfigField;
			if (ConfigField != null)
			{
				if (Object.op_Implicit((Object)(object)fieldText))
				{
					((TMP_Text)fieldText).text = ConfigField.DisplayName;
				}
				if (Object.op_Implicit((Object)(object)tooltipProvider))
				{
					tooltipProvider.SetContent(ConfigField.Tooltip);
				}
				((MonoBehaviour)this).StartCoroutine(DelayedStartCoroutine());
			}
		}

		private IEnumerator DelayedStartCoroutine()
		{
			yield return (object)new WaitForSeconds(0.01f);
			string text = ConfigField.GetValue().ToString(NumberFormatInfo.InvariantInfo);
			if (!(text == inputField.text))
			{
				inputField.SetTextWithoutNotify(text);
			}
		}

		public void OnValueChanged(string newValue)
		{
			if (ConfigField != null && int.TryParse(newValue, out var result))
			{
				if (ConfigField.Minimum.HasValue && ConfigField.Minimum > result)
				{
					inputField.text = ConfigField.Minimum.Value.ToString();
				}
				else if (ConfigField.Maximum.HasValue && ConfigField.Maximum < result)
				{
					inputField.text = ConfigField.Maximum.Value.ToString();
				}
				else
				{
					ConfigField.OnValueChanged(result);
				}
			}
		}

		public void OnEndEdit(string newValue)
		{
			if (ConfigField != null)
			{
				int value = ConfigField.GetValue();
				if (!int.TryParse(newValue, out var result))
				{
					inputField.text = value.ToString();
				}
				if (value != result)
				{
					ConfigField.OnEndEdit(result);
				}
			}
		}
	}
	public class SelectListFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public SearchableDropdown dropdown;

		public GameObject itemPrefab;

		public Button contentToggleButton;

		public Transform contentContainer;

		private readonly List<SelectListItemController> items = new List<SelectListItemController>();

		private Dictionary<object, string> options;

		private SelectListField ConfigField { get; set; }

		public void Start()
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as SelectListField;
			if (ConfigField == null)
			{
				return;
			}
			options = ConfigField.GetOptions().ToDictionary((KeyValuePair<object, string> el) => el.Key, (KeyValuePair<object, string> el) => el.Value);
			dropdown.Options = options.Select((KeyValuePair<object, string> el) => new SearchableDropdown.OptionData(el.Key, el.Value)).ToList();
			((UnityEvent<object>)(dropdown.OnItemSelected ?? (dropdown.OnItemSelected = new SearchableDropdown.DropdownEvent()))).AddListener((UnityAction<object>)AddNewItem);
			if (Object.op_Implicit((Object)(object)tooltipProvider))
			{
				tooltipProvider.SetContent(ConfigField.Tooltip);
			}
			if (Object.op_Implicit((Object)(object)fieldText))
			{
				((TMP_Text)fieldText).text = ConfigField.DisplayName;
			}
			foreach (object item in ConfigField.GetValue())
			{
				AddNewItem(item, skipNotification: true);
			}
		}

		public void AddNewItem(object value)
		{
			AddNewItem(value, skipNotification: false);
			if (!((Component)contentContainer).gameObject.activeSelf)
			{
				ButtonClickedEvent onClick = contentToggleButton.onClick;
				if (onClick != null)
				{
					((UnityEvent)onClick).Invoke();
				}
			}
		}

		public void AddNewItem(object value, bool skipNotification = false)
		{
			if (ConfigField != null && !items.Any((SelectListItemController item) => item.value.Equals(value)))
			{
				GameObject val = Object.Instantiate<GameObject>(itemPrefab, contentContainer);
				SelectListItemController component = val.GetComponent<SelectListItemController>();
				options.TryGetValue(value, out var value2);
				((TMP_Text)component.textComponent).text = value2 ?? "{Missing option}";
				component.value = value;
				val.SetActive(true);
				items.Add(component);
				if (!skipNotification)
				{
					ConfigField.OnItemAdded(value, val.transform.GetSiblingIndex());
				}
			}
		}

		public void DeleteItem(int index)
		{
			if (ConfigField != null)
			{
				items.RemoveAt(index);
				ConfigField.OnItemRemoved(index);
			}
		}

		public void ToggleContent()
		{
			((Component)contentContainer).gameObject.SetActive(!((Component)contentContainer).gameObject.activeSelf);
		}
	}
	public class SelectListItemController : MonoBehaviour
	{
		public TextMeshProUGUI textComponent;

		[HideInInspector]
		public object value;

		public SelectListFieldController fieldController;

		public void DeleteButtonClick()
		{
			fieldController?.DeleteItem(((Component)this).transform.GetSiblingIndex());
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	public class StringFieldController : ConfigFieldController
	{
		public TextMeshProUGUI fieldText;

		public TMP_InputField inputField;

		private StringConfigField ConfigField { get; set; }

		public void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			ConfigField = configField as StringConfigField;
			if (ConfigField != null)
			{
				if (Object.op_Implicit((Object)(object)fieldText))
				{
					((TMP_Text)fieldText).text = ConfigField.DisplayName;
				}
				if (Object.op_Implicit((Object)(object)tooltipProvider))
				{
					tooltipProvider.SetContent(ConfigField.Tooltip);
				}
				((MonoBehaviour)this).StartCoroutine(DelayedStartCoroutine());
			}
		}

		private IEnumerator DelayedStartCoroutine()
		{
			yield return (object)new WaitForSeconds(0.01f);
			string value = ConfigField.GetValue();
			if (!(value == inputField.text))
			{
				inputField.SetTextWithoutNotify(value);
			}
		}

		public void OnValueChanged(string newValue)
		{
			if (ConfigField != null)
			{
				ConfigField.OnValueChanged(newValue);
			}
		}

		public void OnEndEdit(string newValue)
		{
			if (ConfigField != null && !(ConfigField.GetValue() == newValue))
			{
				ConfigField.OnEndEdit(newValue);
			}
		}
	}
}
namespace InLobbyConfig.Components
{
	public class ConfigPanelController : MonoBehaviour
	{
		public GameObject configButton;

		public GameObject popoutPanel;

		private GameObject scrollContent;

		private bool initialized;

		public static GameObject CachedPrefab { get; private set; }

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			((UnityEvent)((Button)configButton.GetComponent<HGButton>()).onClick).AddListener(new UnityAction(TogglePopoutPanel));
		}

		private void Start()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)popoutPanel))
			{
				return;
			}
			HGPopoutPanel component = popoutPanel.GetComponent<HGPopoutPanel>();
			component.popoutPanelTitleText.token = "IN_LOBBY_CONFIG_POPOUT_PANEL_NAME";
			((Component)((Component)component.popoutPanelDescriptionText).transform.parent).gameObject.SetActive(false);
			Transform obj = popoutPanel.GetComponent<ChildLocator>().FindChild("RandomButtonContainer");
			if (obj != null)
			{
				GameObject gameObject = ((Component)obj).gameObject;
				if (gameObject != null)
				{
					gameObject.SetActive(false);
				}
			}
			RectTransform popoutPanelContentContainer = component.popoutPanelContentContainer;
			Object.DestroyImmediate((Object)(object)((Component)popoutPanelContentContainer).GetComponent<GridLayoutGroup>());
			RectTransform component2 = ((Component)popoutPanelContentContainer).GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(0f, 700f);
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.offsetMin = default(Vector2);
			component2.offsetMax = default(Vector2);
			((Component)popoutPanelContentContainer).gameObject.AddComponent<LayoutElement>().minHeight = 700f;
			if (InLobbyConfigPlugin.IsScrollableLobbyUILoaded)
			{
				ModifyIfSLUILoaded((Transform)(object)popoutPanelContentContainer);
			}
			((Component)popoutPanelContentContainer).gameObject.AddComponent<RectMask2D>();
			scrollContent = Object.Instantiate<GameObject>(AssetBundleHelper.LoadPrefab("ScrollContent"), ((Component)popoutPanelContentContainer).transform);
			GameObject val = Object.Instantiate<GameObject>(AssetBundleHelper.LoadPrefab("ScrollBar"), ((Component)popoutPanelContentContainer).transform);
			ScrollRect obj2 = ((Component)popoutPanelContentContainer).gameObject.AddComponent<ScrollRect>();
			obj2.content = scrollContent.GetComponent<RectTransform>();
			obj2.movementType = (MovementType)2;
			obj2.horizontal = false;
			obj2.vertical = true;
			obj2.viewport = popoutPanelContentContainer;
			obj2.scrollSensitivity = 30f;
			obj2.verticalScrollbar = val.GetComponent<Scrollbar>();
			obj2.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			if (popoutPanel.activeSelf)
			{
				InitContent();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void ModifyIfSLUILoaded(Transform contentTransform)
		{
			((Component)contentTransform.parent.parent).GetComponent<DynamicContentSizeFitter>().maxHeight = 700f;
		}

		private void TogglePopoutPanel()
		{
			if (Object.op_Implicit((Object)(object)popoutPanel))
			{
				popoutPanel.SetActive(!popoutPanel.activeSelf);
				if (popoutPanel.activeSelf)
				{
					InitContent();
				}
			}
		}

		private void InitContent()
		{
			if (initialized)
			{
				return;
			}
			foreach (ModConfigEntry @readonly in ModConfigCatalog.ReadonlyList)
			{
				if (@readonly == null)
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)"Skipping over null ModConfigEntry");
					continue;
				}
				if (@readonly.EnableField == null && (@readonly.SectionFields.Count == 0 || @readonly.SectionFields.All((KeyValuePair<string, IEnumerable<IConfigField>> row) => row.Value.Count() == 0)))
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)("Skipping over `" + @readonly.DisplayName + "` because it has no fields assigned"));
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(AssetBundleHelper.LoadPrefab("ModConfigPrefab"), scrollContent.transform);
				if (!Object.op_Implicit((Object)(object)val))
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)"Failed to instantiate `ModConfigPrefab`");
				}
				else
				{
					val.GetComponent<ModConfigController>().configEntry = @readonly;
				}
			}
			initialized = true;
		}

		internal static void CharacterSelectControllerAwake(Action<CharacterSelectController> orig, CharacterSelectController self)
		{
			orig(self);
			((MonoBehaviour)self).StartCoroutine(InitConfigPanel(self));
		}

		private static IEnumerator InitConfigPanel(CharacterSelectController self)
		{
			yield return (object)new WaitForFixedUpdate();
			yield return (object)new WaitForFixedUpdate();
			Transform val = ((Component)self).transform.Find("SafeArea/LeftHandPanel (Layer: Main)");
			Transform val2 = ((Component)self).transform.Find("SafeArea/RightHandPanel");
			if (!Object.op_Implicit((Object)(object)CachedPrefab))
			{
				CachePrefabFromSurvivorGrid(val, "SurvivorChoiceGrid, Panel");
			}
			GameObject val3 = Object.Instantiate<GameObject>(CachedPrefab, ((Component)self).transform.Find("SafeArea"), false);
			Transform val4 = val2.Find("PopoutPanelContainer");
			GameObject val5 = Object.Instantiate<GameObject>(((Component)val4.Find("PopoutPanelPrefab")).gameObject, val4);
			val3.GetComponent<ConfigPanelController>().popoutPanel = val5;
			HGGamepadInputEvent val6 = ((Component)self).GetComponents<HGGamepadInputEvent>().First((HGGamepadInputEvent el) => el.actionName == "UIPageRight");
			val6.requiredTopLayer = ((Component)val).GetComponent<UILayerKey>();
			HGGamepadInputEvent obj = ((Component)self).gameObject.AddComponent<HGGamepadInputEvent>();
			obj.actionName = val6.actionName;
			obj.actionEvent = val6.actionEvent;
			obj.requiredTopLayer = ((Component)val.Find("SurvivorInfoPanel, Active (Layer: Secondary)")).GetComponent<UILayerKey>();
			obj.enabledObjectsIfActive = Array.Empty<GameObject>();
			Transform ruleLayout = val2.Find("RuleLayoutActive (Layer: Tertiary)");
			UILayerKey ruleLayoutLayer = ((Component)ruleLayout).GetComponent<UILayerKey>();
			HGGamepadInputEvent val7 = ((Component)self).GetComponents<HGGamepadInputEvent>().First((HGGamepadInputEvent input) => input.actionName == "UIPageLeft" && (Object)(object)input.requiredTopLayer == (Object)(object)ruleLayoutLayer);
			HGGamepadInputEvent val8 = ((Component)ruleLayout).gameObject.AddComponent<HGGamepadInputEvent>();
			val8.actionName = "UIPageRight";
			val8.actionEvent = val3.GetComponent<EventHolder>().unityEvent;
			val8.requiredTopLayer = ruleLayoutLayer;
			val8.enabledObjectsIfActive = Array.Empty<GameObject>();
			HGGamepadInputEvent obj2 = ((Component)ruleLayout).gameObject.AddComponent<HGGamepadInputEvent>();
			obj2.actionName = val8.actionName;
			obj2.actionEvent = val7.actionEvent;
			obj2.requiredTopLayer = val8.requiredTopLayer;
			obj2.enabledObjectsIfActive = Array.Empty<GameObject>();
			HGGamepadInputEvent component = val3.GetComponent<HGGamepadInputEvent>();
			component.actionEvent.AddListener((UnityAction)delegate
			{
				((Component)ruleLayout).gameObject.SetActive(true);
			});
			HGGamepadInputEvent obj3 = val3.AddComponent<HGGamepadInputEvent>();
			obj3.actionName = "UICancel";
			obj3.actionEvent = component.actionEvent;
			obj3.requiredTopLayer = component.requiredTopLayer;
			obj3.enabledObjectsIfActive = component.enabledObjectsIfActive;
		}

		private static void CachePrefabFromSurvivorGrid(Transform panel, string survivorGridName)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)CachedPrefab))
			{
				Transform obj = panel.Find(survivorGridName);
				CachedPrefab = AssetBundleHelper.LoadPrefab("ConfigPanel");
				CachedPrefab.GetComponent<Image>().sprite = ((Component)panel.Find("BorderImage")).GetComponent<Image>().sprite;
				Sprite sprite = ((Component)obj.Find("SurvivorIconPrefab/BaseOutline")).GetComponent<Image>().sprite;
				Sprite sprite2 = ((Component)obj.Find("SurvivorIconPrefab/HoverOutline")).GetComponent<Image>().sprite;
				UISkinData val = Object.Instantiate<UISkinData>(((BaseSkinController)((Component)obj.Find("WIPClassButtonPrefab")).GetComponent<ButtonSkinController>()).skinData);
				((ColorBlock)(ref val.buttonStyle.colors)).normalColor = Color.white;
				HGButton[] componentsInChildren = CachedPrefab.GetComponentsInChildren<HGButton>();
				foreach (HGButton obj2 in componentsInChildren)
				{
					((BaseSkinController)((Component)obj2).GetComponent<ButtonSkinController>()).skinData = val;
					((Component)((Component)obj2).transform.Find("BaseOutline")).GetComponent<Image>().sprite = sprite;
					((Component)((Component)obj2).transform.Find("HoverOutline")).GetComponent<Image>().sprite = sprite2;
				}
			}
		}
	}
	public class ConfigSectionController : MonoBehaviour
	{
		public BooleanFieldController enableButtonController;

		public Button contentToggleButton;

		public GameObject contentContainer;

		public string sectionName;

		public IEnumerable<IConfigField> fields;

		public BooleanConfigField enableField;

		public TextMeshProUGUI modNameText;

		private bool initialized;

		public void Start()
		{
			((TMP_Text)modNameText).text = "[" + sectionName + "]";
			if (enableField == null)
			{
				((Component)enableButtonController).gameObject.SetActive(false);
			}
			else
			{
				enableButtonController.configField = enableField;
			}
			if (contentContainer.activeSelf)
			{
				InitContent();
			}
		}

		public void ToggleContent()
		{
			if (Object.op_Implicit((Object)(object)contentContainer))
			{
				contentContainer.SetActive(!contentContainer.activeSelf);
				if (contentContainer.activeSelf)
				{
					InitContent();
				}
			}
		}

		private void InitContent()
		{
			if (initialized)
			{
				return;
			}
			foreach (IConfigField field in fields)
			{
				if (!Object.op_Implicit((Object)(object)field.FieldPrefab))
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)$"FieldPrefab for `{field.DisplayName}` of type `{field.GetType()}` doesn't exists");
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(field.FieldPrefab, contentContainer.transform);
				if (!Object.op_Implicit((Object)(object)val))
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)("Failed to instantiate FieldPrefab for `" + field.DisplayName + "`"));
					continue;
				}
				ConfigFieldController component = val.GetComponent<ConfigFieldController>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					InLobbyConfigPlugin.InstanceLogger.LogWarning((object)("FieldPrefab for `" + field.DisplayName + "` doesn't contain `ConfigFieldController`"));
				}
				else
				{
					component.configField = field;
				}
			}
			initialized = true;
		}
	}
	public class DelayedTooltipProvider : TooltipProvider, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public float delayInSeconds = 0.5f;

		void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
		{
			EventSystem current = EventSystem.current;
			MPEventSystem val = (MPEventSystem)(object)((current is MPEventSystem) ? current : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				((MonoBehaviour)this).StartCoroutine(DelayTooltipOpen(val, eventData));
			}
		}

		void IPointerExitHandler.OnPointerExit(PointerEventData eventData)
		{
			((MonoBehaviour)this).StopAllCoroutines();
			EventSystem current = EventSystem.current;
			MPEventSystem val = (MPEventSystem)(object)((current is MPEventSystem) ? current : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				TooltipController.RemoveTooltip(val, (TooltipProvider)(object)this);
			}
		}

		private IEnumerator DelayTooltipOpen(MPEventSystem eventSystem, PointerEventData eventData)
		{
			yield return (object)new WaitForSeconds(delayInSeconds);
			TooltipController.SetTooltip(eventSystem, (TooltipProvider)(object)this, eventData.position, (RectTransform)null);
		}
	}
	public class EventHolder : MonoBehaviour
	{
		public string customName;

		public UnityEvent unityEvent;
	}
	public class FlipVertical : MonoBehaviour
	{
		public void Flip()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			((Component)this).transform.localScale = new Vector3(((Component)this).transform.localScale.x, ((Component)this).transform.localScale.y * -1f, ((Component)this).transform.localScale.z);
		}
	}
	public class ModConfigController : MonoBehaviour
	{
		public BooleanFieldController enableButtonController;

		public Button contentToggleButton;

		public GameObject contentContainer;

		public ModConfigEntry configEntry;

		public TextMeshProUGUI modNameText;

		private bool initialized;

		public void Start()
		{
			if (configEntry != null)
			{
				((TMP_Text)modNameText).text = configEntry.DisplayName;
				if (configEntry.EnableField == null)
				{
					((Component)enableButtonController).gameObject.SetActive(false);
				}
				else
				{
					enableButtonController.configField = configEntry.EnableField;
				}
				if (configEntry.SectionFields.Count == 0 && configEntry.SectionFields.All((KeyValuePair<string, IEnumerable<IConfigField>> row) => row.Value.Count() == 0))
				{
					((Component)contentToggleButton).gameObject.SetActive(false);
				}
				if (contentContainer.activeSelf)
				{
					InitContent();
				}
			}
		}

		public void ToggleContent()
		{
			if (Object.op_Implicit((Object)(object)contentContainer))
			{
				contentContainer.SetActive(!contentContainer.activeSelf);
				if (contentContainer.activeSelf)
				{
					InitContent();
				}
			}
		}

		private void InitContent()
		{
			if (initialized)
			{
				return;
			}
			foreach (KeyValuePair<string, IEnumerable<IConfigField>> sectionField in configEntry.SectionFields)
			{
				ConfigSectionController component = Object.Instantiate<GameObject>(AssetBundleHelper.LoadPrefab("SectionPrefab"), contentContainer.transform).GetComponent<ConfigSectionController>();
				component.sectionName = sectionField.Key;
				component.fields = sectionField.Value;
				configEntry.SectionEnableFields.TryGetValue(sectionField.Key, out component.enableField);
			}
			initialized = true;
		}
	}
	public class RoRToggle : Toggle
	{
		private SelectionState previousState = (SelectionState)4;

		public Sprite onSprite;

		public Sprite offSprite;

		protected override void Start()
		{
			((Toggle)this).Start();
			((UnityEvent<bool>)(object)base.onValueChanged).AddListener((UnityAction<bool>)ToggleImage);
			ToggleImage(((Toggle)this).isOn);
		}

		private void ToggleImage(bool newValue)
		{
			if (Object.op_Implicit((Object)(object)RoR2Application.instance))
			{
				Util.PlaySound("Play_UI_menuClick", ((Component)RoR2Application.instance).gameObject);
			}
			((Selectable)this).image.sprite = (newValue ? onSprite : offSprite);
		}

		protected override void DoStateTransition(SelectionState state, bool instant)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			((Selectable)this).DoStateTransition(state, instant);
			if (previousState != state)
			{
				if ((int)state == 1 && Object.op_Implicit((Object)(object)RoR2Application.instance))
				{
					Util.PlaySound("Play_UI_menuHover", ((Component)RoR2Application.instance).gameObject);
				}
				previousState = state;
			}
		}
	}
	[AddComponentMenu("UI/Searchable Dropdown", 35)]
	[RequireComponent(typeof(RectTransform))]
	public class SearchableDropdown : TMP_InputField, IEventSystemHandler, ICancelHandler
	{
		public class OptionData
		{
			public object Value { get; set; }

			public string Text { get; set; }

			public Sprite Image { get; set; }

			public OptionData()
			{
			}

			public OptionData(object value, string text)
			{
				Value = value;
				Text = text;
			}

			public OptionData(object value, Sprite image)
			{
				Value = value;
				Image = image;
			}

			public OptionData(object value, string text, Sprite image)
			{
				Value = value;
				Text = text;
				Image = image;
			}
		}

		[Serializable]
		public class DropdownEvent : UnityEvent<object>
		{
		}

		internal class FloatTweenRunner
		{
			protected MonoBehaviour m_CoroutineContainer;

			protected IEnumerator m_Tween;

			private static IEnumerator Start(FloatTween tweenInfo)
			{
				if (tweenInfo.ValidTarget())
				{
					float elapsedTime = 0f;
					while ((double)elapsedTime < (double)tweenInfo.duration)
					{
						elapsedTime += (tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime);
						tweenInfo.TweenValue(Mathf.Clamp01(elapsedTime / tweenInfo.duration));
						yield return null;
					}
					tweenInfo.TweenValue(1f);
				}
			}

			public void Init(MonoBehaviour coroutineContainer)
			{
				m_CoroutineContainer = coroutineContainer;
			}

			public void StartTween(FloatTween info)
			{
				if ((Object)(object)m_CoroutineContainer == (Object)null)
				{
					Debug.LogWarning((object)"Coroutine container not configured... did you forget to call Init?");
					return;
				}
				StopTween();
				if (!((Component)m_CoroutineContainer).gameObject.activeInHierarchy)
				{
					info.TweenValue(1f);
					return;
				}
				m_Tween = Start(info);
				m_CoroutineContainer.StartCoroutine(m_Tween);
			}

			public void StopTween()
			{
				if (m_Tween != null)
				{
					m_CoroutineContainer.StopCoroutine(m_Tween);
					m_Tween = null;
				}
			}
		}

		internal struct FloatTween
		{
			public class FloatTweenCallback : UnityEvent<float>
			{
			}

			private FloatTweenCallback m_Target;

			private float m_StartValue;

			private float m_TargetValue;

			private float m_Duration;

			private bool m_IgnoreTimeScale;

			public float startValue
			{
				get
				{
					return m_StartValue;
				}
				set
				{
					m_StartValue = value;
				}
			}

			public float targetValue
			{
				get
				{
					return m_TargetValue;
				}
				set
				{
					m_TargetValue = value;
				}
			}

			public float duration
			{
				get
				{
					return m_Duration;
				}
				set
				{
					m_Duration = value;
				}
			}

			public bool ignoreTimeScale
			{
				get
				{
					return m_IgnoreTimeScale;
				}
				set
				{
					m_IgnoreTimeScale = value;
				}
			}

			public void TweenValue(float floatPercentage)
			{
				if (ValidTarget())
				{
					((UnityEvent<float>)m_Target).Invoke(Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage));
				}
			}

			public void AddOnChangedCallback(UnityAction<float> callback)
			{
				if (m_Target == null)
				{
					m_Target = new FloatTweenCallback();
				}
				((UnityEvent<float>)m_Target).AddListener(callback);
			}

			public bool GetIgnoreTimescale()
			{
				return m_IgnoreTimeScale;
			}

			public float GetDuration()
			{
				return m_Duration;
			}

			public bool ValidTarget()
			{
				return m_Target != null;
			}
		}

		[SerializeField]
		private RectTransform m_Template;

		[Space]
		[SerializeField]
		private TMP_Text m_ItemText;

		[SerializeField]
		private Image m_ItemImage;

		[SerializeField]
		private TMP_Text m_SelectText;

		[Space]
		private GameObject m_Dropdown;

		private GameObject m_Blocker;

		private List<DropdownItem> m_Items = new List<DropdownItem>();

		private FloatTweenRunner m_AlphaTweenRunner;

		private bool validTemplate;

		private Canvas rootCanvas;

		private Vector2 initialContentSizeDelta;

		private Vector2 initialDropdownSizeDelta;

		[SerializeField]
		private DropdownEvent m_OnItemSelected;

		public RectTransform template
		{
			get
			{
				return m_Template;
			}
			set
			{
				m_Template = value;
			}
		}

		public TMP_Text itemText
		{
			get
			{
				return m_ItemText;
			}
			set
			{
				m_ItemText = value;
			}
		}

		public Image itemImage
		{
			get
			{
				return m_ItemImage;
			}
			set
			{
				m_ItemImage = value;
			}
		}

		public List<OptionData> Options { get; set; } = new List<OptionData>();


		public DropdownEvent OnItemSelected
		{
			get
			{
				return m_OnItemSelected;
			}
			set
			{
				m_OnItemSelected = value;
			}
		}

		public bool IsExpanded => (Object)(object)m_Dropdown != (Object)null;

		protected SearchableDropdown()
		{
		}

		protected override void Awake()
		{
			((Selectable)this).Awake();
			m_AlphaTweenRunner = new FloatTweenRunner();
			m_AlphaTweenRunner.Init((MonoBehaviour)(object)this);
			if (Object.op_Implicit((Object)(object)m_Template))
			{
				((UnityEvent<string>)(object)((TMP_InputField)this).onValueChanged).AddListener((UnityAction<string>)ApplyOptionsFilter);
			}
		}

		protected override void OnEnable()
		{
			((TMP_InputField)this).OnEnable();
			((Component)((TMP_InputField)this).textViewport).gameObject.SetActive(false);
			((Component)m_SelectText).gameObject.SetActive(true);
			((Component)m_Template).gameObject.SetActive(false);
		}

		protected override void Start()
		{
			((UIBehaviour)this).Start();
		}

		protected override void OnDisable()
		{
			ImmediateDestroyDropdownList();
			if (!Object.op_Implicit((Object)(object)m_Blocker))
			{
				DestroyBlocker(m_Blocker);
			}
			m_Blocker = null;
		}

		public void AddOptions(List<OptionData> options)
		{
			Options.AddRange(options);
		}

		public void AddOptions(Dictionary<object, string> options)
		{
			foreach (KeyValuePair<object, string> option in options)
			{
				Options.Add(new OptionData(option.Key, option.Value));
			}
		}

		public void AddOptions(Dictionary<object, Sprite> options)
		{
			foreach (KeyValuePair<object, Sprite> option in options)
			{
				Options.Add(new OptionData(option.Key, option.Value));
			}
		}

		public void ClearOptions()
		{
			Options.Clear();
		}

		private void SetupTemplate()
		{
			validTemplate = false;
			if (!Object.op_Implicit((Object)(object)m_Template))
			{
				Debug.LogError((object)"The dropdown template is not assigned. The template needs to be assigned and must have a child GameObject with a Toggle component serving as the item.", (Object)(object)this);
				return;
			}
			GameObject gameObject = ((Component)m_Template).gameObject;
			gameObject.SetActive(true);
			validTemplate = true;
			Button componentInChildren = gameObject.GetComponentInChildren<Button>();
			if (!Object.op_Implicit((Object)(object)componentInChildren) || (Object)(object)((Component)componentInChildren).transform == (Object)(object)template)
			{
				validTemplate = false;
				Debug.LogError((object)"The dropdown template is not valid. The template must have a child GameObject with a Button component serving as the item.", (Object)(object)template);
			}
			else if (!(((Component)componentInChildren).transform.parent is RectTransform))
			{
				validTemplate = false;
				Debug.LogError((object)"The dropdown template is not valid. The child GameObject with a Button component (the item) must have a RectTransform on its parent.", (Object)(object)template);
			}
			else if ((Object)(object)itemText != (Object)null && !itemText.transform.IsChildOf(((Component)componentInChildren).transform))
			{
				validTemplate = false;
				Debug.LogError((object)"The dropdown template is not valid. The Item Text must be on the item GameObject or children of it.", (Object)(object)template);
			}
			else if ((Object)(object)itemImage != (Object)null && !((Component)itemImage).transform.IsChildOf(((Component)componentInChildren).transform))
			{
				validTemplate = false;
				Debug.LogError((object)"The dropdown template is not valid. The Item Image must be on the item GameObject or children of it.", (Object)(object)template);
			}
			if (!validTemplate)
			{
				gameObject.SetActive(false);
				return;
			}
			Canvas orAddComponent = GetOrAddComponent<Canvas>(gameObject);
			orAddComponent.overrideSorting = true;
			orAddComponent.sortingOrder = 30000;
			GetOrAddComponent<GraphicRaycaster>(gameObject);
			GetOrAddComponent<CanvasGroup>(gameObject);
			gameObject.SetActive(false);
			validTemplate = true;
		}

		private static T GetOrAddComponent<T>(GameObject go) where T : Component
		{
			T val = go.GetComponent<T>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = go.AddComponent<T>();
			}
			return val;
		}

		public override void OnPointerClick(PointerEventData eventData)
		{
			Show();
			((Component)((TMP_InputField)this).textViewport).gameObject.SetActive(true);
			((Component)m_SelectText).gameObject.SetActive(false);
			((TMP_InputField)this).OnPointerClick(eventData);
		}

		public virtual void OnCancel(BaseEventData eventData)
		{
			Hide();
		}

		public void Show()
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			if (!((UIBehaviour)this).IsActive() || !((Selectable)this).IsInteractable() || Object.op_Implicit((Object)(object)m_Dropdown))
			{
				return;
			}
			Canvas[] componentsInParent = ((Component)this).gameObject.GetComponentsInParent<Canvas>(false);
			if (componentsInParent.Length == 0)
			{
				return;
			}
			rootCanvas = componentsInParent[^1];
			for (int i = 0; i < componentsInParent.Length; i++)
			{
				if (componentsInParent[i].isRootCanvas)
				{
					rootCanvas = componentsInParent[i];
					break;
				}
			}
			componentsInParent = null;
			if (!validTemplate)
			{
				SetupTemplate();
				if (!validTemplate)
				{
					return;
				}
			}
			((Component)m_Template).gameObject.SetActive(true);
			((Component)m_Template).GetComponent<Canvas>().sortingLayerID = rootCanvas.sortingLayerID;
			m_Dropdown = CreateDropdownList(((Component)m_Template).gameObject);
			((Object)m_Dropdown).name = "Dropdown List";
			m_Dropdown.SetActive(true);
			Transform transform = m_Dropdown.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			((Transform)val).SetParent(((Component)m_Template).transform.parent, false);
			DropdownItem componentInChildren = m_Dropdown.GetComponentInChildren<DropdownItem>();
			Transform transform2 = ((Component)((Transform)componentInChildren.rectTransform).parent).gameObject.transform;
			RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
			initialContentSizeDelta = val2.sizeDelta;
			initialDropdownSizeDelta = val.sizeDelta;
			((Component)componentInChildren.rectTransform).gameObject.SetActive(true);
			m_Items.Clear();
			for (int j = 0; j < Options.Count; j++)
			{
				DropdownItem item = AddItem(Options[j], componentInChildren, m_Items);
				if (Object.op_Implicit((Object)(object)item.button))
				{
					((UnityEvent)item.button.onClick).AddListener((UnityAction)delegate
					{
						OnSelectItem(item.Value);
					});
				}
			}
			RecalculateDropdownBounds();
			AlphaFadeList(0.15f, 0f, 1f);
			((Component)m_Template).gameObject.SetActive(false);
			((Component)componentInChildren).gameObject.SetActive(false);
			m_Blocker = CreateBlocker(rootCanvas);
		}

		private void RecalculateDropdownBounds()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = m_Dropdown.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			DropdownItem componentInChildren = m_Dropdown.GetComponentInChildren<DropdownItem>(true);
			Transform transform2 = ((Component)((Transform)componentInChildren.rectTransform).parent).gameObject.transform;
			RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
			IEnumerable<DropdownItem> source = m_Items.Where((DropdownItem el) => ((Component)el).gameObject.activeSelf);
			val2.sizeDelta = initialContentSizeDelta;
			val.sizeDelta = initialDropdownSizeDelta;
			Rect rect = val2.rect;
			Rect rect2 = componentInChildren.rectTransform.rect;
			Vector2 val3 = ((Rect)(ref rect2)).min - ((Rect)(ref rect)).min + Vector2.op_Implicit(((Transform)componentInChildren.rectTransform).localPosition);
			Vector2 val4 = ((Rect)(ref rect2)).max - ((Rect)(ref rect)).max + Vector2.op_Implicit(((Transform)componentInChildren.rectTransform).localPosition);
			Vector2 size = ((Rect)(ref rect2)).size;
			Vector2 sizeDelta = val2.sizeDelta;
			sizeDelta.y = size.y * (float)source.Count() + val3.y - val4.y;
			val2.sizeDelta = sizeDelta;
			Rect rect3 = val.rect;
			double num = ((Rect)(ref rect3)).height;
			rect3 = val2.rect;
			double num2 = ((Rect)(ref rect3)).height;
			float num3 = (float)(num - num2);
			if ((double)num3 > 0.0)
			{
				val.sizeDelta = new Vector2(val.sizeDelta.x, val.sizeDelta.y - num3);
			}
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			val.GetWorldCorners(array);
			Transform transform3 = ((Component)rootCanvas).transform;
			RectTransform val5 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null);
			Rect rect4 = val5.rect;
			for (int i = 0; i < 2; i++)
			{
				bool flag = false;
				for (int j = 0; j < 4; j++)
				{
					Vector3 val6 = ((Transform)val5).InverseTransformPoint(array[j]);
					double num4 = ((Vector3)(ref val6))[i];
					Vector2 val7 = ((Rect)(ref rect4)).min;
					double num5 = ((Vector2)(ref val7))[i];
					if (num4 < num5)
					{
						double num6 = ((Vector3)(ref val6))[i];
						val7 = ((Rect)(ref rect4)).min;
						double num7 = ((Vector2)(ref val7))[i];
						if (!Mathf.Approximately((float)num6, (float)num7))
						{
							goto IL_0268;
						}
					}
					double num8 = ((Vector3)(ref val6))[i];
					val7 = ((Rect)(ref rect4)).max;
					double num9 = ((Vector2)(ref val7))[i];
					if (!(num8 > num9))
					{
						continue;
					}
					double num10 = ((Vector3)(ref val6))[i];
					val7 = ((Rect)(ref rect4)).max;
					double num11 = ((Vector2)(ref val7))[i];
					if (Mathf.Approximately((float)num10, (float)num11))
					{
						continue;
					}
					goto IL_0268;
					IL_0268:
					flag = true;
					break;
				}
				if (flag)
				{
					RectTransformUtility.FlipLayoutOnAxis(val, i, false, false);
				}
			}
			for (int k = 0; k < source.Count(); k++)
			{
				RectTransform rectTransform = source.ElementAt(k).rectTransform;
				rectTransform.anchorMin = new Vector2(rectTransform.anchorMin.x, 0f);
				rectTransform.anchorMax = new Vector2(rectTransform.anchorMax.x, 0f);
				rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, (float)((double)val3.y + (double)size.y * (double)(source.Count() - 1 - k) + (double)size.y * (double)rectTransform.pivot.y));
				rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, size.y);
			}
		}

		protected virtual GameObject CreateBlocker(Canvas rootCanvas)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00ad: Expected O, but got Unknown
			GameObject val = new GameObject("Blocker");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent(((Component)rootCanvas).transform, false);
			obj.anchorMin = Vector2.op_Implicit(Vector3.zero);
			obj.anchorMax = Vector2.op_Implicit(Vector3.one);
			obj.sizeDelta = Vector2.zero;
			Canvas obj2 = val.AddComponent<Canvas>();
			obj2.overrideSorting = true;
			Canvas component = m_Dropdown.GetComponent<Canvas>();
			obj2.sortingLayerID = component.sortingLayerID;
			obj2.sortingOrder = component.sortingOrder - 1;
			val.AddComponent<GraphicRaycaster>();
			((Graphic)val.AddComponent<Image>()).color = Color.clear;
			((UnityEvent)val.AddComponent<Button>().onClick).AddListener(new UnityAction(Hide));
			return val;
		}

		protected virtual void DestroyBlocker(GameObject blocker)
		{
			Object.Destroy((Object)(object)blocker);
		}

		protected virtual GameObject CreateDropdownList(GameObject template)
		{
			return Object.Instantiate<GameObject>(template);
		}

		protected virtual void DestroyDropdownList(GameObject dropdownList)
		{
			Object.Destroy((Object)(object)dropdownList);
		}

		protected virtual DropdownItem CreateItem(DropdownItem itemTemplate)
		{
			return Object.Instantiate<DropdownItem>(itemTemplate);
		}

		protected virtual void DestroyItem(DropdownItem item)
		{
		}

		private DropdownItem AddItem(OptionData data, DropdownItem itemTemplate, List<DropdownItem> items)
		{
			DropdownItem dropdownItem = CreateItem(itemTemplate);
			((Transform)dropdownItem.rectTransform).SetParent(((Transform)itemTemplate.rectTransform).parent, false);
			((Component)dropdownItem).gameObject.SetActive(true);
			((Object)((Component)dropdownItem).gameObject).name = "Item " + items.Count + ((data.Text != null) ? (": " + data.Text) : "");
			if (Object.op_Implicit((Object)(object)dropdownItem.text))
			{
				dropdownItem.text.text = data.Text;
			}
			if (Object.op_Implicit((Object)(object)dropdownItem.image))
			{
				dropdownItem.image.sprite = data.Image;
				((Behaviour)dropdownItem.image).enabled = Object.op_Implicit((Object)(object)dropdownItem.image.sprite);
			}
			dropdownItem.Value = data.Value;
			items.Add(dropdownItem);
			return dropdownItem;
		}

		private void AlphaFadeList(float duration, float alpha)
		{
			CanvasGroup component = m_Dropdown.GetComponent<CanvasGroup>();
			AlphaFadeList(duration, component.alpha, alpha);
		}

		private void AlphaFadeList(float duration, float start, float end)
		{
			if (!end.Equals(start))
			{
				FloatTween floatTween = default(FloatTween);
				floatTween.duration = duration;
				floatTween.startValue = start;
				floatTween.targetValue = end;
				FloatTween info = floatTween;
				info.AddOnChangedCallback(SetAlpha);
				info.ignoreTimeScale = true;
				m_AlphaTweenRunner.StartTween(info);
			}
		}

		private void SetAlpha(float alpha)
		{
			if (Object.op_Implicit((Object)(object)m_Dropdown))
			{
				m_Dropdown.GetComponent<CanvasGroup>().alpha = alpha;
			}
		}

		public void Hide()
		{
			if (Object.op_Implicit((Object)(object)m_Dropdown))
			{
				AlphaFadeList(0.15f, 0f);
				if (((UIBehaviour)this).IsActive())
				{
					((MonoBehaviour)this).StartCoroutine(DelayedDestroyDropdownList(0.15f));
				}
			}
			if (Object.op_Implicit((Object)(object)m_Blocker))
			{
				DestroyBlocker(m_Blocker);
			}
			m_Blocker = null;
			((Selectable)this).Select();
			((Component)((TMP_InputField)this).textViewport).gameObject.SetActive(false);
			((Component)m_SelectText).gameObject.SetActive(true);
			((TMP_InputField)this).SetTextWithoutNotify(string.Empty);
		}

		private IEnumerator DelayedDestroyDropdownList(float delay)
		{
			yield return (object)new WaitForSecondsRealtime(delay);
			ImmediateDestroyDropdownList();
		}

		private void ImmediateDestroyDropdownList()
		{
			for (int i = 0; i < m_Items.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)m_Items[i]))
				{
					DestroyItem(m_Items[i]);
				}
			}
			m_Items.Clear();
			if (Object.op_Implicit((Object)(object)m_Dropdown))
			{
				DestroyDropdownList(m_Dropdown);
			}
			m_Dropdown = null;
		}

		private void OnSelectItem(object value)
		{
			((UnityEvent<object>)m_OnItemSelected)?.Invoke(value);
			Hide();
		}

		private void ApplyOptionsFilter(string filter)
		{
			foreach (DropdownItem item in m_Items)
			{
				((Component)item).gameObject.SetActive(ContainsInSequence(item.text.text, filter));
			}
			RecalculateDropdownBounds();
		}

		private bool ContainsInSequence(string target, string input)
		{
			string text = target.ToLowerInvariant();
			string text2 = input.ToLowerInvariant();
			if (input.Length == 0 || target.Length == 0)
			{
				return true;
			}
			int num = 0;
			for (int i = 0; i < text.Length; i++)
			{
				if (text[i] == text2[num])
				{
					num++;
				}
				if (num == text2.Length)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace InLobbyConfig.Components.TMP
{
	public class DropdownItem : MonoBehaviour, IEventSystemHandler, ICancelHandler
	{
		public TMP_Text text;

		public Image image;

		public RectTransform rectTransform;

		public Button button;

		[HideInInspector]
		public object Value { get; set; }

		public virtual void OnCancel(BaseEventData eventData)
		{
			SearchableDropdown componentInParent = ((Component)this).GetComponentInParent<SearchableDropdown>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				componentInParent.Hide();
			}
		}
	}
}