Decompiled source of HTFModManager v1.0.1

plugins\HTFModManager\HTFModManager.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HTFModManager")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HTFModManager")]
[assembly: AssemblyTitle("HTFModManager")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 HTFModManager
{
	[BepInPlugin("com.howtofish.htfmodmanager", "HTF Mod Manager", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.howtofish.htfmodmanager";

		public const string Name = "HTF Mod Manager";

		public const string Version = "1.0.1";

		private static ManualLogSource Log;

		private ConfigEntry<KeyCode> _dumpOptionsKey;

		private ConfigEntry<KeyCode> _dumpModsKey;

		private ConfigEntry<KeyCode> _injectModsKey;

		private GameObject _modsButton;

		private GameObject _modsDisplay;

		private GameObject _optionsScreen;

		private GameObject _gameplayDisplayTemplate;

		private GameObject _bloodRowTemplate;

		private GameObject _sliderRowTemplate;

		private GameObject _editButtonTemplate;

		private PluginInfo _selectedPlugin;

		private bool _injected;

		private float _nextAutoInjectTry;

		private bool _configViewOpen;

		private ScrollRect _modsScrollRect;

		private RectTransform _modsViewport;

		private RectTransform _modsContent;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			_dumpOptionsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "DumpOptionsKey", (KeyCode)288, "Dump quirúrgico de OptionsScreen.");
			_dumpModsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "DumpModsKey", (KeyCode)289, "Vuelca plugins BepInEx cargados y ConfigEntry vivos.");
			_injectModsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "InjectModsKey", (KeyCode)290, "Crea/recrea la pestaña MODS nativa dentro de Options.");
			Log.LogInfo((object)"HTF Mod Manager 1.0.1 loaded.");
			Log.LogInfo((object)"F7 = dump quirúrgico de OptionsScreen");
			Log.LogInfo((object)"F8 = dump mods + ConfigEntry");
			Log.LogInfo((object)"F9 = inyectar/recrear pestaña MODS (debug; auto-inject activo)");
		}

		private void OnDestroy()
		{
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(_dumpOptionsKey.Value))
			{
				DumpOptionsScreenFocused();
			}
			if (Input.GetKeyDown(_dumpModsKey.Value))
			{
				DumpLoadedModsAndConfigs();
			}
			if (Input.GetKeyDown(_injectModsKey.Value))
			{
				_injected = false;
				TryInjectModsTab(rebuild: true);
			}
			if (!_injected && Time.unscaledTime >= _nextAutoInjectTry)
			{
				_nextAutoInjectTry = Time.unscaledTime + 1f;
				TryInjectModsTab(rebuild: false);
			}
			if (_configViewOpen && Input.GetKeyDown((KeyCode)27))
			{
				ReturnToModsList();
			}
		}

		private void DumpOptionsScreenFocused()
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			Log.LogInfo((object)"");
			Log.LogInfo((object)"================ HTF MOD MANAGER - OPTIONS FOCUSED DUMP ================");
			GameObject val = FindOptionsScreen();
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"[OPTIONS] No encontré OptionsScreen. Abre Options y pulsa F7 otra vez.");
				Log.LogInfo((object)"================ END OPTIONS FOCUSED DUMP ===============================");
				return;
			}
			Log.LogInfo((object)$"[OPTIONS] root='{GetPath(val.transform)}' activeSelf={val.activeSelf} activeHierarchy={val.activeInHierarchy}");
			DumpTree(val.transform, 0, 5);
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- UPPER BUTTONS ----------------");
			Transform val2 = FindChildRecursive(val.transform, "UpperButtonHolder");
			if ((Object)(object)val2 != (Object)null)
			{
				foreach (Transform item in val2)
				{
					Transform val3 = item;
					Button component = ((Component)val3).GetComponent<Button>();
					if (!((Object)(object)component == (Object)null))
					{
						Log.LogInfo((object)("[TAB] '" + ((Object)val3).name + "' path='" + GetPath(val3) + "' " + $"interactable={((Selectable)component).interactable} persistentListeners={((UnityEventBase)component.onClick).GetPersistentEventCount()}"));
					}
				}
			}
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- DISPLAYS ----------------");
			foreach (Transform item2 in val.transform)
			{
				Transform val4 = item2;
				if (((Object)val4).name.IndexOf("Display", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Log.LogInfo((object)($"[DISPLAY] '{((Object)val4).name}' activeSelf={((Component)val4).gameObject.activeSelf} " + "path='" + GetPath(val4) + "' comps=[" + string.Join(", ", from c in ((Component)val4).GetComponents<Component>()
						where (Object)(object)c != (Object)null
						select ((object)c).GetType().Name) + "]"));
				}
			}
			Log.LogInfo((object)"================ END OPTIONS FOCUSED DUMP ===============================");
			Log.LogInfo((object)"");
		}

		private void DumpTree(Transform root, int depth, int maxDepth)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null || depth > maxDepth)
			{
				return;
			}
			string text = new string(' ', depth * 2);
			Component[] components = ((Component)root).GetComponents<Component>();
			Log.LogInfo((object)($"{text}[GO] '{((Object)root).name}' activeSelf={((Component)root).gameObject.activeSelf} " + $"activeHierarchy={((Component)root).gameObject.activeInHierarchy} " + "comps=[" + string.Join(", ", from c in components
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().Name) + "]"));
			RectTransform val = (RectTransform)(object)((root is RectTransform) ? root : null);
			if ((Object)(object)val != (Object)null)
			{
				Log.LogInfo((object)($"{text}     RECT anchorMin={val.anchorMin} anchorMax={val.anchorMax} pivot={val.pivot} " + $"anchoredPos={val.anchoredPosition} sizeDelta={val.sizeDelta}"));
			}
			if (depth != maxDepth)
			{
				for (int num = 0; num < root.childCount; num++)
				{
					DumpTree(root.GetChild(num), depth + 1, maxDepth);
				}
			}
		}

		private void DumpLoadedModsAndConfigs()
		{
			Log.LogInfo((object)"");
			Log.LogInfo((object)"================ HTF MOD MANAGER - MOD/CONFIG DUMP ================");
			try
			{
				KeyValuePair<string, PluginInfo>[] array = Chainloader.PluginInfos.OrderBy(delegate(KeyValuePair<string, PluginInfo> kv)
				{
					PluginInfo value3 = kv.Value;
					object obj;
					if (value3 == null)
					{
						obj = null;
					}
					else
					{
						BepInPlugin metadata4 = value3.Metadata;
						obj = ((metadata4 != null) ? metadata4.Name : null);
					}
					if (obj == null)
					{
						obj = kv.Key;
					}
					return (string)obj;
				}).ToArray();
				Log.LogInfo((object)$"Loaded BepInEx plugins={array.Length}");
				KeyValuePair<string, PluginInfo>[] array2 = array;
				for (int num = 0; num < array2.Length; num++)
				{
					KeyValuePair<string, PluginInfo> keyValuePair = array2[num];
					PluginInfo value = keyValuePair.Value;
					if (value == null)
					{
						continue;
					}
					BepInPlugin metadata = value.Metadata;
					string text = ((metadata != null) ? metadata.GUID : null) ?? keyValuePair.Key;
					BepInPlugin metadata2 = value.Metadata;
					string text2 = ((metadata2 != null) ? metadata2.Name : null) ?? "?";
					BepInPlugin metadata3 = value.Metadata;
					string text3 = ((metadata3 == null) ? null : metadata3.Version?.ToString()) ?? "?";
					Log.LogInfo((object)"");
					Log.LogInfo((object)("[MOD] name='" + text2 + "' guid='" + text + "' version='" + text3 + "'"));
					BaseUnityPlugin instance = value.Instance;
					if ((Object)(object)instance == (Object)null)
					{
						Log.LogInfo((object)"  Instance=null");
						continue;
					}
					ConfigFile config = instance.Config;
					if (config == null)
					{
						Log.LogInfo((object)"  Config=null");
						continue;
					}
					Log.LogInfo((object)("  ConfigPath='" + config.ConfigFilePath + "'"));
					foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
					{
						ConfigDefinition key = item.Key;
						ConfigEntryBase value2 = item.Value;
						string text4 = value2.SettingType?.FullName ?? "?";
						string text5 = SafeString(value2.BoxedValue);
						ConfigDescription description = value2.Description;
						string text6 = ((description != null) ? description.Description : null) ?? "";
						Log.LogInfo((object)("  [CFG] [" + key.Section + "] " + key.Key + " type=" + text4 + " value='" + text5 + "' desc='" + text6 + "'"));
					}
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[MOD DUMP] Failed: {arg}");
			}
			Log.LogInfo((object)"================ END MOD/CONFIG DUMP ==============================");
			Log.LogInfo((object)"");
		}

		private void TryInjectModsTab(bool rebuild)
		{
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Expected O, but got Unknown
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Expected O, but got Unknown
			if (_injected && !rebuild)
			{
				return;
			}
			GameObject val = FindOptionsScreen();
			if ((Object)(object)val == (Object)null)
			{
				if (rebuild)
				{
					Log.LogWarning((object)"[MODS UI] OptionsScreen no encontrado. Abre Options.");
				}
				return;
			}
			_optionsScreen = val;
			Transform val2 = FindChildRecursive(val.transform, "UpperButtonHolder");
			Transform val3 = (((Object)(object)val2 != (Object)null) ? FindChildDirect(val2, "GameplayButton") : null);
			Transform val4 = FindChildDirect(val.transform, "GameplayDisplay (To toggle)");
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = FindChildRecursive(val.transform, "GameplayDisplay (To toggle)");
			}
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				Log.LogError((object)$"[MODS UI] Faltan plantillas. upper={(Object)(object)val2 != (Object)null}, gameplayButton={(Object)(object)val3 != (Object)null}, gameplayDisplay={(Object)(object)val4 != (Object)null}");
				return;
			}
			_gameplayDisplayTemplate = ((Component)val4).gameObject;
			Transform obj = FindChildRecursive(val4, "BloodRow");
			_bloodRowTemplate = ((obj != null) ? ((Component)obj).gameObject : null);
			Transform obj2 = FindChildRecursive(val4, "SensitivityRow");
			_sliderRowTemplate = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			Transform obj3 = FindChildRecursive(val.transform, "ResetToDefaultButton");
			_editButtonTemplate = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			if ((Object)(object)_bloodRowTemplate == (Object)null)
			{
				Log.LogError((object)"[MODS UI] No encontré GameplayDisplay/Layout/BloodRow como plantilla.");
				return;
			}
			DestroyExistingInjectedUi(val.transform, val2);
			_modsButton = Object.Instantiate<GameObject>(((Component)val3).gameObject, val2, false);
			((Object)_modsButton).name = "ModsButton";
			DisableLocalization(_modsButton);
			SetFirstTmpText(_modsButton, "MODS");
			Button component = _modsButton.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Log.LogError((object)"[MODS UI] El botón clonado no tiene UnityEngine.UI.Button.");
				Object.Destroy((Object)(object)_modsButton);
				_modsButton = null;
				return;
			}
			((UnityEventBase)component.onClick).RemoveAllListeners();
			((UnityEvent)component.onClick).AddListener(new UnityAction(OpenModsTab));
			NormalizeTopTabs(val2);
			_modsDisplay = Object.Instantiate<GameObject>(((Component)val4).gameObject, val.transform, false);
			((Object)_modsDisplay).name = "ModsDisplay (HTFMM)";
			_modsDisplay.SetActive(false);
			DisableLocalization(_modsDisplay);
			ConfigureModsScrollArea();
			Transform val5 = (Transform)(((Object)(object)_modsContent != (Object)null) ? ((object)_modsContent) : ((object)FindChildRecursive(_modsDisplay.transform, "Layout")));
			if ((Object)(object)val5 == (Object)null)
			{
				Log.LogError((object)"[MODS UI] ModsDisplay clonado no tiene Layout.");
				Object.Destroy((Object)(object)_modsDisplay);
				Object.Destroy((Object)(object)_modsButton);
				_modsDisplay = null;
				_modsButton = null;
				return;
			}
			ClearChildren(val5);
			BuildModsList(val5);
			foreach (Transform item in val2)
			{
				Transform val6 = item;
				if (!((Object)(object)((Component)val6).gameObject == (Object)(object)_modsButton))
				{
					Button component2 = ((Component)val6).GetComponent<Button>();
					if ((Object)(object)component2 != (Object)null)
					{
						((UnityEvent)component2.onClick).AddListener(new UnityAction(HideModsDisplayOnly));
					}
				}
			}
			_injected = true;
			_configViewOpen = false;
			Log.LogWarning((object)($"[MODS UI] Pestaña MODS creada. plugins={Chainloader.PluginInfos.Count}. " + "Pulsa MODS dentro de Options."));
		}

		private void OpenModsTab()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if ((Object)(object)_modsDisplay == (Object)null || (Object)(object)_optionsScreen == (Object)null)
			{
				return;
			}
			foreach (Transform item in _optionsScreen.transform)
			{
				Transform val = item;
				if (!((Object)(object)((Component)val).gameObject == (Object)(object)_modsDisplay) && ((Object)val).name.IndexOf("Display", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)val).name.IndexOf("Button", StringComparison.OrdinalIgnoreCase) < 0)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			Transform modsContent = GetModsContent();
			if ((Object)(object)modsContent != (Object)null)
			{
				ClearChildren(modsContent);
				BuildModsList(modsContent);
			}
			_modsDisplay.SetActive(true);
			_configViewOpen = false;
			ScrollToTop();
			Log.LogInfo((object)"[MODS UI] MODS abierto.");
		}

		private void HideModsDisplayOnly()
		{
			if ((Object)(object)_modsDisplay != (Object)null)
			{
				_modsDisplay.SetActive(false);
			}
		}

		private void BuildModsList(Transform layout)
		{
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			_selectedPlugin = null;
			PluginInfo[] array = (from kv in Chainloader.PluginInfos.OrderBy(delegate(KeyValuePair<string, PluginInfo> kv)
				{
					PluginInfo value = kv.Value;
					object obj4;
					if (value == null)
					{
						obj4 = null;
					}
					else
					{
						BepInPlugin metadata6 = value.Metadata;
						obj4 = ((metadata6 != null) ? metadata6.Name : null);
					}
					if (obj4 == null)
					{
						obj4 = kv.Key;
					}
					return (string)obj4;
				})
				select kv.Value into info
				where info != null
				select info).ToArray();
			AddSectionHeader(layout, "MODS");
			PluginInfo[] array2 = array;
			foreach (PluginInfo val in array2)
			{
				GameObject val2 = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
				BepInPlugin metadata = val.Metadata;
				object obj = ((metadata != null) ? metadata.GUID : null);
				if (obj == null)
				{
					BepInPlugin metadata2 = val.Metadata;
					obj = ((metadata2 != null) ? metadata2.Name : null) ?? "Unknown";
				}
				((Object)val2).name = "ModRow_" + Sanitize((string)obj);
				SetLayoutHeight(val2, 58f);
				DisableLocalization(val2);
				BepInPlugin metadata3 = val.Metadata;
				string text = ((metadata3 != null) ? metadata3.Name : null) ?? "Unknown Mod";
				BepInPlugin metadata4 = val.Metadata;
				string text2 = ((metadata4 == null) ? null : metadata4.Version?.ToString()) ?? "?";
				BepInPlugin metadata5 = val.Metadata;
				bool flag = string.Equals((metadata5 != null) ? metadata5.GUID : null, "com.howtofish.htfmodmanager", StringComparison.OrdinalIgnoreCase);
				object obj2;
				if (!flag)
				{
					BaseUnityPlugin instance = val.Instance;
					obj2 = FindConfigEntry((instance != null) ? instance.Config : null, "General", "Enabled");
				}
				else
				{
					obj2 = null;
				}
				ConfigEntryBase val3 = (ConfigEntryBase)obj2;
				SetPreferredRowTitle(val2, flag ? (text + "  v" + text2 + "   [SYSTEM]") : (text + "  v" + text2));
				WidenRowTitle(val2);
				Toggle componentInChildren = val2.GetComponentInChildren<Toggle>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Transform transform = ((Component)componentInChildren).transform;
					RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					if ((Object)(object)val4 != (Object)null)
					{
						val4.anchorMin = new Vector2(0.74f, 0.5f);
						val4.anchorMax = new Vector2(0.74f, 0.5f);
						val4.anchoredPosition = Vector2.zero;
					}
					((UnityEventBase)componentInChildren.onValueChanged).RemoveAllListeners();
					if (val3 != null && val3.SettingType == typeof(bool))
					{
						bool isOn = false;
						try
						{
							isOn = (bool)val3.BoxedValue;
						}
						catch
						{
						}
						componentInChildren.isOn = isOn;
						((Selectable)componentInChildren).interactable = true;
						ConfigEntryBase capturedEntry = val3;
						ConfigFile capturedConfig = val.Instance.Config;
						string capturedName = text;
						((UnityEvent<bool>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
						{
							try
							{
								capturedEntry.BoxedValue = value;
								capturedConfig.Save();
								Log.LogWarning((object)$"[MODS UI] {capturedName}: General.Enabled -> {value}");
							}
							catch (Exception ex)
							{
								Log.LogError((object)("[MODS UI] No pude cambiar Enabled de " + capturedName + ": " + ex.Message));
							}
						});
					}
					else
					{
						((Component)componentInChildren).gameObject.SetActive(false);
					}
				}
				AddEditButton(val2, val);
			}
		}

		private void OpenPluginConfig(PluginInfo info)
		{
			if (info == null || (Object)(object)_modsDisplay == (Object)null)
			{
				return;
			}
			_selectedPlugin = info;
			_configViewOpen = true;
			Transform modsContent = GetModsContent();
			if ((Object)(object)modsContent == (Object)null)
			{
				return;
			}
			ClearChildren(modsContent);
			BepInPlugin metadata = info.Metadata;
			string text = ((metadata != null) ? metadata.Name : null) ?? "Unknown Mod";
			BepInPlugin metadata2 = info.Metadata;
			string text2 = ((metadata2 == null) ? null : metadata2.Version?.ToString()) ?? "?";
			AddSectionHeader(modsContent, text + "  v" + text2);
			BaseUnityPlugin instance = info.Instance;
			ConfigFile val = ((instance != null) ? instance.Config : null);
			if (val == null)
			{
				AddInfoRow(modsContent, "No live ConfigFile available.");
				AddBackToModsRow(modsContent);
				return;
			}
			AddInfoRow(modsContent, "Choose a section:");
			string[] array = (from s in ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)val).Select((KeyValuePair<ConfigDefinition, ConfigEntryBase> p) => p.Key.Section).Distinct<string>(StringComparer.OrdinalIgnoreCase)
				orderby s
				select s).ToArray();
			foreach (string section in array)
			{
				AddSectionNavigationRow(modsContent, info, section);
			}
			AddBackToModsRow(modsContent);
			ScrollToTop();
		}

		private void OpenPluginSection(PluginInfo info, string section)
		{
			if (info == null || (Object)(object)_modsDisplay == (Object)null)
			{
				return;
			}
			_selectedPlugin = info;
			_configViewOpen = true;
			Transform modsContent = GetModsContent();
			if ((Object)(object)modsContent == (Object)null)
			{
				return;
			}
			ClearChildren(modsContent);
			BepInPlugin metadata = info.Metadata;
			string text = ((metadata != null) ? metadata.Name : null) ?? "Unknown Mod";
			BaseUnityPlugin instance = info.Instance;
			ConfigFile val = ((instance != null) ? instance.Config : null);
			AddSectionHeader(modsContent, text + " / " + section);
			if (val == null)
			{
				AddInfoRow(modsContent, "No config.");
				AddActionBackToPluginRow(modsContent, info);
				return;
			}
			KeyValuePair<ConfigDefinition, ConfigEntryBase>[] array = (from p in (IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)val
				where string.Equals(p.Key.Section, section, StringComparison.OrdinalIgnoreCase)
				orderby p.Key.Key
				select p).ToArray();
			for (int num = 0; num < array.Length; num++)
			{
				KeyValuePair<ConfigDefinition, ConfigEntryBase> keyValuePair = array[num];
				ConfigDefinition key = keyValuePair.Key;
				ConfigEntryBase value = keyValuePair.Value;
				BepInPlugin metadata2 = info.Metadata;
				if (string.Equals((metadata2 != null) ? metadata2.GUID : null, "com.howtofish.htfmodmanager", StringComparison.OrdinalIgnoreCase) && string.Equals(key.Section, "General", StringComparison.OrdinalIgnoreCase) && string.Equals(key.Key, "Enabled", StringComparison.OrdinalIgnoreCase))
				{
					AddInfoRow(modsContent, "Enabled: ON (protected)");
				}
				else
				{
					AddGenericConfigRow(modsContent, key, value, val);
				}
			}
			AddActionBackToPluginRow(modsContent, info);
			ScrollToTop();
		}

		private void AddSectionNavigationRow(Transform layout, PluginInfo info, string section)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)val).name = "SectionNav_" + Sanitize(section);
			SetLayoutHeight(val, 54f);
			DisableLocalization(val);
			SetPreferredRowTitle(val, section.ToUpperInvariant());
			WidenRowTitle(val);
			Toggle componentInChildren = val.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			AddActionButton(val, "OPEN", (UnityAction)delegate
			{
				OpenPluginSection(info, section);
			});
		}

		private void AddActionBackToPluginRow(Transform layout, PluginInfo info)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)val).name = "BackToPlugin";
			SetLayoutHeight(val, 54f);
			DisableLocalization(val);
			SetPreferredRowTitle(val, "< BACK");
			WidenRowTitle(val);
			Toggle componentInChildren = val.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			AddActionButton(val, "< BACK", (UnityAction)delegate
			{
				OpenPluginConfig(info);
			});
		}

		private void AddGenericConfigRow(Transform layout, ConfigDefinition definition, ConfigEntryBase entry, ConfigFile config)
		{
			if (entry == null)
			{
				return;
			}
			Type settingType = entry.SettingType;
			string key = definition.Key;
			if (TryGetAcceptableList(entry, out var values) && values.Length != 0)
			{
				AddChoiceConfigRow(layout, key, entry, config, values);
				return;
			}
			if (settingType == typeof(bool))
			{
				AddBoolConfigRow(layout, key, entry, config);
				return;
			}
			if (settingType != null && settingType.IsEnum)
			{
				object[] choices = Enum.GetValues(settingType).Cast<object>().ToArray();
				AddChoiceConfigRow(layout, key, entry, config, choices);
				return;
			}
			if (IsNumericType(settingType))
			{
				AddNumericConfigRow(layout, key, entry, config);
				return;
			}
			if (!(settingType == typeof(string)))
			{
				_ = settingType == typeof(char);
			}
			AddTextConfigRow(layout, key, entry, config);
		}

		private void AddBoolConfigRow(Transform layout, string label, ConfigEntryBase entry, ConfigFile config)
		{
			GameObject obj = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)obj).name = "CfgBool_" + Sanitize(label);
			SetLayoutHeight(obj, 54f);
			DisableLocalization(obj);
			SetPreferredRowTitle(obj, Humanize(label));
			WidenRowTitle(obj);
			Toggle componentInChildren = obj.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			((UnityEventBase)componentInChildren.onValueChanged).RemoveAllListeners();
			bool isOn = false;
			try
			{
				isOn = Convert.ToBoolean(entry.BoxedValue);
			}
			catch
			{
			}
			componentInChildren.isOn = isOn;
			((Selectable)componentInChildren).interactable = true;
			((UnityEvent<bool>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				try
				{
					entry.BoxedValue = value;
					config.Save();
					Log.LogInfo((object)$"[CONFIG] {label} -> {value}");
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[CONFIG] " + label + ": " + ex.Message));
				}
			});
		}

		private void AddNumericConfigRow(Transform layout, string label, ConfigEntryBase entry, ConfigFile config)
		{
			if ((Object)(object)_sliderRowTemplate == (Object)null)
			{
				AddInfoRow(layout, Humanize(label) + ": " + FormatNumericValue(entry.BoxedValue, entry.SettingType));
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(_sliderRowTemplate, layout, false);
			((Object)val).name = "CfgNumber_" + Sanitize(label);
			SetLayoutHeight(val, 58f);
			DisableLocalization(val);
			Component[] componentsInChildren = val.GetComponentsInChildren<Component>(true);
			SetTmpText(((IEnumerable<Component>)componentsInChildren).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TextMeshProUGUI" && (((Object)c.gameObject).name.IndexOf("Text", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)c.gameObject).name.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0))), Humanize(label));
			Slider slider = val.GetComponentInChildren<Slider>(true);
			Component input = ((IEnumerable<Component>)componentsInChildren).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TMP_InputField"));
			double num = 0.0;
			try
			{
				num = Convert.ToDouble(entry.BoxedValue, CultureInfo.InvariantCulture);
			}
			catch
			{
			}
			float min = 0f;
			float max = 0f;
			bool hasRange = TryGetAcceptableRange(entry, ref min, ref max);
			bool wholeNumbers = IsIntegralType(entry.SettingType);
			if ((Object)(object)slider != (Object)null)
			{
				if (hasRange)
				{
					((Component)slider).gameObject.SetActive(true);
					((UnityEventBase)slider.onValueChanged).RemoveAllListeners();
					slider.minValue = min;
					slider.maxValue = max;
					slider.wholeNumbers = wholeNumbers;
					slider.value = Mathf.Clamp((float)num, min, max);
					((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
					{
						try
						{
							object obj2 = ConvertNumeric(value, entry.SettingType);
							entry.BoxedValue = obj2;
							SetInputText(input, FormatNumericValue(obj2, entry.SettingType));
							config.Save();
						}
						catch (Exception ex)
						{
							Log.LogWarning((object)("[CONFIG] " + label + ": " + ex.Message));
						}
					});
				}
				else
				{
					((Component)slider).gameObject.SetActive(false);
				}
			}
			SetInputText(input, FormatNumericValue(entry.BoxedValue, entry.SettingType));
			ExpandInputField(input, hasRange ? 0.85f : 0.6f, 0.95f);
			BindInputCommit(input, delegate(string raw)
			{
				try
				{
					if (!TryConvertStringToType(raw, entry.SettingType, out var value))
					{
						SetInputText(input, FormatNumericValue(entry.BoxedValue, entry.SettingType));
					}
					else
					{
						if (hasRange)
						{
							double val2 = Convert.ToDouble(value, CultureInfo.InvariantCulture);
							val2 = Math.Max(min, Math.Min(max, val2));
							value = ConvertNumeric(val2, entry.SettingType);
						}
						entry.BoxedValue = value;
						if ((Object)(object)slider != (Object)null && hasRange)
						{
							slider.SetValueWithoutNotify(Mathf.Clamp(Convert.ToSingle(value), min, max));
						}
						SetInputText(input, FormatNumericValue(value, entry.SettingType));
						config.Save();
						Log.LogInfo((object)$"[CONFIG] {label} -> {value}");
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[CONFIG] " + label + ": " + ex.Message));
				}
			});
		}

		private void AddTextConfigRow(Transform layout, string label, ConfigEntryBase entry, ConfigFile config)
		{
			if ((Object)(object)_sliderRowTemplate == (Object)null)
			{
				AddInfoRow(layout, Humanize(label) + ": " + SafeString(entry.BoxedValue));
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(_sliderRowTemplate, layout, false);
			((Object)val).name = "CfgText_" + Sanitize(label);
			SetLayoutHeight(val, 58f);
			DisableLocalization(val);
			Component[] componentsInChildren = val.GetComponentsInChildren<Component>(true);
			SetTmpText(((IEnumerable<Component>)componentsInChildren).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TextMeshProUGUI" && (((Object)c.gameObject).name.IndexOf("Text", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)c.gameObject).name.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0))), Humanize(label));
			Slider componentInChildren = val.GetComponentInChildren<Slider>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			Component input = ((IEnumerable<Component>)componentsInChildren).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TMP_InputField"));
			if ((Object)(object)input == (Object)null)
			{
				AddInfoRow(layout, Humanize(label) + ": " + SafeString(entry.BoxedValue));
				Object.Destroy((Object)(object)val);
				return;
			}
			ExpandInputField(input, 0.55f, 0.95f);
			SetInputText(input, SafeString(entry.BoxedValue));
			BindInputCommit(input, delegate(string raw)
			{
				try
				{
					if (!TryConvertStringToType(raw, entry.SettingType, out var value))
					{
						SetInputText(input, SafeString(entry.BoxedValue));
					}
					else
					{
						entry.BoxedValue = value;
						config.Save();
						SetInputText(input, SafeString(value));
						Log.LogInfo((object)$"[CONFIG] {label} -> {value}");
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[CONFIG] " + label + ": " + ex.Message));
				}
			});
		}

		private void AddChoiceConfigRow(Transform layout, string label, ConfigEntryBase entry, ConfigFile config, object[] choices)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			if (choices == null || choices.Length == 0)
			{
				AddInfoRow(layout, Humanize(label) + ": " + SafeString(entry.BoxedValue));
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)val).name = "CfgChoice_" + Sanitize(label);
			SetLayoutHeight(val, 58f);
			DisableLocalization(val);
			SetPreferredRowTitle(val, Humanize(label));
			WidenRowTitle(val);
			Toggle componentInChildren = val.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			GameObject valueHolder = CreateChoiceValueLabel(val, SafeString(entry.BoxedValue));
			AddActionButtonAt(val, "<", 0.7f, 52f, (UnityAction)delegate
			{
				CycleChoice(entry, config, choices, -1, valueHolder);
			});
			AddActionButtonAt(val, ">", 0.94f, 52f, (UnityAction)delegate
			{
				CycleChoice(entry, config, choices, 1, valueHolder);
			});
		}

		private void CycleChoice(ConfigEntryBase entry, ConfigFile config, object[] choices, int delta, GameObject valueHolder)
		{
			if (entry == null || choices == null || choices.Length == 0)
			{
				return;
			}
			int num = Array.FindIndex(choices, (object x) => object.Equals(x, entry.BoxedValue));
			if (num < 0)
			{
				num = 0;
			}
			num = (num + delta) % choices.Length;
			if (num < 0)
			{
				num += choices.Length;
			}
			object obj = choices[num];
			try
			{
				entry.BoxedValue = obj;
				config.Save();
				SetFirstTmpText(valueHolder, SafeString(obj));
				Log.LogInfo((object)$"[CONFIG] choice -> {obj}");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[CONFIG] choice: " + ex.Message));
			}
		}

		private GameObject CreateChoiceValueLabel(GameObject row, string value)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			Component val = ((IEnumerable<Component>)row.GetComponentsInChildren<Component>(true)).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TextMeshProUGUI"));
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val.gameObject, row.transform, false);
			((Object)obj).name = "HTFMM_ChoiceValue";
			DisableLocalization(obj);
			SetFirstTmpText(obj, value);
			Transform transform = obj.transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.anchorMin = new Vector2(0.73f, 0f);
				val2.anchorMax = new Vector2(0.91f, 1f);
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
			}
			return obj;
		}

		private void AddActionButtonAt(GameObject row, string label, float anchorX, float width, UnityAction action)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)row == (Object)null || action == null)
			{
				return;
			}
			GameObject val = null;
			if ((Object)(object)_editButtonTemplate != (Object)null)
			{
				val = Object.Instantiate<GameObject>(_editButtonTemplate, row.transform, false);
				((Object)val).name = "HTFMM_ActionButton_" + label;
				DisableLocalization(val);
				SetFirstTmpText(val, label);
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.anchorMin = new Vector2(anchorX, 0.5f);
					val2.anchorMax = new Vector2(anchorX, 0.5f);
					val2.pivot = new Vector2(0.5f, 0.5f);
					val2.anchoredPosition = Vector2.zero;
					val2.sizeDelta = new Vector2(width, 42f);
				}
				Button component = val.GetComponent<Button>();
				if ((Object)(object)component != (Object)null)
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
					((UnityEvent)component.onClick).AddListener(action);
				}
				else
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private void AddSectionHeader(Transform layout, string textValue)
		{
			GameObject obj = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)obj).name = "Section_" + Sanitize(textValue);
			SetLayoutHeight(obj, 42f);
			DisableLocalization(obj);
			SetPreferredRowTitle(obj, textValue);
			WidenRowTitle(obj);
			Toggle componentInChildren = obj.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
		}

		private void AddInfoRow(Transform layout, string value)
		{
			GameObject obj = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)obj).name = "Info_" + Sanitize(value);
			SetLayoutHeight(obj, 50f);
			DisableLocalization(obj);
			SetPreferredRowTitle(obj, value);
			WidenRowTitle(obj);
			Toggle componentInChildren = obj.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
		}

		private void AddBackToModsRow(Transform layout)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(_bloodRowTemplate, layout, false);
			((Object)val).name = "BackToMods";
			SetLayoutHeight(val, 54f);
			DisableLocalization(val);
			SetPreferredRowTitle(val, "<  BACK TO MODS");
			WidenRowTitle(val);
			Toggle componentInChildren = val.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			AddActionButton(val, "< BACK", new UnityAction(ReturnToModsList));
		}

		private void AddEditButton(GameObject row, PluginInfo info)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (!((Object)(object)row == (Object)null) && info != null)
			{
				AddActionButton(row, "EDIT", (UnityAction)delegate
				{
					OpenPluginConfig(info);
				});
			}
		}

		private void AddActionButton(GameObject row, string label, UnityAction action)
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)row == (Object)null || action == null)
			{
				return;
			}
			GameObject val = null;
			if ((Object)(object)_editButtonTemplate != (Object)null)
			{
				val = Object.Instantiate<GameObject>(_editButtonTemplate, row.transform, false);
				((Object)val).name = "HTFMM_ActionButton";
				DisableLocalization(val);
				SetFirstTmpText(val, label);
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.anchorMin = new Vector2(0.89f, 0.5f);
					val2.anchorMax = new Vector2(0.89f, 0.5f);
					val2.pivot = new Vector2(0.5f, 0.5f);
					val2.anchoredPosition = Vector2.zero;
					val2.sizeDelta = new Vector2(125f, 42f);
				}
				Button component = val.GetComponent<Button>();
				if ((Object)(object)component != (Object)null)
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
					((UnityEvent)component.onClick).AddListener(action);
					return;
				}
				Object.Destroy((Object)(object)val);
				val = null;
			}
			val = new GameObject("HTFMM_ActionButton", new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(Button)
			});
			val.transform.SetParent(row.transform, false);
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.89f, 0.5f);
			component2.anchorMax = new Vector2(0.89f, 0.5f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			component2.anchoredPosition = Vector2.zero;
			component2.sizeDelta = new Vector2(125f, 42f);
			Image component3 = val.GetComponent<Image>();
			Image componentInChildren = row.GetComponentInChildren<Image>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				component3.sprite = componentInChildren.sprite;
				component3.type = componentInChildren.type;
				((Graphic)component3).material = ((Graphic)componentInChildren).material;
				((Graphic)component3).color = ((Graphic)componentInChildren).color;
			}
			Component val3 = ((IEnumerable<Component>)row.GetComponentsInChildren<Component>(true)).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (((object)c).GetType().FullName ?? "") == "TMPro.TextMeshProUGUI"));
			if ((Object)(object)val3 != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(val3.gameObject, val.transform, false);
				((Object)obj).name = "Text (TMP)";
				DisableLocalization(obj);
				SetFirstTmpText(obj, label);
				Transform transform2 = obj.transform;
				RectTransform val4 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.anchorMin = Vector2.zero;
					val4.anchorMax = Vector2.one;
					val4.offsetMin = Vector2.zero;
					val4.offsetMax = Vector2.zero;
				}
			}
			Button component4 = val.GetComponent<Button>();
			((Selectable)component4).targetGraphic = (Graphic)(object)component3;
			((UnityEventBase)component4.onClick).RemoveAllListeners();
			((UnityEvent)component4.onClick).AddListener(action);
		}

		private static void SetLayoutHeight(GameObject row, float height)
		{
			//IL_0050: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)row == (Object)null))
			{
				LayoutElement val = row.GetComponent<LayoutElement>();
				if ((Object)(object)val == (Object)null)
				{
					val = row.AddComponent<LayoutElement>();
				}
				val.minHeight = height;
				val.preferredHeight = height;
				val.flexibleHeight = 0f;
				Transform transform = row.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Vector2 sizeDelta = val2.sizeDelta;
					sizeDelta.y = height;
					val2.sizeDelta = sizeDelta;
				}
			}
		}

		private static void NormalizeTopTabs(Transform upper)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)upper == (Object)null)
			{
				return;
			}
			for (int i = 0; i < upper.childCount; i++)
			{
				Transform child = upper.GetChild(i);
				RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
				if ((Object)(object)val != (Object)null)
				{
					val.sizeDelta = new Vector2(195f, 60f);
				}
			}
		}

		private static void WidenRowTitle(GameObject row)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)row == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = row.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (((object)val).GetType().FullName ?? "") != "TMPro.TextMeshProUGUI")
				{
					continue;
				}
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				val2.anchorMin = new Vector2(0.05f, 0f);
				val2.anchorMax = new Vector2(0.68f, 1f);
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				PropertyInfo property = ((object)val).GetType().GetProperty("enableWordWrapping");
				try
				{
					property?.SetValue(val, false);
				}
				catch
				{
				}
				PropertyInfo property2 = ((object)val).GetType().GetProperty("fontSize");
				try
				{
					if (property2 != null && property2.CanWrite)
					{
						property2.SetValue(val, 25f);
					}
					break;
				}
				catch
				{
					break;
				}
			}
		}

		private static string Humanize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < value.Length; i++)
			{
				char c = value[i];
				if (i > 0 && char.IsUpper(c) && (char.IsLower(value[i - 1]) || char.IsDigit(value[i - 1])))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		private static void SetTmpText(Component c, string value)
		{
			if ((Object)(object)c == (Object)null)
			{
				return;
			}
			PropertyInfo property = ((object)c).GetType().GetProperty("text");
			try
			{
				property?.SetValue(c, value);
			}
			catch
			{
			}
		}

		private static void SetInputText(Component input, string value)
		{
			if ((Object)(object)input == (Object)null)
			{
				return;
			}
			PropertyInfo property = ((object)input).GetType().GetProperty("text");
			try
			{
				property?.SetValue(input, value);
			}
			catch
			{
			}
		}

		private static void BindInputCommit(Component input, Action<string> callback)
		{
			if ((Object)(object)input == (Object)null || callback == null)
			{
				return;
			}
			PropertyInfo property = ((object)input).GetType().GetProperty("onEndEdit");
			object obj = null;
			try
			{
				obj = property?.GetValue(input);
			}
			catch
			{
			}
			if (obj == null)
			{
				return;
			}
			MethodInfo method = obj.GetType().GetMethod("RemoveAllListeners");
			try
			{
				method?.Invoke(obj, null);
			}
			catch
			{
			}
			MethodInfo method2 = obj.GetType().GetMethod("AddListener");
			if (method2 == null)
			{
				return;
			}
			try
			{
				UnityAction<string> val = delegate(string s)
				{
					callback(s);
				};
				method2.Invoke(obj, new object[1] { val });
			}
			catch
			{
			}
		}

		private static bool IsNumericType(Type type)
		{
			if (type == null)
			{
				return false;
			}
			Type type2 = Nullable.GetUnderlyingType(type) ?? type;
			if (!(type2 == typeof(byte)) && !(type2 == typeof(sbyte)) && !(type2 == typeof(short)) && !(type2 == typeof(ushort)) && !(type2 == typeof(int)) && !(type2 == typeof(uint)) && !(type2 == typeof(long)) && !(type2 == typeof(ulong)) && !(type2 == typeof(float)) && !(type2 == typeof(double)))
			{
				return type2 == typeof(decimal);
			}
			return true;
		}

		private static bool IsIntegralType(Type type)
		{
			if (type == null)
			{
				return false;
			}
			Type type2 = Nullable.GetUnderlyingType(type) ?? type;
			if (!(type2 == typeof(byte)) && !(type2 == typeof(sbyte)) && !(type2 == typeof(short)) && !(type2 == typeof(ushort)) && !(type2 == typeof(int)) && !(type2 == typeof(uint)) && !(type2 == typeof(long)))
			{
				return type2 == typeof(ulong);
			}
			return true;
		}

		private static bool TryConvertStringToType(string raw, Type targetType, out object value)
		{
			value = null;
			try
			{
				Type type = Nullable.GetUnderlyingType(targetType) ?? targetType;
				string text = raw ?? "";
				if (type == typeof(string))
				{
					value = text;
					return true;
				}
				if (type == typeof(char))
				{
					if (text.Length == 0)
					{
						return false;
					}
					value = text[0];
					return true;
				}
				if (type.IsEnum)
				{
					value = Enum.Parse(type, text, ignoreCase: true);
					return true;
				}
				if (IsNumericType(type))
				{
					string s = text.Trim().Replace(',', '.');
					if (IsIntegralType(type))
					{
						if (!decimal.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
						{
							return false;
						}
						result = Math.Round(result, 0);
						if (type == typeof(byte))
						{
							value = (byte)result;
						}
						else if (type == typeof(sbyte))
						{
							value = (sbyte)result;
						}
						else if (type == typeof(short))
						{
							value = (short)result;
						}
						else if (type == typeof(ushort))
						{
							value = (ushort)result;
						}
						else if (type == typeof(int))
						{
							value = (int)result;
						}
						else if (type == typeof(uint))
						{
							value = (uint)result;
						}
						else if (type == typeof(long))
						{
							value = (long)result;
						}
						else
						{
							if (!(type == typeof(ulong)))
							{
								return false;
							}
							value = (ulong)result;
						}
						return true;
					}
					if (!double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
					{
						return false;
					}
					if (type == typeof(float))
					{
						value = (float)result2;
					}
					else if (type == typeof(double))
					{
						value = result2;
					}
					else
					{
						if (!(type == typeof(decimal)))
						{
							return false;
						}
						value = (decimal)result2;
					}
					return true;
				}
				value = Convert.ChangeType(text, type, CultureInfo.InvariantCulture);
				return true;
			}
			catch
			{
				value = null;
				return false;
			}
		}

		private static object ConvertNumeric(double value, Type targetType)
		{
			Type type = Nullable.GetUnderlyingType(targetType) ?? targetType;
			if (type == typeof(byte))
			{
				return (byte)Math.Round(value);
			}
			if (type == typeof(sbyte))
			{
				return (sbyte)Math.Round(value);
			}
			if (type == typeof(short))
			{
				return (short)Math.Round(value);
			}
			if (type == typeof(ushort))
			{
				return (ushort)Math.Round(value);
			}
			if (type == typeof(int))
			{
				return (int)Math.Round(value);
			}
			if (type == typeof(uint))
			{
				return (uint)Math.Max(0.0, Math.Round(value));
			}
			if (type == typeof(long))
			{
				return (long)Math.Round(value);
			}
			if (type == typeof(ulong))
			{
				return (ulong)Math.Max(0.0, Math.Round(value));
			}
			if (type == typeof(float))
			{
				return (float)value;
			}
			if (type == typeof(double))
			{
				return value;
			}
			if (type == typeof(decimal))
			{
				return (decimal)value;
			}
			return Convert.ChangeType(value, type);
		}

		private static bool TryGetAcceptableList(ConfigEntryBase entry, out object[] values)
		{
			values = Array.Empty<object>();
			try
			{
				ConfigDescription description = entry.Description;
				object obj = ((description != null) ? description.AcceptableValues : null);
				if (obj == null)
				{
					return false;
				}
				PropertyInfo property = obj.GetType().GetProperty("AcceptableValues");
				if (property == null)
				{
					return false;
				}
				if (!(property.GetValue(obj) is IEnumerable source))
				{
					return false;
				}
				values = source.Cast<object>().ToArray();
				return values.Length != 0;
			}
			catch
			{
				values = Array.Empty<object>();
				return false;
			}
		}

		private static void ExpandInputField(Component input, float anchorMinX, float anchorMaxX)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)input == (Object)null))
			{
				Transform transform = input.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.anchorMin = new Vector2(anchorMinX, 0.5f);
					val.anchorMax = new Vector2(anchorMaxX, 0.5f);
					val.pivot = new Vector2(1f, 0.5f);
					val.anchoredPosition = Vector2.zero;
					val.sizeDelta = new Vector2(0f, 54f);
				}
			}
		}

		private static bool TryGetAcceptableRange(ConfigEntryBase entry, ref float min, ref float max)
		{
			try
			{
				ConfigDescription description = entry.Description;
				object obj = ((description != null) ? description.AcceptableValues : null);
				if (obj == null)
				{
					return false;
				}
				Type type = obj.GetType();
				PropertyInfo property = type.GetProperty("MinValue");
				PropertyInfo property2 = type.GetProperty("MaxValue");
				if (property != null && property2 != null)
				{
					min = Convert.ToSingle(property.GetValue(obj));
					max = Convert.ToSingle(property2.GetValue(obj));
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private void ReturnToModsList()
		{
			if (!((Object)(object)_modsDisplay == (Object)null))
			{
				Transform modsContent = GetModsContent();
				if (!((Object)(object)modsContent == (Object)null))
				{
					ClearChildren(modsContent);
					BuildModsList(modsContent);
					_configViewOpen = false;
					ScrollToTop();
					Log.LogInfo((object)"[MODS UI] Volviendo a lista principal de mods.");
				}
			}
		}

		private ConfigEntryBase FindConfigEntry(ConfigFile config, string section, string key)
		{
			if (config == null)
			{
				return null;
			}
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
			{
				if (string.Equals(item.Key.Section, section, StringComparison.OrdinalIgnoreCase) && string.Equals(item.Key.Key, key, StringComparison.OrdinalIgnoreCase))
				{
					return item.Value;
				}
			}
			return null;
		}

		private void DestroyExistingInjectedUi(Transform options, Transform upper)
		{
			Transform val = FindChildDirect(upper, "ModsButton");
			if ((Object)(object)val != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
			}
			Transform val2 = FindChildDirect(options, "ModsDisplay (HTFMM)");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
			}
			_modsButton = null;
			_modsDisplay = null;
		}

		private void ConfigureModsScrollArea()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			if ((Object)(object)_modsDisplay == (Object)null)
			{
				return;
			}
			Transform val = FindChildRecursive(_modsDisplay.transform, "Layout");
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"[MODS UI] No encontré Layout para convertirlo en contenido scroll.");
				return;
			}
			Transform transform = _modsDisplay.transform;
			Transform obj = ((transform is RectTransform) ? transform : null);
			RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
			if (!((Object)(object)obj == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				Transform val3 = FindChildDirect(_modsDisplay.transform, "HTFMM_Viewport");
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
				}
				GameObject val4 = new GameObject("HTFMM_Viewport", new Type[2]
				{
					typeof(RectTransform),
					typeof(RectMask2D)
				});
				val4.transform.SetParent(_modsDisplay.transform, false);
				RectTransform component = val4.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 0f);
				component.anchorMax = new Vector2(1f, 1f);
				component.pivot = new Vector2(0.5f, 0.5f);
				component.offsetMin = new Vector2(18f, 18f);
				component.offsetMax = new Vector2(-18f, -18f);
				val.SetParent((Transform)(object)component, false);
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(1f, 1f);
				val2.pivot = new Vector2(0.5f, 1f);
				val2.anchoredPosition = Vector2.zero;
				val2.sizeDelta = new Vector2(0f, 0f);
				VerticalLayoutGroup val5 = ((Component)val).GetComponent<VerticalLayoutGroup>();
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = ((Component)val).gameObject.AddComponent<VerticalLayoutGroup>();
				}
				((HorizontalOrVerticalLayoutGroup)val5).spacing = 6f;
				((LayoutGroup)val5).padding = new RectOffset(10, 10, 8, 12);
				((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
				ContentSizeFitter val6 = ((Component)val).GetComponent<ContentSizeFitter>();
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = ((Component)val).gameObject.AddComponent<ContentSizeFitter>();
				}
				val6.horizontalFit = (FitMode)0;
				val6.verticalFit = (FitMode)2;
				ScrollRect val7 = _modsDisplay.GetComponent<ScrollRect>();
				if ((Object)(object)val7 == (Object)null)
				{
					val7 = _modsDisplay.AddComponent<ScrollRect>();
				}
				val7.viewport = component;
				val7.content = val2;
				val7.horizontal = false;
				val7.vertical = true;
				val7.movementType = (MovementType)2;
				val7.inertia = true;
				val7.decelerationRate = 0.135f;
				val7.scrollSensitivity = 28f;
				val7.verticalNormalizedPosition = 1f;
				_modsScrollRect = val7;
				_modsViewport = component;
				_modsContent = val2;
				Log.LogInfo((object)"[MODS UI] ScrollRect configurado para MODS.");
			}
		}

		private Transform GetModsContent()
		{
			if ((Object)(object)_modsContent != (Object)null)
			{
				return (Transform)(object)_modsContent;
			}
			if ((Object)(object)_modsDisplay == (Object)null)
			{
				return null;
			}
			Transform val = FindChildRecursive(_modsDisplay.transform, "Layout");
			_modsContent = (RectTransform)(object)((val is RectTransform) ? val : null);
			return val;
		}

		private void RefreshModsLayout()
		{
			if (!((Object)(object)_modsContent == (Object)null))
			{
				Canvas.ForceUpdateCanvases();
				LayoutRebuilder.ForceRebuildLayoutImmediate(_modsContent);
				if ((Object)(object)_modsViewport != (Object)null)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(_modsViewport);
				}
			}
		}

		private void ScrollToTop()
		{
			RefreshModsLayout();
			if (!((Object)(object)_modsScrollRect == (Object)null))
			{
				_modsScrollRect.verticalNormalizedPosition = 1f;
				_modsScrollRect.StopMovement();
			}
		}

		private GameObject FindOptionsScreen()
		{
			if ((Object)(object)_optionsScreen != (Object)null)
			{
				try
				{
					if ((Object)(object)_optionsScreen.transform != (Object)null)
					{
						return _optionsScreen;
					}
				}
				catch
				{
					_optionsScreen = null;
				}
			}
			Transform[] source = Resources.FindObjectsOfTypeAll<Transform>();
			Transform val = ((IEnumerable<Transform>)source).FirstOrDefault((Func<Transform, bool>)((Transform t) => (Object)(object)t != (Object)null && string.Equals(((Object)t).name, "OptionsScreen", StringComparison.OrdinalIgnoreCase) && GetPath(t).IndexOf("PauseCanvas", StringComparison.OrdinalIgnoreCase) >= 0));
			if ((Object)(object)val != (Object)null)
			{
				_optionsScreen = ((Component)val).gameObject;
				return _optionsScreen;
			}
			Transform val2 = ((IEnumerable<Transform>)source).FirstOrDefault((Func<Transform, bool>)((Transform t) => (Object)(object)t != (Object)null && string.Equals(((Object)t).name, "GameplayButton", StringComparison.OrdinalIgnoreCase) && (Object)(object)((Component)t).GetComponent<Button>() != (Object)null));
			if ((Object)(object)val2 != (Object)null)
			{
				Transform parent = val2.parent;
				while ((Object)(object)parent != (Object)null)
				{
					Transform val3 = FindChildDirect(parent, "UpperButtonHolder");
					if ((Object)(object)val3 == (Object)null)
					{
						val3 = FindChildRecursive(parent, "UpperButtonHolder");
					}
					Transform val4 = FindChildRecursive(parent, "GameplayDisplay (To toggle)");
					if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null)
					{
						_optionsScreen = ((Component)parent).gameObject;
						Log.LogWarning((object)("[MODS UI] Options localizado por estructura: " + GetPath(parent)));
						return _optionsScreen;
					}
					parent = parent.parent;
				}
			}
			Transform val5 = ((IEnumerable<Transform>)source).FirstOrDefault((Func<Transform, bool>)((Transform t) => (Object)(object)t != (Object)null && string.Equals(((Object)t).name, "UpperButtonHolder", StringComparison.OrdinalIgnoreCase) && ((Component)t).GetComponentsInChildren<Button>(true).Length >= 4));
			if ((Object)(object)val5 != (Object)null)
			{
				Transform parent2 = val5.parent;
				while ((Object)(object)parent2 != (Object)null)
				{
					if ((Object)(object)FindChildRecursive(parent2, "GameplayDisplay (To toggle)") != (Object)null)
					{
						_optionsScreen = ((Component)parent2).gameObject;
						Log.LogWarning((object)("[MODS UI] Options localizado por UpperButtonHolder: " + GetPath(parent2)));
						return _optionsScreen;
					}
					parent2 = parent2.parent;
				}
			}
			return null;
		}

		private static Transform FindChildDirect(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if (string.Equals(((Object)child).name, name, StringComparison.OrdinalIgnoreCase))
				{
					return child;
				}
			}
			return null;
		}

		private static Transform FindChildRecursive(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase))
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindChildRecursive(root.GetChild(i), name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static void ClearChildren(Transform root)
		{
			if (!((Object)(object)root == (Object)null))
			{
				for (int num = root.childCount - 1; num >= 0; num--)
				{
					Object.DestroyImmediate((Object)(object)((Component)root.GetChild(num)).gameObject);
				}
			}
		}

		private static void DisableLocalization(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && (((object)val).GetType().FullName ?? ((object)val).GetType().Name).IndexOf("LocalizeStringEvent", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.enabled = false;
					}
				}
			}
		}

		private static void SetFirstTmpText(GameObject root, string text)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text2 = ((object)val).GetType().FullName ?? "";
				if (text2 != "TMPro.TextMeshProUGUI" && text2 != "TMPro.TMP_Text")
				{
					continue;
				}
				PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				if (property != null && property.CanWrite)
				{
					try
					{
						property.SetValue(val, text);
						break;
					}
					catch
					{
					}
				}
			}
		}

		private static void SetPreferredRowTitle(GameObject row, string text)
		{
			if ((Object)(object)row == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = row.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (((object)val).GetType().FullName ?? "") != "TMPro.TextMeshProUGUI")
				{
					continue;
				}
				string text2 = ((Object)val.gameObject).name ?? "";
				if (text2.IndexOf("Title", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("Text", StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				PropertyInfo property = ((object)val).GetType().GetProperty("text");
				if (property != null && property.CanWrite)
				{
					try
					{
						property.SetValue(val, text);
						return;
					}
					catch
					{
					}
				}
			}
			SetFirstTmpText(row, text);
		}

		private static string GetPath(Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return "";
			}
			Stack<string> stack = new Stack<string>();
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				stack.Push(((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", stack);
		}

		private static string FormatNumericValue(object value, Type settingType)
		{
			if (value == null)
			{
				return "";
			}
			try
			{
				if (IsIntegralType(settingType))
				{
					return Convert.ToDecimal(value, CultureInfo.InvariantCulture).ToString("0", CultureInfo.InvariantCulture);
				}
				if (IsNumericType(settingType))
				{
					return Convert.ToDecimal(value, CultureInfo.InvariantCulture).ToString("0.##", CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
			return SafeString(value);
		}

		private static string SafeString(object value)
		{
			try
			{
				return value?.ToString() ?? "null";
			}
			catch
			{
				return "<ToString failed>";
			}
		}

		private static string Sanitize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return "Unknown";
			}
			return new string(value.Select((char ch) => (!char.IsLetterOrDigit(ch)) ? '_' : ch).ToArray());
		}
	}
}