Decompiled source of Supermans Configs v1.1.0

SupermansConfigs.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModMenu
{
	internal class ConfigMenu : MonoBehaviour
	{
		private class ModInfo
		{
			public string Guid;

			public string Title;

			public string Version;

			public ConfigFile Config;

			public List<KeyValuePair<string, List<ConfigEntryBase>>> Sections;
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
		private static class MouseCapturePatch
		{
			private static void Postfix()
			{
				if (IsOpen)
				{
					ZCursor.LockState = (CursorLockMode)0;
					ZCursor.Show();
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TakeInput")]
		private static class PlayerTakeInputPatch
		{
			private static void Postfix(ref bool __result)
			{
				if (IsOpen)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch]
		private static class ControllerTakeInputPatch
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null);
			}

			private static bool Prepare()
			{
				return (TargetMethod() as MethodInfo)?.ReturnType == typeof(bool);
			}

			private static void Postfix(ref bool __result)
			{
				if (IsOpen)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Menu), "Update")]
		private static class MenuPatch
		{
			private static bool Prefix()
			{
				return !BlockGameMenu;
			}
		}

		private const int WindowId = 1397574990;

		private static readonly KeyCode[] Modifiers;

		private static ConfigEntryBase _capturing;

		private static bool _refreshRequested;

		private static int _suppressFrame;

		private static KeyCode[] _bindableKeys;

		private List<ModInfo> _mods = new List<ModInfo>();

		private int _selected;

		private int _pendingSelect = -1;

		private bool _showUpdates;

		private string _searchInput = "";

		private string _search = "";

		private Vector2 _listScroll;

		private Vector2 _entryScroll;

		private Rect _rect = new Rect(0f, 0f, 860f, 640f);

		private bool _centered;

		private string _tooltip = "";

		private float _confirmResetUntil;

		private readonly Dictionary<ConfigEntryBase, string> _textBuffers = new Dictionary<ConfigEntryBase, string>();

		private GUIStyle _window;

		private GUIStyle _header;

		private GUIStyle _modHeader;

		private GUIStyle _label;

		private GUIStyle _wrap;

		private GUIStyle _tip;

		private GUIStyle _toast;

		private GUIStyle _modButton;

		private GUIStyle _modButtonSelected;

		internal static bool IsOpen { get; private set; }

		internal static bool IsCapturingKey
		{
			get
			{
				if (_capturing == null)
				{
					return Time.frameCount <= _suppressFrame;
				}
				return true;
			}
		}

		internal static bool BlockGameMenu
		{
			get
			{
				if (!IsOpen)
				{
					return Time.frameCount <= _suppressFrame;
				}
				return true;
			}
		}

		internal static void Toggle()
		{
			if (IsOpen)
			{
				Close();
				return;
			}
			IsOpen = true;
			_refreshRequested = true;
			UpdateChecker.RequestScan();
		}

		private static void Close()
		{
			IsOpen = false;
			_capturing = null;
			_suppressFrame = Time.frameCount;
		}

		private void Update()
		{
			if (IsOpen && ZInput.instance != null)
			{
				if (_capturing != null)
				{
					UpdateKeyCapture();
				}
				else if (ZInput.GetKeyDown((KeyCode)27, false))
				{
					Close();
					SaveUnsaved();
				}
			}
		}

		private void OnGUI()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: 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_01aa: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				DrawToast();
				return;
			}
			if ((int)Event.current.type == 8)
			{
				if (_mods.Count == 0 || _pendingSelect == -2 || _refreshRequested)
				{
					RefreshMods();
				}
				_refreshRequested = false;
				if (_pendingSelect >= 0)
				{
					_selected = _pendingSelect;
					_showUpdates = false;
					_entryScroll = Vector2.zero;
				}
				if (_pendingSelect == -3)
				{
					_showUpdates = true;
					_entryScroll = Vector2.zero;
				}
				_pendingSelect = -1;
				_search = _searchInput.Trim();
			}
			BuildStyles();
			float value = Plugin.UiScale.Value;
			GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(value, value, 1f));
			float num = (float)Screen.width / value;
			float num2 = (float)Screen.height / value;
			((Rect)(ref _rect)).width = Mathf.Min(860f, num - 20f);
			((Rect)(ref _rect)).height = Mathf.Min(640f, num2 - 20f);
			if (!_centered)
			{
				((Rect)(ref _rect)).x = (num - ((Rect)(ref _rect)).width) / 2f;
				((Rect)(ref _rect)).y = (num2 - ((Rect)(ref _rect)).height) / 2f;
				_centered = true;
			}
			_rect = GUILayout.Window(1397574990, _rect, new WindowFunction(DrawWindow), $"Supermans Configs  ({Plugin.MenuKey.Value} to close)", _window, Array.Empty<GUILayoutOption>());
			((Rect)(ref _rect)).x = Mathf.Clamp(((Rect)(ref _rect)).x, 0f, num - ((Rect)(ref _rect)).width);
			((Rect)(ref _rect)).y = Mathf.Clamp(((Rect)(ref _rect)).y, 0f, num2 - ((Rect)(ref _rect)).height);
		}

		private void DrawWindow(int id)
		{
			//IL_00cb: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Invalid comparison between Unknown and I4
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
			GUILayout.Label("Search all mods", _label, Array.Empty<GUILayoutOption>());
			_searchInput = GUILayout.TextField(_searchInput, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			int count = UpdateChecker.Findings.Count;
			if (GUILayout.Button((count > 0) ? $"<b><color=#7ad1ff>Updates ({count})</color></b>" : "Updates <size=11><color=#a89a86>(up to date)</color></size>", (_showUpdates && _search.Length == 0) ? _modButtonSelected : _modButton, Array.Empty<GUILayoutOption>()))
			{
				_pendingSelect = -3;
				_searchInput = "";
			}
			GUILayout.Space(4f);
			_listScroll = GUILayout.BeginScrollView(_listScroll, Array.Empty<GUILayoutOption>());
			for (int i = 0; i < _mods.Count; i++)
			{
				GUIStyle val = ((i == _selected && !_showUpdates && _search.Length == 0) ? _modButtonSelected : _modButton);
				UpdateChecker.Finding finding = UpdateChecker.For(_mods[i].Guid);
				string text = ((finding == null) ? "" : (finding.NeedsRestart ? "  <color=#7ad1ff>restart</color>" : "  <color=#7ad1ff>update</color>"));
				if (GUILayout.Button(_mods[i].Title + "\n<size=11><color=#a89a86>v" + _mods[i].Version + "</color>" + text + "</size>", val, Array.Empty<GUILayoutOption>()))
				{
					_pendingSelect = i;
					_searchInput = "";
				}
			}
			if (_mods.Count == 0)
			{
				GUILayout.Label("No Supermans mods found.", _label, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			if (GUILayout.Button("Refresh list", Array.Empty<GUILayoutOption>()))
			{
				_pendingSelect = -2;
			}
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			_entryScroll = GUILayout.BeginScrollView(_entryScroll, Array.Empty<GUILayoutOption>());
			if (_search.Length > 0)
			{
				DrawSearchResults();
			}
			else if (_showUpdates)
			{
				DrawUpdates();
			}
			else if (_selected < _mods.Count)
			{
				DrawMod(_mods[_selected]);
			}
			GUILayout.EndScrollView();
			GUILayout.Label(_tooltip, _tip, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(44f) });
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (_search.Length == 0 && !_showUpdates && _selected < _mods.Count)
			{
				ModInfo modInfo = _mods[_selected];
				bool flag = Time.realtimeSinceStartup < _confirmResetUntil;
				if (GUILayout.Button(flag ? ("Click again to reset " + modInfo.Title) : "Reset this mod to defaults", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(280f) }))
				{
					if (flag)
					{
						foreach (KeyValuePair<string, List<ConfigEntryBase>> section in modInfo.Sections)
						{
							foreach (ConfigEntryBase item in section.Value)
							{
								item.BoxedValue = item.DefaultValue;
							}
						}
						_textBuffers.Clear();
						_confirmResetUntil = 0f;
					}
					else
					{
						_confirmResetUntil = Time.realtimeSinceStartup + 3f;
					}
				}
				GUILayout.Label("<size=11><color=#a89a86>Saved to BepInEx/config/" + modInfo.Guid + ".cfg</color></size>", _label, Array.Empty<GUILayoutOption>());
			}
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
			{
				Close();
				SaveUnsaved();
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.EndHorizontal();
			if ((int)Event.current.type == 7)
			{
				_tooltip = GUI.tooltip;
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void DrawMod(ModInfo mod)
		{
			GUILayout.Label(mod.Title, _modHeader, Array.Empty<GUILayoutOption>());
			foreach (KeyValuePair<string, List<ConfigEntryBase>> section in mod.Sections)
			{
				GUILayout.Label(PrettySection(section.Key), _header, Array.Empty<GUILayoutOption>());
				foreach (ConfigEntryBase item in section.Value)
				{
					DrawEntry(item);
				}
				GUILayout.Space(6f);
			}
		}

		private void DrawUpdates()
		{
			GUILayout.Label("Updates", _modHeader, Array.Empty<GUILayoutOption>());
			if (UpdateChecker.Findings.Count == 0)
			{
				GUILayout.Label("All your Supermans mods are up to date.", _label, Array.Empty<GUILayoutOption>());
			}
			foreach (UpdateChecker.Finding finding in UpdateChecker.Findings)
			{
				GUILayout.Label(finding.Title, _header, Array.Empty<GUILayoutOption>());
				GUILayout.Label(finding.Message, _wrap, Array.Empty<GUILayoutOption>());
				GUILayout.Space(4f);
			}
			GUILayout.Space(10f);
			GUILayout.Label("<size=11><color=#a89a86>Checks your Gale profile and " + (string.IsNullOrWhiteSpace(Plugin.ModsFolder.Value) ? "no mods folder" : Plugin.ModsFolder.Value) + $" every {Plugin.CheckMinutes.Value:0} min. New Supermans mods are added to this menu automatically once Valheim loads them.</color></size>", _wrap, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Check now", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
			{
				UpdateChecker.RequestScan();
			}
		}

		private void DrawToast()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0040: 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)
			if (!string.IsNullOrEmpty(UpdateChecker.ToastText) && !(Time.realtimeSinceStartup > UpdateChecker.ToastUntil))
			{
				BuildStyles();
				float value = Plugin.UiScale.Value;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(value, value, 1f));
				float num = 520f;
				GUI.Box(new Rect(((float)Screen.width / value - num) / 2f, 40f, num, 34f), UpdateChecker.ToastText, _toast);
			}
		}

		private void DrawSearchResults()
		{
			bool flag = false;
			foreach (ModInfo mod in _mods)
			{
				List<ConfigEntryBase> list = mod.Sections.SelectMany((KeyValuePair<string, List<ConfigEntryBase>> s) => s.Value).Where(Matches).ToList();
				if (list.Count == 0)
				{
					continue;
				}
				flag = true;
				GUILayout.Label(mod.Title, _modHeader, Array.Empty<GUILayoutOption>());
				foreach (ConfigEntryBase item in list)
				{
					DrawEntry(item);
				}
				GUILayout.Space(6f);
			}
			if (!flag)
			{
				GUILayout.Label("Nothing matches \"" + _search + "\".", _label, Array.Empty<GUILayoutOption>());
			}
		}

		private bool Matches(ConfigEntryBase entry)
		{
			if (!Contains(entry.Definition.Key) && !Contains(PrettyKey(entry.Definition.Key)) && !Contains(entry.Definition.Section))
			{
				ConfigDescription description = entry.Description;
				return Contains((description != null) ? description.Description : null);
			}
			return true;
		}

		private bool Contains(string text)
		{
			if (text != null)
			{
				return text.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private void DrawEntry(ConfigEntryBase entry)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			Type settingType = entry.SettingType;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			string text = PrettyKey(entry.Definition.Key);
			ConfigDescription description = entry.Description;
			GUILayout.Label(new GUIContent(text, ((description != null) ? description.Description : null) ?? ""), _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
			Array acceptableList = GetAcceptableList(entry);
			if (settingType == typeof(bool))
			{
				DrawBool(entry);
			}
			else if (settingType == typeof(KeyCode) || settingType == typeof(KeyboardShortcut))
			{
				DrawKey(entry);
			}
			else if (acceptableList != null)
			{
				DrawCycle(entry, acceptableList);
			}
			else if (settingType.IsEnum && !settingType.IsDefined(typeof(FlagsAttribute), inherit: false))
			{
				DrawCycle(entry, Enum.GetValues(settingType));
			}
			else if (IsNumeric(settingType))
			{
				DrawNumber(entry);
			}
			else if (settingType == typeof(string))
			{
				DrawString(entry);
			}
			else
			{
				DrawGeneric(entry);
			}
			bool enabled = GUI.enabled;
			GUI.enabled = !object.Equals(entry.BoxedValue, entry.DefaultValue);
			if (GUILayout.Button(new GUIContent("Reset", "Default: " + entry.DefaultValue), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
			{
				entry.BoxedValue = entry.DefaultValue;
				_textBuffers.Remove(entry);
			}
			GUI.enabled = enabled;
			GUILayout.EndHorizontal();
		}

		private static void DrawBool(ConfigEntryBase entry)
		{
			bool flag = (bool)entry.BoxedValue;
			bool flag2 = GUILayout.Toggle(flag, flag ? " On" : " Off", Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (flag2 != flag)
			{
				entry.BoxedValue = flag2;
			}
		}

		private static void DrawCycle(ConfigEntryBase entry, Array values)
		{
			int num = Array.IndexOf(values, entry.BoxedValue);
			if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }) && values.Length > 0)
			{
				entry.BoxedValue = values.GetValue((num <= 0) ? (values.Length - 1) : (num - 1));
			}
			GUILayout.Box(entry.BoxedValue?.ToString() ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }) && values.Length > 0)
			{
				entry.BoxedValue = values.GetValue((num + 1) % values.Length);
			}
		}

		private void DrawKey(ConfigEntryBase entry)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (GUILayout.Button((_capturing == entry) ? "<color=#ffd27a>Press a key...  (Esc cancels)</color>" : entry.BoxedValue.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				_capturing = entry;
				GUIUtility.keyboardControl = 0;
			}
			if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
			{
				entry.BoxedValue = ((entry.SettingType == typeof(KeyCode)) ? ((object)(KeyCode)0) : ((object)KeyboardShortcut.Empty));
				_capturing = null;
			}
		}

		private void DrawNumber(ConfigEntryBase entry)
		{
			Type settingType = entry.SettingType;
			bool flag = settingType != typeof(float) && settingType != typeof(double) && settingType != typeof(decimal);
			double num = Convert.ToDouble(entry.BoxedValue, CultureInfo.InvariantCulture);
			if (TryGetRange(entry, out var min, out var max))
			{
				float num2 = GUILayout.HorizontalSlider((float)num, (float)min, (float)max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				if (!Mathf.Approximately(num2, (float)num))
				{
					double value = (flag ? Math.Round(num2) : Math.Round(num2, Decimals(max - min)));
					SetNumber(entry, value);
					_textBuffers.Remove(entry);
				}
			}
			else
			{
				GUILayout.FlexibleSpace();
			}
			string text = "num" + ((object)entry).GetHashCode();
			if (GUI.GetNameOfFocusedControl() != text || !_textBuffers.ContainsKey(entry))
			{
				_textBuffers[entry] = FormatNumber(entry.BoxedValue);
			}
			GUI.SetNextControlName(text);
			string text2 = GUILayout.TextField(_textBuffers[entry], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			if (text2 != _textBuffers[entry])
			{
				_textBuffers[entry] = text2;
				if (double.TryParse(text2.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					SetNumber(entry, result);
				}
			}
		}

		private static void DrawString(ConfigEntryBase entry)
		{
			string text = ((string)entry.BoxedValue) ?? "";
			string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (text2 != text)
			{
				entry.BoxedValue = text2;
			}
		}

		private void DrawGeneric(ConfigEntryBase entry)
		{
			string text = "gen" + ((object)entry).GetHashCode();
			if (GUI.GetNameOfFocusedControl() != text || !_textBuffers.ContainsKey(entry))
			{
				_textBuffers[entry] = entry.GetSerializedValue();
			}
			GUI.SetNextControlName(text);
			string text2 = GUILayout.TextField(_textBuffers[entry], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (text2 == _textBuffers[entry])
			{
				return;
			}
			_textBuffers[entry] = text2;
			try
			{
				if (TomlTypeConverter.CanConvert(entry.SettingType))
				{
					entry.BoxedValue = TomlTypeConverter.ConvertToValue(text2, entry.SettingType);
				}
			}
			catch
			{
			}
		}

		private static void UpdateKeyCapture()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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)
			if (_bindableKeys == null)
			{
				_bindableKeys = (from KeyCode k in Enum.GetValues(typeof(KeyCode))
					where (int)k != 0 && (int)k != 323 && (int)k != 324 && (int)k < 330
					select k).Distinct().ToArray();
			}
			if (ZInput.GetKeyDown((KeyCode)27, false))
			{
				_capturing = null;
				_suppressFrame = Time.frameCount;
				return;
			}
			bool flag = _capturing.SettingType == typeof(KeyboardShortcut);
			KeyCode[] bindableKeys = _bindableKeys;
			foreach (KeyCode val in bindableKeys)
			{
				if (!ZInput.GetKeyDown(val, false) || (flag && Modifiers.Contains(val)))
				{
					continue;
				}
				if (flag)
				{
					KeyCode[] array = Modifiers.Where((KeyCode m) => ZInput.GetKey(m, false)).ToArray();
					_capturing.BoxedValue = (object)new KeyboardShortcut(val, array);
				}
				else
				{
					_capturing.BoxedValue = val;
				}
				_capturing = null;
				_suppressFrame = Time.frameCount;
				break;
			}
		}

		private void RefreshMods()
		{
			string selectedGuid = ((_selected < _mods.Count) ? _mods[_selected].Guid : null);
			_mods = new List<ModInfo>();
			_textBuffers.Clear();
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				if ((Object)(object)((value != null) ? value.Instance : null) == (Object)null || !Plugin.IsSupermanMod(value))
				{
					continue;
				}
				string gUID = value.Metadata.GUID;
				string input = value.Metadata.Name ?? gUID;
				List<KeyValuePair<string, List<ConfigEntryBase>>> list = new List<KeyValuePair<string, List<ConfigEntryBase>>>();
				foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> pair in value.Instance.Config)
				{
					if (IsBrowsable(pair.Value))
					{
						List<ConfigEntryBase> list2 = list.FirstOrDefault((KeyValuePair<string, List<ConfigEntryBase>> s) => s.Key == pair.Key.Section).Value;
						if (list2 == null)
						{
							list2 = new List<ConfigEntryBase>();
							list.Add(new KeyValuePair<string, List<ConfigEntryBase>>(pair.Key.Section, list2));
						}
						list2.Add(pair.Value);
					}
				}
				if (list.Count != 0)
				{
					list.Sort((KeyValuePair<string, List<ConfigEntryBase>> a, KeyValuePair<string, List<ConfigEntryBase>> b) => string.CompareOrdinal(a.Key, b.Key));
					_mods.Add(new ModInfo
					{
						Guid = gUID,
						Title = Regex.Replace(input, "^Supermans?\\s*", "", RegexOptions.IgnoreCase),
						Version = value.Metadata.Version.ToString(),
						Config = value.Instance.Config,
						Sections = list
					});
				}
			}
			_mods = _mods.OrderBy((ModInfo m) => m.Guid == "supermans.configs").ThenBy<ModInfo, string>((ModInfo m) => m.Title, StringComparer.OrdinalIgnoreCase).ToList();
			_selected = Math.Max(0, _mods.FindIndex((ModInfo m) => m.Guid == selectedGuid));
		}

		private static bool IsBrowsable(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			object[] array = ((description != null) ? description.Tags : null);
			if (array == null)
			{
				return true;
			}
			object[] array2 = array;
			foreach (object obj in array2)
			{
				if (obj != null && !(obj.GetType().Name != "ConfigurationManagerAttributes"))
				{
					object obj2 = obj.GetType().GetField("Browsable")?.GetValue(obj);
					if (obj2 is bool && !(bool)obj2)
					{
						return false;
					}
				}
			}
			return true;
		}

		private void SaveUnsaved()
		{
			foreach (ModInfo mod in _mods)
			{
				if (!mod.Config.SaveOnConfigSet)
				{
					mod.Config.Save();
				}
			}
		}

		private static bool IsNumeric(Type t)
		{
			if (!(t == typeof(int)) && !(t == typeof(float)) && !(t == typeof(double)) && !(t == typeof(long)) && !(t == typeof(short)) && !(t == typeof(byte)) && !(t == typeof(uint)) && !(t == typeof(ulong)) && !(t == typeof(ushort)) && !(t == typeof(sbyte)))
			{
				return t == typeof(decimal);
			}
			return true;
		}

		private static void SetNumber(ConfigEntryBase entry, double value)
		{
			try
			{
				entry.BoxedValue = Convert.ChangeType(value, entry.SettingType, CultureInfo.InvariantCulture);
			}
			catch (OverflowException)
			{
			}
		}

		private static string FormatNumber(object value)
		{
			if (value is float num)
			{
				return num.ToString("0.###", CultureInfo.InvariantCulture);
			}
			if (value is double num2)
			{
				return num2.ToString("0.###", CultureInfo.InvariantCulture);
			}
			return Convert.ToString(value, CultureInfo.InvariantCulture);
		}

		private static int Decimals(double span)
		{
			double num = span / 200.0;
			if (num <= 0.0)
			{
				return 2;
			}
			return Mathf.Clamp(Mathf.CeilToInt(0f - (float)Math.Log10(num)), 0, 4);
		}

		private static bool TryGetRange(ConfigEntryBase entry, out double min, out double max)
		{
			min = (max = 0.0);
			ConfigDescription description = entry.Description;
			object obj = ((description != null) ? description.AcceptableValues : null);
			if (obj == null || !obj.GetType().IsGenericType || obj.GetType().GetGenericTypeDefinition() != typeof(AcceptableValueRange<>))
			{
				return false;
			}
			min = Convert.ToDouble(obj.GetType().GetProperty("MinValue").GetValue(obj, null), CultureInfo.InvariantCulture);
			max = Convert.ToDouble(obj.GetType().GetProperty("MaxValue").GetValue(obj, null), CultureInfo.InvariantCulture);
			return max > min;
		}

		private static Array GetAcceptableList(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			object obj = ((description != null) ? description.AcceptableValues : null);
			if (obj == null || !obj.GetType().IsGenericType || obj.GetType().GetGenericTypeDefinition() != typeof(AcceptableValueList<>))
			{
				return null;
			}
			return obj.GetType().GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj, null) as Array;
		}

		private static string PrettySection(string section)
		{
			return Regex.Replace(section, "^\\s*\\d+\\s*-\\s*", "");
		}

		private static string PrettyKey(string key)
		{
			return Regex.Replace(key, "(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])", " ");
		}

		private void BuildStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0040: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_00e3: 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_00f4: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_0277: Expected O, but got Unknown
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Expected O, but got Unknown
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			if (_window == null)
			{
				_window = new GUIStyle(GUI.skin.window)
				{
					richText = true,
					fontSize = 15,
					padding = new RectOffset(12, 12, 28, 10)
				};
				Texture2D background = SolidTexture(new Color(0.11f, 0.09f, 0.07f, 0.97f));
				_window.normal.background = background;
				_window.onNormal.background = background;
				GUIStyleState normal = _window.normal;
				GUIStyleState onNormal = _window.onNormal;
				Color textColor = default(Color);
				((Color)(ref textColor))..ctor(1f, 0.82f, 0.48f);
				onNormal.textColor = textColor;
				normal.textColor = textColor;
				_label = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					wordWrap = false
				};
				_wrap = new GUIStyle(_label)
				{
					wordWrap = true
				};
				_toast = new GUIStyle(GUI.skin.box)
				{
					richText = true,
					alignment = (TextAnchor)4,
					fontSize = 14
				};
				_toast.normal.background = SolidTexture(new Color(0.11f, 0.09f, 0.07f, 0.92f));
				_toast.normal.textColor = new Color(1f, 0.82f, 0.48f);
				_header = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					fontStyle = (FontStyle)1,
					fontSize = 14
				};
				_header.normal.textColor = new Color(1f, 0.82f, 0.48f);
				_modHeader = new GUIStyle(_header)
				{
					fontSize = 18
				};
				_modHeader.normal.textColor = Color.white;
				_tip = new GUIStyle(GUI.skin.box)
				{
					wordWrap = true,
					richText = true,
					alignment = (TextAnchor)0,
					fontSize = 12
				};
				_tip.normal.textColor = new Color(0.85f, 0.8f, 0.72f);
				_modButton = new GUIStyle(GUI.skin.button)
				{
					richText = true,
					alignment = (TextAnchor)3,
					padding = new RectOffset(10, 6, 6, 6)
				};
				_modButtonSelected = new GUIStyle(_modButton);
				Texture2D background2 = SolidTexture(new Color(0.55f, 0.38f, 0.12f, 1f));
				_modButtonSelected.normal.background = background2;
				_modButtonSelected.hover.background = background2;
				textColor = (_modButtonSelected.normal.textColor = (_modButtonSelected.hover.textColor = Color.white));
			}
		}

		private static Texture2D SolidTexture(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		static ConfigMenu()
		{
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Modifiers = (KeyCode[])(object)array;
			_suppressFrame = -1;
		}
	}
	[BepInPlugin("supermans.configs", "Supermans Configs", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "supermans.configs";

		public const string Name = "Supermans Configs";

		public const string Version = "1.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> MenuKey;

		internal static ConfigEntry<float> UiScale;

		internal static ConfigEntry<string> ExtraMods;

		internal static ConfigEntry<bool> UpdateNotifications;

		internal static ConfigEntry<float> CheckMinutes;

		internal static ConfigEntry<string> ModsFolder;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("1 - General", "MenuKey", (KeyCode)283, "Opens/closes the Supermans Configs menu.");
			UiScale = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "UiScale", 1f, new ConfigDescription("Size of the settings menu.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.75f, 2f), Array.Empty<object>()));
			ExtraMods = ((BaseUnityPlugin)this).Config.Bind<string>("1 - General", "ExtraMods", "chestlink.valheim", "Comma-separated plugin GUIDs to list in the menu besides mods whose name or GUID contains \"superman\".");
			UpdateNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Updates", "Notifications", true, "Show a notice on screen when a Supermans mod is added or updated.");
			CheckMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Updates", "CheckMinutes", 5f, new ConfigDescription("How often (minutes) to look for added or updated Supermans mods.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()));
			ModsFolder = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Updates", "ModsFolder", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "My Designed Mods for Valheim"), "Folder holding your packaged Supermans_*-<version>.zip files. A newer zip here than what is installed shows as an update. Leave empty to skip.");
			((Component)this).gameObject.AddComponent<ConfigMenu>();
			_harmony = new Harmony("supermans.configs");
			_harmony.PatchAll();
			Log.LogInfo((object)"Supermans Configs 1.1.0 loaded");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			UpdateChecker.Tick();
			if (ZInput.instance != null && !ConfigMenu.IsCapturingKey && ZInput.GetKeyDown(MenuKey.Value, false) && !IsTyping())
			{
				ConfigMenu.Toggle();
			}
		}

		internal static bool IsSupermanMod(PluginInfo info)
		{
			string guid = info.Metadata.GUID;
			string text = info.Metadata.Name ?? guid;
			if (guid.IndexOf("superman", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("superman", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return (ExtraMods.Value ?? "").Split(new char[1] { ',' }).Any((string s) => string.Equals(s.Trim(), guid, StringComparison.OrdinalIgnoreCase));
			}
			return true;
		}

		private static bool IsTyping()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible())
			{
				return TextInput.IsVisible();
			}
			return true;
		}
	}
	internal static class UpdateChecker
	{
		internal class Finding
		{
			public string Package;

			public string Title;

			public string PluginGuid;

			public string Message;

			public bool NeedsRestart;
		}

		private class Package
		{
			public string Name;

			public Version Version;

			public string Dir;

			public PluginInfo Loaded;
		}

		private static readonly HashSet<string> Notified = new HashSet<string>();

		private static float _nextScan = 5f;

		internal static List<Finding> Findings { get; private set; } = new List<Finding>();

		internal static string ToastText { get; private set; }

		internal static float ToastUntil { get; private set; }

		internal static void RequestScan()
		{
			_nextScan = 0f;
		}

		internal static void Tick()
		{
			if (Time.realtimeSinceStartup < _nextScan)
			{
				return;
			}
			_nextScan = Time.realtimeSinceStartup + Mathf.Max(1f, Plugin.CheckMinutes.Value) * 60f;
			try
			{
				Scan();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Update check failed: " + ex.Message));
			}
		}

		internal static Finding For(string pluginGuid)
		{
			return Findings.FirstOrDefault((Finding f) => f.PluginGuid == pluginGuid);
		}

		private static void Scan()
		{
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Package> dictionary = ScanInstalled();
			Dictionary<string, Version> dictionary2 = ScanModsFolder();
			List<Finding> list = new List<Finding>();
			foreach (Package value2 in dictionary.Values)
			{
				if (value2.Loaded == null)
				{
					list.Add(new Finding
					{
						Package = value2.Name,
						Title = Pretty(value2.Name),
						NeedsRestart = true,
						Message = $"v{value2.Version} was added to your Gale profile. Restart Valheim to load it."
					});
				}
				else if (value2.Version != null && value2.Version > value2.Loaded.Metadata.Version)
				{
					list.Add(new Finding
					{
						Package = value2.Name,
						Title = Pretty(value2.Name),
						PluginGuid = value2.Loaded.Metadata.GUID,
						NeedsRestart = true,
						Message = $"Updated to v{value2.Version} (running v{value2.Loaded.Metadata.Version}). Restart Valheim to apply."
					});
				}
			}
			foreach (KeyValuePair<string, Version> item in dictionary2)
			{
				dictionary.TryGetValue(Normalize(item.Key), out var value);
				if (value == null || !(value.Version != null) || !(value.Version >= item.Value))
				{
					Finding obj = new Finding
					{
						Package = item.Key,
						Title = Pretty(item.Key)
					};
					object pluginGuid;
					if (value == null)
					{
						pluginGuid = null;
					}
					else
					{
						PluginInfo loaded = value.Loaded;
						pluginGuid = ((loaded != null) ? loaded.Metadata.GUID : null);
					}
					obj.PluginGuid = (string)pluginGuid;
					obj.Message = ((value == null) ? $"New mod v{item.Value} is in your mods folder. Import it in Gale (Import > local mod)." : $"v{item.Value} is in your mods folder (installed v{value.Version}). Import it in Gale (Import > local mod).");
					list.Add(obj);
				}
			}
			Findings = list.OrderBy<Finding, string>((Finding f) => f.Title, StringComparer.OrdinalIgnoreCase).ToList();
			int num = Findings.Count((Finding f) => Notified.Add(f.Package + "|" + f.Message));
			if (num > 0 && Plugin.UpdateNotifications.Value)
			{
				ToastText = ((num == 1) ? $"Supermans Configs: {Findings.First().Title} has an update. Press {Plugin.MenuKey.Value} for details." : $"Supermans Configs: {num} mod updates found. Press {Plugin.MenuKey.Value} for details.");
				ToastUntil = Time.realtimeSinceStartup + 12f;
			}
		}

		private static Dictionary<string, Package> ScanInstalled()
		{
			Dictionary<string, Package> dictionary = new Dictionary<string, Package>();
			if (!Directory.Exists(Paths.PluginPath))
			{
				return dictionary;
			}
			string[] files = Directory.GetFiles(Paths.PluginPath, "manifest.json", SearchOption.AllDirectories);
			foreach (string path in files)
			{
				string json = File.ReadAllText(path);
				string text = JsonString(json, "name");
				if (text != null && IsSuperman(text))
				{
					string directoryName = Path.GetDirectoryName(path);
					if (Directory.GetFiles(directoryName, "*", SearchOption.AllDirectories).Any((string f) => f.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)))
					{
						dictionary[Normalize(text)] = new Package
						{
							Name = text,
							Version = ParseVersion(JsonString(json, "version_number")),
							Dir = directoryName
						};
					}
				}
			}
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				if (value != null && value.Location != null && Plugin.IsSupermanMod(value))
				{
					string pluginDir = Path.GetFullPath(Path.GetDirectoryName(value.Location));
					Package package = dictionary.Values.FirstOrDefault((Package p) => pluginDir.StartsWith(Path.GetFullPath(p.Dir), StringComparison.OrdinalIgnoreCase));
					if (package != null)
					{
						package.Loaded = value;
					}
				}
			}
			return dictionary;
		}

		private static Dictionary<string, Version> ScanModsFolder()
		{
			Dictionary<string, Version> dictionary = new Dictionary<string, Version>(StringComparer.OrdinalIgnoreCase);
			string value = Plugin.ModsFolder.Value;
			if (string.IsNullOrWhiteSpace(value) || !Directory.Exists(value))
			{
				return dictionary;
			}
			string[] files = Directory.GetFiles(value, "*.zip");
			for (int i = 0; i < files.Length; i++)
			{
				Match match = Regex.Match(Path.GetFileNameWithoutExtension(files[i]), "^(?<name>.+?)-(?<ver>\\d+(?:\\.\\d+){1,3})$");
				if (match.Success && IsSuperman(match.Groups["name"].Value))
				{
					Version version = ParseVersion(match.Groups["ver"].Value);
					string value2 = match.Groups["name"].Value;
					if (version != null && (!dictionary.TryGetValue(value2, out var value3) || version > value3))
					{
						dictionary[value2] = version;
					}
				}
			}
			return dictionary;
		}

		private static bool IsSuperman(string name)
		{
			return name.IndexOf("superman", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static string Normalize(string name)
		{
			return Regex.Replace(name, "[^a-zA-Z0-9]", "").ToLowerInvariant();
		}

		private static string Pretty(string package)
		{
			return Regex.Replace(package, "^Supermans?[_ ]*", "", RegexOptions.IgnoreCase).Replace('_', ' ');
		}

		private static string JsonString(string json, string key)
		{
			Match match = Regex.Match(json, "\"" + key + "\"\\s*:\\s*\"([^\"]*)\"");
			if (!match.Success)
			{
				return null;
			}
			return match.Groups[1].Value;
		}

		private static Version ParseVersion(string text)
		{
			try
			{
				return string.IsNullOrEmpty(text) ? null : new Version(text);
			}
			catch
			{
				return null;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}