Decompiled source of SettingsPlus v1.1.0

SettingsPlus.dll

Decompiled 18 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Fusion;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Localization;
using SSSGame.UI;
using SSSGame.Weather;
using SandSailorStudio.Localization;
using SandSailorStudio.UI;
using SandSailorStudio.WorldGen;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SettingsPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.0+73c92fd9f13dedca88f0d9075e047a3c248bbb9f")]
[assembly: AssemblyProduct("Settings Plus")]
[assembly: AssemblyTitle("SettingsPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 AskaSettingsPlus
{
	[HarmonyPatch(typeof(PauseMenu))]
	public static class PauseMenuButtonPatch
	{
		private const string CloneName = "SettingsPlus_MenuButton";

		private const string ButtonLabel = "Settings Plus";

		private const string SaveMethodName = "BtnSave";

		private static UnityAction _menuButtonClick;

		[HarmonyPostfix]
		[HarmonyPatch("OnActivate")]
		public static void OnActivate(PauseMenu __instance)
		{
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Expected O, but got Unknown
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				RectTransform buttonsPanel = __instance.buttonsPanel;
				if ((Object)(object)buttonsPanel == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[SettingsPlus] PauseMenu.buttonsPanel was null; cannot inject button.");
				}
				else
				{
					if (!SettingsPanel.IsHostOrSingleplayer())
					{
						return;
					}
					foreach (Transform componentsInChild in ((Component)buttonsPanel).GetComponentsInChildren<Transform>(true))
					{
						if (((Object)componentsInChild).name == "SettingsPlus_MenuButton")
						{
							return;
						}
					}
					Button[] array = Il2CppArrayBase<Button>.op_Implicit(((Component)buttonsPanel).GetComponentsInChildren<Button>(true));
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append("[SettingsPlus] buttons under buttonsPanel (count=").Append(array.Length).Append("):");
					Button val = null;
					foreach (Button val2 in array)
					{
						UnityEventBase onClick = (UnityEventBase)(object)val2.onClick;
						int persistentEventCount = onClick.GetPersistentEventCount();
						string[] array2 = new string[persistentEventCount];
						for (int j = 0; j < persistentEventCount; j++)
						{
							string text = (array2[j] = onClick.GetPersistentMethodName(j));
							if ((Object)(object)val == (Object)null && text == "BtnSave")
							{
								val = val2;
							}
						}
						stringBuilder.Append("\n  '").Append(((Object)((Component)val2).gameObject).name).Append("' activeSelf=")
							.Append(((Component)val2).gameObject.activeSelf)
							.Append(" onClick=")
							.Append((persistentEventCount == 0) ? "(none)" : string.Join(",", array2));
					}
					if ((Object)(object)val == (Object)null)
					{
						stringBuilder.Append("\n[SettingsPlus] No button with a '").Append("BtnSave").Append("' persistent listener found - not injecting.");
						Plugin.Log.LogWarning((object)stringBuilder.ToString());
						return;
					}
					if (Plugin.DebugLogging)
					{
						Plugin.Log.LogInfo((object)stringBuilder.ToString());
					}
					Transform transform = ((Component)val).transform;
					Transform parent = transform.parent;
					int siblingIndex = transform.GetSiblingIndex();
					GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
					((Object)val3).name = "SettingsPlus_MenuButton";
					val3.SetActive(true);
					foreach (LocalizedText componentsInChild2 in val3.GetComponentsInChildren<LocalizedText>(true))
					{
						if ((Object)(object)componentsInChild2 != (Object)null)
						{
							Object.DestroyImmediate((Object)(object)componentsInChild2);
						}
					}
					TMP_Text componentInChildren = val3.GetComponentInChildren<TMP_Text>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.text = "Settings Plus";
					}
					else
					{
						Plugin.Log.LogWarning((object)"[SettingsPlus] No TMP_Text found in the cloned button; label not set.");
					}
					Button val4 = val3.GetComponent<Button>() ?? val3.GetComponentInChildren<Button>(true);
					if ((Object)(object)val4 != (Object)null)
					{
						UnityEventBase onClick2 = (UnityEventBase)(object)val4.onClick;
						int persistentEventCount2 = onClick2.GetPersistentEventCount();
						for (int k = 0; k < persistentEventCount2; k++)
						{
							onClick2.SetPersistentListenerState(k, (UnityEventCallState)0);
						}
						onClick2.RemoveAllListeners();
						if ((Delegate)(object)_menuButtonClick == (Delegate)null)
						{
							_menuButtonClick = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)new Action(OnMenuButtonClicked));
						}
						((UnityEvent)val4.onClick).AddListener(_menuButtonClick);
					}
					else
					{
						Plugin.Log.LogWarning((object)"[SettingsPlus] No Button found in the cloned object; click handler not wired.");
					}
					val3.transform.SetSiblingIndex(siblingIndex);
					if (Plugin.DebugLogging)
					{
						ManualLogSource log = Plugin.Log;
						BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(63, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[SettingsPlus] Injected '");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>("Settings Plus");
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("' button before Save (sibling index ");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(siblingIndex);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(").");
						}
						log.LogInfo(val5);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val6 = new BepInExErrorLogInterpolatedStringHandler(54, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[SettingsPlus] Exception injecting pause-menu button: ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val6);
			}
		}

		private static void OnMenuButtonClicked()
		{
			if (Plugin.DebugLogging)
			{
				Plugin.Log.LogInfo((object)"[SettingsPlus] Settings Plus button clicked");
			}
			SettingsPanel.Open();
		}
	}
	[BepInPlugin("mugsy33.settingsplus", "Settings Plus", "1.1.0")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.settingsplus";

		public const string PluginName = "Settings Plus";

		public const string PluginVersion = "1.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ConfigEnabled;

		internal static readonly bool DebugLogging;

		public override void Load()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ConfigEnabled = ((BasePlugin)this).Config.Bind<bool>("SettingsPlus", "Enabled", true, "Master on/off switch for this tool.");
			ClassInjector.RegisterTypeInIl2Cpp<SettingsPanel>();
			GameObject val = new GameObject("SettingsPlus_Panel");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			SettingsPanel.Instance = val.AddComponent<SettingsPanel>();
			if (DebugLogging)
			{
				Log.LogInfo((object)"[SettingsPlus] SettingsPanel controller registered.");
			}
			Harmony.CreateAndPatchAll(typeof(PauseMenuButtonPatch), (string)null);
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Settings Plus");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.1.0");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded.");
			}
			log.LogInfo(val2);
		}
	}
	public class SettingsPanel : MonoBehaviour
	{
		private sealed class KnobRow
		{
			public RectTransform Rect;

			public string Title;

			public string Description;
		}

		private sealed class RenderedSection
		{
			public WorldCustomizationSection Section;

			public string TitleKey;

			public string Title;

			public readonly List<WorldCustomizationCategory> Categories = new List<WorldCustomizationCategory>();
		}

		private const string Tag = "[SettingsPlus]";

		private const float RowHeight = 60f;

		private const float HeaderHeight = 48f;

		private const float HeaderFontSize = 32f;

		private const float TabHeight = 52f;

		private const float CategTabHeight = 41.600002f;

		private const float ItemFontScale = 1.18f;

		private const float SectionRowTop = 108f;

		private const float CategColumnWidth = 250f;

		private const float IconSlot = 34f;

		private const float SelectedUnderline = 3f;

		private const float SectionRowHeight = 64f;

		private const float CategoryScale = 0.8f;

		private const float SectionTabTextSize = 22f;

		private const float BannerHeight = 52f;

		internal static readonly string[] AllowedSectionKeys = new string[8] { "custom.difficulty", "custom.world", "custom.start.villager.survival", "custom.start.blueprints", "custom.win.conditions", "Vegetation", "custom.start.conditions", "custom.start.villagers.proficiencies" };

		private static readonly string[] DevExtraSectionKeys = new string[2] { "custom.start.villagers", "custom.start.items" };

		internal static readonly bool ShowStartOnlySections = false;

		private static readonly Dictionary<string, string[]> SectionCategoryAllowlist = new Dictionary<string, string[]>
		{
			["custom.world"] = new string[3] { "custom.weather", "custom.wildlife", "misc.fishing" },
			["Vegetation"] = new string[2] { "custom.vegetables", "misc.farming" },
			["custom.start.conditions"] = new string[2] { "custom.player.stats", "custom.player.affinities" },
			["custom.start.villagers.proficiencies"] = new string[1] { "custom.villager.affinities" }
		};

		private static readonly string[] DeniedKnobNameKeys = new string[1] { "worldcustomization.mi_difficulty_weather_startseason" };

		private static readonly string[] ReloadOnlyCategoryKeys = new string[4] { "custom.villager.survival", "custom.player.stats", "custom.player.affinities", "custom.villager.affinities" };

		private static readonly Dictionary<string, string> SectionTitleOverrides = new Dictionary<string, string>
		{
			["custom.start.villager.survival"] = "Villager",
			["custom.start.villagers.proficiencies"] = "Villager"
		};

		private static readonly Dictionary<string, string> CategoryTitleOverrides = new Dictionary<string, string>
		{
			["custom.player.stats"] = "Stats",
			["custom.villager.survival"] = "Stats",
			["custom.vegetables"] = "Plants"
		};

		private static readonly Dictionary<string, string> WithheldCategoryReasons = new Dictionary<string, string>
		{
			["custom.player.proficiencies"] = "would overwrite skills you have earned",
			["custom.villager.proficiencies"] = "would overwrite skills you have earned"
		};

		private static readonly Dictionary<string, int> CategoryOrder = new Dictionary<string, int>
		{
			["custom.villager.survival"] = 0,
			["custom.villager.affinities"] = 1,
			["custom.player.stats"] = 0,
			["custom.player.affinities"] = 1
		};

		private static readonly string[] RedundantCategoryPrefixes = new string[2] { "Player ", "Villager " };

		private static readonly Color ScreenBackground = new Color(0.043f, 0.067f, 0.11f, 1f);

		private static readonly Color PanelBackground = new Color(0.055f, 0.082f, 0.129f, 0.98f);

		private static readonly Color TabUnselected = new Color(0.07f, 0.102f, 0.157f, 1f);

		private static readonly Color TabSelected = new Color(0.42f, 0.32f, 0.11f, 1f);

		private static readonly Color GoldAccent = new Color(0.788f, 0.643f, 0.153f, 1f);

		private static readonly Color TabStroke = new Color(1f, 1f, 1f, 0.28f);

		private static readonly Color CategTabUnselected = new Color(0.078f, 0.114f, 0.176f, 1f);

		private static readonly Color CategTabSelected = new Color(0.42f, 0.32f, 0.11f, 1f);

		private static readonly Color CategStripBackground = new Color(0.051f, 0.075f, 0.118f, 0.98f);

		public static SettingsPanel Instance;

		private GameObject _overlay;

		private RectTransform _contentRect;

		private RectTransform _tabStripRect;

		private RectTransform _categStripRect;

		private TextMeshProUGUI _titleText;

		private readonly List<UnityAction> _tabActions = new List<UnityAction>();

		private readonly List<Image> _tabHighlights = new List<Image>();

		private readonly List<Image> _tabUnderlines = new List<Image>();

		private readonly List<Image> _tabIcons = new List<Image>();

		private readonly List<RenderedSection> _renderedSections = new List<RenderedSection>();

		private readonly List<UnityAction> _categActions = new List<UnityAction>();

		private readonly List<Image> _categHighlights = new List<Image>();

		private readonly List<Image> _categUnderlines = new List<Image>();

		private readonly List<Image> _categIcons = new List<Image>();

		private readonly List<Image> _headerIcons = new List<Image>();

		private readonly List<WorldCustomizationCategory> _currentCategories = new List<WorldCustomizationCategory>();

		private IconTextPairComponent _categHeaderPrefab;

		private static UnityAction _closeClick;

		private readonly List<KnobRow> _rows = new List<KnobRow>();

		private RectTransform _viewportRect;

		private GameObject _tooltipGo;

		private RectTransform _tooltipRect;

		private TMP_Text _tooltipLabel;

		private TMP_Text _tooltipTitle;

		private bool _tooltipUnavailable;

		private KnobRow _hoveredRow;

		private RectTransform _bannerRect;

		private float _nextBannerCheck;

		private static readonly Vector2 TooltipCursorOffset = new Vector2(18f, -18f);

		private const string CompositeJoin = " - ";

		private readonly Dictionary<int, int> _levelsAtOpen = new Dictionary<int, int>();

		private readonly Dictionary<int, string> _knobCategory = new Dictionary<int, string>();

		private readonly List<int> _costLevelsAtOpen = new List<int>();

		private GameCustomizationManager _costManager;

		internal static bool IsDeniedKnob(string nameKey)
		{
			for (int i = 0; i < DeniedKnobNameKeys.Length; i++)
			{
				if (DeniedKnobNameKeys[i] == nameKey)
				{
					return true;
				}
			}
			return false;
		}

		[HideFromIl2Cpp]
		internal static string WithheldReason(string categoryKey)
		{
			if (!WithheldCategoryReasons.TryGetValue(categoryKey ?? string.Empty, out var value))
			{
				return string.Empty;
			}
			return value;
		}

		[HideFromIl2Cpp]
		private static void SortCategories(List<WorldCustomizationCategory> categories)
		{
			for (int i = 1; i < categories.Count; i++)
			{
				WorldCustomizationCategory val = categories[i];
				int num = CategoryRank(val);
				int num2 = i - 1;
				while (num2 >= 0 && CategoryRank(categories[num2]) > num)
				{
					categories[num2 + 1] = categories[num2];
					num2--;
				}
				categories[num2 + 1] = val;
			}
		}

		[HideFromIl2Cpp]
		internal static int CategoryRankOf(WorldCustomizationCategory cat)
		{
			return CategoryRank(cat);
		}

		[HideFromIl2Cpp]
		private static int CategoryRank(WorldCustomizationCategory cat)
		{
			if (!CategoryOrder.TryGetValue(((cat != null) ? cat.titleKey : null) ?? string.Empty, out var value))
			{
				return int.MaxValue;
			}
			return value;
		}

		[HideFromIl2Cpp]
		internal static string SectionLabel(string titleKey)
		{
			if (!SectionTitleOverrides.TryGetValue(titleKey ?? string.Empty, out var value))
			{
				return Localize(titleKey);
			}
			return value;
		}

		[HideFromIl2Cpp]
		internal static string CategoryLabel(string titleKey)
		{
			if (CategoryTitleOverrides.TryGetValue(titleKey ?? string.Empty, out var value))
			{
				return value;
			}
			string text = Localize(titleKey);
			for (int i = 0; i < RedundantCategoryPrefixes.Length; i++)
			{
				string text2 = RedundantCategoryPrefixes[i];
				if (text.Length > text2.Length && text.StartsWith(text2, StringComparison.Ordinal))
				{
					return text.Substring(text2.Length);
				}
			}
			return text;
		}

		internal static bool IsReloadOnlyCategory(string categoryKey)
		{
			for (int i = 0; i < ReloadOnlyCategoryKeys.Length; i++)
			{
				if (ReloadOnlyCategoryKeys[i] == categoryKey)
				{
					return true;
				}
			}
			return false;
		}

		private static void Log(string msg)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (Plugin.DebugLogging)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(1, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(msg);
				}
				log.LogInfo(val);
			}
		}

		private static void Warn(string msg)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(1, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(msg);
			}
			log.LogWarning(val);
		}

		internal static string Localize(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return string.Empty;
			}
			if (key.IndexOf('+') >= 0)
			{
				return LocalizeComposite(key);
			}
			try
			{
				LocalizationManager instance = LocalizationManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					string text = instance.Loc(key, false);
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			catch (Exception ex)
			{
				Warn("Loc('" + key + "') threw: " + ex.Message);
			}
			return key;
		}

		[HideFromIl2Cpp]
		private static string LocalizeComposite(string key)
		{
			string[] array = key.Split('+');
			List<string> list = new List<string>(array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					string text2 = Localize(text);
					if (!string.IsNullOrEmpty(text2))
					{
						list.Add(text2);
					}
				}
			}
			if (list.Count <= 0)
			{
				return key;
			}
			return string.Join(" - ", list);
		}

		public static void Open()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			try
			{
				if ((Object)(object)Instance == (Object)null)
				{
					Warn("Open() called but SettingsPanel.Instance is null.");
				}
				else
				{
					Instance.OpenInternal();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(13, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Open threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		public static bool IsHostOrSingleplayer()
		{
			try
			{
				NetworkRunner val = Object.FindObjectOfType<NetworkRunner>();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				return val.IsServer || val.IsSharedModeMasterClient;
			}
			catch (Exception ex)
			{
				Warn("host check threw: " + ex.Message);
				return false;
			}
		}

		private void OpenInternal()
		{
			if (!IsHostOrSingleplayer())
			{
				Warn("host-only; not opening for a non-host client.");
				return;
			}
			SnapshotCostLevels();
			SnapshotKnobLevels();
			if ((Object)(object)_overlay == (Object)null)
			{
				BuildOverlay();
			}
			_overlay.SetActive(true);
			RebuildTabs();
			Log("overlay opened.");
		}

		private void BuildOverlay()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b7: Expected O, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Expected O, but got Unknown
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Expected O, but got Unknown
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Expected O, but got Unknown
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Expected O, but got Unknown
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_060b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_067d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Expected O, but got Unknown
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0708: Unknown result type (might be due to invalid IL or missing references)
			//IL_0722: Unknown result type (might be due to invalid IL or missing references)
			//IL_0745: Unknown result type (might be due to invalid IL or missing references)
			//IL_074f: Expected O, but got Unknown
			try
			{
				_overlay = new GameObject("SettingsPlus_Overlay");
				Object.DontDestroyOnLoad((Object)(object)_overlay);
				Canvas obj = _overlay.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 32000;
				CanvasScaler obj2 = _overlay.AddComponent<CanvasScaler>();
				obj2.uiScaleMode = (ScaleMode)1;
				obj2.referenceResolution = new Vector2(1600f, 900f);
				obj2.screenMatchMode = (ScreenMatchMode)0;
				obj2.matchWidthOrHeight = 0.5f;
				_overlay.AddComponent<GraphicRaycaster>();
				GameObject val = new GameObject("Background");
				RectTransform obj3 = val.AddComponent<RectTransform>();
				((Transform)obj3).SetParent(_overlay.transform, false);
				obj3.anchorMin = Vector2.zero;
				obj3.anchorMax = Vector2.one;
				obj3.offsetMin = Vector2.zero;
				obj3.offsetMax = Vector2.zero;
				((Graphic)val.AddComponent<Image>()).color = ScreenBackground;
				GameObject val2 = new GameObject("Title");
				RectTransform obj4 = val2.AddComponent<RectTransform>();
				((Transform)obj4).SetParent(_overlay.transform, false);
				obj4.anchorMin = new Vector2(0.5f, 1f);
				obj4.anchorMax = new Vector2(0.5f, 1f);
				obj4.pivot = new Vector2(0.5f, 1f);
				obj4.anchoredPosition = new Vector2(0f, -40f);
				obj4.sizeDelta = new Vector2(700f, 60f);
				TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val3).text = "Settings Plus";
				((TMP_Text)val3).fontSize = 40f;
				((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
				_titleText = val3;
				GameObject val4 = new GameObject("CloseButton");
				RectTransform obj5 = val4.AddComponent<RectTransform>();
				((Transform)obj5).SetParent(_overlay.transform, false);
				obj5.anchorMin = new Vector2(1f, 1f);
				obj5.anchorMax = new Vector2(1f, 1f);
				obj5.pivot = new Vector2(1f, 1f);
				obj5.anchoredPosition = new Vector2(-20f, -20f);
				obj5.sizeDelta = new Vector2(130f, 48f);
				Image val5 = val4.AddComponent<Image>();
				((Graphic)val5).color = new Color(0.545f, 0.125f, 0.125f, 1f);
				Button obj6 = val4.AddComponent<Button>();
				((Selectable)obj6).targetGraphic = (Graphic)(object)val5;
				GameObject val6 = new GameObject("Label");
				RectTransform obj7 = val6.AddComponent<RectTransform>();
				((Transform)obj7).SetParent(val4.transform, false);
				obj7.anchorMin = Vector2.zero;
				obj7.anchorMax = Vector2.one;
				obj7.offsetMin = Vector2.zero;
				obj7.offsetMax = Vector2.zero;
				TextMeshProUGUI obj8 = val6.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj8).text = "CLOSE";
				((TMP_Text)obj8).fontSize = 24f;
				((TMP_Text)obj8).alignment = (TextAlignmentOptions)514;
				if ((Delegate)(object)_closeClick == (Delegate)null)
				{
					_closeClick = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)new Action(OnCloseClicked));
				}
				((UnityEvent)obj6.onClick).AddListener(_closeClick);
				GameObject val7 = new GameObject("TabStrip");
				_tabStripRect = val7.AddComponent<RectTransform>();
				((Transform)_tabStripRect).SetParent(_overlay.transform, false);
				_tabStripRect.anchorMin = new Vector2(0f, 1f);
				_tabStripRect.anchorMax = new Vector2(1f, 1f);
				_tabStripRect.pivot = new Vector2(0.5f, 1f);
				_tabStripRect.offsetMin = new Vector2(30f, 0f);
				_tabStripRect.offsetMax = new Vector2(-30f, 0f);
				_tabStripRect.anchoredPosition = new Vector2(0f, -108f);
				_tabStripRect.sizeDelta = new Vector2(_tabStripRect.sizeDelta.x, 64f);
				((Graphic)val7.AddComponent<Image>()).color = PanelBackground;
				HorizontalLayoutGroup obj9 = val7.AddComponent<HorizontalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj9).spacing = 8f;
				((LayoutGroup)obj9).padding = new RectOffset(8, 8, 6, 6);
				((HorizontalOrVerticalLayoutGroup)obj9).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj9).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj9).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj9).childForceExpandHeight = true;
				GameObject val8 = new GameObject("CategStrip");
				_categStripRect = val8.AddComponent<RectTransform>();
				((Transform)_categStripRect).SetParent(_overlay.transform, false);
				_categStripRect.anchorMin = new Vector2(0f, 0f);
				_categStripRect.anchorMax = new Vector2(0f, 1f);
				_categStripRect.pivot = new Vector2(0f, 1f);
				_categStripRect.offsetMin = new Vector2(30f, 76f);
				_categStripRect.offsetMax = new Vector2(280f, -190f);
				((Graphic)val8.AddComponent<Image>()).color = CategStripBackground;
				VerticalLayoutGroup obj10 = val8.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj10).spacing = 6f;
				((LayoutGroup)obj10).padding = new RectOffset(8, 8, 8, 8);
				((HorizontalOrVerticalLayoutGroup)obj10).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj10).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj10).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj10).childForceExpandHeight = false;
				GameObject val9 = new GameObject("Frame");
				RectTransform val10 = val9.AddComponent<RectTransform>();
				((Transform)val10).SetParent(_overlay.transform, false);
				val10.anchorMin = new Vector2(0f, 0f);
				val10.anchorMax = new Vector2(1f, 1f);
				val10.pivot = new Vector2(0.5f, 0.5f);
				val10.offsetMin = new Vector2(298f, 76f);
				val10.offsetMax = new Vector2(-30f, -190f);
				((Graphic)val9.AddComponent<Image>()).color = PanelBackground;
				ScrollRect obj11 = val9.AddComponent<ScrollRect>();
				obj11.horizontal = false;
				obj11.vertical = true;
				obj11.movementType = (MovementType)2;
				obj11.scrollSensitivity = 30f;
				GameObject val11 = new GameObject("Viewport");
				RectTransform val12 = val11.AddComponent<RectTransform>();
				((Transform)val12).SetParent((Transform)(object)val10, false);
				val12.anchorMin = Vector2.zero;
				val12.anchorMax = Vector2.one;
				val12.pivot = new Vector2(0f, 1f);
				val12.offsetMin = new Vector2(8f, 8f);
				val12.offsetMax = new Vector2(-8f, -8f);
				((Graphic)val11.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.35f);
				val11.AddComponent<RectMask2D>();
				GameObject val13 = new GameObject("Content");
				_contentRect = val13.AddComponent<RectTransform>();
				((Transform)_contentRect).SetParent((Transform)(object)val12, false);
				_contentRect.anchorMin = new Vector2(0f, 1f);
				_contentRect.anchorMax = new Vector2(1f, 1f);
				_contentRect.pivot = new Vector2(0.5f, 1f);
				_contentRect.anchoredPosition = Vector2.zero;
				_contentRect.sizeDelta = new Vector2(0f, 0f);
				VerticalLayoutGroup obj12 = val13.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj12).spacing = 8f;
				((LayoutGroup)obj12).padding = new RectOffset(12, 12, 8, 8);
				((HorizontalOrVerticalLayoutGroup)obj12).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj12).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj12).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj12).childForceExpandHeight = false;
				val13.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
				obj11.viewport = val12;
				obj11.content = _contentRect;
				_viewportRect = val12;
				BuildReloadBanner();
				Log("overlay built (Canvas ScreenSpaceOverlay ScaleWithScreenSize 1600x900, sortingOrder=32000, section row + category row + scrollable content frame + reload banner).");
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val14 = new BepInExErrorLogInterpolatedStringHandler(21, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val14).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val14).AppendLiteral(" BuildOverlay threw: ");
					((BepInExLogInterpolatedStringHandler)val14).AppendFormatted<Exception>(ex);
				}
				log.LogError(val14);
			}
		}

		private static void ClearChildren(RectTransform rt)
		{
			if ((Object)(object)rt == (Object)null)
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < ((Transform)rt).childCount; i++)
			{
				list.Add(((Component)((Transform)rt).GetChild(i)).gameObject);
			}
			foreach (GameObject item in list)
			{
				Object.DestroyImmediate((Object)(object)item);
			}
		}

		private void ClearContent()
		{
			_rows.Clear();
			HideTooltip();
			ClearChildren(_contentRect);
		}

		private void RebuildTabs()
		{
			_tabActions.Clear();
			_tabHighlights.Clear();
			_tabUnderlines.Clear();
			_tabIcons.Clear();
			_renderedSections.Clear();
			ClearChildren(_tabStripRect);
			ClearContent();
			WorldCustomizationConfig active;
			try
			{
				active = WorldCustomizationConfig.GetActive();
			}
			catch (Exception ex)
			{
				Warn("GetActive threw: " + ex.Message + " - no config to render.");
				return;
			}
			if ((Object)(object)active == (Object)null)
			{
				Warn("no active WorldCustomizationConfig (not in a loaded save?).");
				return;
			}
			List<WorldCustomizationSection> sections = active.sections;
			if (sections == null)
			{
				Warn("config has no sections.");
				return;
			}
			for (int i = 0; i < sections.Count; i++)
			{
				WorldCustomizationSection val = sections[i];
				if (val == null)
				{
					continue;
				}
				string text = val.titleKey ?? string.Empty;
				if (!IsAllowedSection(text))
				{
					continue;
				}
				if (val.isHidden)
				{
					Log("section '" + text + "' isHidden - skipped.");
					continue;
				}
				if (!SectionHasRenderableKnobs(active, val, text))
				{
					Log("section '" + text + "' has no renderable knobs - skipped.");
					continue;
				}
				string text2 = SectionLabel(text);
				RenderedSection renderedSection = null;
				for (int j = 0; j < _renderedSections.Count; j++)
				{
					if (_renderedSections[j].Title == text2)
					{
						renderedSection = _renderedSections[j];
						break;
					}
				}
				bool flag = renderedSection == null;
				if (flag)
				{
					renderedSection = new RenderedSection
					{
						Section = val,
						TitleKey = text,
						Title = text2
					};
				}
				List<WorldCustomizationCategory> categories = val.categories;
				int num = 0;
				while (categories != null && num < categories.Count)
				{
					WorldCustomizationCategory val2 = categories[num];
					if (ShouldShowCategory(text, val2))
					{
						renderedSection.Categories.Add(val2);
					}
					num++;
				}
				if (flag && renderedSection.Categories.Count > 0)
				{
					_renderedSections.Add(renderedSection);
				}
			}
			for (int k = 0; k < _renderedSections.Count; k++)
			{
				SortCategories(_renderedSections[k].Categories);
			}
			Log($"rendered sections = {_renderedSections.Count}.");
			if (_renderedSections.Count == 0)
			{
				Warn("no allowlisted sections present in the active config.");
				return;
			}
			for (int l = 0; l < _renderedSections.Count; l++)
			{
				try
				{
					BuildTabEntry(_renderedSections[l], l);
				}
				catch (Exception ex2)
				{
					Warn($"BuildTabEntry[{l}] '{_renderedSections[l].TitleKey}' threw: {ex2.GetType().Name}: {ex2.Message}");
				}
			}
			Log($"tabs built = {_tabHighlights.Count}.");
			ApplyGameFontToTitle();
			SelectSection(0);
		}

		[HideFromIl2Cpp]
		internal static bool IsSectionAllowed(string key)
		{
			return IsAllowedSection(key);
		}

		[HideFromIl2Cpp]
		internal static bool SectionHasAnyRenderableKnob(WorldCustomizationConfig cfg, WorldCustomizationSection section, string sectionKey)
		{
			return SectionHasRenderableKnobs(cfg, section, sectionKey);
		}

		private static bool IsAllowedSection(string key)
		{
			for (int i = 0; i < AllowedSectionKeys.Length; i++)
			{
				if (AllowedSectionKeys[i] == key)
				{
					return true;
				}
			}
			if (ShowStartOnlySections)
			{
				for (int j = 0; j < DevExtraSectionKeys.Length; j++)
				{
					if (DevExtraSectionKeys[j] == key)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool SectionHasRenderableKnobs(WorldCustomizationConfig cfg, WorldCustomizationSection section, string sectionKey)
		{
			List<WorldCustomizationCategory> categories = section.categories;
			if (categories == null)
			{
				return false;
			}
			for (int i = 0; i < categories.Count; i++)
			{
				WorldCustomizationCategory val = categories[i];
				if (val == null || !ShouldShowCategory(sectionKey, val))
				{
					continue;
				}
				List<int> items = val.items;
				if (items == null)
				{
					continue;
				}
				for (int j = 0; j < items.Count; j++)
				{
					try
					{
						WorldCustomizationData data = cfg.GetData(items[j]);
						if (!((Object)(object)data == (Object)null) && !data.isHidden && !string.IsNullOrEmpty(data.nameKey) && !IsDeniedKnob(data.nameKey))
						{
							WorldCustomizationSelector val2 = ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>();
							if ((Object)(object)val2 != (Object)null && (Object)(object)val2.parent == (Object)null)
							{
								return true;
							}
						}
					}
					catch
					{
					}
				}
			}
			return false;
		}

		[HideFromIl2Cpp]
		private void BuildTabEntry(RenderedSection rs, int index)
		{
			//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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			string title = rs.Title;
			GameObject val = new GameObject("Tab_" + rs.TitleKey);
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)_tabStripRect, false);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = TabUnselected;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredHeight = 52f;
			obj.minHeight = 52f;
			obj.flexibleWidth = 1f;
			AddIconSlot(val2, _tabIcons);
			AddStroke(val2, TabStroke, 1f);
			GameObject val5 = new GameObject("Label");
			RectTransform obj2 = val5.AddComponent<RectTransform>();
			((Transform)obj2).SetParent((Transform)(object)val2, false);
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(52f, 4f);
			obj2.offsetMax = new Vector2(-8f, -4f);
			TextMeshProUGUI val6 = val5.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val6).text = title;
			((TMP_Text)val6).fontSize = 22f;
			((TMP_Text)val6).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val6).enableWordWrapping = false;
			((TMP_Text)val6).overflowMode = (TextOverflowModes)1;
			((Graphic)val6).raycastTarget = false;
			ApplyGameFontToLabel((TMP_Text)(object)val6);
			_tabUnderlines.Add(AddSelectedUnderline(val2));
			UnityAction val7 = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
			{
				SelectSection(index);
			});
			_tabActions.Add(val7);
			((UnityEvent)val4.onClick).AddListener(val7);
			_tabHighlights.Add(val3);
		}

		private void SelectSection(int index)
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (index < 0 || index >= _renderedSections.Count)
				{
					Warn($"SelectSection({index}) out of range (count={_renderedSections.Count}).");
					return;
				}
				for (int i = 0; i < _tabHighlights.Count; i++)
				{
					if ((Object)(object)_tabHighlights[i] != (Object)null)
					{
						((Graphic)_tabHighlights[i]).color = ((i == index) ? TabSelected : TabUnselected);
					}
					if (i < _tabUnderlines.Count && (Object)(object)_tabUnderlines[i] != (Object)null)
					{
						((Component)_tabUnderlines[i]).gameObject.SetActive(i == index);
					}
				}
				BuildCategoryStrip(_renderedSections[index]);
				Log($"selected section {index} '{_renderedSections[index].TitleKey}'.");
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" SelectSection(");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(index);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		[HideFromIl2Cpp]
		private void BuildCategoryStrip(RenderedSection rs)
		{
			_headerIcons.Clear();
			_categActions.Clear();
			_categHighlights.Clear();
			_categUnderlines.Clear();
			_categIcons.Clear();
			_currentCategories.Clear();
			ClearChildren(_categStripRect);
			ClearContent();
			for (int i = 0; i < rs.Categories.Count; i++)
			{
				_currentCategories.Add(rs.Categories[i]);
			}
			for (int j = 0; j < _currentCategories.Count; j++)
			{
				try
				{
					BuildCategoryTab(_currentCategories[j], j);
				}
				catch (Exception ex)
				{
					Warn($"BuildCategoryTab[{j}] threw: {ex.GetType().Name}: {ex.Message}");
				}
			}
			Log($"section '{rs.TitleKey}': category tabs built = {_categHighlights.Count}.");
			if (_currentCategories.Count > 0)
			{
				SelectCategory(0);
			}
			else
			{
				Warn("section '" + rs.TitleKey + "' has no shown categories to tab.");
			}
		}

		private void BuildCategoryTab(WorldCustomizationCategory cat, int index)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			string text = CategoryLabel(cat.titleKey);
			GameObject val = new GameObject("CatTab_" + cat.titleKey);
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)_categStripRect, false);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = CategTabUnselected;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredHeight = 41.600002f;
			obj.minHeight = 41.600002f;
			obj.flexibleWidth = 1f;
			AddIconSlot(val2, _categIcons);
			AddStroke(val2, TabStroke, 1f);
			GameObject val5 = new GameObject("Label");
			RectTransform obj2 = val5.AddComponent<RectTransform>();
			((Transform)obj2).SetParent((Transform)(object)val2, false);
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(50f, 3f);
			obj2.offsetMax = new Vector2(-6f, -3f);
			TextMeshProUGUI val6 = val5.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val6).text = text;
			((TMP_Text)val6).fontSize = 17.6f;
			((TMP_Text)val6).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val6).enableWordWrapping = false;
			((TMP_Text)val6).overflowMode = (TextOverflowModes)1;
			((Graphic)val6).raycastTarget = false;
			ApplyGameFontToLabel((TMP_Text)(object)val6);
			_categUnderlines.Add(AddSelectedUnderline(val2));
			UnityAction val7 = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
			{
				SelectCategory(index);
			});
			_categActions.Add(val7);
			((UnityEvent)val4.onClick).AddListener(val7);
			_categHighlights.Add(val3);
		}

		private void SelectCategory(int index)
		{
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_009d: 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)
			try
			{
				if (index < 0 || index >= _currentCategories.Count)
				{
					Warn($"SelectCategory({index}) out of range (count={_currentCategories.Count}).");
					return;
				}
				for (int i = 0; i < _categHighlights.Count; i++)
				{
					if ((Object)(object)_categHighlights[i] != (Object)null)
					{
						((Graphic)_categHighlights[i]).color = ((i == index) ? CategTabSelected : CategTabUnselected);
					}
					if (i < _categUnderlines.Count && (Object)(object)_categUnderlines[i] != (Object)null)
					{
						((Component)_categUnderlines[i]).gameObject.SetActive(i == index);
					}
				}
				ClearContent();
				WorldCustomizationConfig active;
				try
				{
					active = WorldCustomizationConfig.GetActive();
				}
				catch (Exception ex)
				{
					Warn("GetActive threw during render: " + ex.Message + ".");
					return;
				}
				if ((Object)(object)active == (Object)null)
				{
					Warn("no active config during render.");
					return;
				}
				WorldCustomizationCategory val = _currentCategories[index];
				int value = RenderCategory(active, val);
				Log($"selected category {index} '{val.titleKey}': knobs rendered = {value}.");
			}
			catch (Exception ex2)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" SelectCategory(");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(index);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
				}
				log.LogError(val2);
			}
		}

		private int RenderCategory(WorldCustomizationConfig cfg, WorldCustomizationCategory cat)
		{
			string value = Localize(cat.titleKey);
			AddStyledCategoryHeader(cat);
			List<int> items = cat.items;
			int value2 = items?.Count ?? 0;
			int num = 0;
			int num2 = 0;
			if (items != null)
			{
				for (int i = 0; i < items.Count; i++)
				{
					int num3 = items[i];
					try
					{
						WorldCustomizationData data = cfg.GetData(num3);
						if ((Object)(object)data == (Object)null)
						{
							Warn($"knob id={num3}: GetData returned null; skipping.");
							num2++;
							continue;
						}
						if (data.isHidden)
						{
							num2++;
							continue;
						}
						string text = data.nameKey ?? string.Empty;
						if (string.IsNullOrEmpty(text) || IsDeniedKnob(text))
						{
							num2++;
							continue;
						}
						WorldCustomizationSelector val = ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>();
						if ((Object)(object)val == (Object)null)
						{
							Log($"knob id={num3} nameKey='{text}': not a WorldCustomizationSelector; skipping.");
							num2++;
						}
						else if ((Object)(object)val.parent != (Object)null)
						{
							num2++;
						}
						else if (AddKnobRow(num3, val, text))
						{
							num++;
						}
						else
						{
							num2++;
						}
					}
					catch (Exception ex)
					{
						Warn($"knob id={num3} threw: {ex.GetType().Name}: {ex.Message}");
						num2++;
					}
				}
			}
			Log($"category '{cat.titleKey}' ({value}) items={value2} shown={num} skipped={num2}.");
			return num;
		}

		internal static bool ShouldShowCategory(string sectionKey, WorldCustomizationCategory cat)
		{
			if (cat == null)
			{
				return false;
			}
			if (cat.isHidden)
			{
				return false;
			}
			if (!SectionCategoryAllowlist.TryGetValue(sectionKey, out var value))
			{
				return true;
			}
			string text = cat.titleKey ?? string.Empty;
			for (int i = 0; i < value.Length; i++)
			{
				if (value[i] == text)
				{
					return true;
				}
			}
			return false;
		}

		private IconTextPairComponent GetCategHeaderPrefab()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_categHeaderPrefab != (Object)null)
			{
				return _categHeaderPrefab;
			}
			try
			{
				Il2CppArrayBase<WorldCustomizationSectionTabPage> val = Resources.FindObjectsOfTypeAll<WorldCustomizationSectionTabPage>();
				IconTextPairComponent val2 = null;
				for (int i = 0; i < val.Length; i++)
				{
					WorldCustomizationSectionTabPage val3 = val[i];
					if ((Object)(object)val3 == (Object)null)
					{
						continue;
					}
					IconTextPairComponent val4 = null;
					try
					{
						val4 = val3.categHeaderPrefab;
					}
					catch
					{
					}
					if (!((Object)(object)val4 == (Object)null))
					{
						if ((Object)(object)val2 == (Object)null)
						{
							val2 = val4;
						}
						bool flag = false;
						try
						{
							Scene scene = ((Component)val3).gameObject.scene;
							flag = !((Scene)(ref scene)).IsValid();
						}
						catch
						{
						}
						if (flag)
						{
							_categHeaderPrefab = val4;
							break;
						}
					}
				}
				if ((Object)(object)_categHeaderPrefab == (Object)null)
				{
					_categHeaderPrefab = val2;
				}
			}
			catch (Exception ex)
			{
				Warn("GetCategHeaderPrefab threw: " + ex.Message + ".");
			}
			Log("categHeaderPrefab obtained = " + (((Object)(object)_categHeaderPrefab != (Object)null) ? "yes" : "no") + ".");
			return _categHeaderPrefab;
		}

		private void ApplyGameFontToTitle()
		{
			if ((Object)(object)_titleText != (Object)null)
			{
				ApplyGameFontToLabel((TMP_Text)(object)_titleText);
			}
		}

		private void ApplyGameFontToLabel(TMP_Text label)
		{
			if ((Object)(object)label == (Object)null)
			{
				return;
			}
			IconTextPairComponent categHeaderPrefab = GetCategHeaderPrefab();
			if ((Object)(object)categHeaderPrefab == (Object)null)
			{
				return;
			}
			try
			{
				TMP_Text componentInChildren = ((Component)categHeaderPrefab).GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.font != (Object)null)
				{
					label.font = componentInChildren.font;
				}
			}
			catch (Exception ex)
			{
				Warn("font copy failed: " + ex.Message);
			}
		}

		[HideFromIl2Cpp]
		private static void AddStroke(RectTransform parent, Color color, float thickness)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			AddStrokeEdge(parent, color, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, 0f - thickness), Vector2.zero);
			AddStrokeEdge(parent, color, new Vector2(0f, 0f), new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, thickness));
			AddStrokeEdge(parent, color, new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero, new Vector2(thickness, 0f));
			AddStrokeEdge(parent, color, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f - thickness, 0f), Vector2.zero);
		}

		[HideFromIl2Cpp]
		private static void AddStrokeEdge(RectTransform parent, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Stroke");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			obj.anchorMin = anchorMin;
			obj.anchorMax = anchorMax;
			obj.offsetMin = offsetMin;
			obj.offsetMax = offsetMax;
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = color;
			((Graphic)obj2).raycastTarget = false;
		}

		[HideFromIl2Cpp]
		private static void AddIconSlot(RectTransform parent, List<Image> into)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Icon");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			obj.anchorMin = new Vector2(0f, 0.5f);
			obj.anchorMax = new Vector2(0f, 0.5f);
			obj.pivot = new Vector2(0f, 0.5f);
			obj.anchoredPosition = new Vector2(12f, 0f);
			obj.sizeDelta = new Vector2(34f, 34f);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).raycastTarget = false;
			((Behaviour)val2).enabled = false;
			into.Add(val2);
		}

		[HideFromIl2Cpp]
		private static Image AddSelectedUnderline(RectTransform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Underline");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			obj.anchorMin = new Vector2(0f, 0f);
			obj.anchorMax = new Vector2(1f, 0f);
			obj.pivot = new Vector2(0.5f, 0f);
			obj.offsetMin = Vector2.zero;
			obj.offsetMax = new Vector2(0f, 3f);
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = GoldAccent;
			((Graphic)obj2).raycastTarget = false;
			val.SetActive(false);
			return obj2;
		}

		[HideFromIl2Cpp]
		private void BuildReloadBanner()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003e: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ReloadBanner");
			_bannerRect = val.AddComponent<RectTransform>();
			((Transform)_bannerRect).SetParent(_overlay.transform, false);
			_bannerRect.anchorMin = new Vector2(0f, 0f);
			_bannerRect.anchorMax = new Vector2(1f, 0f);
			_bannerRect.pivot = new Vector2(0.5f, 0f);
			_bannerRect.offsetMin = new Vector2(30f, 12f);
			_bannerRect.offsetMax = new Vector2(-30f, 64f);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.3f, 0.22f, 0.06f, 0.98f);
			GameObject val2 = new GameObject("Label");
			RectTransform obj = val2.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)_bannerRect, false);
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(16f, 4f);
			obj.offsetMax = new Vector2(-16f, -4f);
			TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val3).text = "You changed a setting that only takes effect on a fresh game load. Save the game, quit to the main menu, and load this world again to apply it.";
			((TMP_Text)val3).fontSize = 22f;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val3).enableWordWrapping = true;
			((Graphic)val3).raycastTarget = false;
			((Graphic)val3).color = new Color(0.98f, 0.93f, 0.78f, 1f);
			ApplyGameFontToLabel((TMP_Text)(object)val3);
			val.SetActive(false);
		}

		[HideFromIl2Cpp]
		private void UpdateReloadBanner()
		{
			if ((Object)(object)_bannerRect == (Object)null)
			{
				return;
			}
			bool flag = false;
			try
			{
				WorldCustomizationConfig active = WorldCustomizationConfig.GetActive();
				if ((Object)(object)active != (Object)null)
				{
					foreach (KeyValuePair<int, int> item in _levelsAtOpen)
					{
						if (_knobCategory.TryGetValue(item.Key, out var value) && IsReloadOnlyCategory(value))
						{
							WorldCustomizationData data = active.GetData(item.Key);
							WorldCustomizationSelector val = (((Object)(object)data != (Object)null) ? ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>() : null);
							if (!((Object)(object)val == (Object)null) && val.GetSelectedLevel() != item.Value)
							{
								flag = true;
								break;
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Warn("reload banner check threw: " + ex.Message);
				return;
			}
			GameObject gameObject = ((Component)_bannerRect).gameObject;
			if (gameObject.activeSelf != flag)
			{
				gameObject.SetActive(flag);
			}
		}

		[HideFromIl2Cpp]
		private void AddStyledCategoryHeader(WorldCustomizationCategory cat)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject("CategoryHeader");
				RectTransform val2 = val.AddComponent<RectTransform>();
				((Transform)val2).SetParent((Transform)(object)_contentRect, false);
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(1f, 1f);
				val2.pivot = new Vector2(0.5f, 1f);
				LayoutElement obj = val.AddComponent<LayoutElement>();
				obj.preferredHeight = 48f;
				obj.minHeight = 48f;
				obj.flexibleWidth = 1f;
				AddIconSlot(val2, _headerIcons);
				GameObject val3 = new GameObject("Label");
				RectTransform obj2 = val3.AddComponent<RectTransform>();
				((Transform)obj2).SetParent((Transform)(object)val2, false);
				obj2.anchorMin = Vector2.zero;
				obj2.anchorMax = Vector2.one;
				obj2.offsetMin = new Vector2(52f, 6f);
				obj2.offsetMax = new Vector2(-8f, 0f);
				TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val4).text = CategoryLabel(cat.titleKey);
				((TMP_Text)val4).fontSize = 32f;
				((TMP_Text)val4).alignment = (TextAlignmentOptions)4097;
				((TMP_Text)val4).enableWordWrapping = false;
				((Graphic)val4).raycastTarget = false;
				ApplyGameFontToLabel((TMP_Text)(object)val4);
				GameObject val5 = new GameObject("Rule");
				RectTransform obj3 = val5.AddComponent<RectTransform>();
				((Transform)obj3).SetParent((Transform)(object)val2, false);
				obj3.anchorMin = new Vector2(0f, 0f);
				obj3.anchorMax = new Vector2(1f, 0f);
				obj3.pivot = new Vector2(0.5f, 0f);
				obj3.offsetMin = Vector2.zero;
				obj3.offsetMax = new Vector2(0f, 2f);
				Image obj4 = val5.AddComponent<Image>();
				((Graphic)obj4).color = GoldAccent;
				((Graphic)obj4).raycastTarget = false;
			}
			catch (Exception ex)
			{
				Warn($"category header for '{cat.titleKey}' threw: {ex.Message}; falling back.");
				AddCategoryHeader(cat.titleKey);
			}
		}

		private void AddCategoryHeaderNative(WorldCustomizationCategory cat)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			IconTextPairComponent categHeaderPrefab = GetCategHeaderPrefab();
			if ((Object)(object)categHeaderPrefab != (Object)null)
			{
				try
				{
					GameObject val = Object.Instantiate<GameObject>(((Component)categHeaderPrefab).gameObject);
					RectTransform obj = val.GetComponent<RectTransform>() ?? val.AddComponent<RectTransform>();
					((Transform)obj).SetParent((Transform)(object)_contentRect, false);
					val.SetActive(true);
					obj.anchorMin = new Vector2(0f, 1f);
					obj.anchorMax = new Vector2(0f, 1f);
					obj.pivot = new Vector2(0f, 1f);
					LayoutElement obj2 = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>();
					obj2.preferredHeight = 48f;
					obj2.minHeight = 48f;
					obj2.flexibleWidth = 1f;
					IconTextPairComponent component = val.GetComponent<IconTextPairComponent>();
					if ((Object)(object)component != (Object)null)
					{
						if ((Object)(object)cat.icon != (Object)null)
						{
							component.SetSprite(cat.icon);
						}
						string text = cat.titleKey ?? string.Empty;
						component.SetLocText(ref text);
						string text2 = CategoryLabel(text);
						if (text2 != Localize(text))
						{
							foreach (TMP_Text componentsInChild in val.GetComponentsInChildren<TMP_Text>(true))
							{
								if (!((Object)(object)componentsInChild == (Object)null))
								{
									LocalizedText component2 = ((Component)componentsInChild).GetComponent<LocalizedText>();
									if ((Object)(object)component2 != (Object)null)
									{
										Object.DestroyImmediate((Object)(object)component2);
									}
									componentsInChild.text = text2;
								}
							}
						}
						foreach (TMP_Text componentsInChild2 in val.GetComponentsInChildren<TMP_Text>(true))
						{
							if (!((Object)(object)componentsInChild2 == (Object)null))
							{
								componentsInChild2.enableAutoSizing = false;
								componentsInChild2.fontSize = 32f;
							}
						}
						Log($"category '{cat.titleKey}': native categHeader instantiated (icon={(Object)(object)cat.icon != (Object)null}).");
						return;
					}
					Warn("category '" + cat.titleKey + "': instantiated header has no IconTextPairComponent; falling back.");
					Object.DestroyImmediate((Object)(object)val);
				}
				catch (Exception ex)
				{
					Warn($"category '{cat.titleKey}': native categHeader failed ({ex.GetType().Name}: {ex.Message}); falling back.");
				}
			}
			AddCategoryHeader(cat.titleKey);
			Log("category '" + cat.titleKey + "': text header (fallback).");
		}

		private void AddCategoryHeader(string titleKey)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			string text = CategoryLabel(titleKey);
			GameObject val = new GameObject("Header");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)_contentRect, false);
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = new Vector2(0f, 1f);
			obj.pivot = new Vector2(0f, 1f);
			TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj2).text = text;
			((TMP_Text)obj2).fontSize = 26f;
			((TMP_Text)obj2).fontStyle = (FontStyles)1;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)4097;
			((Graphic)obj2).color = new Color(1f, 0.85f, 0.4f, 1f);
			LayoutElement obj3 = val.AddComponent<LayoutElement>();
			obj3.preferredHeight = 48f;
			obj3.minHeight = 48f;
			obj3.flexibleWidth = 1f;
		}

		private bool AddKnobRow(int id, WorldCustomizationSelector selector, string nameKey)
		{
			//IL_00ce: 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)
			IWorldCustomizationPanel val = ((WorldCustomizationData)selector).CreateUIPanel(_contentRect);
			bool flag = val != null;
			Log($"knob id={id} nameKey='{nameKey}' CreateUIPanel={(flag ? "NON-NULL" : "null")}.");
			if (!flag)
			{
				return false;
			}
			val.SetPanel((WorldCustomizationData)(object)selector);
			if ((Object)(object)val.gameObject == (Object)null)
			{
				return false;
			}
			GameObject gameObject = val.gameObject;
			gameObject.transform.SetParent((Transform)(object)_contentRect, false);
			RectTransform component = gameObject.GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchorMin = new Vector2(0f, 1f);
				component.anchorMax = new Vector2(0f, 1f);
				component.pivot = new Vector2(0f, 1f);
			}
			LayoutElement obj = gameObject.GetComponent<LayoutElement>() ?? gameObject.AddComponent<LayoutElement>();
			obj.preferredHeight = 60f;
			obj.minHeight = 60f;
			obj.flexibleWidth = 1f;
			foreach (TMP_Text componentsInChild in gameObject.GetComponentsInChildren<TMP_Text>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null) && !(componentsInChild.fontSize <= 0f))
				{
					componentsInChild.enableAutoSizing = false;
					componentsInChild.fontSize *= 1.18f;
				}
			}
			ResolveCompositeRowLabel(gameObject, nameKey);
			string text = string.Empty;
			try
			{
				text = Localize(((WorldCustomizationData)selector).descriptionKey);
			}
			catch (Exception ex)
			{
				Warn("knob '" + nameKey + "': descriptionKey read threw: " + ex.Message);
			}
			if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(text))
			{
				_rows.Add(new KnobRow
				{
					Rect = component,
					Title = Localize(nameKey),
					Description = text
				});
			}
			return true;
		}

		[HideFromIl2Cpp]
		private void ResolveCompositeRowLabel(GameObject panelGo, string nameKey)
		{
			if (string.IsNullOrEmpty(nameKey) || nameKey.IndexOf('+') < 0)
			{
				return;
			}
			string text = Localize(nameKey);
			if (text == nameKey)
			{
				return;
			}
			try
			{
				foreach (TMP_Text componentsInChild in panelGo.GetComponentsInChildren<TMP_Text>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null) && !(componentsInChild.text != nameKey))
					{
						LocalizedText component = ((Component)componentsInChild).GetComponent<LocalizedText>();
						if ((Object)(object)component != (Object)null)
						{
							Object.DestroyImmediate((Object)(object)component);
						}
						componentsInChild.text = text;
						Log($"knob '{nameKey}': relabelled to '{text}'.");
					}
				}
			}
			catch (Exception ex)
			{
				Warn("knob '" + nameKey + "': relabel threw: " + ex.Message);
			}
		}

		private bool EnsureTooltip()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_tooltipGo != (Object)null)
			{
				return true;
			}
			if (_tooltipUnavailable)
			{
				return false;
			}
			try
			{
				TooltipDetailsTabPage val = null;
				Il2CppArrayBase<TooltipDetailsTabPage> val2 = Resources.FindObjectsOfTypeAll<TooltipDetailsTabPage>();
				for (int i = 0; i < val2.Length; i++)
				{
					TooltipDetailsTabPage val3 = val2[i];
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.tooltipLabel == (Object)null))
					{
						bool flag = false;
						try
						{
							Scene scene = ((Component)val3).gameObject.scene;
							flag = ((Scene)(ref scene)).IsValid();
						}
						catch
						{
						}
						if (!flag)
						{
							val = val3;
							break;
						}
						if ((Object)(object)val == (Object)null)
						{
							val = val3;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Warn("tooltip: no TooltipDetailsTabPage prefab found; tooltips disabled.");
					_tooltipUnavailable = true;
					return false;
				}
				GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject);
				((Object)val4).name = "SettingsPlus_Tooltip";
				_tooltipRect = val4.GetComponent<RectTransform>() ?? val4.AddComponent<RectTransform>();
				((Transform)_tooltipRect).SetParent(_overlay.transform, false);
				((Transform)_tooltipRect).SetAsLastSibling();
				_tooltipRect.anchorMin = new Vector2(0f, 1f);
				_tooltipRect.anchorMax = new Vector2(0f, 1f);
				_tooltipRect.pivot = new Vector2(0f, 1f);
				TooltipDetailsTabPage component = val4.GetComponent<TooltipDetailsTabPage>();
				if ((Object)(object)component != (Object)null)
				{
					try
					{
						((TabPage)component)._DeactivateAndRemoveAllConstraintSources();
					}
					catch (Exception ex)
					{
						Warn("tooltip: constraint removal threw: " + ex.Message);
					}
					((TabPage)component).AutoPosition = false;
					((Behaviour)component).enabled = false;
					if ((Object)(object)((TabPage)component).indicatorArrow != (Object)null)
					{
						((Component)((TabPage)component).indicatorArrow).gameObject.SetActive(false);
					}
					if ((Object)(object)((TabPage)component).subTitle != (Object)null)
					{
						((Component)((TabPage)component).subTitle).gameObject.SetActive(false);
					}
					_tooltipLabel = (TMP_Text)(object)component.tooltipLabel;
					if ((Object)(object)((TabPage)component).title != (Object)null)
					{
						_tooltipTitle = ((Component)((TabPage)component).title).GetComponentInChildren<TMP_Text>(true);
					}
				}
				if ((Object)(object)_tooltipLabel == (Object)null)
				{
					_tooltipLabel = val4.GetComponentInChildren<TMP_Text>(true);
				}
				foreach (LocalizedText componentsInChild in val4.GetComponentsInChildren<LocalizedText>(true))
				{
					Object.DestroyImmediate((Object)(object)componentsInChild);
				}
				foreach (CanvasGroup componentsInChild2 in val4.GetComponentsInChildren<CanvasGroup>(true))
				{
					componentsInChild2.alpha = 1f;
					componentsInChild2.blocksRaycasts = false;
					componentsInChild2.interactable = false;
				}
				foreach (Graphic componentsInChild3 in val4.GetComponentsInChildren<Graphic>(true))
				{
					componentsInChild3.raycastTarget = false;
				}
				val4.SetActive(false);
				_tooltipGo = val4;
				Log($"tooltip: cloned '{((Object)((Component)val).gameObject).name}' (label={(Object)(object)_tooltipLabel != (Object)null}, title={(Object)(object)_tooltipTitle != (Object)null}).");
				return true;
			}
			catch (Exception ex2)
			{
				Warn($"tooltip: clone failed ({ex2.GetType().Name}: {ex2.Message}); tooltips disabled.");
				_tooltipUnavailable = true;
				return false;
			}
		}

		private void UpdateTooltipHover()
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (_rows.Count == 0)
			{
				HideTooltip();
				return;
			}
			Vector2 val = Vector2.op_Implicit(Input.mousePosition);
			KnobRow knobRow = null;
			if ((Object)(object)_viewportRect == (Object)null || RectTransformUtility.RectangleContainsScreenPoint(_viewportRect, val, (Camera)null))
			{
				for (int i = 0; i < _rows.Count; i++)
				{
					KnobRow knobRow2 = _rows[i];
					if ((Object)(object)knobRow2.Rect != (Object)null && RectTransformUtility.RectangleContainsScreenPoint(knobRow2.Rect, val, (Camera)null))
					{
						knobRow = knobRow2;
						break;
					}
				}
			}
			if (knobRow == null)
			{
				HideTooltip();
				return;
			}
			if (knobRow != _hoveredRow)
			{
				ShowTooltip(knobRow);
			}
			PositionTooltip(val);
		}

		[HideFromIl2Cpp]
		private void ShowTooltip(KnobRow row)
		{
			if (EnsureTooltip())
			{
				_hoveredRow = row;
				if ((Object)(object)_tooltipTitle != (Object)null)
				{
					_tooltipTitle.text = row.Title;
				}
				if ((Object)(object)_tooltipLabel != (Object)null)
				{
					_tooltipLabel.text = row.Description;
				}
				_tooltipGo.SetActive(true);
			}
		}

		private void PositionTooltip(Vector2 screenPos)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_tooltipGo == (Object)null) && _tooltipGo.activeSelf)
			{
				RectTransform component = _overlay.GetComponent<RectTransform>();
				Vector2 val = default(Vector2);
				if (!((Object)(object)component == (Object)null) && RectTransformUtility.ScreenPointToLocalPointInRectangle(component, screenPos, (Camera)null, ref val))
				{
					Rect rect = component.rect;
					float num = val.x - ((Rect)(ref rect)).xMin + TooltipCursorOffset.x;
					float num2 = val.y - ((Rect)(ref rect)).yMax + TooltipCursorOffset.y;
					Rect rect2 = _tooltipRect.rect;
					Vector2 size = ((Rect)(ref rect2)).size;
					num = Mathf.Min(num, ((Rect)(ref rect)).width - size.x);
					num2 = Mathf.Max(num2, 0f - (((Rect)(ref rect)).height - size.y));
					_tooltipRect.anchoredPosition = new Vector2(num, num2);
				}
			}
		}

		private void HideTooltip()
		{
			_hoveredRow = null;
			if ((Object)(object)_tooltipGo != (Object)null && _tooltipGo.activeSelf)
			{
				_tooltipGo.SetActive(false);
			}
		}

		[HideFromIl2Cpp]
		private void SnapshotKnobLevels()
		{
			_levelsAtOpen.Clear();
			_knobCategory.Clear();
			try
			{
				WorldCustomizationConfig active = WorldCustomizationConfig.GetActive();
				if ((Object)(object)active == (Object)null || active.sections == null)
				{
					return;
				}
				List<WorldCustomizationSection> sections = active.sections;
				for (int i = 0; i < sections.Count; i++)
				{
					WorldCustomizationSection val = sections[i];
					if (val == null || val.isHidden)
					{
						continue;
					}
					string text = val.titleKey ?? string.Empty;
					if (!IsAllowedSection(text))
					{
						continue;
					}
					List<WorldCustomizationCategory> categories = val.categories;
					int num = 0;
					while (categories != null && num < categories.Count)
					{
						WorldCustomizationCategory val2 = categories[num];
						if (ShouldShowCategory(text, val2))
						{
							RecordCategoryLevels(active, val2, val2.titleKey ?? string.Empty);
						}
						num++;
					}
				}
			}
			catch (Exception ex)
			{
				Warn("level snapshot threw: " + ex.Message);
			}
		}

		[HideFromIl2Cpp]
		private void RecordCategoryLevels(WorldCustomizationConfig cfg, WorldCustomizationCategory cat, string categoryKey)
		{
			List<int> items = cat.items;
			int num = 0;
			while (items != null && num < items.Count)
			{
				int num2 = items[num];
				WorldCustomizationData data = cfg.GetData(num2);
				if (!((Object)(object)data == (Object)null) && !data.isHidden)
				{
					WorldCustomizationSelector val = ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>();
					if (!((Object)(object)val == (Object)null))
					{
						RecordSelectorLevel(val, categoryKey);
					}
				}
				num++;
			}
		}

		[HideFromIl2Cpp]
		private void RecordSelectorLevel(WorldCustomizationSelector selector, string categoryKey)
		{
			try
			{
				_levelsAtOpen[((WorldCustomizationData)selector).id] = selector.GetSelectedLevel();
				_knobCategory[((WorldCustomizationData)selector).id] = categoryKey;
			}
			catch (Exception ex)
			{
				Warn($"level read threw for id {((WorldCustomizationData)selector).id}: {ex.Message}");
				return;
			}
			List<WorldCustomizationData> val = new List<WorldCustomizationData>();
			bool children;
			try
			{
				children = ((WorldCustomizationData)selector).GetChildren(val);
			}
			catch (Exception ex2)
			{
				Warn($"GetChildren threw for id {((WorldCustomizationData)selector).id}: {ex2.Message}");
				return;
			}
			int num = 0;
			while (children && num < val.Count)
			{
				WorldCustomizationSelector val2 = (((Object)(object)val[num] != (Object)null) ? ((Il2CppObjectBase)val[num]).TryCast<WorldCustomizationSelector>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					RecordSelectorLevel(val2, categoryKey);
				}
				num++;
			}
		}

		[HideFromIl2Cpp]
		private HashSet<string> ChangedCategories()
		{
			HashSet<string> hashSet = new HashSet<string>();
			if (_levelsAtOpen.Count == 0)
			{
				return hashSet;
			}
			try
			{
				WorldCustomizationConfig active = WorldCustomizationConfig.GetActive();
				if ((Object)(object)active == (Object)null)
				{
					return hashSet;
				}
				foreach (KeyValuePair<int, int> item in _levelsAtOpen)
				{
					WorldCustomizationData data = active.GetData(item.Key);
					WorldCustomizationSelector val = (((Object)(object)data != (Object)null) ? ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>() : null);
					if (!((Object)(object)val == (Object)null))
					{
						int selectedLevel = val.GetSelectedLevel();
						if (selectedLevel != item.Value)
						{
							string value;
							string text = (_knobCategory.TryGetValue(item.Key, out value) ? value : "?");
							hashSet.Add(text);
							Log($"changed: '{((WorldCustomizationData)val).nameKey}' ({text}) level {item.Value} -> {selectedLevel}.");
						}
					}
				}
			}
			catch (Exception ex)
			{
				Warn("change detection threw: " + ex.Message);
			}
			return hashSet;
		}

		private void SnapshotCostLevels()
		{
			_costLevelsAtOpen.Clear();
			_costManager = null;
			try
			{
				_costManager = Object.FindObjectOfType<GameCustomizationManager>();
				if ((Object)(object)_costManager == (Object)null)
				{
					Warn("costs: no GameCustomizationManager in the scene; Costs changes apply on reload only.");
					return;
				}
				List<WorldCustomizationSelector> requiredPreparationData = _costManager.requiredPreparationData;
				if (requiredPreparationData != null)
				{
					for (int i = 0; i < requiredPreparationData.Count; i++)
					{
						_costLevelsAtOpen.Add(((Object)(object)requiredPreparationData[i] != (Object)null) ? requiredPreparationData[i].GetSelectedLevel() : (-1));
					}
				}
			}
			catch (Exception ex)
			{
				Warn("costs: snapshot threw: " + ex.Message);
				_costManager = null;
			}
		}

		private void ReapplyCostsIfChanged()
		{
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			if ((Object)(object)_costManager == (Object)null || _costLevelsAtOpen.Count == 0)
			{
				return;
			}
			try
			{
				List<WorldCustomizationSelector> requiredPreparationData = _costManager.requiredPreparationData;
				if (requiredPreparationData == null || requiredPreparationData.Count != _costLevelsAtOpen.Count)
				{
					return;
				}
				bool flag = false;
				for (int i = 0; i < requiredPreparationData.Count; i++)
				{
					WorldCustomizationSelector val = requiredPreparationData[i];
					int num = (((Object)(object)val != (Object)null) ? val.GetSelectedLevel() : (-1));
					if (num != _costLevelsAtOpen[i])
					{
						flag = true;
						Log($"costs: '{(((Object)(object)val != (Object)null) ? ((WorldCustomizationData)val).nameKey : "?")}' level {_costLevelsAtOpen[i]} -> {num}.");
					}
				}
				if (flag)
				{
					_costManager.ResetItemsCustomization();
					_costManager.PrepareItemsForCustomization();
					Log("costs: re-applied to the running session.");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" costs: re-apply threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
			}
		}

		[HideFromIl2Cpp]
		private void ApplyChangedCategories(HashSet<string> changed)
		{
			if (changed.Count != 0)
			{
				List<string> values = new List<string>(changed);
				Log("changed categories on close: " + string.Join(", ", values) + ".");
				if (changed.Contains("custom.weather"))
				{
					ReapplyWeather();
				}
			}
		}

		[HideFromIl2Cpp]
		private void ReapplyWeather()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			try
			{
				WeatherSystem instance = WeatherSystem.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					Warn("weather: no WeatherSystem instance; weather changes apply on reload only.");
					return;
				}
				bool flag = false;
				instance.LoadCustomization(ref flag);
				Log("weather: re-applied to the running session.");
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" weather: re-apply threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private void OnCloseClicked()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			try
			{
				Hide();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" OnCloseClicked threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private void Hide()
		{
			if ((Object)(object)_overlay != (Object)null && _overlay.activeSelf)
			{
				HideTooltip();
				_overlay.SetActive(false);
				Log("overlay hidden.");
				ReapplyCostsIfChanged();
				ApplyChangedCategories(ChangedCategories());
			}
		}

		private void Update()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			try
			{
				if ((Object)(object)_overlay == (Object)null || !_overlay.activeSelf)
				{
					return;
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					Hide();
					return;
				}
				UpdateTooltipHover();
				if (Time.unscaledTime >= _nextBannerCheck)
				{
					_nextBannerCheck = Time.unscaledTime + 0.4f;
					UpdateReloadBanner();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(15, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Update threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SettingsPlus";

		public const string PLUGIN_NAME = "Settings Plus";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace AskaShared.Game
{
	public static class LocalPlayerTool
	{
		private static bool _failureLogged;

		public static Character LocalCharacter { get; private set; }

		public static GameObject AttachOnSpawn(Character character, ManualLogSource log, string objectName, Vector3 localPosition, params Type[] components)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				if ((Object)(object)character == (Object)null)
				{
					return null;
				}
				if (!character.IsPlayer() || ((NetworkBehaviour)character).GetLocalAuthorityMask() != 1)
				{
					return null;
				}
				LocalCharacter = character;
				if (string.IsNullOrEmpty(objectName))
				{
					throw new ArgumentException("objectName is required and must be unique to this mod.", "objectName");
				}
				Transform transform = ((Component)character).gameObject.transform;
				if ((Object)(object)transform.Find(objectName) != (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject(objectName);
				val.transform.SetParent(transform, false);
				val.transform.localPosition = localPosition;
				if (components != null)
				{
					foreach (Type type in components)
					{
						if (type != null)
						{
							val.AddComponent(Il2CppType.From(type));
						}
					}
				}
				ManualLogSource val2 = log;
				if (val2 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(objectName);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" attached to local player '");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)((Component)character).gameObject).name);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'.");
					}
					val2.LogInfo(val3);
				}
				return val;
			}
			catch (Exception ex)
			{
				if (!_failureLogged)
				{
					_failureLogged = true;
					ManualLogSource val2 = log;
					if (val2 != null)
					{
						BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(121, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(objectName);
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": attaching to the local player threw - this mod will do nothing this session, reported once rather than once per spawn: ");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<Exception>(ex);
						}
						val2.LogError(val4);
					}
				}
				return null;
			}
		}
	}
}