Decompiled source of SettingsPlus v1.2.0

SettingsPlus.Core.dll

Decompiled a week ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[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.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3a7b9d73885e7b2693f6cee496dcc24fe2b7094d")]
[assembly: AssemblyProduct("SettingsPlus.Core")]
[assembly: AssemblyTitle("SettingsPlus.Core")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AskaSettingsPlus.Core
{
	public static class CharacterWrite
	{
		public static float? ForAffinity(float newValue, float baseValue)
		{
			if (baseValue != newValue)
			{
				return newValue;
			}
			return null;
		}

		public static float? ForProficiency(float oldValue, float newValue, float baseValue)
		{
			if (newValue > oldValue && baseValue < newValue)
			{
				return newValue;
			}
			if (newValue < oldValue && baseValue > newValue)
			{
				return newValue;
			}
			return null;
		}
	}
	public static class SectionStep
	{
		public static int Next(int count, int current, int step)
		{
			return ((current + step) % count + count) % count;
		}
	}
}

SettingsPlus.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using AskaSettingsPlus.Core;
using AskaShared.Game;
using AskaShared.UI;
using BepInEx;
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 Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Localization;
using SSSGame.UI;
using SSSGame.Weather;
using SandSailorStudio.Attributes;
using SandSailorStudio.Localization;
using SandSailorStudio.UI;
using SandSailorStudio.WorldGen;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
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.2.0")]
[assembly: AssemblyInformationalVersion("1.2.0+3a7b9d73885e7b2693f6cee496dcc24fe2b7094d")]
[assembly: AssemblyProduct("Settings Plus")]
[assembly: AssemblyTitle("SettingsPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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
{
	internal static class ButtonGlyphs
	{
		internal const int Apply = 0;

		internal const int Reset = 1;

		internal const int SectionBefore = 2;

		internal const int SectionAfter = 3;

		private const string ApplyGlyph = "Panel/ButtonApply/Glyph";

		private const string ResetGlyph = "Panel/ButtonReset/Glyph";

		private const string StripStartGlyph = "Panel/ControlsPage/Keyboard & Gamepad/TabsButtons/LayoutGroup/Tutorial";

		private const string StripEndGlyph = "Panel/ControlsPage/Keyboard & Gamepad/TabsButtons/LayoutGroup/Tutorial (1)";

		internal static List<GlyphDisplayComponent> Add(Transform parent)
		{
			SettingsMenu prefab = MenuManager.Instance.GetPrefab<SettingsMenu>();
			if ((Object)(object)prefab == (Object)null)
			{
				throw new InvalidOperationException("MenuManager has no SettingsMenu prefab.");
			}
			Transform transform = ((Component)prefab).transform;
			List<GlyphDisplayComponent> obj = new List<GlyphDisplayComponent>
			{
				Clone(transform, "Panel/ButtonApply/Glyph", parent),
				Clone(transform, "Panel/ButtonReset/Glyph", parent),
				Clone(transform, "Panel/ControlsPage/Keyboard & Gamepad/TabsButtons/LayoutGroup/Tutorial", parent),
				Clone(transform, "Panel/ControlsPage/Keyboard & Gamepad/TabsButtons/LayoutGroup/Tutorial (1)", parent)
			};
			InputAction pageNavigation = InputManager.controls.MenuControls.PageNavigation;
			obj[2]._controllerInputActionCache = pageNavigation;
			obj[3]._controllerInputActionCache = pageNavigation;
			return obj;
		}

		private static GlyphDisplayComponent Clone(Transform menu, string path, Transform parent)
		{
			GameObject obj = UiParts.CloneInto(UiParts.Child(menu, path), parent);
			obj.SetActive(false);
			GlyphDisplayComponent component = obj.GetComponent<GlyphDisplayComponent>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("The Settings menu's '" + path + "' has no GlyphDisplayComponent.");
			}
			return component;
		}
	}
	internal static class CharacterWrites
	{
		private const string Tag = "[SettingsPlus]";

		private const int FirstProficiency = 300;

		private const int LastProficiency = 316;

		private static readonly HashSet<string> AffinityCategories = new HashSet<string> { "custom.player.affinities", "custom.villager.affinities" };

		private static readonly HashSet<string> ProficiencyCategories = new HashSet<string> { "custom.player.proficiencies", "custom.villager.proficiencies" };

		private static readonly Dictionary<(int Sheet, int Setting), float> RecordedValues = new Dictionary<(int, int), float>();

		private static PlayerManager _players;

		private static PopulationManager _population;

		internal static bool IsProficiency(string categoryKey)
		{
			return ProficiencyCategories.Contains(categoryKey);
		}

		internal static void RecordValues()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			RecordedValues.Clear();
			HashSet<int> hashSet = new HashSet<int>();
			bool flag = default(bool);
			foreach (Character item in ReachableCharacters())
			{
				try
				{
					CharacterDataSheet dataSheet = item.dataSheet;
					Il2CppReferenceArray<BaseStats> val = (((Object)(object)dataSheet != (Object)null) ? dataSheet.baseStats : null);
					if (val == null || !hashSet.Add(((Object)dataSheet).GetInstanceID()))
					{
						continue;
					}
					for (int i = 0; i < ((Il2CppArrayBase<BaseStats>)(object)val).Length; i++)
					{
						BaseStats val2 = ((Il2CppArrayBase<BaseStats>)(object)val)[i];
						if (val2 != null && (Object)(object)val2.customizationSelector != (Object)null)
						{
							RecordedValues[(((Object)dataSheet).GetInstanceID(), ((WorldCustomizationData)val2.customizationSelector).id)] = val2.Value;
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(43, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("[SettingsPlus]");
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" characters: recording a data sheet threw: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
					}
					log.LogError(val3);
				}
			}
			if (Plugin.DebugLogging)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(59, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" characters: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(RecordedValues.Count);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" value(s) recorded from ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(hashSet.Count);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" data sheet(s) ");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("in ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<double>(stopwatch.Elapsed.TotalMilliseconds, "0.0");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ms.");
				}
				log2.LogInfo(val4);
			}
		}

		internal static void Apply(List<(WorldCustomizationSelector Setting, string Category)> changes)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			HashSet<int> hashSet = new HashSet<int>();
			HashSet<int> hashSet2 = new HashSet<int>();
			foreach (var change in changes)
			{
				if (AffinityCategories.Contains(change.Category))
				{
					hashSet.Add(((WorldCustomizationData)change.Setting).id);
				}
				else if (ProficiencyCategories.Contains(change.Category))
				{
					hashSet2.Add(((WorldCustomizationData)change.Setting).id);
				}
			}
			if (hashSet.Count == 0 && hashSet2.Count == 0)
			{
				return;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			int num = 0;
			bool flag = default(bool);
			foreach (Character item in ReachableCharacters())
			{
				try
				{
					num += Write(item, hashSet, hashSet2);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(44, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" characters: write threw for one character: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
			if (Plugin.DebugLogging)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(62, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" characters: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" value(s) written for ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(hashSet.Count + hashSet2.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" changed setting(s) in ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(stopwatch.Elapsed.TotalMilliseconds, "0.0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ms.");
				}
				log2.LogInfo(val2);
			}
		}

		private static List<Character> ReachableCharacters()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			List<Character> list = new List<Character>();
			try
			{
				if ((Object)(object)_players == (Object)null)
				{
					_players = Object.FindObjectOfType<PlayerManager>();
				}
				Player val = (((Object)(object)_players != (Object)null) ? _players.LocalPlayer : null);
				if (val != null && (Object)(object)val.playerCharacter != (Object)null)
				{
					list.Add((Character)(object)val.playerCharacter);
				}
				if ((Object)(object)_population == (Object)null)
				{
					_population = Object.FindObjectOfType<PopulationManager>();
				}
				List<Villager> val2 = (((Object)(object)_population != (Object)null) ? _population.GetAllVillagers() : null);
				int num = 0;
				while (val2 != null && num < val2.Count)
				{
					if ((Object)(object)val2[num] != (Object)null)
					{
						list.Add((Character)(object)val2[num]);
					}
					num++;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(28, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" characters: listing threw: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log.LogError(val3);
			}
			return list;
		}

		private static int Write(Character character, HashSet<int> affinities, HashSet<int> proficiencies)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			CharacterDataSheet dataSheet = character.dataSheet;
			AttributeManager attributeManager = character.GetAttributeManager();
			Il2CppReferenceArray<BaseStats> val = (((Object)(object)dataSheet != (Object)null) ? dataSheet.baseStats : null);
			if (val == null || (Object)(object)attributeManager == (Object)null)
			{
				return 0;
			}
			int num = 0;
			bool flag = false;
			bool flag3 = default(bool);
			for (int i = 0; i < ((Il2CppArrayBase<BaseStats>)(object)val).Length; i++)
			{
				BaseStats val2 = ((Il2CppArrayBase<BaseStats>)(object)val)[i];
				AttributeCustomizationSelector val3 = ((val2 != null) ? val2.customizationSelector : null);
				if ((Object)(object)val3 == (Object)null || (Object)(object)val2.baseStat == (Object)null)
				{
					continue;
				}
				bool flag2 = affinities.Contains(((WorldCustomizationData)val3).id);
				if (!flag2 && !proficiencies.Contains(((WorldCustomizationData)val3).id))
				{
					continue;
				}
				Attribute attribute = attributeManager.GetAttribute(val2.baseStat.attributeId);
				if (attribute == null)
				{
					continue;
				}
				float baseValue = attribute.baseValue;
				float? num2;
				if (flag2)
				{
					num2 = CharacterWrite.ForAffinity(val2.Value, baseValue);
				}
				else
				{
					if (!RecordedValues.TryGetValue((((Object)dataSheet).GetInstanceID(), ((WorldCustomizationData)val3).id), out var value))
					{
						continue;
					}
					num2 = CharacterWrite.ForProficiency(value, val2.Value, baseValue);
				}
				if (!num2.HasValue)
				{
					continue;
				}
				((Property)attribute).SetValue(num2.Value);
				num++;
				flag |= !flag2 && num2.Value < baseValue;
				if (Plugin.DebugLogging)
				{
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(33, 5, ref flag3);
					if (flag3)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("[SettingsPlus]");
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" characters: '");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(character.GetName());
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' attribute ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(((Property)attribute).id);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<float>(baseValue);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<float>(num2.Value);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(".");
					}
					log.LogInfo(val4);
				}
			}
			if (flag)
			{
				RepickHighestProficiency(character, attributeManager);
			}
			return num;
		}

		private static void RepickHighestProficiency(Character character, AttributeManager attributes)
		{
			Villager val = ((Il2CppObjectBase)character).TryCast<Villager>();
			Property val2 = (((Object)(object)val != (Object)null) ? val.HighestProficiency : null);
			if (val2 == null)
			{
				return;
			}
			Attribute val3 = null;
			for (int i = 300; i <= 316; i++)
			{
				Attribute attribute = attributes.GetAttribute(i);
				if (attribute != null && (val3 == null || ((Property)attribute).GetValue() > ((Property)val3).GetValue()))
				{
					val3 = attribute;
				}
			}
			if (val3 != null && ((Property)val3).GetValue() > val2.GetValue())
			{
				val._OnProficiencyLevelChanged(((Property)val3).id, ((Property)val3).GetValue());
			}
		}
	}
	internal enum EffectTiming
	{
		AtOnce,
		WorldReload
	}
	internal static class EffectTimings
	{
		private static readonly Dictionary<string, EffectTiming> ByCategory = new Dictionary<string, EffectTiming>
		{
			["custom.villager.survival"] = EffectTiming.WorldReload,
			["custom.player.stats"] = EffectTiming.WorldReload
		};

		internal static EffectTiming Of(string categoryKey)
		{
			if (!ByCategory.TryGetValue(categoryKey, out var value))
			{
				return EffectTiming.AtOnce;
			}
			return value;
		}
	}
	public static class ForgeLink
	{
		public static void Open()
		{
			SettingsPanel.Open();
		}

		public static string GetBlockedReason()
		{
			string text = SettingsPanel.BlockedReasonKey();
			if (text != null)
			{
				return ModStrings.Get(text);
			}
			return null;
		}
	}
	internal sealed class MenuHost : ContextMenu
	{
		private Action _onBack;

		internal static bool ControllerInUse => (int)MenuManager.CurrentInputMode == 2;

		public MenuHost(IntPtr pointer)
			: base(pointer)
		{
		}

		[HideFromIl2Cpp]
		internal unsafe static void Register()
		{
			ClassInjector.RegisterTypeInIl2Cpp<MenuHost>();
			INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<MenuHost>.NativeClassPtr);
			(((object)val).GetType().GetProperty("HasReferences") ?? throw new InvalidOperationException("Il2CppInterop's class wrapper has no HasReferences flag.")).SetValue(val, true);
		}

		[HideFromIl2Cpp]
		internal static MenuHost AddTo(GameObject root, Action onBack)
		{
			if (root.activeSelf)
			{
				throw new InvalidOperationException("The menu host needs an inactive root.");
			}
			PauseMenu instance = Menu.GetInstance<PauseMenu>();
			if ((Object)(object)instance == (Object)null)
			{
				throw new InvalidOperationException("The pause menu is not open; the menu host takes its input context.");
			}
			MenuHost menuHost = root.AddComponent<MenuHost>();
			menuHost._onBack = onBack;
			RunGameConstructor(menuHost);
			((Menu)menuHost).preferedInitialSelectables = new List<SelectablePriority>();
			((ContextMenu)menuHost).GroupsToClose = new List<TabGroup>();
			((Menu)menuHost).DeactivatePrevious = true;
			((Menu)menuHost).autoSelect = true;
			((ContextMenu)menuHost).context = ((ContextMenu)instance).context;
			return menuHost;
		}

		[HideFromIl2Cpp]
		private unsafe static void RunGameConstructor(MenuHost host)
		{
			IntPtr intPtr = IL2CPP.il2cpp_class_get_method_from_name(Il2CppClassPointerStore<ContextMenu>.NativeClassPtr, ".ctor", 0);
			if (intPtr == IntPtr.Zero)
			{
				throw new InvalidOperationException("The game's ContextMenu has no constructor without parameters.");
			}
			IntPtr zero = IntPtr.Zero;
			IL2CPP.il2cpp_runtime_invoke(intPtr, ((Il2CppObjectBase)host).Pointer, (void**)null, ref zero);
			Il2CppException.RaiseExceptionIfNecessary(zero);
		}

		internal void Open()
		{
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			MenuManager.Instance.OpenMenu((Menu)(object)this, (MenuParameters)null);
		}

		internal void SelectFirst(Selectable control)
		{
			((Menu)this)._selectionBuffer.Clear();
			((Menu)this)._selectionBuffer.Add(control);
			if (((Menu)this).IsActive && ControllerInUse)
			{
				control.Select();
			}
		}

		public override void OnBackPressed()
		{
			_onBack();
		}
	}
	[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.2.0")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.settingsplus";

		public const string PluginName = "Settings Plus";

		public const string PluginVersion = "1.2.0";

		internal static ManualLogSource Log;

		internal static readonly bool DebugLogging;

		public override void Load()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: 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_007d: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ModStrings.Init(Log, "[SettingsPlus][strings]");
			ClassInjector.RegisterTypeInIl2Cpp<SettingsPanel>();
			MenuHost.Register();
			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.2.0");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded.");
			}
			log.LogInfo(val2);
		}
	}
	internal static class RowMarker
	{
		internal static void Mark(SettingRow row, string categoryKey, Color color)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			EffectTiming num = EffectTimings.Of(categoryKey);
			string text = TimingLine(num, categoryKey);
			row.Description = (string.IsNullOrEmpty(row.Description) ? text : (row.Description + "\n\n" + text));
			if (num == EffectTiming.WorldReload && !((Object)(object)NameLabel(row) == (Object)null))
			{
				row.NameMarker = KitMarker.Suffix(KitStrings.WorldReloadMarker, color);
				Show(row);
			}
		}

		private static string TimingLine(EffectTiming timing, string categoryKey)
		{
			if (CharacterWrites.IsProficiency(categoryKey))
			{
				return ModStrings.Get("timing.proficiency_rule");
			}
			return timing switch
			{
				EffectTiming.AtOnce => KitStrings.AtOnceLine, 
				EffectTiming.WorldReload => KitStrings.WorldReloadLine, 
				_ => throw new ArgumentOutOfRangeException("timing", timing, "No timing line for this effect timing."), 
			};
		}

		internal static void Show(SettingRow row)
		{
			if (row.NameMarker != null)
			{
				TMP_Text obj = NameLabel(row);
				LocalizedText component = ((Component)obj).GetComponent<LocalizedText>();
				if ((Object)(object)component != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component);
				}
				obj.richText = true;
				obj.text += row.NameMarker;
			}
		}

		private static TMP_Text NameLabel(SettingRow row)
		{
			WorldCustomizationSelectorPanel component = ((Component)row.Rect).GetComponent<WorldCustomizationSelectorPanel>();
			if (!((Object)(object)component != (Object)null))
			{
				return null;
			}
			return component.nameLabel;
		}
	}
	internal sealed class SettingRow
	{
		internal RectTransform Rect;

		internal Selectable Selectable;

		internal string Description;

		internal string NameMarker;

		internal IWorldCustomizationPanel Control;

		internal WorldCustomizationSelector Setting;

		internal IncreaseDecreasePanel Steps;

		internal Color ValueRestColor;
	}
	internal sealed class SettingRows
	{
		private readonly Il2CppReferenceArray<EventSystemNotifierTarget> _noClickTargets = new Il2CppReferenceArray<EventSystemNotifierTarget>(0L);

		private readonly List<EventSystemNotifierTarget> _noSubmitTargets = new List<EventSystemNotifierTarget>();

		internal SettingRow Add(WorldCustomizationSelector setting, RectTransform parent)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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)
			IWorldCustomizationPanel val = ((WorldCustomizationData)setting).CreateUIPanel(parent);
			if (val == null || (Object)(object)val.gameObject == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(65, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SettingsPlus] setting '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((WorldCustomizationData)setting).nameKey);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': the game made no control; row skipped.");
				}
				log.LogWarning(val2);
				return null;
			}
			val.SetPanel((WorldCustomizationData)(object)setting);
			GameObject gameObject = val.gameObject;
			ResolveCompositeRowLabel(gameObject, ((WorldCustomizationData)setting).nameKey);
			foreach (Button componentsInChild in gameObject.GetComponentsInChildren<Button>(true))
			{
				if ((Object)(object)((Component)componentsInChild).GetComponent<UIMouseSoundEvent>() == (Object)null)
				{
					((Component)componentsInChild).gameObject.AddComponent<UIMouseSoundEvent>();
				}
			}
			IncreaseDecreasePanel val3 = gameObject.GetComponentInChildren<IncreaseDecreasePanel>(true);
			ChangeAtOnce(gameObject, val3);
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.ValueText == (Object)null)
			{
				val3 = null;
			}
			return new SettingRow
			{
				Rect = gameObject.GetComponent<RectTransform>(),
				Selectable = gameObject.GetComponent<Selectable>(),
				Description = SettingsPanel.Localize(((WorldCustomizationData)setting).descriptionKey),
				Control = val,
				Setting = setting,
				Steps = val3,
				ValueRestColor = (Color)(((Object)(object)val3 != (Object)null) ? ((Graphic)val3.ValueText).color : default(Color))
			};
		}

		private void ChangeAtOnce(GameObject control, IncreaseDecreasePanel steps)
		{
			foreach (SubSelectable componentsInChild in control.GetComponentsInChildren<SubSelectable>(true))
			{
				Object.DestroyImmediate((Object)(object)componentsInChild);
			}
			foreach (SubSelectableGroup componentsInChild2 in control.GetComponentsInChildren<SubSelectableGroup>(true))
			{
				Object.DestroyImmediate((Object)(object)componentsInChild2);
			}
			foreach (UIEventWidgetUser componentsInChild3 in control.GetComponentsInChildren<UIEventWidgetUser>(true))
			{
				Object.DestroyImmediate((Object)(object)componentsInChild3);
			}
			foreach (Selectable componentsInChild4 in control.GetComponentsInChildren<Selectable>(true))
			{
				if (!((Object)(object)((Component)componentsInChild4).gameObject == (Object)(object)control))
				{
					Navigation navigation = componentsInChild4.navigation;
					navigation.mode = (Mode)0;
					componentsInChild4.navigation = navigation;
				}
			}
			List<MonoBehaviour> val = new List<MonoBehaviour>();
			if ((Object)(object)steps != (Object)null && ((Behaviour)steps).isActiveAndEnabled)
			{
				val.Add((MonoBehaviour)(object)steps);
			}
			Slider componentInChildren = control.GetComponentInChildren<Slider>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				val.Add((MonoBehaviour)(object)componentInChildren);
			}
			EventSystemNotifierTarget val2 = control.AddComponent<EventSystemNotifierTarget>();
			val2.targets = val;
			val2.activationCooldown = 0f;
			val2._waitTime = 0f;
			EventSystemNotifier val3 = control.AddComponent<EventSystemNotifier>();
			val3.moveTargets = new Il2CppReferenceArray<EventSystemNotifierTarget>((EventSystemNotifierTarget[])(object)new EventSystemNotifierTarget[1] { val2 });
			val3.clickTargets = _noClickTargets;
			val3.submitTargets = _noSubmitTargets;
		}

		internal static void Refresh(SettingRow row)
		{
			row.Control.SetPanel((WorldCustomizationData)(object)row.Setting);
			ResolveCompositeRowLabel(row.Control.gameObject, ((WorldCustomizationData)row.Setting).nameKey);
			RowMarker.Show(row);
		}

		private static void ResolveCompositeRowLabel(GameObject control, string nameKey)
		{
			if (string.IsNullOrEmpty(nameKey) || nameKey.IndexOf('+') < 0)
			{
				return;
			}
			string text = SettingsPanel.Localize(nameKey);
			if (text == nameKey)
			{
				return;
			}
			foreach (TMP_Text componentsInChild in control.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;
				}
			}
		}
	}
	public class SettingsPanel : MonoBehaviour
	{
		private const string Tag = "[SettingsPlus]";

		internal static readonly string[] AllowedSectionKeys = new string[7] { "custom.difficulty", "custom.world", "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[3] { "custom.player.stats", "custom.player.proficiencies", "custom.player.affinities" },
			["custom.start.villagers.proficiencies"] = new string[3] { "custom.villager.survival", "custom.villager.proficiencies", "custom.villager.affinities" }
		};

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

		public static SettingsPanel Instance;

		private SettingsScreen _screen;

		private const string CompositeJoin = " - ";

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

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

		private readonly List<int> _recordedCostLevels = 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;
		}

		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()
		{
			return BlockedReasonKey() == null;
		}

		internal static string BlockedReasonKey()
		{
			try
			{
				NetworkRunner val = Object.FindObjectOfType<NetworkRunner>();
				if ((Object)(object)val == (Object)null)
				{
					return "reason.no_world";
				}
				return (val.IsServer || val.IsSharedModeMasterClient) ? null : "reason.not_host";
			}
			catch (Exception ex)
			{
				Warn("host check threw: " + ex.Message);
				return "reason.no_world";
			}
		}

		private void OpenInternal()
		{
			if (_screen != null && _screen.IsAlive)
			{
				return;
			}
			if (!IsHostOrSingleplayer())
			{
				Warn("host-only; not opening for a non-host client.");
				return;
			}
			WorldCustomizationConfig active = WorldCustomizationConfig.GetActive();
			if ((Object)(object)active == (Object)null || active.sections == null)
			{
				Warn("no active WorldCustomizationConfig (not in a loaded save?).");
				return;
			}
			if (Plugin.DebugLogging)
			{
				LogConfigKeys(active.sections);
			}
			List<ShownSection> list = ShownSections(active);
			if (list.Count == 0)
			{
				Warn("no allowlisted sections present in the active config.");
				return;
			}
			SnapshotCostLevels();
			SnapshotKnobLevels();
			_screen = SettingsScreen.Build(list, IsUnapplied, Apply, ResetToDefaults, Back);
			Log($"screen opened with {list.Count} sections.");
		}

		[HideFromIl2Cpp]
		private static void LogConfigKeys(List<WorldCustomizationSection> sections)
		{
			StringBuilder stringBuilder = new StringBuilder("config keys:");
			for (int i = 0; i < sections.Count; i++)
			{
				WorldCustomizationSection val = sections[i];
				if (val == null)
				{
					continue;
				}
				stringBuilder.Append("\n  section '").Append(val.titleKey).Append("' hidden=")
					.Append(val.isHidden)
					.Append(':');
				List<WorldCustomizationCategory> categories = val.categories;
				int num = 0;
				while (categories != null && num < categories.Count)
				{
					WorldCustomizationCategory val2 = categories[num];
					if (val2 != null)
					{
						stringBuilder.Append("\n    category '").Append(val2.titleKey).Append("' hidden=")
							.Append(val2.isHidden)
							.Append(" items=")
							.Append((val2.items != null) ? val2.items.Count : 0);
					}
					num++;
				}
			}
			Log(stringBuilder.ToString());
		}

		[HideFromIl2Cpp]
		internal static bool IsSectionAllowed(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;
		}

		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;
		}

		[HideFromIl2Cpp]
		private static List<ShownSection> ShownSections(WorldCustomizationConfig cfg)
		{
			List<ShownSection> list = new List<ShownSection>();
			List<WorldCustomizationSection> sections = cfg.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 (!IsSectionAllowed(text))
				{
					continue;
				}
				ShownSection shownSection = new ShownSection
				{
					TitleKey = text,
					Layout = val.customLayout
				};
				List<WorldCustomizationCategory> categories = val.categories;
				int num = 0;
				while (categories != null && num < categories.Count)
				{
					if (ShouldShowCategory(text, categories[num]))
					{
						ShownCategory shownCategory = new ShownCategory
						{
							TitleKey = (categories[num].titleKey ?? string.Empty)
						};
						AddShownSettings(cfg, categories[num], shownCategory.Settings);
						if (shownCategory.Settings.Count > 0)
						{
							shownSection.Categories.Add(shownCategory);
						}
					}
					num++;
				}
				if (shownSection.Categories.Count > 0)
				{
					list.Add(shownSection);
				}
			}
			return list;
		}

		[HideFromIl2Cpp]
		private static void AddShownSettings(WorldCustomizationConfig cfg, WorldCustomizationCategory cat, List<WorldCustomizationSelector> into)
		{
			List<int> items = cat.items;
			int num = 0;
			while (items != null && num < items.Count)
			{
				WorldCustomizationData data = cfg.GetData(items[num]);
				if (!((Object)(object)data == (Object)null) && !data.isHidden && !string.IsNullOrEmpty(data.nameKey) && !IsDeniedKnob(data.nameKey))
				{
					WorldCustomizationSelector val = ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>();
					if ((Object)(object)val != (Object)null && (Object)(object)val.parent == (Object)null)
					{
						into.Add(val);
					}
				}
				num++;
			}
		}

		[HideFromIl2Cpp]
		private void SnapshotKnobLevels()
		{
			_recordedLevels.Clear();
			_knobCategory.Clear();
			foreach (ShownSection item in ShownSections(WorldCustomizationConfig.GetActive()))
			{
				foreach (ShownCategory category in item.Categories)
				{
					foreach (WorldCustomizationSelector setting in category.Settings)
					{
						RecordSelectorLevel(setting, category.TitleKey);
					}
				}
			}
			CharacterWrites.RecordValues();
		}

		[HideFromIl2Cpp]
		private void RecordSelectorLevel(WorldCustomizationSelector selector, string categoryKey)
		{
			try
			{
				_recordedLevels[((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 bool IsUnapplied(WorldCustomizationSelector setting)
		{
			if (_recordedLevels.TryGetValue(((WorldCustomizationData)setting).id, out var value))
			{
				return setting.GetSelectedLevel() != value;
			}
			return false;
		}

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

		private void SnapshotCostLevels()
		{
			_recordedCostLevels.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++)
					{
						_recordedCostLevels.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 || _recordedCostLevels.Count == 0)
			{
				return;
			}
			try
			{
				List<WorldCustomizationSelector> requiredPreparationData = _costManager.requiredPreparationData;
				if (requiredPreparationData == null || requiredPreparationData.Count != _recordedCostLevels.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 != _recordedCostLevels[i])
					{
						flag = true;
						Log($"costs: '{(((Object)(object)val != (Object)null) ? ((WorldCustomizationData)val).nameKey : "?")}' level {_recordedCostLevels[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(List<(WorldCustomizationSelector Setting, string Category)> changes)
		{
			if (changes.Count == 0)
			{
				return;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (var change in changes)
			{
				hashSet.Add(change.Category);
			}
			Log("applied categories: " + string.Join(", ", hashSet) + ".");
			if (hashSet.Contains("custom.weather"))
			{
				ReapplyWeather();
			}
		}

		[HideFromIl2Cpp]
		private static List<string> WorldReloadNames(List<(WorldCustomizationSelector Setting, string Category)> changes)
		{
			List<string> list = new List<string>();
			foreach (var change in changes)
			{
				if ((Object)(object)change.Setting.parent == (Object)null && EffectTimings.Of(change.Category) == EffectTiming.WorldReload)
				{
					list.Add(Localize(((WorldCustomizationData)change.Setting).nameKey));
				}
			}
			return list;
		}

		[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 Apply()
		{
			List<(WorldCustomizationSelector, string)> list = UnappliedChanges();
			if (list.Count != 0)
			{
				ReapplyCostsIfChanged();
				ApplyChangedCategories(list);
				CharacterWrites.Apply(list);
				SnapshotCostLevels();
				SnapshotKnobLevels();
				_screen.ShowChanges();
				_screen.ShowApplyNote(WorldReloadNames(list));
			}
		}

		private void Back()
		{
			if (UnappliedChanges().Count == 0)
			{
				Close();
			}
			else
			{
				KitConfirmDialog.Ask(KitStrings.ApplyChangesMessage, 32000, ApplyAndClose, DiscardAndClose, Plugin.Log);
			}
		}

		private void ApplyAndClose()
		{
			if (_screen != null)
			{
				Apply();
				Close();
			}
		}

		private void DiscardAndClose()
		{
			if (_screen != null)
			{
				RestoreRecordedLevels();
				Close();
			}
		}

		[HideFromIl2Cpp]
		private void RestoreRecordedLevels()
		{
			WorldCustomizationConfig active = WorldCustomizationConfig.GetActive();
			foreach (int key in _recordedLevels.Keys)
			{
				WorldCustomizationData data = active.GetData(key);
				WorldCustomizationSelector val = (((Object)(object)data != (Object)null) ? ((Il2CppObjectBase)data).TryCast<WorldCustomizationSelector>() : null);
				if ((Object)(object)val != (Object)null && ((Object)(object)val.parent == (Object)null || !_recordedLevels.ContainsKey(((WorldCustomizationData)val.parent).id)))
				{
					ParentFirst(val, RestoreLevel);
				}
			}
		}

		[HideFromIl2Cpp]
		private void RestoreLevel(WorldCustomizationSelector setting)
		{
			if (_recordedLevels.TryGetValue(((WorldCustomizationData)setting).id, out var value))
			{
				setting.SelectLevel(value);
			}
		}

		[HideFromIl2Cpp]
		private void ResetToDefaults()
		{
			foreach (ShownSection item in ShownSections(WorldCustomizationConfig.GetActive()))
			{
				foreach (ShownCategory category in item.Categories)
				{
					foreach (WorldCustomizationSelector setting in category.Settings)
					{
						ParentFirst(setting, SetDefault);
					}
				}
			}
			_screen.RefreshRows();
		}

		[HideFromIl2Cpp]
		private static void SetDefault(WorldCustomizationSelector setting)
		{
			((WorldCustomizationData)setting).SetDefault();
		}

		[HideFromIl2Cpp]
		private static void ParentFirst(WorldCustomizationSelector setting, Action<WorldCustomizationSelector> write)
		{
			write(setting);
			List<WorldCustomizationData> val = new List<WorldCustomizationData>();
			if (!((WorldCustomizationData)setting).GetChildren(val))
			{
				return;
			}
			for (int i = 0; i < val.Count; i++)
			{
				WorldCustomizationSelector val2 = (((Object)(object)val[i] != (Object)null) ? ((Il2CppObjectBase)val[i]).TryCast<WorldCustomizationSelector>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					ParentFirst(val2, write);
				}
			}
		}

		private void Close()
		{
			_screen.Close();
			_screen = null;
			Log("screen closed.");
		}

		private void FinishOpen()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			try
			{
				_screen.FinishWhenOpen();
			}
			catch (Exception ex)
			{
				_screen = null;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" the screen did not open: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			if (_screen == null)
			{
				return;
			}
			try
			{
				if (!_screen.IsAlive)
				{
					_screen = null;
				}
				else if (!_screen.IsBuilt)
				{
					FinishOpen();
				}
				else if (KitConfirmDialog.IsOpen)
				{
					_screen.HideTooltip();
				}
				else
				{
					_screen.Tick();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(37, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("[SettingsPlus]");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Update threw; the screen is closed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				if (_screen != null)
				{
					Close();
				}
			}
		}
	}
	internal sealed class SettingsScreen
	{
		private sealed class SectionPage
		{
			public ShownSection Section;

			public Button Tab;

			public GameObject Scroll;

			public RectTransform Viewport;

			public RectTransform Content;

			public RectTransform Bar;

			public bool Filled;

			public readonly List<SettingRow> Rows = new List<SettingRow>();

			public readonly List<Selectable> Chain = new List<Selectable>();
		}

		internal const int SortingOrder = 32000;

		private static readonly Vector2 ReferenceResolution = new Vector2(1280f, 720f);

		private const float WheelStep = 30f;

		private const float OpenLimitSeconds = 3f;

		private const float ButtonGap = 8f;

		private const string BackButtonName = "ButtonBack";

		private const string ResetButtonName = "ButtonReset";

		private const float NoteGap = 6f;

		private const float NoteSideMargin = 20f;

		private const float NoteLineHeight = 20f;

		private const float NoteTextSize = 16f;

		private const float TooltipGap = 8f;

		private const float GlyphGap = 6f;

		private const float GlyphEdgeMargin = 6f;

		private const float FootMargin = 16f;

		private const float MinFootWidth = 150f;

		private const int MostNoteLines = 2;

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

		private readonly List<object> _listeners = new List<object>();

		private readonly List<SectionPage> _pages = new List<SectionPage>();

		private Func<WorldCustomizationSelector, bool> _isUnapplied;

		private Action _buildParts;

		private float _openBy;

		private GameObject _canvas;

		private MenuHost _host;

		private GameObject _headerTemplate;

		private KitNote _note;

		private KitTooltip _tooltip;

		private Color _markerColor;

		private Color _tabRest;

		private Color _tabHover;

		private Color _tabSelected;

		private SectionPage _shown;

		private RectTransform _frame;

		private SettingRow _described;

		private readonly SettingRows _rows = new SettingRows();

		private RectTransform _canvasRect;

		private RectTransform _tooltipBox;

		private TMP_Text _tooltipText;

		private float _tooltipTextSize;

		private TextOverflowModes _tooltipOverflow;

		private bool _tooltipTextFitted;

		private float _frameRight;

		private bool _boxBesideFrame;

		private InputAction _pageAction;

		private InputAction _applyAction;

		private InputAction _resetAction;

		private Button _backButton;

		private Button _applyButton;

		private Button _resetButton;

		private List<GlyphDisplayComponent> _glyphs = new List<GlyphDisplayComponent>();

		private bool _glyphsShown;

		private IntPtr _selectedObject;

		private SettingRow _selectedRow;

		internal bool IsAlive => (Object)(object)_canvas != (Object)null;

		internal bool IsBuilt => _buildParts == null;

		internal static SettingsScreen Build(List<ShownSection> sections, Func<WorldCustomizationSelector, bool> isUnapplied, Action onApply, Action onReset, Action onBack)
		{
			SettingsScreen screen = new SettingsScreen
			{
				_isUnapplied = isUnapplied
			};
			try
			{
				screen.BuildRoot(onBack);
			}
			catch
			{
				screen.Close();
				throw;
			}
			screen._buildParts = delegate
			{
				screen.BuildParts(sections, onApply, onReset, onBack);
			};
			screen._openBy = Time.unscaledTime + 3f;
			screen.FinishWhenOpen();
			return screen;
		}

		internal void FinishWhenOpen()
		{
			if (!((Menu)_host).IsActive)
			{
				if (Time.unscaledTime <= _openBy)
				{
					return;
				}
				Close();
				throw new InvalidOperationException($"The menu manager did not open the screen in {3f} s.");
			}
			Action buildParts = _buildParts;
			_buildParts = null;
			try
			{
				buildParts();
			}
			catch
			{
				Close();
				throw;
			}
		}

		internal void Close()
		{
			if ((Object)(object)_host != (Object)null && ((Menu)_host).IsActive)
			{
				((Menu)_host).Close();
			}
			else if ((Object)(object)_canvas != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_canvas);
			}
		}

		internal void RefreshRows()
		{
			foreach (SectionPage page in _pages)
			{
				foreach (SettingRow row in page.Rows)
				{
					SettingRows.Refresh(row);
					ShowChange(row);
				}
			}
		}

		internal void ShowChanges()
		{
			foreach (SectionPage page in _pages)
			{
				foreach (SettingRow row in page.Rows)
				{
					ShowChange(row);
				}
			}
		}

		private void ShowChange(SettingRow row)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)row.Steps != (Object)null)
			{
				((Graphic)row.Steps.ValueText).color = (_isUnapplied(row.Setting) ? _markerColor : row.ValueRestColor);
			}
		}

		private void WatchValue(SettingRow row)
		{
			if (!((Object)(object)row.Steps == (Object)null))
			{
				UnityAction<int> val = UnityAction<int>.op_Implicit((Action<int>)delegate
				{
					ShowChange(row);
				});
				_listeners.Add(val);
				((UnityEvent<int>)(object)row.Steps.OnValueChanged).AddListener(val);
				ShowChange(row);
			}
		}

		internal void ShowApplyNote(List<string> reloadNames)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			List<(string, Color)> list = new List<(string, Color)> { (KitStrings.Applied, _note.RestColor) };
			if (reloadNames.Count > 0)
			{
				list.Add((KitStrings.WorldReloadNote(reloadNames.ConvertAll<string>(KitRichText.Plain)), _markerColor));
			}
			_note.Show(list);
		}

		internal void Tick()
		{
			bool controllerInUse = MenuHost.ControllerInUse;
			if (controllerInUse != _glyphsShown)
			{
				ShowGlyphs(controllerInUse);
				HideTooltip();
			}
			if (((Menu)_host).IsActive)
			{
				StepSectionOnPageAction();
				if (controllerInUse)
				{
					PressButtonOnPanelAction();
				}
			}
			if (_tooltip != null)
			{
				DescribeRow(controllerInUse);
			}
		}

		private void PressButtonOnPanelAction()
		{
			if (_applyAction.WasPressedThisFrame())
			{
				((UnityEvent)_applyButton.onClick).Invoke();
			}
			else if (_resetAction.WasPressedThisFrame())
			{
				((UnityEvent)_resetButton.onClick).Invoke();
			}
		}

		private void ShowGlyphs(bool shown)
		{
			_glyphsShown = shown;
			if (shown)
			{
				PlaceGlyphs();
			}
			foreach (GlyphDisplayComponent glyph in _glyphs)
			{
				((Component)glyph).gameObject.SetActive(shown);
				if (shown)
				{
					glyph.Refresh();
				}
			}
		}

		private void StepSectionOnPageAction()
		{
			if (_pageAction.WasPerformedThisFrame())
			{
				int index = SectionStep.Next(_pages.Count, _pages.IndexOf(_shown), Math.Sign(_pageAction.ReadValue<float>()));
				if (_pages[index] != _shown)
				{
					Select(index);
				}
			}
		}

		private void DescribeRow(bool controller)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000f: 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)
			Vector2 pointer = Vector2.op_Implicit(Input.mousePosition);
			SettingRow settingRow = (controller ? SelectedRow() : RowUnder(pointer));
			if (settingRow == null)
			{
				HideTooltip();
				return;
			}
			if (settingRow != _described)
			{
				_described = settingRow;
				RestoreTooltipText();
				_tooltip.Show(settingRow.Description);
				if (controller)
				{
					PlaceForController();
				}
			}
			if (!controller)
			{
				_tooltip.Follow(pointer);
			}
			else if (_boxBesideFrame)
			{
				PlaceBesideFrame(settingRow);
			}
		}

		private SettingRow SelectedRow()
		{
			EventSystem current = EventSystem.current;
			GameObject val = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				_selectedObject = IntPtr.Zero;
				return null;
			}
			if (((Il2CppObjectBase)val).Pointer != _selectedObject)
			{
				_selectedObject = ((Il2CppObjectBase)val).Pointer;
				_selectedRow = RowOf(val.transform);
			}
			return _selectedRow;
		}

		private SettingRow RowOf(Transform part)
		{
			List<SettingRow> rows = _shown.Rows;
			for (int i = 0; i < rows.Count; i++)
			{
				if (part.IsChildOf((Transform)(object)rows[i].Rect))
				{
					return rows[i];
				}
			}
			return null;
		}

		private void PlaceForController()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0039: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			//IL_00c8: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			Vector2 sizeDelta = _tooltipBox.sizeDelta;
			Rect val = RectIn(_canvasRect, _frame);
			_frameRight = ((Rect)(ref val)).xMax;
			float num = _frameRight + 8f + sizeDelta.x;
			val = _canvasRect.rect;
			_boxBesideFrame = num <= ((Rect)(ref val)).xMax;
			if (_boxBesideFrame)
			{
				return;
			}
			Rect val2 = Around(VisibleRect(((Component)_applyButton).transform), VisibleRect(((Component)_backButton).transform));
			float num2 = ((Rect)(ref val2)).xMax + 8f;
			float num3 = Mathf.Min(sizeDelta.x, _frameRight - 16f - num2);
			val = RectIn(_canvasRect, _shown.Viewport);
			float num4 = ((Rect)(ref val)).yMin - 8f - ((Rect)(ref val2)).yMin;
			float x = sizeDelta.x;
			val = _tooltipText.rectTransform.rect;
			float num5 = x - ((Rect)(ref val)).width;
			if (num3 < 150f || num4 <= num5)
			{
				_tooltip.Hide();
				return;
			}
			if (num3 < sizeDelta.x)
			{
				((Vector2)(ref sizeDelta))..ctor(num3, _tooltipText.GetPreferredValues(_tooltipText.text, num3 - num5, 0f).y + num5);
			}
			if (sizeDelta.y > num4)
			{
				sizeDelta.y = num4;
				_tooltipText.enableAutoSizing = true;
				_tooltipText.fontSizeMax = _tooltipTextSize;
				_tooltipText.fontSizeMin = _tooltipTextSize * 0.6f;
				_tooltipText.overflowMode = (TextOverflowModes)1;
				_tooltipTextFitted = true;
			}
			_tooltipBox.sizeDelta = sizeDelta;
			MoveBox(num2, ((Rect)(ref val2)).yMin + sizeDelta.y);
		}

		private void RestoreTooltipText()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (_tooltipTextFitted)
			{
				_tooltipTextFitted = false;
				_tooltipText.enableAutoSizing = false;
				_tooltipText.fontSize = _tooltipTextSize;
				_tooltipText.overflowMode = _tooltipOverflow;
			}
		}

		private Rect VisibleRect(Transform control)
		{
			//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_0027: 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_0039: 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)
			Rect val = RectIn(_canvasRect, ((Il2CppObjectBase)control).Cast<RectTransform>());
			foreach (Graphic componentsInChild in ((Component)control).GetComponentsInChildren<Graphic>())
			{
				val = Around(val, RectIn(_canvasRect, componentsInChild.rectTransform));
			}
			return val;
		}

		private static Rect Around(Rect a, Rect b)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			return Rect.MinMaxRect(Mathf.Min(((Rect)(ref a)).xMin, ((Rect)(ref b)).xMin), Mathf.Min(((Rect)(ref a)).yMin, ((Rect)(ref b)).yMin), Mathf.Max(((Rect)(ref a)).xMax, ((Rect)(ref b)).xMax), Mathf.Max(((Rect)(ref a)).yMax, ((Rect)(ref b)).yMax));
		}

		private void PlaceBesideFrame(SettingRow row)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = _canvasRect.rect;
			Rect val = RectIn(_canvasRect, row.Rect);
			float yMax = ((Rect)(ref val)).yMax;
			MoveBox(_frameRight + 8f, Mathf.Clamp(yMax, ((Rect)(ref rect)).yMin + _tooltipBox.sizeDelta.y, ((Rect)(ref rect)).yMax));
		}

		private void MoveBox(float left, float top)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = _canvasRect.rect;
			_tooltipBox.anchoredPosition = new Vector2(left - ((Rect)(ref rect)).xMin, top - ((Rect)(ref rect)).yMax);
		}

		private SettingRow RowUnder(Vector2 pointer)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!RectTransformUtility.RectangleContainsScreenPoint(_shown.Viewport, pointer, (Camera)null))
			{
				return null;
			}
			List<SettingRow> rows = _shown.Rows;
			for (int i = 0; i < rows.Count; i++)
			{
				if (RectTransformUtility.RectangleContainsScreenPoint(rows[i].Rect, pointer, (Camera)null))
				{
					return rows[i];
				}
			}
			return null;
		}

		internal void HideTooltip()
		{
			_described = null;
			if (_tooltip != null && _tooltip.IsShown)
			{
				_tooltip.Hide();
			}
		}

		private void BuildRoot(Action onBack)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			_canvas = new GameObject("SettingsPlus_Screen");
			_canvas.SetActive(false);
			Canvas obj = _canvas.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 32000;
			CanvasScaler obj2 = _canvas.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = ReferenceResolution;
			obj2.screenMatchMode = (ScreenMatchMode)1;
			_canvas.AddComponent<GraphicRaycaster>();
			_host = MenuHost.AddTo(_canvas, onBack);
			_canvas.SetActive(true);
			_canvasRect = _canvas.GetComponent<RectTransform>();
			_host.Open();
		}

		private void BuildParts(List<ShownSection> sections, Action onApply, Action onReset, Action onBack)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Expected O, but got Unknown
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = UiParts.NewRect("Backdrop", _canvas.transform);
			UiParts.Stretch(obj);
			((Graphic)((Component)obj).gameObject.AddComponent<Image>()).color = BackdropColor;
			RectTransform val = UiParts.NewRect("Templates", _canvas.transform);
			((Component)val).gameObject.SetActive(false);
			GameObject val2 = UiParts.CloneInto(((Component)WorldSetupParts.Page()).transform, (Transform)(object)val);
			WorldCustomizationTabPage val3 = Need<WorldCustomizationTabPage>(val2.GetComponent<WorldCustomizationTabPage>(), "WorldCustomizationTabPage");
			WorldCustomizationSectionTabPage val4 = Need<WorldCustomizationSectionTabPage>(val2.GetComponentInChildren<WorldCustomizationSectionTabPage>(true), "WorldCustomizationSectionTabPage");
			TabGroup val5 = Need<TabGroup>(val2.GetComponent<TabGroup>(), "TabGroup");
			_tabRest = val5.normalColor;
			_tabHover = val5.highlightColor;
			_tabSelected = val5.selectColor;
			Transform transform = ((Component)Need<TabButton>(val3.sectionTabButtonPrefab, "sectionTabButtonPrefab")).transform;
			RectTransform val6 = Need<RectTransform>(((Il2CppObjectBase)transform.parent).TryCast<RectTransform>(), "section strip");
			Transform transform2 = ((Component)val4).transform;
			GameObject val7 = Need<GameObject>(val4.fallbackLayout, "fallbackLayout");
			GameObject gameObject = ((Component)Need<IconTextPairComponent>(val4.categHeaderPrefab, "categHeaderPrefab")).gameObject;
			_headerTemplate = KitHeader.Template(gameObject.transform, (Transform)(object)val);
			_markerColor = ((Graphic)KitHeader.Title(_headerTemplate)).color;
			Object.DestroyImmediate((Object)(object)gameObject);
			Object.DestroyImmediate((Object)(object)((Component)UiParts.Child(val2.transform, "NewGamePage_Custom")).gameObject);
			Transform val8 = UiParts.Child(val2.transform, "ButtonGroup");
			string labelKey = LabelKey(UiParts.Child(val8, "ButtonReset"));
			for (int num = val8.childCount - 1; num >= 0; num--)
			{
				if (((Object)val8.GetChild(num)).name != "ButtonBack")
				{
					Object.DestroyImmediate((Object)(object)((Component)val8.GetChild(num)).gameObject);
				}
			}
			VerticalLayoutGroup component = ((Component)val8).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)component != (Object)null)
			{
				((LayoutGroup)component).childAlignment = (TextAnchor)7;
			}
			Transform val9 = UiParts.Child(val8, "ButtonBack");
			((Component)val9).gameObject.AddComponent<UIMouseSoundEvent>();
			_backButton = Need<Button>(((Component)val9).GetComponent<Button>(), "ButtonBack Button");
			UiParts.Hook(_backButton, Pressed(onBack), _listeners);
			_applyButton = AddButton(val9, "ButtonApply", "common.apply", 0, onApply);
			_resetButton = AddButton(val9, "ButtonReset", labelKey, 1, onReset);
			RectTransform topButton = Need<RectTransform>(((Component)_applyButton).GetComponent<RectTransform>(), "ButtonApply RectTransform");
			Object.DestroyImmediate((Object)(object)((Component)UiParts.Child((Transform)(object)val6, "GameSettingsButton")).gameObject);
			UiParts.StripAll(val2, "WorldCustomizationTabPage", "TabGroupControls", "TransformEventsHelper", "WorldCustomizationSectionTabPage", "TooltipDetailsTabPage");
			val7.SetActive(false);
			for (int i = 0; i < sections.Count; i++)
			{
				_pages.Add(BuildSectionPage(sections[i], i, transform, (Transform)(object)val6, val7.transform, transform2));
			}
			RectTransform component2 = val2.GetComponent<RectTransform>();
			((Transform)component2).SetParent(_canvas.transform, false);
			val2.SetActive(true);
			((Component)transform2).gameObject.SetActive(true);
			Centre(component2, val6);
			_frame = component2;
			_note = BuildNote(topButton);
			bool flag = default(bool);
			try
			{
				_glyphs = ButtonGlyphs.Add(_canvas.transform);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val10 = new BepInExErrorLogInterpolatedStringHandler(76, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val10).AppendLiteral("[SettingsPlus] The button glyphs could not be built; the screen shows none. ");
					((BepInExLogInterpolatedStringHandler)val10).AppendFormatted<Exception>(ex);
				}
				log.LogError(val10);
			}
			try
			{
				KitTooltip tooltip = KitTooltip.Build(((Component)WorldSetupParts.TooltipDetailsPage()).transform, _canvas.transform);
				_tooltipBox = ((Il2CppObjectBase)((Transform)_canvasRect).GetChild(((Transform)_canvasRect).childCount - 1)).Cast<RectTransform>();
				_tooltipText = Need<TMP_Text>(((Component)UiParts.Child((Transform)(object)_tooltipBox, "Text (TMP)")).GetComponent<TMP_Text>(), "tooltip text");
				_tooltipTextSize = _tooltipText.fontSize;
				_tooltipOverflow = _tooltipText.overflowMode;
				_tooltip = tooltip;
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val10 = new BepInExErrorLogInterpolatedStringHandler(77, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val10).AppendLiteral("[SettingsPlus] The tooltip box could not be built; rows show no description. ");
					((BepInExLogInterpolatedStringHandler)val10).AppendFormatted<Exception>(ex2);
				}
				log2.LogError(val10);
			}
			MenuControlsActions menuControls = InputManager.controls.MenuControls;
			_pageAction = menuControls.PageNavigation;
			_applyAction = menuControls.PanelAction1;
			_resetAction = menuControls.PanelAction2;
			Select(0);
		}

		private void PlaceGlyphs()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (_glyphs.Count != 0)
			{
				PlaceBeside(_glyphs[0], VisibleRect(((Component)_applyButton).transform), -1f);
				PlaceBeside(_glyphs[1], VisibleRect(((Component)_resetButton).transform), -1f);
				PlaceBeside(_glyphs[2], RectIn(_canvasRect, ((Il2CppObjectBase)((Component)_pages[0].Tab).transform).Cast<RectTransform>()), -1f);
				PlaceBeside(_glyphs[3], RectIn(_canvasRect, ((Il2CppObjectBase)((Component)_pages[_pages.Count - 1].Tab).transform).Cast<RectTransform>()), 1f);
			}
		}

		private void PlaceBeside(GlyphDisplayComponent glyph, Rect at, float side)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = ((Il2CppObjectBase)((Component)glyph).transform).Cast<RectTransform>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			obj.anchorMax = val;
			obj.anchorMin = val;
			obj.pivot = new Vector2(0.5f - side * 0.5f, 0.5f);
			Rect rect = _canvasRect.rect;
			Rect rect2 = obj.rect;
			float width = ((Rect)(ref rect2)).width;
			float num = ((side < 0f) ? ((Rect)(ref at)).xMin : ((Rect)(ref at)).xMax) + side * 6f;
			num = Mathf.Clamp(num, ((Rect)(ref rect)).xMin + 6f + ((side < 0f) ? width : 0f), ((Rect)(ref rect)).xMax - 6f - ((side > 0f) ? width : 0f));
			obj.anchoredPosition = new Vector2(num, ((Rect)(ref at)).center.y);
		}

		private SectionPage BuildSectionPage(ShownSection section, int index, Transform tabSource, Transform strip, Transform scrollSource, Transform pageArea)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UiParts.CloneInto(tabSource, strip);
			((Object)val).name = "Tab_" + section.TitleKey;
			Graphic val2 = Need<Graphic>(Need<TabButton>(val.GetComponent<TabButton>(), "TabButton").image ?? val.GetComponent<Graphic>(), "section tab image");
			IconTextPairComponent component = val.GetComponent<IconTextPairComponent>();
			TMP_Text val3 = Need<TMP_Text>((((Object)(object)component != (Object)null) ? component.text : null) ?? val.GetComponentInChildren<TMP_Text>(true), "section tab label");
			UiParts.Strip(val, "TabButton", "IconTextPairComponent");
			UiParts.StripAll(val, "LocalizedText");
			val3.text = SettingsPanel.Localize(section.TitleKey);
			val2.color = Color.white;
			val2.raycastTarget = true;
			Button val4 = UiParts.HoverButton(val, val2, _tabRest);
			Navigation navigation = ((Selectable)val4).navigation;
			navigation.mode = (Mode)0;
			((Selectable)val4).navigation = navigation;
			UiParts.Hook(val4, delegate
			{
				Select(index);
			}, _listeners);
			val.SetActive(true);
			GameObject val5 = (((Object)(object)section.Layout != (Object)null) ? SideBySideLayout.Clone(section.Layout, pageArea) : UiParts.CloneInto(scrollSource, pageArea));
			ScrollRect val6 = Need<ScrollRect>(val5.GetComponentInChildren<ScrollRect>(true), "ScrollRect");
			val6.scrollSensitivity = 30f;
			RectTransform val7 = (((Object)(object)val6.viewport != (Object)null) ? val6.viewport : val5.GetComponent<RectTransform>());
			if ((Object)(object)((Component)val7).GetComponent<Graphic>() == (Object)null)
			{
				((Graphic)((Component)val7).gameObject.AddComponent<Image>()).color = Color.clear;
			}
			return new SectionPage
			{
				Section = section,
				Tab = val4,
				Scroll = val5,
				Viewport = val7,
				Content = Need<RectTransform>(val6.content, "ScrollRect.content"),
				Bar = (((Object)(object)val6.verticalScrollbar != (Object)null) ? ((Component)val6.verticalScrollbar).GetComponent<RectTransform>() : null)
			};
		}

		private void Select(int index)
		{
			//IL_004e: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			HideTooltip();
			_selectedObject = IntPtr.Zero;
			for (int i = 0; i < _pages.Count; i++)
			{
				bool flag = i == index;
				_pages[i].Scroll.SetActive(flag);
				Tint(_pages[i].Tab, flag ? _tabSelected : _tabRest, flag ? _tabSelected : _tabHover);
			}
			_shown = _pages[index];
			if (!_shown.Filled)
			{
				Fill(_shown);
			}
			if (_shown.Chain.Count > 0)
			{
				_host.SelectFirst(_shown.Chain[0]);
			}
		}

		private static void Tint(Button tab, Color rest, Color hover)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			ColorBlock colors = ((Selectable)tab).colors;
			((ColorBlock)(ref colors)).normalColor = rest;
			((ColorBlock)(ref colors)).highlightedColor = hover;
			((ColorBlock)(ref colors)).pressedColor = hover;
			((ColorBlock)(ref colors)).selectedColor = rest;
			((ColorBlock)(ref colors)).disabledColor = rest;
			((Selectable)tab).colors = colors;
		}

		private void Fill(SectionPage page)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			page.Filled = true;
			bool flag = default(bool);
			foreach (ShownCategory category in page.Section.Categories)
			{
				string title = SettingsPanel.Localize(category.TitleKey);
				RectTransform val = ColumnFor(page, category, title);
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(87, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SettingsPlus] category '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(category.TitleKey);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': the section's layout has no place for it; category skipped.");
					}
					log.LogWarning(val2);
					continue;
				}
				foreach (WorldCustomizationSelector setting in category.Settings)
				{
					try
					{
						SettingRow settingRow = _rows.Add(setting, SideBySideLayout.Slot(val, setting));
						if (settingRow != null)
						{
							RowMarker.Mark(settingRow, category.TitleKey, _markerColor);
							WatchValue(settingRow);
							page.Rows.Add(settingRow);
						}
					}
					catch (Exception ex)
					{
						ManualLogSource log2 = Plugin.Log;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SettingsPlus] setting '");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((WorldCustomizationData)setting).nameKey);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': row skipped: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
						}
						log2.LogWarning(val2);
					}
				}
			}
			FitToFrame(page);
			ChainRows(page);
			((Menu)_host).RefreshSelectables();
		}

		private void ChainRows(SectionPage page)
		{
			List<Selectable> chain = page.Chain;
			foreach (SettingRow row in page.Rows)
			{
				if ((Object)(object)row.Selectable != (Object)null)
				{
					chain.Add(row.Selectable);
				}
			}
			for (int i = 0; i < chain.Count; i++)
			{
				Navigation navigation = chain[i].navigation;
				navigation.mode = (Mode)4;
				navigation.selectOnUp = ((i > 0) ? chain[i - 1] : null);
				navigation.selectOnDown = (Selectable)((i + 1 < chain.Count) ? ((object)chain[i + 1]) : ((object)_applyButton));
				navigation.selectOnLeft = null;
				navigation.selectOnRight = null;
				chain[i].navigation = navigation;
			}
		}

		private RectTransform ColumnFor(SectionPage page, ShownCategory category, string title)
		{
			WorldCustomizationLayout component = page.Scroll.GetComponent<WorldCustomizationLayout>();
			if ((Object)(object)component != (Object)null)
			{
				return SideBySideLayout.Column(component, category.TitleKey, title);
			}
			KitHeader.Add(_headerTemplate, (Transform)(object)page.Content, title);
			return page.Content;
		}

		private void FitToFrame(SectionPage page)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0071: 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)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (((Transform)page.Content).childCount != 0)
			{
				Canvas.ForceUpdateCanvases();
				Rect rect = _frame.rect;
				Rect val = RectIn(_frame, page.Viewport);
				Rect val2 = RectIn(_frame, ((Component)((Transform)page.Content).GetChild(0)).GetComponent<RectTransform>());
				float xMax;
				if (!((Object)(object)page.Bar != (Object)null))
				{
					xMax = ((Rect)(ref val2)).xMax;
				}
				else
				{
					Rect val3 = RectIn(_frame, page.Bar);
					xMax = ((Rect)(ref val3)).xMax;
				}
				float num = xMax;
				float right = (((Rect)(ref rect)).xMax - num - (((Rect)(ref val2)).xMin - ((Rect)(ref rect)).xMin)) / 2f;
				Rect val4 = RectIn(_frame, _note.Label.rectTransform);
				float bottomDown = ((Rect)(ref val)).yMin - (((Rect)(ref val4)).yMax + 8f);
				Move(page.Viewport, right, bottomDown);
				if ((Object)(object)page.Bar != (Object)null)
				{
					Move(page.Bar, right, bottomDown);
				}
			}
		}

		private static void Move(RectTransform part, float right, float bottomDown)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0034: 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)
			part.offsetMin = new Vector2(part.offsetMin.x + right, part.offsetMin.y - bottomDown);
			part.offsetMax = new Vector2(part.offsetMax.x + right, part.offsetMax.y);
		}

		private static Rect RectIn(RectTransform space, RectTransform part)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = part.rect;
			Vector2 val = Vector2.op_Implicit(((Transform)space).InverseTransformPoint(((Transform)part).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).min))));
			Vector2 val2 = Vector2.op_Implicit(((Transform)space).InverseTransformPoint(((Transform)part).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).max))));
			return Rect.MinMaxRect(val.x, val.y, val2.x, val2.y);
		}

		private static void Centre(RectTransform frame, RectTransform strip)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			frame.anchorMax = val;
			frame.anchorMin = val;
			Rect rect = frame.rect;
			float y = ((Transform)strip).localPosition.y;
			float yMax = ((Rect)(ref rect)).yMax;
			Rect rect2 = strip.rect;
			float num = Mathf.Max(yMax, y + ((Rect)(ref rect2)).yMax);
			float yMin = ((Rect)(ref rect)).yMin;
			rect2 = strip.rect;
			float num2 = Mathf.Min(yMin, y + ((Rect)(ref rect2)).yMin);
			frame.anchoredPosition = new Vector2(0f - ((Rect)(ref rect)).center.x, (0f - (num + num2)) / 2f);
		}

		private KitNote BuildNote(RectTransform topButton)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			Canvas.ForceUpdateCanvases();
			RectTransform component = _canvas.GetComponent<RectTransform>();
			Rect val = RectIn(component, _frame);
			Rect val2 = RectIn(component, topButton);
			float num = ((Rect)(ref val2)).yMax + 6f + 20f;
			TMP_Text component2 = UiParts.CloneInto(KitHeader.Title(_headerTemplate).transform, _canvas.transform).GetComponent<TMP_Text>();
			((Object)component2).name = "Note";
			component2.text = string.Empty;
			component2.enableAutoSizing = false;
			component2.fontSize = 16f;
			((Graphic)component2).color = KitFieldFrame.RestColor;
			component2.alignment = (TextAlignmentOptions)514;
			((Graphic)component2).raycastTarget = false;
			RectTransform rectTransform = component2.rectTransform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val3;
			rectTransform.anchorMin = val3;
			rectTransform.pivot = new Vector2(0.5f, 0f);
			rectTransform.sizeDelta = new Vector2(((Rect)(ref val)).width - 40f, 20f);
			rectTransform.anchoredPosition = new Vector2(((Rect)(ref val)).center.x, num);
			return KitNote.From(component2);
		}

		private static string LabelKey(Transform button)
		{
			string key = Need<LocalizedText>(((Component)UiParts.Label(button)).GetComponent<LocalizedText>(), ((Object)button).name + " LocalizedText").key;
			if (string.IsNullOrEmpty(key))
			{
				throw new InvalidOperationException("The world setup screen's '" + ((Object)button).name + "' label has no localization key.");
			}
			return key;
		}

		private Button AddButton(Transform back, string name, string labelKey, int index, Action onClick)
		{
			Button obj = KitButton.Build(back, back.parent, Pressed(onClick), _listeners);
			((Object)obj).name = name;
			((Component)obj).transform.SetSiblingIndex(index);
			Need<LocalizedText>(((Component)UiParts.Label(((Component)obj).transform)).GetComponent<LocalizedText>(), name + " LocalizedText").key = labelKey;
			return obj;
		}

		private static Action Pressed(Action action)
		{
			return delegate
			{
				EventSystem current = EventSystem.current;
				if ((Object)(object)current != (Object)null && !MenuHost.ControllerInUse)
				{
					current.SetSelectedGameObject((GameObject)null);
				}
				action();
			};
		}

		private static T Need<T>(T part, string name) where T : Object
		{
			if (!((Object)(object)part != (Object)null))
			{
				throw new InvalidOperationException("The world setup screen's '" + name + "' was not found.");
			}
			return part;
		}
	}
	internal sealed class ShownSection
	{
		internal string TitleKey;

		internal GameObject Layout;

		internal readonly List<ShownCategory> Categories = new List<ShownCategory>();
	}
	internal sealed class ShownCategory
	{
		internal string TitleKey;

		internal readonly List<WorldCustomizationSelector> Settings = new List<WorldCustomizationSelector>();
	}
	internal static class SideBySideLayout
	{
		internal static GameObject Clone(GameObject prefab, Transform parent)
		{
			GameObject val = UiParts.CloneInto(prefab.transform, parent);
			val.SetActive(false);
			UiParts.StripAll(val, "TransformEventsHelper");
			return val;
		}

		internal static RectTransform Column(WorldCustomizationLayout layout, string categoryKey, string title)
		{
			GameObject contentParent = layout.GetContentParent(categoryKey);
			if ((Object)(object)contentParent == (Object)null || (Object)(object)contentParent == (Object)(object)((Component)layout).gameObject)
			{
				return null;
			}
			WorldCustomizationLayout component = contentParent.GetComponent<WorldCustomizationLayout>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetSectionName(title);
			}
			return contentParent.GetComponent<RectTransform>();
		}

		internal static RectTransform Slot(RectTransform column, WorldCustomizationSelector setting)
		{
			WorldCustomizationLayout component = ((Component)column).GetComponent<WorldCustomizationLayout>();
			if (!((Object)(object)component != (Object)null))
			{
				return column;
			}
			return component.GetContentParent(((Object)setting).name).GetComponent<RectTransform>();
		}
	}
	internal static class Strings
	{
		internal const string ProficiencyRuleLine = "timing.proficiency_rule";

		internal const string NoWorldReason = "reason.no_world";

		internal const st