Decompiled source of ConfigurationManager v1.0.0

ConfigurationManager.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConfigurationManager.UI;
using ConfigurationManager.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("BepInEx.ConfigurationManager")]
[assembly: AssemblyTitle("BepInEx.ConfigurationManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("https://github.com/BepInEx/BepInEx.ConfigurationManager")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ConfigurationManager
{
	internal sealed class ConfigSettingEntry : SettingEntryBase
	{
		public ConfigEntryBase Entry { get; }

		public override Type SettingType => Entry.SettingType;

		public ConfigSettingEntry(ConfigEntryBase entry, BaseUnityPlugin owner)
		{
			Entry = entry;
			DispName = entry.Definition.Key;
			Category = entry.Definition.Section;
			ConfigDescription description = entry.Description;
			base.Description = ((description != null) ? description.Description : null);
			TypeConverter converter = TomlTypeConverter.GetConverter(entry.SettingType);
			if (converter != null)
			{
				base.ObjToStr = (object o) => converter.ConvertToString(o, entry.SettingType);
				base.StrToObj = (string s) => converter.ConvertToObject(s, entry.SettingType);
			}
			ConfigDescription description2 = entry.Description;
			AcceptableValueBase val = ((description2 != null) ? description2.AcceptableValues : null);
			if (val != null)
			{
				GetAcceptableValues(val);
			}
			base.DefaultValue = entry.DefaultValue;
			ConfigDescription description3 = entry.Description;
			SetFromAttributes((description3 != null) ? description3.Tags : null, owner);
		}

		private void GetAcceptableValues(AcceptableValueBase values)
		{
			Type type = ((object)values).GetType();
			PropertyInfo property = type.GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public);
			if (property != null)
			{
				base.AcceptableValues = ((IEnumerable)property.GetValue(values, null)).Cast<object>().ToArray();
				return;
			}
			PropertyInfo property2 = type.GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public);
			PropertyInfo property3 = type.GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public);
			if (property2 != null && property3 != null)
			{
				base.AcceptableValueRange = new KeyValuePair<object, object>(property2.GetValue(values, null), property3.GetValue(values, null));
				base.ShowRangeAsPercent = ((base.AcceptableValueRange.Key.Equals(0) || base.AcceptableValueRange.Key.Equals(1)) && base.AcceptableValueRange.Value.Equals(100)) || (base.AcceptableValueRange.Key.Equals(0f) && base.AcceptableValueRange.Value.Equals(1f));
			}
		}

		public override object Get()
		{
			return Entry.BoxedValue;
		}

		protected override void SetValue(object newVal)
		{
			Entry.BoxedValue = newVal;
		}
	}
	internal class ManagerSettings
	{
		public ConfigEntry<bool> ShowAdvanced { get; }

		public ConfigEntry<bool> ShowKeybinds { get; }

		public ConfigEntry<bool> ShowSettings { get; }

		public ConfigEntry<KeyboardShortcut> Keybind { get; }

		public ConfigEntry<bool> HideSingleSection { get; }

		public ConfigEntry<bool> PluginConfigCollapsedDefault { get; }

		public ConfigEntry<LocalizationManager.Language> Language { get; }

		public ConfigEntry<Color> BackgroundColor { get; }

		public ConfigEntry<Color> FontColor { get; }

		public ConfigEntry<int> FontSize { get; }

		public ConfigEntry<Color> AdvancedSettingColor { get; }

		public ConfigEntry<int> WindowX { get; }

		public ConfigEntry<int> WindowY { get; }

		public ConfigEntry<int> WindowWidth { get; }

		public ConfigEntry<int> WindowHeight { get; }

		public ConfigEntry<float> ColumnLeftRatio { get; }

		public bool ShowDebug { get; set; }

		public bool IsWindowChanged { get; set; }

		public ManagerSettings(ConfigFile config)
		{
			//IL_006d: 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_0087: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			ShowAdvanced = config.Bind<bool>("Filtering", "Show advanced", false, (ConfigDescription)null);
			ShowKeybinds = config.Bind<bool>("Filtering", "Show keybinds", true, (ConfigDescription)null);
			ShowSettings = config.Bind<bool>("Filtering", "Show settings", true, (ConfigDescription)null);
			Keybind = config.Bind<KeyboardShortcut>("General", "Show config manager", new KeyboardShortcut((KeyCode)282, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), new ConfigDescription("The shortcut used to toggle the config manager window on and off.\nThe key can be overridden by a game-specific plugin if necessary, in that case this setting is ignored.", (AcceptableValueBase)null, Array.Empty<object>()));
			HideSingleSection = config.Bind<bool>("General", "Hide single sections", false, new ConfigDescription("Show section title for plugins with only one section", (AcceptableValueBase)null, Array.Empty<object>()));
			PluginConfigCollapsedDefault = config.Bind<bool>("General", "Plugin collapsed default", true, new ConfigDescription("If set to true plugins will be collapsed when opening the configuration manager window", (AcceptableValueBase)null, Array.Empty<object>()));
			Language = config.Bind<LocalizationManager.Language>("General", "Language", LocalizationManager.Language.English, (ConfigDescription)null);
			Language.SettingChanged += delegate
			{
				LocalizationManager.CurrentLanguage = Language.Value;
			};
			BackgroundColor = config.Bind<Color>("UI", "Background color", new Color(0f, 0f, 0f, 0.75f), (ConfigDescription)null);
			FontColor = config.Bind<Color>("UI", "Font color", new Color(1f, 1f, 1f, 1f), (ConfigDescription)null);
			FontSize = config.Bind<int>("UI", "Font size", 14, new ConfigDescription("", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 40), Array.Empty<object>()));
			AdvancedSettingColor = config.Bind<Color>("UI", "Advanced setting color", new Color(1f, 0.95f, 0.67f, 1f), (ConfigDescription)null);
			BackgroundColor.SettingChanged += OnUISettingsChanged;
			FontSize.SettingChanged += OnUISettingsChanged;
			WindowX = config.Bind<int>("Window", "X Position", -1, (ConfigDescription)null);
			WindowY = config.Bind<int>("Window", "Y Position", -1, (ConfigDescription)null);
			WindowWidth = config.Bind<int>("Window", "Width", 650, (ConfigDescription)null);
			WindowHeight = config.Bind<int>("Window", "Height", -1, (ConfigDescription)null);
			ColumnLeftRatio = config.Bind<float>("Window", "ColumnLeftRatio", 0.4f, new ConfigDescription("The width ratio of the setting name", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			WindowX.SettingChanged += delegate
			{
				OnWindowChanged(this);
			};
			WindowY.SettingChanged += delegate
			{
				OnWindowChanged(this);
			};
			WindowWidth.SettingChanged += delegate
			{
				OnWindowChanged(this);
			};
			WindowHeight.SettingChanged += delegate
			{
				OnWindowChanged(this);
			};
			ColumnLeftRatio.SettingChanged += delegate
			{
				OnWindowChanged(this);
			};
		}

		private static void OnUISettingsChanged(object obj, EventArgs args)
		{
			StyleManager.CleanCache();
		}

		private static void OnWindowChanged(ManagerSettings settings)
		{
			settings.IsWindowChanged = true;
		}
	}
	internal class PluginSettingsDataManager
	{
		private readonly ManagerSettings _settings;

		private string _modsWithoutSettings;

		private List<SettingEntryBase> _allSettings;

		private List<PluginSettingsData> _filteredSettings = new List<PluginSettingsData>();

		private string _searchString = string.Empty;

		public IReadOnlyList<PluginSettingsData> FilteredSettings => _filteredSettings;

		public string ModsWithoutSettings => _modsWithoutSettings;

		public string SearchString
		{
			get
			{
				return _searchString;
			}
			set
			{
				if (value == null)
				{
					value = string.Empty;
				}
				if (!(_searchString == value))
				{
					_searchString = value;
					BuildFilteredSettingList();
				}
			}
		}

		public PluginSettingsDataManager(ManagerSettings settings)
		{
			_settings = settings;
		}

		public void BuildSettingList()
		{
			SettingSearcher.CollectSettings(out var results, out var modsWithoutSettings, _settings.ShowDebug);
			_modsWithoutSettings = string.Join(", ", (from x in modsWithoutSettings
				select x.TrimStart(new char[1] { '!' }) into x
				orderby x
				select x).ToArray());
			_allSettings = results.ToList();
			BuildFilteredSettingListAsync();
		}

		public async Task BuildFilteredSettingListAsync()
		{
			await Task.Run(delegate
			{
				BuildFilteredSettingList();
			});
		}

		public void BuildFilteredSettingList()
		{
			IEnumerable<SettingEntryBase> source = _allSettings;
			string[] searchStrings = SearchString.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (!_settings.ShowAdvanced.Value)
			{
				source = source.Where((SettingEntryBase x) => !x.IsAdvanced);
			}
			if (!_settings.ShowKeybinds.Value)
			{
				source = source.Where((SettingEntryBase x) => !IsKeyboardShortcut(x));
			}
			if (!_settings.ShowSettings.Value)
			{
				source = source.Where((SettingEntryBase x) => x.IsAdvanced || IsKeyboardShortcut(x));
			}
			if (searchStrings.Length != 0)
			{
				source = source.Where((SettingEntryBase x) => ContainsSearchString(x, searchStrings));
			}
			bool settingsAreCollapsed = _settings.PluginConfigCollapsedDefault.Value;
			HashSet<string> nonDefaultCollapsingStateByPluginName = new HashSet<string>();
			foreach (PluginSettingsData filteredSetting in _filteredSettings)
			{
				if (filteredSetting.Collapsed != settingsAreCollapsed)
				{
					nonDefaultCollapsingStateByPluginName.Add(filteredSetting.Info.Name);
				}
			}
			_filteredSettings = (from x in (from x in source
					group x by x.PluginInfo).Select(delegate(IGrouping<BepInPlugin, SettingEntryBase> pluginSettings)
				{
					Dictionary<string, int> categoryOrder = pluginSettings.Select((SettingEntryBase x) => x.Category).Distinct().Select((string category, int index) => new { category, index })
						.ToDictionary(pair => pair.category, pair => pair.index);
					int value;
					IEnumerable<PluginSettingsData.PluginSettingsGroupData> source2 = from x in pluginSettings
						group x by x.Category into x
						orderby (!categoryOrder.TryGetValue(x.Key, out value)) ? int.MaxValue : value, x.Key
						select new PluginSettingsData.PluginSettingsGroupData
						{
							Name = x.Key,
							Settings = (from set in x
								orderby set.Order descending, set.DispName
								select set).ToList()
						};
					return new PluginSettingsData
					{
						Info = pluginSettings.Key,
						Categories = source2.ToList(),
						Collapsed = (nonDefaultCollapsingStateByPluginName.Contains(pluginSettings.Key.Name) ? (!settingsAreCollapsed) : settingsAreCollapsed)
					};
				})
				orderby x.Info.Name
				select x).ToList();
		}

		private static bool IsKeyboardShortcut(SettingEntryBase x)
		{
			if (!(x.SettingType == typeof(KeyboardShortcut)))
			{
				return x.SettingType == typeof(KeyCode);
			}
			return true;
		}

		private static bool ContainsSearchString(SettingEntryBase setting, string[] searchStrings)
		{
			foreach (string s2 in searchStrings)
			{
				if (!Check(setting.PluginInfo.Name, s2) && !Check(setting.PluginInfo.GUID, s2) && !Check(setting.DispName, s2) && !Check(setting.Category, s2) && !Check(setting.Description, s2) && !Check(setting.DefaultValue?.ToString(), s2) && !Check(setting.Get()?.ToString(), s2))
				{
					return false;
				}
			}
			return true;
			static bool Check(string target, string s)
			{
				if (target != null)
				{
					return target.IndexOf(s, StringComparison.InvariantCultureIgnoreCase) >= 0;
				}
				return false;
			}
		}
	}
	internal sealed class PluginSettingsData
	{
		public sealed class PluginSettingsGroupData
		{
			public string Name { get; set; }

			public List<SettingEntryBase> Settings { get; set; }
		}

		private bool _collapsed;

		public BepInPlugin Info { get; set; }

		public List<PluginSettingsGroupData> Categories { get; set; }

		public int Height { get; set; }

		public bool Collapsed
		{
			get
			{
				return _collapsed;
			}
			set
			{
				_collapsed = value;
				Height = 0;
			}
		}
	}
	internal class PropertySettingEntry : SettingEntryBase
	{
		private Type _settingType;

		public object Instance { get; internal set; }

		public PropertyInfo Property { get; internal set; }

		public override string Category
		{
			get
			{
				return base.Category;
			}
			protected internal set
			{
				base.Category = value;
			}
		}

		public override string DispName
		{
			get
			{
				if (!string.IsNullOrEmpty(base.DispName))
				{
					return base.DispName;
				}
				return Property.Name;
			}
			protected internal set
			{
				base.DispName = value;
			}
		}

		public override Type SettingType => _settingType ?? (_settingType = Property.PropertyType);

		public PropertySettingEntry(object instance, PropertyInfo settingProp, BaseUnityPlugin pluginInstance)
		{
			SetFromAttributes(settingProp.GetCustomAttributes(inherit: false), pluginInstance);
			if (!base.Browsable.HasValue)
			{
				base.Browsable = settingProp.CanRead && settingProp.CanWrite;
			}
			base.ReadOnly = settingProp.CanWrite;
			Property = settingProp;
			Instance = instance;
		}

		public override object Get()
		{
			return Property.GetValue(Instance, null);
		}

		protected override void SetValue(object newVal)
		{
			Property.SetValue(Instance, newVal, null);
		}
	}
	internal static class SettingSearcher
	{
		private static readonly ICollection<string> _updateMethodNames = new string[4] { "Update", "FixedUpdate", "LateUpdate", "OnGUI" };

		public static void CollectSettings(out IEnumerable<SettingEntryBase> results, out List<string> modsWithoutSettings, bool showDebug)
		{
			modsWithoutSettings = new List<string>();
			try
			{
				results = GetBepInExCoreConfig();
			}
			catch (Exception ex)
			{
				results = Enumerable.Empty<SettingEntryBase>();
				ConfigurationManager.Logger.LogError((object)ex);
			}
			BaseUnityPlugin[] array = Utils.FindPlugins();
			foreach (BaseUnityPlugin val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					Type type = ((object)val).GetType();
					BepInPlugin metadata = val.Info.Metadata;
					string item = ((metadata != null) ? metadata.Name : null) ?? ((object)val).GetType().FullName;
					if (type.GetCustomAttributes(typeof(BrowsableAttribute), inherit: false).Cast<BrowsableAttribute>().Any((BrowsableAttribute x) => !x.Browsable))
					{
						modsWithoutSettings.Add(item);
						continue;
					}
					List<SettingEntryBase> list = new List<SettingEntryBase>();
					list.AddRange(GetPluginConfig(val).Cast<SettingEntryBase>());
					list.RemoveAll((SettingEntryBase x) => x.Browsable == false);
					if (list.Count == 0)
					{
						modsWithoutSettings.Add(item);
					}
					if (showDebug && type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any((MethodInfo x) => _updateMethodNames.Contains(x.Name)))
					{
						PropertySettingEntry propertySettingEntry = new PropertySettingEntry(val, type.GetProperty("enabled"), val);
						propertySettingEntry.Category = "Advanced Debug Setting";
						propertySettingEntry.DispName = "!Allow plugin to run on every frame";
						propertySettingEntry.Description = "Disabling this will disable some or all of the plugin's functionality.\nHooks and event-based functionality will not be disabled.\nThis setting will be lost after game restart.";
						propertySettingEntry.IsAdvanced = true;
						list.Add(propertySettingEntry);
					}
					if (list.Count > 0)
					{
						results = results.Concat(list);
					}
				}
				catch (Exception ex2)
				{
					object obj;
					if (val == null)
					{
						obj = null;
					}
					else
					{
						PluginInfo info = val.Info;
						if (info == null)
						{
							obj = null;
						}
						else
						{
							BepInPlugin metadata2 = info.Metadata;
							obj = ((metadata2 != null) ? metadata2.Name : null);
						}
					}
					if (obj == null)
					{
						obj = ((object)val)?.GetType().FullName;
					}
					string text = (string)obj;
					ConfigurationManager.Logger.LogError((object)("Failed to collect settings of the following plugin: " + text));
					ConfigurationManager.Logger.LogError((object)ex2);
				}
			}
		}

		private static IEnumerable<SettingEntryBase> GetBepInExCoreConfig()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			PropertyInfo property = typeof(ConfigFile).GetProperty("CoreConfig", BindingFlags.Static | BindingFlags.NonPublic);
			if (property == null)
			{
				throw new ArgumentNullException("coreConfigProp");
			}
			ConfigFile source = (ConfigFile)property.GetValue(null, null);
			BepInPlugin bepinMeta = new BepInPlugin("BepInEx", "BepInEx", typeof(Chainloader).Assembly.GetName().Version.ToString());
			return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)source).Select((Func<KeyValuePair<ConfigDefinition, ConfigEntryBase>, SettingEntryBase>)((KeyValuePair<ConfigDefinition, ConfigEntryBase> kvp) => new ConfigSettingEntry(kvp.Value, null)
			{
				IsAdvanced = true,
				PluginInfo = bepinMeta
			}));
		}

		private static IEnumerable<ConfigSettingEntry> GetPluginConfig(BaseUnityPlugin plugin)
		{
			return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)plugin.Config).Select((KeyValuePair<ConfigDefinition, ConfigEntryBase> kvp) => new ConfigSettingEntry(kvp.Value, plugin));
		}
	}
	[BepInPlugin("com.bepis.bepinex.configurationmanager", "Configuration Manager", "1.0.0")]
	public class ConfigurationManager : BaseUnityPlugin
	{
		internal const string GUID = "com.bepis.bepinex.configurationmanager";

		internal const string Name = "Configuration Manager";

		internal const string Version = "1.0.0";

		internal static ManualLogSource Logger;

		internal static ConfigurationManager Instance;

		private ManagerSettings _settings;

		private ConfigWindow _windowManager;

		private PluginSettingsDataManager _settingsDataManager;

		private CursorManager _cursorManager;

		public bool OverrideHotkey;

		private bool _displayingWindow;

		public bool DisplayingWindow
		{
			get
			{
				return _displayingWindow;
			}
			set
			{
				if (_displayingWindow != value)
				{
					_displayingWindow = value;
					SettingFieldDrawer.ClearCache();
					if (_displayingWindow)
					{
						_windowManager.OnWindowShown();
						_settingsDataManager.BuildSettingList();
						_cursorManager.SaveCursorState();
					}
					else
					{
						_cursorManager.RestoreCursorState();
						_windowManager.SaveWindowPosition();
					}
					this.DisplayingWindowChanged?.Invoke(this, new ValueChangedEventArgs<bool>(value));
				}
			}
		}

		public event EventHandler<ValueChangedEventArgs<bool>> DisplayingWindowChanged;

		public static void RegisterCustomSettingDrawer(Type settingType, Action<SettingEntryBase> onGuiDrawer)
		{
			if (settingType == null)
			{
				throw new ArgumentNullException("settingType");
			}
			if (onGuiDrawer == null)
			{
				throw new ArgumentNullException("onGuiDrawer");
			}
			if (SettingFieldDrawer.SettingDrawHandlers.ContainsKey(settingType))
			{
				Logger.LogWarning((object)("Tried to add a setting drawer for type " + settingType.FullName + " while one already exists."));
			}
			else
			{
				SettingFieldDrawer.SettingDrawHandlers[settingType] = onGuiDrawer;
			}
		}

		public void BuildSettingList()
		{
			_settingsDataManager.BuildSettingList();
		}

		private void Start()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_settings = new ManagerSettings(((BaseUnityPlugin)this).Config);
			_settingsDataManager = new PluginSettingsDataManager(_settings);
			_windowManager = new ConfigWindow(_settings, _settingsDataManager);
			_cursorManager = new CursorManager();
			_cursorManager.Initialize();
			LocalizationManager.CurrentLanguage = _settings.Language.Value;
			try
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			catch (IOException ex)
			{
				Logger.Log((LogLevel)12, (object)("WARNING: Failed to write to config directory, expect issues!\nError message:" + ex.Message));
			}
			catch (UnauthorizedAccessException ex2)
			{
				Logger.Log((LogLevel)12, (object)("WARNING: Permission denied to write to config directory, expect issues!\nError message:" + ex2.Message));
			}
		}

		private void Update()
		{
			//IL_0029: 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)
			if (DisplayingWindow)
			{
				_cursorManager.SetUnlockCursor(0, cursorVisible: true);
			}
			if (!OverrideHotkey)
			{
				KeyboardShortcut value = _settings.Keybind.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					DisplayingWindow = !DisplayingWindow;
				}
			}
		}

		private void LateUpdate()
		{
			if (DisplayingWindow)
			{
				_cursorManager.SetUnlockCursor(0, cursorVisible: true);
			}
		}

		private void OnGUI()
		{
			if (DisplayingWindow)
			{
				_cursorManager.SetUnlockCursor(0, cursorVisible: true);
				_windowManager.DrawWindow();
			}
		}
	}
	public abstract class SettingEntryBase
	{
		private static readonly PropertyInfo[] _myProperties = typeof(SettingEntryBase).GetProperties(BindingFlags.Instance | BindingFlags.Public);

		public object[] AcceptableValues { get; protected set; }

		public KeyValuePair<object, object> AcceptableValueRange { get; protected set; }

		public bool? ShowRangeAsPercent { get; protected set; }

		public Action<ConfigEntryBase> CustomDrawer { get; private set; }

		public bool? Browsable { get; protected set; }

		public virtual string Category { get; protected internal set; }

		public object DefaultValue { get; protected set; }

		public bool HideDefaultButton { get; protected set; }

		public bool HideSettingName { get; protected set; }

		public string Description { get; protected internal set; }

		public virtual string DispName { get; protected internal set; }

		public BepInPlugin PluginInfo { get; protected internal set; }

		public bool? ReadOnly { get; protected set; }

		public abstract Type SettingType { get; }

		public BaseUnityPlugin PluginInstance { get; private set; }

		public bool IsAdvanced { get; internal set; }

		public int Order { get; protected set; }

		public Func<object, string> ObjToStr { get; internal set; }

		public Func<string, object> StrToObj { get; internal set; }

		public abstract object Get();

		public void Set(object newVal)
		{
			if (ReadOnly != true)
			{
				SetValue(newVal);
			}
		}

		protected abstract void SetValue(object newVal);

		internal void SetFromAttributes(object[] attribs, BaseUnityPlugin pluginInstance)
		{
			PluginInstance = pluginInstance;
			PluginInfo = ((pluginInstance != null) ? pluginInstance.Info.Metadata : null);
			if (attribs == null || attribs.Length == 0)
			{
				return;
			}
			foreach (object obj in attribs)
			{
				if (obj == null)
				{
					continue;
				}
				if (!(obj is DisplayNameAttribute displayNameAttribute))
				{
					if (!(obj is CategoryAttribute categoryAttribute))
					{
						if (!(obj is DescriptionAttribute descriptionAttribute))
						{
							if (!(obj is DefaultValueAttribute defaultValueAttribute))
							{
								if (!(obj is ReadOnlyAttribute readOnlyAttribute))
								{
									if (!(obj is BrowsableAttribute browsableAttribute))
									{
										Action<SettingEntryBase> action = obj as Action<SettingEntryBase>;
										if (action == null)
										{
											if (obj is string text)
											{
												switch (text)
												{
												case "ReadOnly":
													ReadOnly = true;
													break;
												case "Browsable":
													Browsable = true;
													break;
												case "Unbrowsable":
												case "Hidden":
													Browsable = false;
													break;
												case "Advanced":
													IsAdvanced = true;
													break;
												}
												continue;
											}
											Type type = obj.GetType();
											if (!(type.Name == "ConfigurationManagerAttributes"))
											{
												break;
											}
											FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
											foreach (var item in from my in _myProperties
												join other in fields on my.Name equals other.Name
												select new { my, other })
											{
												try
												{
													object value = item.other.GetValue(obj);
													if (value != null)
													{
														item.my.SetValue(this, value, null);
													}
												}
												catch (Exception ex)
												{
													ConfigurationManager.Logger.LogWarning((object)("Failed to copy value " + item.my.Name + " from provided tag object " + type.FullName + " - " + ex.Message));
												}
											}
										}
										else
										{
											CustomDrawer = delegate
											{
												action(this);
											};
										}
									}
									else
									{
										Browsable = browsableAttribute.Browsable;
									}
								}
								else
								{
									ReadOnly = readOnlyAttribute.IsReadOnly;
								}
							}
							else
							{
								DefaultValue = defaultValueAttribute.Value;
							}
						}
						else
						{
							Description = descriptionAttribute.Description;
						}
					}
					else
					{
						Category = categoryAttribute.Category;
					}
				}
				else
				{
					DispName = displayNameAttribute.DisplayName;
				}
			}
		}
	}
	internal class SettingFieldDrawer
	{
		private sealed class ColorCacheEntry
		{
			public Color Last;

			public Texture2D Tex;
		}

		private static readonly IEnumerable<KeyCode> _keysToCheck;

		private static readonly Dictionary<SettingEntryBase, ComboBox> _comboBoxCache;

		private static readonly Dictionary<SettingEntryBase, ColorCacheEntry> _colorCache;

		private readonly ConfigWindow _instance;

		private static SettingEntryBase _currentKeyboardShortcutToSet;

		private readonly Dictionary<Type, bool> _canCovertCache = new Dictionary<Type, bool>();

		public static Dictionary<Type, Action<SettingEntryBase>> SettingDrawHandlers { get; }

		public static bool SettingKeyboardShortcut => _currentKeyboardShortcutToSet != null;

		static SettingFieldDrawer()
		{
			_keysToCheck = KeyboardShortcut.AllKeyCodes.Except((IEnumerable<KeyCode>)(object)new KeyCode[2]
			{
				(KeyCode)323,
				default(KeyCode)
			}).ToArray();
			_comboBoxCache = new Dictionary<SettingEntryBase, ComboBox>();
			_colorCache = new Dictionary<SettingEntryBase, ColorCacheEntry>();
			SettingDrawHandlers = new Dictionary<Type, Action<SettingEntryBase>>
			{
				{
					typeof(bool),
					DrawBoolField
				},
				{
					typeof(KeyboardShortcut),
					DrawKeyboardShortcut
				},
				{
					typeof(Color),
					DrawColor
				},
				{
					typeof(Vector2),
					DrawVector2
				},
				{
					typeof(Vector3),
					DrawVector3
				},
				{
					typeof(Vector4),
					DrawVector4
				},
				{
					typeof(Quaternion),
					DrawQuaternion
				}
			};
		}

		public SettingFieldDrawer(ConfigWindow instance)
		{
			_instance = instance;
		}

		public void DrawSettingValue(SettingEntryBase setting)
		{
			//IL_00b7: 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)
			if (setting.CustomDrawer != null)
			{
				setting.CustomDrawer((setting is ConfigSettingEntry configSettingEntry) ? configSettingEntry.Entry : null);
			}
			else if (setting.ShowRangeAsPercent.HasValue && setting.AcceptableValueRange.Key != null)
			{
				DrawRangeField(setting);
			}
			else if (setting.AcceptableValues != null)
			{
				DrawListField(setting);
			}
			else if (setting.SettingType.IsEnum)
			{
				if (setting.SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any())
				{
					DrawFlagsField(setting, Enum.GetValues(setting.SettingType), _instance.RightColumnWidth);
					return;
				}
				Array values = Enum.GetValues(setting.SettingType);
				Rect settingWindowRect = _instance.SettingWindowRect;
				DrawComboboxField(setting, values, ((Rect)(ref settingWindowRect)).yMax);
			}
			else
			{
				DrawFieldBasedOnValueType(setting);
			}
		}

		public static void ClearCache()
		{
			_comboBoxCache.Clear();
			foreach (KeyValuePair<SettingEntryBase, ColorCacheEntry> item in _colorCache)
			{
				Object.Destroy((Object)(object)item.Value.Tex);
			}
			_colorCache.Clear();
		}

		public static void DrawCenteredLabel(string text, params GUILayoutOption[] options)
		{
			GUILayout.BeginHorizontal(options);
			GUILayout.FlexibleSpace();
			GUILayout.Label(text, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		public static void DrawCategoryHeader(string text)
		{
			GUILayout.Label(text, StyleManager.HeaderStyle, Array.Empty<GUILayoutOption>());
		}

		public static bool DrawPluginHeader(GUIContent content, bool isCollapsed)
		{
			if (isCollapsed)
			{
				content.text += "\n...";
			}
			return GUILayout.Button(content, StyleManager.HeaderStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
		}

		public static bool DrawCurrentDropdown()
		{
			if (ComboBox.CurrentDropdownDrawer != null)
			{
				ComboBox.CurrentDropdownDrawer();
				ComboBox.CurrentDropdownDrawer = null;
				return true;
			}
			return false;
		}

		private void DrawListField(SettingEntryBase setting)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			object[] acceptableValues = setting.AcceptableValues;
			if (acceptableValues.Length == 0)
			{
				throw new ArgumentException("AcceptableValueListAttribute returned an empty list of acceptable values. You need to supply at least 1 option.");
			}
			if (!setting.SettingType.IsInstanceOfType(acceptableValues.FirstOrDefault((object x) => x != null)))
			{
				throw new ArgumentException("AcceptableValueListAttribute returned a list with items of type other than the settng type itself.");
			}
			Rect settingWindowRect = _instance.SettingWindowRect;
			DrawComboboxField(setting, acceptableValues, ((Rect)(ref settingWindowRect)).yMax);
		}

		private void DrawFieldBasedOnValueType(SettingEntryBase setting)
		{
			if (SettingDrawHandlers.TryGetValue(setting.SettingType, out var value))
			{
				value(setting);
			}
			else
			{
				DrawUnknownField(setting, _instance.RightColumnWidth);
			}
		}

		private static void DrawBoolField(SettingEntryBase setting)
		{
			bool flag = (bool)setting.Get();
			bool flag2 = GUILayout.Toggle(flag, flag ? "Enabled".Translate() : "Disabled".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (flag2 != flag)
			{
				setting.Set(flag2);
			}
		}

		private static void DrawFlagsField(SettingEntryBase setting, IList enumValues, int maxWidth)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			long num = Convert.ToInt64(setting.Get());
			var array = (from Enum x in enumValues
				select new
				{
					name = x.ToString(),
					val = Convert.ToInt64(x)
				}).ToArray();
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)maxWidth) });
			int i = 0;
			while (i < array.Length)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				int num2 = 0;
				for (; i < array.Length; i++)
				{
					var anon = array[i];
					if (anon.val != 0L)
					{
						int num3 = (int)GUI.skin.toggle.CalcSize(new GUIContent(anon.name)).x;
						num2 += num3;
						if (num2 > maxWidth)
						{
							break;
						}
						GUI.changed = false;
						bool flag = GUILayout.Toggle((num & anon.val) == anon.val, anon.name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
						if (GUI.changed)
						{
							long value = (flag ? (num | anon.val) : (num & ~anon.val));
							setting.Set(Enum.ToObject(setting.SettingType, value));
						}
					}
				}
				GUILayout.EndHorizontal();
			}
			GUI.changed = false;
			GUILayout.EndVertical();
			GUILayout.FlexibleSpace();
		}

		private static void DrawComboboxField(SettingEntryBase setting, IList list, float windowYmax)
		{
			//IL_003f: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			GUIContent val = ObjectToGuiContent(setting.Get());
			Rect rect = GUILayoutUtility.GetRect(val, GUI.skin.button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (!_comboBoxCache.TryGetValue(setting, out var value))
			{
				value = new ComboBox(rect, val, list.Cast<object>().Select(ObjectToGuiContent).ToArray(), GUI.skin.button, windowYmax);
				_comboBoxCache[setting] = value;
			}
			else
			{
				value.Rect = rect;
				value.ButtonContent = val;
			}
			value.Show(delegate(int id)
			{
				if (id >= 0 && id < list.Count)
				{
					setting.Set(list[id]);
				}
			});
		}

		private static GUIContent ObjectToGuiContent(object x)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (x is Enum)
			{
				Type type = x.GetType();
				DescriptionAttribute descriptionAttribute = type.GetMember(x.ToString()).FirstOrDefault()?.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false).Cast<DescriptionAttribute>().FirstOrDefault();
				if (descriptionAttribute == null)
				{
					return new GUIContent(x.ToString().ToProperCase());
				}
				return new GUIContent(descriptionAttribute.Description);
			}
			return new GUIContent(x.ToString());
		}

		private static void DrawRangeField(SettingEntryBase setting)
		{
			object obj = setting.Get();
			float num = (float)Convert.ToDouble(obj, CultureInfo.InvariantCulture);
			float num2 = (float)Convert.ToDouble(setting.AcceptableValueRange.Key, CultureInfo.InvariantCulture);
			float num3 = (float)Convert.ToDouble(setting.AcceptableValueRange.Value, CultureInfo.InvariantCulture);
			float num4 = GUILayout.HorizontalSlider(num, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (Math.Abs(num4 - num) > Mathf.Abs(num3 - num2) / 1000f)
			{
				object newVal = Convert.ChangeType(num4, setting.SettingType, CultureInfo.InvariantCulture);
				setting.Set(newVal);
			}
			if (setting.ShowRangeAsPercent == true)
			{
				DrawCenteredLabel(Mathf.Round(100f * Mathf.Abs(num4 - num2) / Mathf.Abs(num3 - num2)) + "%", GUILayout.Width(50f));
				return;
			}
			string text = Convert.ToString(obj, CultureInfo.InvariantCulture).AppendZeroIfFloat(setting.SettingType);
			string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			if (!(text2 != text))
			{
				return;
			}
			try
			{
				float num5 = (float)Convert.ToDouble(text2, CultureInfo.InvariantCulture);
				float num6 = Mathf.Clamp(num5, num2, num3);
				setting.Set(Convert.ChangeType(num6, setting.SettingType, CultureInfo.InvariantCulture));
			}
			catch (FormatException)
			{
			}
		}

		private void DrawUnknownField(SettingEntryBase setting, int rightColumnWidth)
		{
			if (setting.ObjToStr != null && setting.StrToObj != null)
			{
				string text = setting.ObjToStr(setting.Get()).AppendZeroIfFloat(setting.SettingType);
				string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width((float)rightColumnWidth),
					GUILayout.MaxWidth((float)rightColumnWidth)
				});
				if (text2 != text)
				{
					setting.Set(setting.StrToObj(text2));
				}
			}
			else
			{
				object obj = setting.Get();
				string text3 = ((obj == null) ? "NULL" : Convert.ToString(obj, CultureInfo.InvariantCulture).AppendZeroIfFloat(setting.SettingType));
				if (CanCovert(text3, setting.SettingType))
				{
					string text4 = GUILayout.TextField(text3, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width((float)rightColumnWidth),
						GUILayout.MaxWidth((float)rightColumnWidth)
					});
					if (text4 != text3)
					{
						setting.Set(Convert.ChangeType(text4, setting.SettingType, CultureInfo.InvariantCulture));
					}
				}
				else
				{
					GUILayout.TextArea(text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)rightColumnWidth) });
				}
			}
			GUILayout.FlexibleSpace();
		}

		private bool CanCovert(string value, Type type)
		{
			if (_canCovertCache.ContainsKey(type))
			{
				return _canCovertCache[type];
			}
			try
			{
				object obj = Convert.ChangeType(value, type);
				_canCovertCache[type] = true;
				return true;
			}
			catch
			{
				_canCovertCache[type] = false;
				return false;
			}
		}

		private static void DrawKeyboardShortcut(SettingEntryBase setting)
		{
			//IL_0102: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (_currentKeyboardShortcutToSet == setting)
			{
				GUILayout.Label("Press any key combination".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUIUtility.keyboardControl = -1;
				foreach (KeyCode item in _keysToCheck)
				{
					if (Input.GetKeyUp(item))
					{
						setting.Set((object)new KeyboardShortcut(item, _keysToCheck.Where((Func<KeyCode, bool>)Input.GetKey).ToArray()));
						_currentKeyboardShortcutToSet = null;
						break;
					}
				}
				if (GUILayout.Button("Cancel".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
				{
					_currentKeyboardShortcutToSet = null;
				}
			}
			else
			{
				if (GUILayout.Button(setting.Get().ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
				{
					_currentKeyboardShortcutToSet = setting;
				}
				if (GUILayout.Button("Clear".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
				{
					setting.Set(KeyboardShortcut.Empty);
					_currentKeyboardShortcutToSet = null;
				}
			}
		}

		private static void DrawVector2(SettingEntryBase obj)
		{
			//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0027: 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_003d: 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)
			Vector2 val = (Vector2)obj.Get();
			Vector2 val2 = val;
			val.x = DrawSingleVectorSlider(val.x, "X");
			val.y = DrawSingleVectorSlider(val.y, "Y");
			if (val != val2)
			{
				obj.Set(val);
			}
		}

		private static void DrawVector3(SettingEntryBase obj)
		{
			//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (Vector3)obj.Get();
			Vector3 val2 = val;
			val.x = DrawSingleVectorSlider(val.x, "X");
			val.y = DrawSingleVectorSlider(val.y, "Y");
			val.z = DrawSingleVectorSlider(val.z, "Z");
			if (val != val2)
			{
				obj.Set(val);
			}
		}

		private static void DrawVector4(SettingEntryBase obj)
		{
			//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Vector4 val = (Vector4)obj.Get();
			Vector4 val2 = val;
			val.x = DrawSingleVectorSlider(val.x, "X");
			val.y = DrawSingleVectorSlider(val.y, "Y");
			val.z = DrawSingleVectorSlider(val.z, "Z");
			val.w = DrawSingleVectorSlider(val.w, "W");
			if (val != val2)
			{
				obj.Set(val);
			}
		}

		private static void DrawQuaternion(SettingEntryBase obj)
		{
			//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = (Quaternion)obj.Get();
			Quaternion val2 = val;
			val.x = DrawSingleVectorSlider(val.x, "X");
			val.y = DrawSingleVectorSlider(val.y, "Y");
			val.z = DrawSingleVectorSlider(val.z, "Z");
			val.w = DrawSingleVectorSlider(val.w, "W");
			if (val != val2)
			{
				obj.Set(val);
			}
		}

		private static float DrawSingleVectorSlider(float setting, string label)
		{
			GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			float.TryParse(GUILayout.TextField(setting.ToString("F", CultureInfo.InvariantCulture), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }), NumberStyles.Any, CultureInfo.InvariantCulture, out var result);
			return result;
		}

		private static void DrawColor(SettingEntryBase obj)
		{
			//IL_0006: 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_006c: 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_00f4: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0032: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			Color val = (Color)obj.Get();
			if (!_colorCache.TryGetValue(obj, out var value))
			{
				value = new ColorCacheEntry
				{
					Tex = new Texture2D(40, 10, (TextureFormat)5, false),
					Last = val
				};
				value.Tex.FillTexture(val);
				_colorCache[obj] = value;
			}
			GUILayout.Label("R", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			val.r = GUILayout.HorizontalSlider(val.r, 0f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Label("G", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			val.g = GUILayout.HorizontalSlider(val.g, 0f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Label("B", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			val.b = GUILayout.HorizontalSlider(val.b, 0f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Label("A", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			val.a = GUILayout.HorizontalSlider(val.a, 0f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Space(4f);
			if (val != value.Last)
			{
				obj.Set(val);
				value.Tex.FillTexture(val);
				value.Last = val;
			}
			GUILayout.Label((Texture)(object)value.Tex, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
		}
	}
	public sealed class ValueChangedEventArgs<TValue> : EventArgs
	{
		public TValue NewValue { get; }

		public ValueChangedEventArgs(TValue newValue)
		{
			NewValue = newValue;
		}
	}
}
namespace ConfigurationManager.UI
{
	internal class ConfigWindow
	{
		private const string SearchBoxName = "searchBox";

		private int _tipsHeight;

		private Vector2 _settingWindowScrollPos;

		private const int WindowId = -68;

		private readonly ManagerSettings _settings;

		private readonly PluginSettingsDataManager _dataManager;

		private readonly WindowResizeHandler _resizeHandler;

		private readonly SettingFieldDrawer _fieldDrawer;

		internal Rect SettingWindowRect { get; private set; }

		internal int LeftColumnWidth { get; private set; }

		internal int RightColumnWidth { get; private set; }

		private void DrawWindowHeader()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Show: ".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			bool flag = GUILayout.Toggle(_settings.ShowSettings.Value, "Normal settings".Translate(), Array.Empty<GUILayoutOption>());
			if (_settings.ShowSettings.Value != flag)
			{
				_settings.ShowSettings.Value = flag;
				_dataManager.BuildFilteredSettingListAsync();
			}
			flag = GUILayout.Toggle(_settings.ShowKeybinds.Value, "Keyboard shortcuts".Translate(), Array.Empty<GUILayoutOption>());
			if (_settings.ShowKeybinds.Value != flag)
			{
				_settings.ShowKeybinds.Value = flag;
				_dataManager.BuildFilteredSettingListAsync();
			}
			Color color = GUI.color;
			GUI.color = _settings.AdvancedSettingColor.Value;
			flag = GUILayout.Toggle(_settings.ShowAdvanced.Value, "Advanced settings".Translate(), Array.Empty<GUILayoutOption>());
			if (_settings.ShowAdvanced.Value != flag)
			{
				_settings.ShowAdvanced.Value = flag;
				_dataManager.BuildFilteredSettingListAsync();
			}
			GUI.color = color;
			flag = GUILayout.Toggle(_settings.ShowDebug, "Debug mode".Translate(), Array.Empty<GUILayoutOption>());
			if (_settings.ShowDebug != flag)
			{
				_settings.ShowDebug = flag;
				_dataManager.BuildSettingList();
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search settings: ".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			GUI.SetNextControlName("searchBox");
			_dataManager.SearchString = GUILayout.TextField(_dataManager.SearchString, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (GUILayout.Button("Clear".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				_dataManager.SearchString = string.Empty;
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Language: ".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			if (GUILayout.Button("EN / 中文", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				LocalizationManager.ToggleLanguage();
				_settings.Language.Value = LocalizationManager.CurrentLanguage;
			}
			if (GUILayout.Button("Config Folder".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				try
				{
					Utils.TryOpen(Paths.ConfigPath);
				}
				catch (SystemException ex)
				{
					ConfigurationManager.Logger.Log((LogLevel)10, (object)ex.Message);
				}
			}
			if (_settings.ShowDebug && GUILayout.Button("Open Unity Log".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				try
				{
					Utils.OpenLog();
				}
				catch (SystemException ex2)
				{
					ConfigurationManager.Logger.Log((LogLevel)10, (object)ex2.Message);
				}
			}
			if (_settings.ShowDebug && GUILayout.Button("Open BepInEx Log".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				try
				{
					Utils.OpenBepInExLog();
				}
				catch (SystemException ex3)
				{
					ConfigurationManager.Logger.Log((LogLevel)10, (object)ex3.Message);
				}
			}
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(_settings.PluginConfigCollapsedDefault.Value ? "Expand All".Translate() : "Collapse All".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				bool flag2 = !_settings.PluginConfigCollapsedDefault.Value;
				_settings.PluginConfigCollapsedDefault.Value = flag2;
				foreach (PluginSettingsData filteredSetting in _dataManager.FilteredSettings)
				{
					filteredSetting.Collapsed = flag2;
				}
			}
			GUILayout.EndHorizontal();
		}

		private void DrawScrollItems()
		{
			//IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Invalid comparison between Unknown and I4
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			_settingWindowScrollPos = GUILayout.BeginScrollView(_settingWindowScrollPos, false, true, Array.Empty<GUILayoutOption>());
			float y = _settingWindowScrollPos.y;
			Rect val = SettingWindowRect;
			float height = ((Rect)(ref val)).height;
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			if (string.IsNullOrEmpty(_dataManager.SearchString))
			{
				DrawTips();
				if (_tipsHeight == 0 && (int)Event.current.type == 7)
				{
					val = GUILayoutUtility.GetLastRect();
					_tipsHeight = (int)((Rect)(ref val)).height;
				}
			}
			int num = _tipsHeight;
			foreach (PluginSettingsData filteredSetting in _dataManager.FilteredSettings)
			{
				if (filteredSetting.Height == 0 || ((float)(num + filteredSetting.Height) >= y && (float)num <= y + height))
				{
					try
					{
						DrawSinglePlugin(filteredSetting, _dataManager.SearchString);
					}
					catch (ArgumentException)
					{
					}
					if (filteredSetting.Height == 0 && (int)Event.current.type == 7)
					{
						val = GUILayoutUtility.GetLastRect();
						filteredSetting.Height = (int)((Rect)(ref val)).height;
					}
				}
				else
				{
					try
					{
						GUILayout.Space((float)filteredSetting.Height);
					}
					catch (ArgumentException)
					{
					}
				}
				num += filteredSetting.Height;
			}
			if (_settings.ShowDebug)
			{
				GUILayout.Space(10f);
				GUILayout.Label("Plugins with no options available: ".Translate() + _dataManager.ModsWithoutSettings, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Space(70f);
			}
			GUILayout.EndVertical();
			GUILayout.EndScrollView();
		}

		private void DrawTips()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Tip: Click plugin names to expand. Click setting names to see their descriptions.".Translate(), Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		private void DrawSinglePlugin(PluginSettingsData plugin, string searchString)
		{
			//IL_009d: 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_00a3: Expected O, but got Unknown
			//IL_00b7: 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_00bd: 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_0108: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUIContent content = (_settings.ShowDebug ? new GUIContent($"{plugin.Info.Name.TrimStart(new char[1] { '!' })} {plugin.Info.Version}", "GUID: " + plugin.Info.GUID) : new GUIContent($"{plugin.Info.Name.TrimStart(new char[1] { '!' })} {plugin.Info.Version}"));
			bool flag = !string.IsNullOrEmpty(searchString);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Color color = GUI.color;
			GUI.color = Color.gray;
			if (GUILayout.Button(new GUIContent("Reload".Translate() + "      ", "Trigger Config.Reload() event to apply settings from the config file".Translate()), GUI.skin.label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				Utils.TryReloadConfig(plugin.Info.GUID);
			}
			GUI.color = color;
			if (SettingFieldDrawer.DrawPluginHeader(content, plugin.Collapsed && !flag) && !flag)
			{
				plugin.Collapsed = !plugin.Collapsed;
			}
			GUI.color = Color.gray;
			if (GUILayout.Button(new GUIContent("Open File".Translate(), "Open the plugin config file".Translate()), GUI.skin.label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				Utils.TryOpen(Path.Combine(Paths.ConfigPath, plugin.Info.GUID + ".cfg"));
			}
			GUI.color = color;
			GUILayout.EndHorizontal();
			if (flag || !plugin.Collapsed)
			{
				foreach (PluginSettingsData.PluginSettingsGroupData category in plugin.Categories)
				{
					GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
					if (!string.IsNullOrEmpty(category.Name) && (plugin.Categories.Count > 1 || !_settings.HideSingleSection.Value))
					{
						SettingFieldDrawer.DrawCategoryHeader(category.Name);
					}
					foreach (SettingEntryBase setting in category.Settings)
					{
						DrawSingleSetting(setting);
						GUILayout.Space(2f);
					}
					GUILayout.EndVertical();
				}
			}
			GUILayout.EndVertical();
		}

		private void DrawSingleSetting(SettingEntryBase setting)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			try
			{
				DrawSettingName(setting);
				_fieldDrawer.DrawSettingValue(setting);
				DrawDefaultButton(setting);
			}
			catch (Exception arg)
			{
				ConfigurationManager.Logger.Log((LogLevel)2, (object)$"Failed to draw setting {setting.DispName} - {arg}");
				GUILayout.Label("Failed to draw this field, check log for details.".Translate(), Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndHorizontal();
		}

		private void DrawSettingName(SettingEntryBase setting)
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!setting.HideSettingName)
			{
				Color color = GUI.color;
				if (setting.IsAdvanced)
				{
					GUI.color = _settings.AdvancedSettingColor.Value;
				}
				GUILayout.Label(new GUIContent(setting.DispName.TrimStart(new char[1] { '!' }), setting.Description), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width((float)(LeftColumnWidth - 20)),
					GUILayout.MaxWidth((float)LeftColumnWidth)
				});
				GUI.color = color;
			}
		}

		private static void DrawDefaultButton(SettingEntryBase setting)
		{
			if (setting.HideDefaultButton)
			{
				return;
			}
			if (setting.DefaultValue != null)
			{
				if (DefaultButton())
				{
					setting.Set(setting.DefaultValue);
				}
			}
			else if (setting.SettingType.IsClass && DefaultButton())
			{
				setting.Set(null);
			}
			static bool DefaultButton()
			{
				GUILayout.Space(5f);
				return GUILayout.Button("Reset".Translate(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			}
		}

		public ConfigWindow(ManagerSettings settings, PluginSettingsDataManager dataManager)
		{
			_settings = settings;
			_dataManager = dataManager;
			_resizeHandler = new WindowResizeHandler();
			_fieldDrawer = new SettingFieldDrawer(this);
		}

		public void OnWindowShown()
		{
			CalculateWindowRect();
		}

		public void SaveWindowPosition()
		{
			//IL_000c: 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_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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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)
			ConfigEntry<int> windowX = _settings.WindowX;
			Rect settingWindowRect = SettingWindowRect;
			windowX.Value = (int)((Rect)(ref settingWindowRect)).x;
			ConfigEntry<int> windowY = _settings.WindowY;
			settingWindowRect = SettingWindowRect;
			windowY.Value = (int)((Rect)(ref settingWindowRect)).y;
			ConfigEntry<int> windowWidth = _settings.WindowWidth;
			settingWindowRect = SettingWindowRect;
			windowWidth.Value = (int)((Rect)(ref settingWindowRect)).width;
			ConfigEntry<int> windowHeight = _settings.WindowHeight;
			settingWindowRect = SettingWindowRect;
			windowHeight.Value = (int)((Rect)(ref settingWindowRect)).height;
		}

		public void DrawWindow()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00da: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (_settings.IsWindowChanged)
			{
				CalculateWindowRect();
				_settings.IsWindowChanged = false;
			}
			StyleManager.CreateStyles(_settings);
			GUISkin skin = GUI.skin;
			GUI.skin = StyleManager.CustomSkin;
			GUI.Box(SettingWindowRect, GUIContent.none, StyleManager.WindowStyle);
			SettingWindowRect = _resizeHandler.HandleWindowResize(SettingWindowRect, out var columnWidthsChanged);
			Rect settingWindowRect;
			if (columnWidthsChanged)
			{
				settingWindowRect = SettingWindowRect;
				LeftColumnWidth = Mathf.RoundToInt(((Rect)(ref settingWindowRect)).width * _settings.ColumnLeftRatio.Value);
				settingWindowRect = SettingWindowRect;
				RightColumnWidth = (int)((Rect)(ref settingWindowRect)).width - LeftColumnWidth - 115;
			}
			SettingWindowRect = GUILayout.Window(-68, SettingWindowRect, new WindowFunction(DrawSettingsWindow), "Plugin / mod settings".Translate(), Array.Empty<GUILayoutOption>());
			settingWindowRect = SettingWindowRect;
			bool flag = ((Rect)(ref settingWindowRect)).Contains(Event.current.mousePosition);
			bool flag2 = Input.GetMouseButton(0) && Input.GetMouseButtonDown(0);
			if (!SettingFieldDrawer.SettingKeyboardShortcut && flag && flag2)
			{
				Input.ResetInputAxes();
			}
			GUI.skin = skin;
		}

		private void CalculateWindowRect()
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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)
			int num = ((_settings.WindowWidth.Value > 0) ? _settings.WindowWidth.Value : Mathf.Min(Screen.width, 650));
			int num2 = ((_settings.WindowHeight.Value > 0) ? _settings.WindowHeight.Value : ((Screen.height < 560) ? Screen.height : (Screen.height - 100)));
			int num3 = ((_settings.WindowX.Value >= 0) ? _settings.WindowX.Value : Mathf.RoundToInt((float)(Screen.width - num) / 2f));
			int num4 = ((_settings.WindowY.Value >= 0) ? _settings.WindowY.Value : Mathf.RoundToInt((float)(Screen.height - num2) / 2f));
			SettingWindowRect = new Rect((float)num3, (float)num4, (float)num, (float)num2);
			Rect settingWindowRect = SettingWindowRect;
			LeftColumnWidth = Mathf.RoundToInt(((Rect)(ref settingWindowRect)).width * _settings.ColumnLeftRatio.Value);
			settingWindowRect = SettingWindowRect;
			RightColumnWidth = (int)((Rect)(ref settingWindowRect)).width - LeftColumnWidth - 115;
		}

		private void DrawSettingsWindow(int id)
		{
			//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_0023: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Rect settingWindowRect = SettingWindowRect;
			GUILayout.BeginArea(new Rect(((Rect)(ref settingWindowRect)).width - 27f, 1f, 25f, 21f));
			if (GUILayout.Button("X", Array.Empty<GUILayoutOption>()))
			{
				ConfigurationManager.Instance.DisplayingWindow = false;
			}
			GUILayout.EndArea();
			settingWindowRect = SettingWindowRect;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref settingWindowRect)).width, 20f);
			GUI.DragWindow(val);
			Color color = GUI.color;
			GUI.color = _settings.FontColor.Value;
			GUILayout.Space(3f);
			DrawWindowHeader();
			DrawScrollItems();
			GUI.color = color;
			if (!SettingFieldDrawer.DrawCurrentDropdown())
			{
				DrawTooltip(SettingWindowRect);
			}
		}

		private static void DrawTooltip(Rect area)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(GUI.tooltip))
			{
				Event current = Event.current;
				GUIStyle tooltipStyle = StyleManager.TooltipStyle;
				float num = tooltipStyle.CalcHeight(new GUIContent(GUI.tooltip), 400f) + 10f;
				float num2 = ((current.mousePosition.x + 400f > ((Rect)(ref area)).width) ? (((Rect)(ref area)).width - 400f) : current.mousePosition.x);
				float num3 = ((current.mousePosition.y + 25f + num > ((Rect)(ref area)).height) ? (current.mousePosition.y - num) : (current.mousePosition.y + 25f));
				GUI.Box(new Rect(num2, num3, 400f, num), GUI.tooltip, tooltipStyle);
			}
		}
	}
	internal static class StyleManager
	{
		public static GUISkin CustomSkin { get; private set; }

		public static GUIStyle WindowStyle { get; private set; }

		public static GUIStyle HeaderStyle { get; private set; }

		public static GUIStyle TooltipStyle { get; private set; }

		public static GUIStyle ResizeHandleStyle { get; private set; }

		public static GUIStyle DropdownBackgroundStyle { get; private set; }

		public static void CreateStyles(ManagerSettings settings)
		{
			if (!((Object)(object)CustomSkin != (Object)null))
			{
				Reinitialize(settings);
			}
		}

		public static void CleanCache()
		{
			Object.Destroy((Object)(object)CustomSkin);
			CustomSkin = null;
		}

		private static void Reinitialize(ManagerSettings settings)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001f: 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_0039: Expected O, but got Unknown
			//IL_003c: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0068: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00bc: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_010e: Expected O, but got Unknown
			int value = settings.FontSize.Value;
			Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false);
			val.SetPixel(0, 0, settings.BackgroundColor.Value);
			val.Apply();
			Texture2D val2 = new Texture2D(1, 1, (TextureFormat)5, false);
			val2.SetPixel(0, 0, Color.black);
			val2.Apply();
			WindowStyle = new GUIStyle
			{
				normal = new GUIStyleState
				{
					background = val
				}
			};
			HeaderStyle = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)1,
				wordWrap = true,
				stretchWidth = true,
				fontSize = value + 2
			};
			TooltipStyle = new GUIStyle
			{
				normal = new GUIStyleState
				{
					textColor = Color.white,
					background = val2
				},
				wordWrap = true,
				alignment = (TextAnchor)4
			};
			ResizeHandleStyle = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 30
			};
			DropdownBackgroundStyle = new GUIStyle
			{
				normal = new GUIStyleState
				{
					background = val
				}
			};
			CustomSkin = Object.Instantiate<GUISkin>(GUI.skin);
			CustomSkin.toggle.wordWrap = true;
			UpdateCustomSkinFontSize(value);
		}

		private static void UpdateCustomSkinFontSize(int fontSize)
		{
			CustomSkin.label.fontSize = fontSize;
			CustomSkin.button.fontSize = fontSize;
			CustomSkin.textField.fontSize = fontSize;
			CustomSkin.toggle.fontSize = fontSize;
			CustomSkin.box.fontSize = fontSize;
			CustomSkin.window.fontSize = fontSize;
		}
	}
	internal class WindowResizeHandler
	{
		private const int ResizeHandleSize = 30;

		private const int MinWindowWidth = 200;

		private const int MinWindowHeight = 100;

		private bool _isResizing;

		private Vector2 _resizeStart;

		public Rect HandleWindowResize(Rect windowRect, out bool columnWidthsChanged)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			//IL_007b: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_0138: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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)
			columnWidthsChanged = false;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref windowRect)).x + ((Rect)(ref windowRect)).width - 15f, ((Rect)(ref windowRect)).y + ((Rect)(ref windowRect)).height - 15f, 30f, 30f);
			Event current = Event.current;
			bool flag = ((Rect)(ref val)).Contains(current.mousePosition);
			if (flag)
			{
				GUI.Box(val, "↘", StyleManager.ResizeHandleStyle);
			}
			if ((int)current.type == 0 && flag)
			{
				_isResizing = true;
				_resizeStart = current.mousePosition;
				current.Use();
			}
			else if ((int)current.type == 1 && _isResizing)
			{
				_isResizing = false;
				current.Use();
			}
			else if ((int)current.type == 3 && _isResizing)
			{
				Vector2 val2 = current.mousePosition - _resizeStart;
				float num = Mathf.Max(200f, ((Rect)(ref windowRect)).width + val2.x);
				float num2 = Mathf.Max(100f, ((Rect)(ref windowRect)).height + val2.y);
				((Rect)(ref windowRect))..ctor(((Rect)(ref windowRect)).x, ((Rect)(ref windowRect)).y, num, num2);
				columnWidthsChanged = true;
				_resizeStart = current.mousePosition;
				current.Use();
			}
			return windowRect;
		}
	}
}
namespace ConfigurationManager.Utilities
{
	public static class LocalizationManager
	{
		public enum Language
		{
			English,
			Chinese
		}

		private static Language _currentLanguage = Language.English;

		private static readonly Dictionary<string, string> _chineseTranslations = new Dictionary<string, string>
		{
			["Plugin / mod settings"] = "插件/模组设置",
			["Show: "] = "显示: ",
			["Normal settings"] = "常规设置",
			["Keyboard shortcuts"] = "键位设置",
			["Advanced settings"] = "进阶设置",
			["Debug mode"] = "调试模式",
			["Search settings: "] = "搜索设置: ",
			["Clear"] = "清除",
			["Config Folder"] = "配置文件夹",
			["Open Unity Log"] = "打开Unity日志",
			["Open BepInEx Log"] = "打开BepInEx日志",
			["Expand All"] = "全部展开",
			["Collapse All"] = "全部收起",
			["Tip: Click plugin names to expand. Click setting names to see their descriptions."] = "提示:点击插件名称可展开,点击设置名称可查看说明。",
			["Reload"] = "重新加载",
			["Trigger Config.Reload() event to apply settings from the config file"] = "触发 Config.Reload() 事件以应用配置文件中的设置",
			["Open File"] = "打开文件",
			["Open the plugin config file"] = "打开插件配置文件",
			["Reset"] = "重置",
			["Enabled"] = "已启用",
			["Disabled"] = "已禁用",
			["Press any key combination"] = "按下任意按键组合",
			["Cancel"] = "取消",
			["Plugins with no options available: "] = "无配置选项的mod: ",
			["Failed to draw this field, check log for details."] = "无法绘制此字段,详情请查看日志。",
			["Language: "] = "语言: "
		};

		public static Language CurrentLanguage
		{
			get
			{
				return _currentLanguage;
			}
			set
			{
				if (value != _currentLanguage)
				{
					_currentLanguage = value;
					LocalizationManager.OnLanguageChanged?.Invoke(value);
				}
			}
		}

		public static event Action<Language> OnLanguageChanged;

		public static void AddTranslation(string englishText, string chineseText)
		{
			_chineseTranslations[englishText] = chineseText;
		}

		public static string GetTranslation(string text)
		{
			if (_currentLanguage == Language.English)
			{
				return text;
			}
			if (!_chineseTranslations.TryGetValue(text, out var value))
			{
				return text;
			}
			return value;
		}

		public static void ToggleLanguage()
		{
			CurrentLanguage = ((_currentLanguage == Language.English) ? Language.Chinese : Language.English);
		}
	}
	public static class LocalizationExtensions
	{
		public static string Translate(this string text)
		{
			return LocalizationManager.GetTranslation(text);
		}
	}
	internal class ComboBox
	{
		private static bool forceToUnShow;

		private static int useControlID = -1;

		private readonly string buttonStyle;

		private bool isClickedComboButton;

		private readonly GUIContent[] listContent;

		private readonly GUIStyle listStyle;

		private readonly int _windowYmax;

		private Vector2 _scrollPosition = Vector2.zero;

		public Rect Rect { get; set; }

		public GUIContent ButtonContent { get; set; }

		public static Action CurrentDropdownDrawer { get; set; }

		public ComboBox(Rect rect, GUIContent buttonContent, GUIContent[] listContent, GUIStyle listStyle, float windowYmax)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			Rect = rect;
			ButtonContent = buttonContent;
			this.listContent = listContent;
			buttonStyle = "button";
			this.listStyle = listStyle;
			_windowYmax = (int)windowYmax;
		}

		public void Show(Action<int> onItemSelected)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_005b: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: 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)
			if (forceToUnShow)
			{
				forceToUnShow = false;
				isClickedComboButton = false;
			}
			bool flag = false;
			int controlID = GUIUtility.GetControlID((FocusType)2);
			Vector2 val = Vector2.zero;
			if ((int)Event.current.GetTypeForControl(controlID) == 1 && isClickedComboButton)
			{
				flag = true;
				val = Event.current.mousePosition;
			}
			if (GUI.Button(Rect, ButtonContent, GUIStyle.op_Implicit(buttonStyle)))
			{
				if (useControlID == -1)
				{
					useControlID = controlID;
					isClickedComboButton = false;
				}
				if (useControlID != controlID)
				{
					forceToUnShow = true;
					useControlID = controlID;
				}
				isClickedComboButton = true;
			}
			if (isClickedComboButton)
			{
				GUI.enabled = false;
				GUI.color = new Color(1f, 1f, 1f, 2f);
				Rect rect = Rect;
				float x = ((Rect)(ref rect)).x;
				rect = Rect;
				Vector2 location = GUIUtility.GUIToScreenPoint(new Vector2(x, ((Rect)(ref rect)).y + listStyle.CalcHeight(listContent[0], 1f)));
				rect = Rect;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(((Rect)(ref rect)).width, listStyle.CalcHeight(listContent[0], 1f) * (float)listContent.Length);
				Rect innerRect = new Rect(0f, 0f, val2.x, val2.y);
				Rect outerRectScreen = new Rect(location.x, location.y, val2.x, val2.y);
				if (((Rect)(ref outerRectScreen)).yMax > (float)_windowYmax)
				{
					((Rect)(ref outerRectScreen)).height = (float)_windowYmax - ((Rect)(ref outerRectScreen)).y;
					ref Rect reference = ref outerRectScreen;
					((Rect)(ref reference)).width = ((Rect)(ref reference)).width + 20f;
				}
				if (val != Vector2.zero && ((Rect)(ref outerRectScreen)).Contains(GUIUtility.GUIToScreenPoint(val)))
				{
					flag = false;
				}
				CurrentDropdownDrawer = delegate
				{
					//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)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0051: 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_005e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0070: Unknown result type (might be due to invalid IL or missing references)
					GUI.enabled = true;
					Vector2 val3 = GUIUtility.ScreenToGUIPoint(location);
					Rect val4 = default(Rect);
					((Rect)(ref val4))..ctor(val3.x, val3.y, ((Rect)(ref outerRectScreen)).width, ((Rect)(ref outerRectScreen)).height);
					GUI.Box(val4, GUIContent.none, StyleManager.DropdownBackgroundStyle);
					_scrollPosition = GUI.BeginScrollView(val4, _scrollPosition, innerRect, false, false);
					int num = GUI.SelectionGrid(innerRect, -1, listContent, 1, listStyle);
					if (num != -1)
					{
						onItemSelected(num);
						isClickedComboButton = false;
					}
					GUI.EndScrollView(true);
				};
			}
			if (flag)
			{
				isClickedComboButton = false;
			}
		}
	}
	internal class CursorManager
	{
		private PropertyInfo _curLockState;

		private PropertyInfo _curVisible;

		private int _previousCursorLockState;

		private bool _previousCursorVisible;

		private bool _obsoleteCursor;

		public void Initialize()
		{
			Type typeFromHandle = typeof(Cursor);
			_curLockState = typeFromHandle.GetProperty("lockState", BindingFlags.Static | BindingFlags.Public);
			_curVisible = typeFromHandle.GetProperty("visible", BindingFlags.Static | BindingFlags.Public);
			if (_curLockState == null && _curVisible == null)
			{
				_obsoleteCursor = true;
				_curLockState = typeof(Screen).GetProperty("lockCursor", BindingFlags.Static | BindingFlags.Public);
				_curVisible = typeof(Screen).GetProperty("showCursor", BindingFlags.Static | BindingFlags.Public);
			}
		}

		public void SaveCursorState()
		{
			if (_curLockState != null)
			{
				_previousCursorLockState = (_obsoleteCursor ? Convert.ToInt32((bool)_curLockState.GetValue(null, null)) : ((int)_curLockState.GetValue(null, null)));
				_previousCursorVisible = (bool)_curVisible.GetValue(null, null);
			}
		}

		public void RestoreCursorState()
		{
			if (!_previousCursorVisible || _previousCursorLockState != 0)
			{
				SetUnlockCursor(_previousCursorLockState, _previousCursorVisible);
			}
		}

		public void SetUnlockCursor(int lockState, bool cursorVisible)
		{
			if (_curLockState != null)
			{
				if (_obsoleteCursor)
				{
					_curLockState.SetValue(null, Convert.ToBoolean(lockState), null);
				}
				else
				{
					_curLockState.SetValue(null, lockState, null);
				}
				_curVisible.SetValue(null, cursorVisible, null);
			}
		}
	}
	internal static class Utils
	{
		public static string ToProperCase(this string str)
		{
			if (string.IsNullOrEmpty(str))
			{
				return string.Empty;
			}
			if (str.Length < 2)
			{
				return str;
			}
			string text = str.Substring(0, 1).ToUpper();
			for (int i = 1; i < str.Length; i++)
			{
				if (char.IsUpper(str[i]))
				{
					text += " ";
				}
				text += str[i];
			}
			return text;
		}

		public static BaseUnityPlugin[] FindPlugins()
		{
			return Chainloader.PluginInfos.Values.Select((PluginInfo x) => x.Instance).Union(Object.FindObjectsOfType(typeof(BaseUnityPlugin)).Cast<BaseUnityPlugin>()).ToArray();
		}

		public static string AppendZero(this string s)
		{
			if (s.Contains("."))
			{
				return s;
			}
			return s + ".0";
		}

		public static string AppendZeroIfFloat(this string s, Type type)
		{
			if (!(type == typeof(float)) && !(type == typeof(double)) && !(type == typeof(decimal)))
			{
				return s;
			}
			return s.AppendZero();
		}

		public static void FillTexture(this Texture2D tex, Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < ((Texture)tex).width; i++)
			{
				for (int j = 0; j < ((Texture)tex).height; j++)
				{
					tex.SetPixel(i, j, color);
				}
			}
			tex.Apply(false);
		}

		public static bool TryReloadConfig(string guid)
		{
			if (!Chainloader.PluginInfos.TryGetValue(guid, out var value))
			{
				return false;
			}
			BaseUnityPlugin instance = value.Instance;
			if (instance != null)
			{
				instance.Config.Reload();
			}
			ConfigurationManager.Logger.LogDebug((object)("Reload " + (object)value.Instance));
			return (Object)(object)value.Instance != (Object)null;
		}

		public static bool TryOpen(string path)
		{
			if (string.IsNullOrEmpty(path))
			{
				return false;
			}
			try
			{
				Application.OpenURL(path);
				return true;
			}
			catch (Exception ex)
			{
				ConfigurationManager.Logger.LogWarning((object)("Exception when trying to load " + path));
				ConfigurationManager.Logger.LogWarning((object)ex);
				return false;
			}
		}

		public static void OpenBepInExLog()
		{
			string path = Path.Combine(Paths.BepInExRootPath, "LogOutput.log");
			TryOpen(path);
		}

		public static void OpenLog()
		{
			List<string> list = new List<string>();
			string text = Path.Combine(Application.dataPath, "..");
			list.Add(Path.Combine(text, "output_log.txt"));
			list.Add(Path.Combine(Application.dataPath, "output_log.txt"));
			PropertyInfo property = typeof(Application).GetProperty("consoleLogPath", BindingFlags.Static | BindingFlags.Public);
			if (property != null)
			{
				string item = property.GetValue(null, null) as string;
				list.Add(item);
			}
			if (Directory.Exists(Application.persistentDataPath))
			{
				string item2 = Directory.GetFiles(Application.persistentDataPath, "output_log.txt", SearchOption.AllDirectories).FirstOrDefault();
				list.Add(item2);
			}
			string path = list.Where(File.Exists).OrderByDescending(File.GetLastWriteTimeUtc).FirstOrDefault();
			if (!TryOpen(path))
			{
				list.Clear();
				list.AddRange(Directory.GetFiles(text, "LogOutput.log*", SearchOption.AllDirectories));
				list.AddRange(Directory.GetFiles(text, "output_log.txt", SearchOption.AllDirectories));
				path = list.Where(File.Exists).OrderByDescending(File.GetLastWriteTimeUtc).FirstOrDefault();
				if (!TryOpen(path))
				{
					throw new FileNotFoundException("No log files were found");
				}
			}
		}
	}
}