Decompiled source of ModSettingsMenu v1.3.0
BepInEx/plugins/ModSettingsMenu/ModSettingsMenu.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ModSettingsMenu.Api; using ModSettingsMenu.Configuration; using ModSettingsMenu.Localization; using ModSettingsMenu.Runtime; using SunkenlandLocalizationAPI.Api; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ModSettingsMenu")] [assembly: AssemblyDescription("Mod Settings Menu mod for Sunkenland by Ice Box Studio")] [assembly: AssemblyCompany("Ice Box Studio")] [assembly: AssemblyProduct("ModSettingsMenu")] [assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")] [assembly: ComVisible(false)] [assembly: Guid("6d512f55-e9ee-445c-9fb4-93ed6c1ef50a")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.3.0.0")] namespace ModSettingsMenu { [BepInPlugin("IceBoxStudio.Sunkenland.ModSettingsMenu", "ModSettingsMenu", "1.3.0")] [BepInDependency("IceBoxStudio.Sunkenland.LocalizationAPI", "1.2.0")] public sealed class ModSettingsMenu : BaseUnityPlugin { private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModSettingsRegistry.RefreshRequested += RefreshMenus; LocalizationApi.LanguageChanged += RefreshLocalizedText; try { Log.LogInfo((object)"============================================="); Log.LogInfo((object)("ModSettingsMenu " + I18n.Text("plugin.initializing"))); Log.LogInfo((object)(I18n.Text("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)")); _harmony = new Harmony("IceBoxStudio.Sunkenland.ModSettingsMenu"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)("ModSettingsMenu " + I18n.Text("plugin.initialized"))); Log.LogInfo((object)"============================================="); } catch (Exception arg) { Log.LogError((object)$"Failed to initialize Mod Settings Menu: {arg}"); } } private static void RefreshMenus() { ModSettingsMenuController.Refresh(); } private static void RefreshLocalizedText(string language) { ModSettingsMenuController.RefreshLocalizedText(); } } public static class PluginInfo { public const string PLUGIN_GUID = "IceBoxStudio.Sunkenland.ModSettingsMenu"; public const string PLUGIN_NAME = "ModSettingsMenu"; public const string PLUGIN_VERSION = "1.3.0"; } } namespace ModSettingsMenu.Runtime { internal sealed class ConfigRows { private readonly Transform _content; private readonly GameObject _row; private readonly GameObject _heading; private readonly GameObject _toggle; private readonly GameObject _dropdown; private readonly KeybindCapture _keybindCapture; private readonly ModInfoRow _info; private readonly List<GameObject> _createdRows = new List<GameObject>(); public ConfigRows(Transform content, GameObject row, GameObject heading, GameObject toggle, GameObject dropdown, KeybindCapture keybindCapture, ModInfoRow info) { _content = content; _row = row; _heading = heading; _toggle = toggle; _dropdown = dropdown; _keybindCapture = keybindCapture; _info = info; } public void Build(ModConfig mod) { ClearRows(); if (mod == null) { CreateHeading(I18n.Text("menu.no_configurable_mods")); } else { GameObject val = _info?.Create(mod); if ((Object)(object)val != (Object)null) { CompleteRow(val); } List<ConfigEntryBase> list = (from entry in mod.ConfigFile.GetConfigEntries() orderby ModSettingsOrder.GetSectionOrder(mod, entry.Definition.Section) select entry).ThenBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Section, StringComparer.OrdinalIgnoreCase).ThenBy((ConfigEntryBase entry) => ModSettingsOrder.GetEntryOrder(mod, entry)).ThenBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Key, StringComparer.OrdinalIgnoreCase) .ToList(); string text = null; foreach (ConfigEntryBase item in list) { if (!string.Equals(text, item.Definition.Section, StringComparison.OrdinalIgnoreCase)) { text = item.Definition.Section; CreateHeading(SplitName(LocalizationApi.GetConfigSection(text, mod.ConfigFile))); } CreateEntryRow(mod, item); } } LayoutRebuild(); } public void Reset(ModConfig mod) { if (mod != null) { ConfigEntryBase[] configEntries = mod.ConfigFile.GetConfigEntries(); foreach (ConfigEntryBase obj in configEntries) { ConfigValues.TrySetValue(obj, obj.DefaultValue); } Build(mod); } } private void ClearRows() { foreach (GameObject createdRow in _createdRows) { if ((Object)(object)createdRow != (Object)null) { Object.Destroy((Object)(object)createdRow); } } _createdRows.Clear(); } private void CreateHeading(string text) { GameObject val = Object.Instantiate<GameObject>(_heading, _content); ((Object)val).name = "Mod Settings Section - " + text; val.SetActive(false); NativeUi.DisableLocalization(val); NativeUi.SetText(val, text); CompleteRow(val); } private void CreateEntryRow(ModConfig mod, ConfigEntryBase entry) { Type settingType = entry.SettingType; ConfigDescription description = entry.Description; AcceptableValueBase acceptable = ((description != null) ? description.AcceptableValues : null); IReadOnlyList<object> values; float min; float max; if (settingType == typeof(bool)) { CreateBoolRow(entry); } else if (settingType == typeof(KeyCode)) { CreateKeybindRow(entry); } else if (settingType.IsEnum) { CreateDropdownRow(entry, Enum.GetValues(settingType).Cast<object>().ToList()); } else if (ConfigValues.TryGetAcceptableValues(acceptable, out values)) { CreateDropdownRow(entry, values); } else if (ConfigValues.TryGetNumericRange(acceptable, out min, out max) && ConfigValues.IsSliderType(settingType)) { CreateSliderRow(mod, entry, min, max); } else { CreateInputRow(entry); } } private void CreateBoolRow(ConfigEntryBase entry) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(_toggle, _content); ((Object)val).name = GetRowName(entry); val.SetActive(false); NativeUi.DisableLocalization(val); Toggle toggle = val.GetComponent<Toggle>(); if ((Object)(object)toggle == (Object)null) { Object.Destroy((Object)(object)val); CreateInputRow(entry); return; } toggle.onValueChanged = new ToggleEvent(); toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue); ((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value) { if (!ConfigValues.TrySetValue(entry, value)) { toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue); } }); NativeUi.SetText(val, GetSettingText(entry)); CompleteRow(val); } private void CreateKeybindRow(ConfigEntryBase entry) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown GameObject val = NewRow(GetRowName(entry)); HideSlider(val); Transform val2 = NativeUi.FindValueBackground(val); SetValueLayout(val, val2, 0.65f, 20f); TMP_Text buttonText = NativeUi.FindValueText(val); Button button = (((Object)(object)val2 == (Object)null) ? null : (((Component)val2).GetComponent<Button>() ?? ((Component)val2).gameObject.AddComponent<Button>())); if ((Object)(object)button == (Object)null || (Object)(object)buttonText == (Object)null) { Object.Destroy((Object)(object)val); CreateInputRow(entry); return; } button.onClick = new ButtonClickedEvent(); ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { _keybindCapture.Begin(entry, button, buttonText); }); NativeUi.SetRowTitle(val, GetSettingText(entry)); buttonText.text = KeybindCapture.FormatKeyCode(entry.BoxedValue); CompleteRow(val); } private void CreateSliderRow(ModConfig mod, ConfigEntryBase entry, float min, float max) { GameObject val = NewRow(GetRowName(entry)); Slider slider = val.GetComponentInChildren<Slider>(true); if ((Object)(object)slider == (Object)null) { Object.Destroy((Object)(object)val); CreateInputRow(entry); return; } SetValueLayout(val, NativeUi.FindValueBackground(val), 0.75f, 20f); Image sliderFill = (((Object)(object)slider.fillRect == (Object)null) ? null : ((Component)slider.fillRect).GetComponent<Image>()); double? sliderStep = ModSettingsMetadata.GetSliderStep(mod, entry); double step = ConfigValues.GetSliderStep(min, max, entry.SettingType, sliderStep); float num = ConfigValues.SnapSliderValue(Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture), min, max, entry.SettingType, step); slider.minValue = min; slider.maxValue = max; slider.wholeNumbers = ConfigValues.IsIntegralType(entry.SettingType); slider.SetValueWithoutNotify(num); TMP_Text valueText = NativeUi.FindValueText(val); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float sliderValue) { float num2 = ConfigValues.SnapSliderValue(sliderValue, min, max, entry.SettingType, step); if (Math.Abs(sliderValue - num2) > 0.0001f) { slider.SetValueWithoutNotify(num2); } object value = ConfigValues.ConvertSliderValue(num2, entry.SettingType); if (!ConfigValues.TrySetValue(entry, value)) { float valueWithoutNotify = Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture); slider.SetValueWithoutNotify(valueWithoutNotify); } if ((Object)(object)valueText != (Object)null) { valueText.text = ConfigValues.FormatValue(entry.BoxedValue); } UpdateSliderFill(sliderFill, slider); }); NativeUi.SetRowTitle(val, GetSettingText(entry)); if ((Object)(object)valueText != (Object)null) { valueText.text = ConfigValues.FormatValue(ConfigValues.ConvertSliderValue(num, entry.SettingType)); } CompleteRow(val); } private void CreateDropdownRow(ConfigEntryBase entry, IReadOnlyList<object> values) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown GameObject val = NewRow(GetRowName(entry)); HideSlider(val); SetValueLayout(val, NativeUi.FindValueBackground(val), 0.65f, 20f); TMP_Dropdown dropdown = AddControl<TMP_Dropdown>(val, _dropdown); if ((Object)(object)dropdown == (Object)null || values.Count == 0) { Object.Destroy((Object)(object)val); CreateInputRow(entry); return; } dropdown.ClearOptions(); foreach (object value in values) { dropdown.options.Add(new OptionData(GetConfigValueText(entry, value))); } int valueWithoutNotify = values.Select((object value, int index) => new { value, index }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue))?.index ?? 0; dropdown.onValueChanged = new DropdownEvent(); dropdown.SetValueWithoutNotify(valueWithoutNotify); dropdown.RefreshShownValue(); ((UnityEvent<int>)(object)dropdown.onValueChanged).AddListener((UnityAction<int>)delegate(int index) { if (index >= 0 && index < values.Count && !ConfigValues.TrySetValue(entry, values[index])) { int valueWithoutNotify2 = values.Select((object value, int valueIndex) => new { value, valueIndex }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue))?.valueIndex ?? 0; dropdown.SetValueWithoutNotify(valueWithoutNotify2); dropdown.RefreshShownValue(); } }); NativeUi.SetRowTitle(val, GetSettingText(entry)); CompleteRow(val); } private void CreateInputRow(ConfigEntryBase entry) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewRow(GetRowName(entry)); HideSlider(val); Transform val2 = NativeUi.FindValueBackground(val); TMP_Text val3 = NativeUi.FindValueText(val); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val); return; } SetValueLayout(val, val2, 0.3f, 20f); GameObject val4 = new GameObject("Input", new Type[3] { typeof(RectTransform), typeof(Image), typeof(TMP_InputField) }); val4.transform.SetParent(val2, false); RectTransform component = val4.GetComponent<RectTransform>(); NativeUi.Stretch(component); component.offsetMin = new Vector2(0f, 10f); component.offsetMax = new Vector2(0f, -10f); Image component2 = val4.GetComponent<Image>(); ((Graphic)component2).color = Color.white; Button component3 = ((Component)val2).GetComponent<Button>(); PrepareBackground(component3); if ((Object)(object)component3 != (Object)null && (Object)(object)((Selectable)component3).targetGraphic != (Object)null) { ((Selectable)component3).targetGraphic.color = Color.clear; } GameObject val5 = new GameObject("Text Viewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val5.transform.SetParent(val4.transform, false); RectTransform component4 = val5.GetComponent<RectTransform>(); NativeUi.Stretch(component4); component4.offsetMin = new Vector2(12f, 2f); component4.offsetMax = new Vector2(-12f, -2f); TMP_InputField input = val4.GetComponent<TMP_InputField>(); val3.transform.SetParent(val5.transform, false); ((Graphic)val3).color = Color.black; val3.alignment = (TextAlignmentOptions)4097; ((Graphic)val3).raycastTarget = false; ((Selectable)input).targetGraphic = (Graphic)(object)component2; input.textViewport = component4; input.textComponent = val3; input.lineType = (LineType)0; input.richText = false; input.onEndEdit = new SubmitEvent(); input.SetTextWithoutNotify(entry.GetSerializedValue()); ((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)delegate(string value) { if (!ConfigValues.TrySetSerializedValue(entry, value)) { input.SetTextWithoutNotify(entry.GetSerializedValue()); } }); NativeUi.SetRowTitle(val, GetSettingText(entry)); CompleteRow(val); } private void CompleteRow(GameObject row) { row.SetActive(true); _createdRows.Add(row); } private GameObject NewRow(string name) { GameObject obj = Object.Instantiate<GameObject>(_row, _content); ((Object)obj).name = name; obj.SetActive(false); NativeUi.DisableLocalization(obj); return obj; } private T AddControl<T>(GameObject row, GameObject source) where T : Component { Transform val = NativeUi.FindValueBackground(row); if ((Object)(object)val == (Object)null || (Object)(object)source == (Object)null) { return default(T); } TMP_Text val2 = NativeUi.FindValueText(row); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } PrepareBackground(((Component)val).GetComponent<Button>()); GameObject obj = Object.Instantiate<GameObject>(source, val); ((Object)obj).name = ((Object)source).name; NativeUi.DisableLocalization(obj); NativeUi.Stretch(obj.GetComponent<RectTransform>()); return obj.GetComponentInChildren<T>(true); } private static void SetValueLayout(GameObject row, Transform valueBackground, float titleWidth, float rightInset) { //IL_0048: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Transform obj = row.transform.Find("TitleAndSlider"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); RectTransform val2 = (RectTransform)(object)((valueBackground is RectTransform) ? valueBackground : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { HorizontalLayoutGroup component = row.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } val.anchorMin = Vector2.zero; val.anchorMax = new Vector2(titleWidth, 1f); val.offsetMin = new Vector2(10f, 0f); val.offsetMax = new Vector2(-10f, 0f); val2.anchorMin = new Vector2(titleWidth, 0f); val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(10f, 0f); val2.offsetMax = new Vector2(0f - rightInset, 0f); } } private void LayoutRebuild() { RectTransform component = ((Component)_content).GetComponent<RectTransform>(); LayoutRebuilder.ForceRebuildLayoutImmediate(component); _info?.Repair(); LayoutRebuilder.ForceRebuildLayoutImmediate(component); ScrollRect componentInParent = ((Component)_content).GetComponentInParent<ScrollRect>(); if ((Object)(object)componentInParent != (Object)null) { componentInParent.verticalNormalizedPosition = 1f; } } private static string GetRowName(ConfigEntryBase entry) { return "Mod Setting - " + entry.Definition.Key; } private static string GetSettingText(ConfigEntryBase entry) { return SplitName(LocalizationApi.GetConfigDisplayName(entry)); } private static string GetConfigValueText(ConfigEntryBase entry, object value) { string result = default(string); if (!LocalizationApi.TryGetConfigDisplayValue(entry, value, ref result)) { return ConfigValues.FormatValue(value); } return result; } private static string SplitName(string text) { if (string.IsNullOrWhiteSpace(text)) { return text; } StringBuilder stringBuilder = new StringBuilder(text.Length + 8); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '_') { if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ') { stringBuilder.Append(' '); } continue; } bool flag = i > 0 && !char.IsWhiteSpace(text[i - 1]); if (char.IsUpper(c) && flag && (char.IsLower(text[i - 1]) || (i + 1 < text.Length && char.IsLower(text[i + 1]))) && stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ') { stringBuilder.Append(' '); } stringBuilder.Append(c); } return stringBuilder.ToString().Trim(); } private static void PrepareBackground(Button button) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //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_0057: 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_0021: 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) if (!((Object)(object)button == (Object)null)) { Graphic targetGraphic = ((Selectable)button).targetGraphic; if ((Object)(object)targetGraphic != (Object)null) { ColorBlock colors = ((Selectable)button).colors; targetGraphic.color = ((ColorBlock)(ref colors)).normalColor; targetGraphic.raycastTarget = false; } button.onClick = new ButtonClickedEvent(); ((Selectable)button).transition = (Transition)0; Navigation navigation = ((Selectable)button).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)button).navigation = navigation; } } private static void HideSlider(GameObject row) { Slider componentInChildren = row.GetComponentInChildren<Slider>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Component)componentInChildren).gameObject.SetActive(false); } CustomTMPSlider component = row.GetComponent<CustomTMPSlider>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } private static void UpdateSliderFill(Image fill, Slider slider) { if (!((Object)(object)fill == (Object)null) && !((Object)(object)slider == (Object)null)) { float num = slider.maxValue - slider.minValue; fill.fillAmount = ((num <= 0f) ? 0f : Mathf.Clamp01((slider.value - slider.minValue) / num)); } } } internal sealed class KeybindCapture { private ConfigEntryBase _entry; private TMP_Text _buttonText; private int _startFrame; public bool IsActive => _entry != null; public void Begin(ConfigEntryBase entry, Button button, TMP_Text buttonText) { _entry = entry; _buttonText = buttonText; _startFrame = Time.frameCount; _buttonText.text = I18n.Text("menu.press_a_key"); NativeUi.SelectObject(((Component)button).gameObject); } public void CaptureInput() { //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_0031: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (Time.frameCount <= _startFrame) { return; } foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && Input.GetKeyDown(value)) { if ((int)value == 27) { Finish(save: false, (KeyCode)0); } else { Finish(save: true, value); } break; } } } public void Cancel() { if (IsActive) { Finish(save: false, (KeyCode)0); } } public unsafe static string FormatKeyCode(object value) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!(value is KeyCode val)) { return ConfigValues.FormatValue(value); } return ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString(); } private void Finish(bool save, KeyCode keyCode) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (save && _entry != null && !ConfigValues.TrySetValue(_entry, keyCode)) { keyCode = (KeyCode)_entry.BoxedValue; } else if (_entry != null) { keyCode = (KeyCode)_entry.BoxedValue; } if ((Object)(object)_buttonText != (Object)null) { _buttonText.text = FormatKeyCode(keyCode); } _entry = null; _buttonText = null; } } internal sealed class ModInfoRow { private sealed class MetadataPart { public string Text { get; } public string Name { get; } public string Url { get; } public MetadataPart(string text, string name = null, string url = null) { Text = text; Name = name; Url = url; } } private sealed class ModLink { public string Name { get; } public string Url { get; } public int Start { get; } public int Length { get; } public ModLink(string name, string url, int start, int length) { Name = name; Url = url; Start = start; Length = length; } } private readonly Transform _content; private readonly GameObject _slider; private readonly GameObject _divider; private readonly GameObject _linkButton; private readonly GameObject _description; private readonly TMP_Text _descriptionFont; private GameObject _row; private IReadOnlyList<ModLink> _links = Array.Empty<ModLink>(); private bool _linksCreated; public ModInfoRow(Transform content, GameObject slider, GameObject divider, GameObject linkButton, GameObject description, TMP_Text descriptionFont) { _content = content; _slider = slider; _divider = divider; _linkButton = linkButton; _description = description; _descriptionFont = descriptionFont; } public GameObject Create(ModConfig mod) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) _row = null; _links = Array.Empty<ModLink>(); _linksCreated = false; ModSettingsRegistration modSettingsRegistration = mod?.Registration; if (modSettingsRegistration == null) { return null; } List<ModLink> links; string text = BuildText(modSettingsRegistration, out links); if (string.IsNullOrWhiteSpace(text)) { return null; } GameObject val = NewRow(); HideRowContents(val); RectTransform component = val.GetComponent<RectTransform>(); RectTransform component2 = _slider.GetComponent<RectTransform>(); RectTransform component3 = _description.GetComponent<RectTransform>(); RectTransform component4 = _divider.GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null) { Object.Destroy((Object)(object)val); return null; } float num = Mathf.Max(765f, component2.sizeDelta.x); float width = Mathf.Max(1f, num - 20f); RectTransform infoRect; TMP_Text infoLabel; float height; GameObject val2 = CreateText(val, text, width, out infoRect, out infoLabel, out height); if ((Object)(object)val2 == (Object)null) { Object.Destroy((Object)(object)val); return null; } float num2 = height + 2f + 12f + 6f; component.sizeDelta = new Vector2(num, num2); SetTextRect(infoRect, component3, height, num2, 6f, 10f); val2.SetActive(true); GameObject val3 = Object.Instantiate<GameObject>(_divider, val.transform); ((Object)val3).name = "Information Divider"; val3.SetActive(false); HideChildren(val3); Image component5 = val3.GetComponent<Image>(); RectTransform component6 = val3.GetComponent<RectTransform>(); if ((Object)(object)component5 == (Object)null || (Object)(object)component6 == (Object)null) { Object.Destroy((Object)(object)val3); Object.Destroy((Object)(object)val); return null; } ((Graphic)component5).raycastTarget = false; DisableLayoutDrivers(val3); component6.anchorMin = new Vector2(0f, 0.5f); component6.anchorMax = new Vector2(1f, 0.5f); component6.pivot = new Vector2(0.5f, 0.5f); component6.sizeDelta = new Vector2(0f, 2f); component6.anchoredPosition = new Vector2(0f, (0f - num2) * 0.5f + 6f + 1f); ((Transform)component6).localScale = ((Transform)component4).localScale; ((Transform)component6).localRotation = ((Transform)component4).localRotation; val3.SetActive(true); _row = val; _links = links; return val; } public void Repair() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_row == (Object)null) { return; } Transform transform = _row.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Transform obj = transform.Find("Information Text"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); Transform obj2 = transform.Find("Information Divider"); RectTransform val3 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { return; } TMP_Text val4 = ((Component)val2).GetComponent<TMP_Text>() ?? ((Component)val2).GetComponentInChildren<TMP_Text>(true); if (!((Object)(object)val4 == (Object)null)) { Rect rect = val.rect; StretchRow(val, 765f, ((Rect)(ref rect)).height); ((Transform)val).localScale = Vector3.one; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(10f, val2.offsetMin.y); val2.offsetMax = new Vector2(-10f, val2.offsetMax.y); ((Transform)val2).localScale = Vector3.one; Canvas.ForceUpdateCanvases(); val4.ForceMeshUpdate(true, true); float num = Mathf.Max(_descriptionFont.fontSize, val4.renderedHeight); float num2 = num + 2f + 12f + 6f; StretchRow(val, 765f, num2); SetTextRect(val2, null, num, num2, 6f, 10f); val3.anchorMin = new Vector2(0f, 0.5f); val3.anchorMax = new Vector2(1f, 0.5f); val3.sizeDelta = new Vector2(0f, 2f); val3.anchoredPosition = new Vector2(0f, (0f - num2) * 0.5f + 6f + 1f); ((Transform)val3).localScale = Vector3.one; if (!_linksCreated && _links.Count > 0) { Canvas.ForceUpdateCanvases(); val4.ForceMeshUpdate(true, true); CreateLinkButtons(_row, val2, val4, _links); } _linksCreated = true; } } private GameObject CreateText(GameObject row, string text, float width, out RectTransform infoRect, out TMP_Text infoLabel, out float height) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) infoRect = null; infoLabel = null; height = 0f; GameObject val = Object.Instantiate<GameObject>(_description, row.transform); ((Object)val).name = "Information Text"; val.SetActive(false); NativeUi.DisableLocalization(val); infoRect = val.GetComponent<RectTransform>(); infoLabel = val.GetComponent<TMP_Text>() ?? val.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)infoRect == (Object)null || (Object)(object)infoLabel == (Object)null || (Object)(object)_descriptionFont == (Object)null) { Object.Destroy((Object)(object)val); infoRect = null; infoLabel = null; return null; } infoLabel.enableAutoSizing = false; infoLabel.enableWordWrapping = true; infoLabel.richText = true; infoLabel.overflowMode = (TextOverflowModes)0; infoLabel.alignment = (TextAlignmentOptions)257; infoLabel.fontSize = _descriptionFont.fontSize; infoLabel.text = text.Trim(); DisableLayoutDrivers(val); height = Mathf.Max(_descriptionFont.fontSize, infoLabel.GetPreferredValues(infoLabel.text, width, 0f).y); return val; } private void CreateLinkButtons(GameObject row, RectTransform infoRect, TMP_Text infoText, IReadOnlyList<ModLink> links) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)infoRect == (Object)null || (Object)(object)infoText == (Object)null) { return; } infoText.ForceMeshUpdate(true, true); for (int i = 0; i < links.Count; i++) { ModLink link = links[i]; List<Rect> linkBounds = GetLinkBounds(infoText, link); for (int j = 0; j < linkBounds.Count; j++) { CreateLinkButton(row, infoRect, infoText, link, linkBounds[j], j); } } } private void CreateLinkButton(GameObject row, RectTransform infoRect, TMP_Text infoText, ModLink link, Rect bounds, int segment) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(_linkButton, row.transform); ((Object)val).name = link.Name + " Link " + segment; val.SetActive(false); NativeUi.DisableLocalization(val); NativeUi.SetText(val, string.Empty); Button component = val.GetComponent<Button>(); Image component2 = val.GetComponent<Image>(); if ((Object)(object)component2 == (Object)null) { GameObject val2 = new GameObject("Link Hit Area", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = Vector2.zero; component3.offsetMax = Vector2.zero; component2 = val2.GetComponent<Image>(); } if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val); return; } Graphic[] componentsInChildren = val.GetComponentsInChildren<Graphic>(true); foreach (Graphic val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)(object)component2)) { Color color = val3.color; color.a = 0f; val3.color = color; val3.raycastTarget = false; } } ((Graphic)component2).color = Color.clear; ((Graphic)component2).raycastTarget = true; ((Selectable)component).targetGraphic = (Graphic)(object)component2; component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { Application.OpenURL(link.Url); }); ((Selectable)component).transition = (Transition)0; ((Selectable)component).interactable = true; Navigation navigation = ((Selectable)component).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component).navigation = navigation; RectTransform component4 = val.GetComponent<RectTransform>(); if ((Object)(object)component4 == (Object)null) { Object.Destroy((Object)(object)val); return; } component4.anchorMin = new Vector2(0.5f, 0.5f); component4.anchorMax = new Vector2(0.5f, 0.5f); component4.pivot = new Vector2(0.5f, 0.5f); component4.sizeDelta = ((Rect)(ref bounds)).size + new Vector2(4f, 4f); ((Transform)component4).localScale = ((Transform)infoRect).localScale; ((Transform)component4).localRotation = ((Transform)infoRect).localRotation; ((Transform)component4).localPosition = row.transform.InverseTransformPoint(((Transform)infoRect).TransformPoint(new Vector3(((Rect)(ref bounds)).center.x, ((Rect)(ref bounds)).center.y, 0f))); ConfigureHover(val, infoText, link); val.SetActive(true); } private static void ConfigureHover(GameObject buttonObject, TMP_Text infoText, ModLink link) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown if (!((Object)(object)buttonObject == (Object)null) && !((Object)(object)infoText == (Object)null) && link.Start >= 0 && link.Start + link.Length <= infoText.text.Length) { string normalText = infoText.text; string hoverText = normalText.Substring(0, link.Start) + "<u>" + normalText.Substring(link.Start, link.Length) + "</u>" + normalText.Substring(link.Start + link.Length); EventTrigger obj = buttonObject.GetComponent<EventTrigger>() ?? buttonObject.AddComponent<EventTrigger>(); obj.triggers.Clear(); Entry val = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent<BaseEventData>)(object)val.callback).AddListener((UnityAction<BaseEventData>)delegate { infoText.text = hoverText; }); obj.triggers.Add(val); Entry val2 = new Entry { eventID = (EventTriggerType)1 }; ((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate { infoText.text = normalText; }); obj.triggers.Add(val2); } } private static List<Rect> GetLinkBounds(TMP_Text text, ModLink link) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00e8: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_0083: Unknown result type (might be due to invalid IL or missing references) List<Rect> list = new List<Rect>(); TMP_TextInfo textInfo = text.textInfo; int num = Math.Min(link.Start + link.Length, textInfo.characterCount); int num2 = -1; float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; for (int i = link.Start; i < num; i++) { TMP_CharacterInfo val = textInfo.characterInfo[i]; if (!val.isVisible) { continue; } if (num2 != val.lineNumber) { if (num2 >= 0) { list.Add(Rect.MinMaxRect(num3, num4, num5, num6)); } num2 = val.lineNumber; num3 = val.bottomLeft.x; num4 = val.bottomLeft.y; num5 = val.topRight.x; num6 = val.topRight.y; } else { num3 = Mathf.Min(num3, val.bottomLeft.x); num4 = Mathf.Min(num4, val.bottomLeft.y); num5 = Mathf.Max(num5, val.topRight.x); num6 = Mathf.Max(num6, val.topRight.y); } } if (num2 >= 0) { list.Add(Rect.MinMaxRect(num3, num4, num5, num6)); } return list; } private static string BuildText(ModSettingsRegistration registration, out List<ModLink> links) { List<MetadataPart> list = new List<MetadataPart>(); bool hasValue = registration.NexusModsId.HasValue; bool flag = !string.IsNullOrWhiteSpace(registration.ThunderstoreTeam); bool flag2 = hasValue && flag; if (!string.IsNullOrWhiteSpace(registration.Version)) { list.Add(new MetadataPart("V" + registration.Version.Trim())); } if (!string.IsNullOrWhiteSpace(registration.Author)) { list.Add(new MetadataPart(registration.Author.Trim())); } if (hasValue) { list.Add(new MetadataPart(flag2 ? "Nexus" : I18n.Text("menu.open_nexus_page"), "Nexus Mods", ModSettingsRegistry.GetNexusModsUrl(registration.NexusModsId.Value))); } if (flag) { list.Add(new MetadataPart(flag2 ? "Thunderstore" : I18n.Text("menu.open_thunderstore_page"), "Thunderstore", ModSettingsRegistry.GetThunderstoreUrl(registration.ThunderstoreTeam, registration.ThunderstoreModName))); } links = new List<ModLink>(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < list.Count; i++) { if (i > 0) { stringBuilder.Append(" · "); } MetadataPart metadataPart = list[i]; int length = stringBuilder.Length; stringBuilder.Append(metadataPart.Text); if (!string.IsNullOrWhiteSpace(metadataPart.Url)) { links.Add(new ModLink(metadataPart.Name, metadataPart.Url, length, metadataPart.Text.Length)); } } if (!string.IsNullOrWhiteSpace(registration.Description)) { if (stringBuilder.Length > 0) { stringBuilder.Append("\n\n"); } stringBuilder.Append(registration.Description.Trim()); } return stringBuilder.ToString(); } private GameObject NewRow() { GameObject obj = Object.Instantiate<GameObject>(_slider, _content); ((Object)obj).name = "Mod Settings Information"; obj.SetActive(false); NativeUi.DisableLocalization(obj); HorizontalLayoutGroup component = obj.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } return obj; } private static void HideRowContents(GameObject row) { HideChildren(row); Slider componentInChildren = row.GetComponentInChildren<Slider>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Component)componentInChildren).gameObject.SetActive(false); } CustomTMPSlider component = row.GetComponent<CustomTMPSlider>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } private static void HideChildren(GameObject root) { for (int i = 0; i < root.transform.childCount; i++) { ((Component)root.transform.GetChild(i)).gameObject.SetActive(false); } } private static void SetTextRect(RectTransform rect, RectTransform source, float height, float rowHeight, float verticalPadding, float horizontalPadding) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = new Vector2(horizontalPadding, rowHeight - verticalPadding - height); rect.offsetMax = new Vector2(0f - horizontalPadding, 0f - verticalPadding); ((Transform)rect).localScale = (((Object)(object)source == (Object)null) ? Vector3.one : ((Transform)source).localScale); ((Transform)rect).localRotation = (((Object)(object)source == (Object)null) ? Quaternion.identity : ((Transform)source).localRotation); } private static void StretchRow(RectTransform rect, float nativeWidth, float height) { //IL_0007: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0f, rect.anchorMin.y); rect.anchorMax = new Vector2(1f, rect.anchorMax.y); Vector2 sizeDelta = rect.sizeDelta; sizeDelta.x = 0f; sizeDelta.y = height; rect.sizeDelta = sizeDelta; rect.offsetMin = new Vector2(0f, rect.offsetMin.y); rect.offsetMax = new Vector2(0f, rect.offsetMax.y); Rect rect2 = rect.rect; if (((Rect)(ref rect2)).width < 1f) { rect.sizeDelta = new Vector2(nativeWidth, height); } } private static void DisableLayoutDrivers(GameObject root) { if (!((Object)(object)root == (Object)null)) { LayoutGroup[] componentsInChildren = root.GetComponentsInChildren<LayoutGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } ContentSizeFitter[] componentsInChildren2 = root.GetComponentsInChildren<ContentSizeFitter>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Behaviour)componentsInChildren2[i]).enabled = false; } AspectRatioFitter[] componentsInChildren3 = root.GetComponentsInChildren<AspectRatioFitter>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } LayoutElement[] componentsInChildren4 = root.GetComponentsInChildren<LayoutElement>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { ((Behaviour)componentsInChildren4[i]).enabled = false; } } } } public static class ModSettingsMenuController { private static Button _titleSource; private static Button _pauseSource; private static GameObject _titleButton; private static GameObject _pauseButton; private static ModSettingsPanel _panel; private static readonly FieldInfo TitleSettingsButtonField = AccessTools.Field(typeof(UIMenu), "btnOpenSettings"); private static readonly FieldInfo PauseSettingsButtonField = AccessTools.Field(typeof(UIGameMenu), "btnSettings"); public static void AddTitleButton(Button source) { _titleButton = AddButton(_titleButton, ref _titleSource, source, inTitleMenu: true); } public static void AddTitleButton(UIMenu menu) { if ((Object)(object)menu == (Object)null) { ManualLogSource log = ModSettingsMenu.Log; if (log != null) { log.LogInfo((object)"Mainframe title menu is null."); } return; } if (TitleSettingsButtonField == null) { ManualLogSource log2 = ModSettingsMenu.Log; if (log2 != null) { log2.LogError((object)"Mainframe title settings field is missing."); } return; } Button button = GetButton(menu, TitleSettingsButtonField); if ((Object)(object)button == (Object)null) { ManualLogSource log3 = ModSettingsMenu.Log; if (log3 != null) { log3.LogError((object)"Mainframe title settings button is null."); } return; } ManualLogSource log4 = ModSettingsMenu.Log; if (log4 != null) { log4.LogInfo((object)"Mainframe title settings button found."); } AddTitleButton(button); } public static void AddPauseButton(Button source) { _pauseButton = AddButton(_pauseButton, ref _pauseSource, source, inTitleMenu: false); } public static void CaptureInput(UISettings settings) { if (_panel != null && _panel.IsHost(settings)) { _panel.RepairTabLabels(); _panel.CaptureInput(); } } public static void Refresh() { _panel?.Refresh(); } public static void RefreshLocalizedText() { NativeUi.SetText(_titleButton, I18n.Text("menu.mod_settings")); NativeUi.SetText(_pauseButton, I18n.Text("menu.mod_settings")); _panel?.Refresh(); } public static void Close(UISettings settings) { if (_panel != null && _panel.IsHost(settings)) { _panel.Close(); } } public static bool HandleEscape() { if (_panel == null || !_panel.IsCapturingKeybind) { return false; } _panel.CancelKeybind(); return true; } private static GameObject AddButton(GameObject current, ref Button currentSource, Button source, bool inTitleMenu) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return current; } if ((Object)(object)current != (Object)null && (Object)(object)currentSource == (Object)(object)source) { return current; } if ((Object)(object)current != (Object)null) { Object.Destroy((Object)(object)current); } GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Component)source).transform.parent); ((Object)val).name = "Mod Settings Button"; val.transform.SetSiblingIndex(((Component)source).transform.GetSiblingIndex() + 1); NativeUi.DisableLocalization(val); Button component = val.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("Cloned settings button is missing Button."); } Navigation navigation = ((Selectable)source).navigation; Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown; component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { Open(inTitleMenu); }); NativeUi.SetText(val, I18n.Text("menu.mod_settings")); ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)component; ((Selectable)source).navigation = navigation; Navigation navigation2 = ((Selectable)component).navigation; ((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)source; ((Navigation)(ref navigation2)).selectOnDown = selectOnDown; ((Selectable)component).navigation = navigation2; if ((Object)(object)selectOnDown != (Object)null) { Navigation navigation3 = selectOnDown.navigation; ((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)component; selectOnDown.navigation = navigation3; } currentSource = source; ManualLogSource log = ModSettingsMenu.Log; if (log != null) { log.LogInfo((object)(inTitleMenu ? "Added title mod settings button." : "Added pause mod settings button.")); } return val; } private static Button GetButton(object menu, FieldInfo field) { if (menu != null && !(field == null)) { object? value = field.GetValue(menu); return (Button)((value is Button) ? value : null); } return null; } private static void Open(bool inTitleMenu) { try { UISettings val = (((Object)(object)Mainframe.code == (Object)null) ? null : Mainframe.code.uiSettings); if (!((Object)(object)val == (Object)null)) { val.Open(inTitleMenu); if (inTitleMenu) { Mainframe.code.UIMenu.Close(); } else if ((Object)(object)Global.code != (Object)null) { Global.code.uiGameMenu.Close(); } if (_panel == null || !_panel.IsHost(val)) { _panel?.Destroy(); _panel = ModSettingsPanel.Create(val); } _panel.Show(); } } catch (Exception arg) { ManualLogSource log = ModSettingsMenu.Log; if (log != null) { log.LogError((object)$"Failed to open mod settings: {arg}"); } } } } internal sealed class ModSettingsPanel { private static readonly string[] ToggleFields = new string[5] { "togglePanelGeneral", "togglePanelKeybinding", "togglePanelGraphics", "togglePanelAudio", "togglePanelControllers" }; private readonly UISettings _settings; private readonly GameObject _panel; private readonly GameObject _tabTemplate; private readonly GameObject _tabScrollObject; private readonly ScrollRect _tabScroll; private readonly RectTransform _tabContent; private readonly GameObject _nativeContent; private readonly List<GameObject> _nativeTabs; private readonly Button _resetButton; private readonly Button _closeButton; private readonly Button _modResetButton; private readonly Button _modCloseButton; private readonly ConfigRows _rows; private readonly KeybindCapture _keybindCapture; private readonly List<GameObject> _tabs = new List<GameObject>(); private readonly List<TMP_Text[]> _tabLabels = new List<TMP_Text[]>(); private readonly List<string> _tabNames = new List<string>(); private readonly List<int> _tabDiagnosticFrames = new List<int>(); private IReadOnlyList<ModConfig> _mods = Array.Empty<ModConfig>(); private string _selectedGuid; private bool _savedNativeState; private bool _contentState; private List<bool> _tabStates; private bool _resetState; private bool _closeState; public bool IsCapturingKeybind => _keybindCapture.IsActive; private ModSettingsPanel(UISettings settings, GameObject panel, GameObject tabTemplate, GameObject tabScrollObject, ScrollRect tabScroll, RectTransform tabContent, GameObject nativeContent, List<GameObject> nativeTabs, Button resetButton, Button closeButton, Button modResetButton, Button modCloseButton, ConfigRows rows, KeybindCapture keybindCapture) { _settings = settings; _panel = panel; _tabTemplate = tabTemplate; _tabScrollObject = tabScrollObject; _tabScroll = tabScroll; _tabContent = tabContent; _nativeContent = nativeContent; _nativeTabs = nativeTabs; _resetButton = resetButton; _closeButton = closeButton; _modResetButton = modResetButton; _modCloseButton = modCloseButton; _rows = rows; _keybindCapture = keybindCapture; } public static ModSettingsPanel Create(UISettings settings) { GameObject obj = GetPrivate<GameObject>(settings, "panelKeybinding"); Slider val = GetPrivate<Slider>(settings, "sliderMouseSensitivity"); Toggle val2 = GetPrivate<Toggle>(settings, "toggleCameraShake"); TMP_Dropdown val3 = GetPrivate<TMP_Dropdown>(settings, "dropdownLanguage"); Toggle val4 = GetPrivate<Toggle>(settings, "togglePanelGeneral"); Button val5 = GetPrivate<Button>(settings, "btnResetToDefaultSettings"); Button val6 = GetPrivate<Button>(settings, "btnClose"); if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { throw new InvalidOperationException("UISettings is missing a required native template."); } Transform parent = obj.transform.parent; if ((Object)(object)parent == (Object)null || (Object)(object)parent.parent == (Object)null) { throw new InvalidOperationException("Native keybinding panel is missing its content container."); } GameObject val7 = Object.Instantiate<GameObject>(obj, parent.parent); ((Object)val7).name = "Mod Settings Panel"; val7.transform.SetSiblingIndex(parent.GetSiblingIndex()); CopyRectTransform(((Component)parent).GetComponent<RectTransform>(), val7.GetComponent<RectTransform>()); val7.SetActive(false); NativeUi.DisableLocalization(val7); LocalizedKeybindingButton[] componentsInChildren = val7.GetComponentsInChildren<LocalizedKeybindingButton>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } ScrollRect[] componentsInChildren2 = val7.GetComponentsInChildren<ScrollRect>(true); if (componentsInChildren2.Length == 0 || componentsInChildren2.Any((ScrollRect item) => (Object)(object)item.content == (Object)null)) { Object.Destroy((Object)(object)val7); throw new InvalidOperationException("Native keybinding panel is missing a scroll content area."); } ScrollRect[] array = componentsInChildren2; for (int i = 0; i < array.Length; i++) { NativeUi.ClearLayout((Transform)(object)array[i].content); } for (int num = 1; num < componentsInChildren2.Length; num++) { Transform parent2 = ((Component)componentsInChildren2[num]).transform.parent; if ((Object)(object)parent2 != (Object)null) { ((Component)parent2).gameObject.SetActive(false); } } ScrollRect obj2 = componentsInChildren2[0]; Scrollbar verticalScrollbar = obj2.verticalScrollbar; if ((Object)(object)verticalScrollbar == (Object)null) { Object.Destroy((Object)(object)val7); throw new InvalidOperationException("Native keybinding scroll is missing a vertical scrollbar."); } Transform parent3 = ((Component)obj2).transform.parent; StretchWidth((RectTransform)(object)((parent3 is RectTransform) ? parent3 : null)); Transform transform = ((Component)obj2).transform; BalanceScrollMargins((RectTransform)(object)((transform is RectTransform) ? transform : null)); obj2.scrollSensitivity = 50f; Button modResetButton = CloneButton(val5, parent.parent, "Mod Settings Reset Button"); Button modCloseButton = CloneButton(val6, parent.parent, "Mod Settings Close Button"); Transform val8 = FindRow(val); GameObject divider = FindTemplate(val8, "TitleAndSlider/Slider mouse sensitivity/Background"); GameObject val9 = FindTemplate(((Component)val3).transform, "Label"); TMP_Text component = val9.GetComponent<TMP_Text>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val7); throw new InvalidOperationException("Native dropdown label is missing TextMeshProUGUI."); } KeybindCapture keybindCapture = new KeybindCapture(); ConfigRows rows = new ConfigRows(info: new ModInfoRow((Transform)(object)obj2.content, ((Component)val8).gameObject, divider, ((Component)val6).gameObject, val9, component), content: (Transform)(object)obj2.content, row: ((Component)val8).gameObject, heading: FindGroupHeading(val8), toggle: ((Component)val2).gameObject, dropdown: ((Component)val3).gameObject, keybindCapture: keybindCapture); ScrollRect scroll; RectTransform content; GameObject tabScrollObject = CreateTabScroll(((Component)val4).transform.parent, verticalScrollbar, out scroll, out content); return new ModSettingsPanel(settings, val7, ((Component)val4).gameObject, tabScrollObject, scroll, content, ((Component)parent).gameObject, GetPrivateToggleGameObjects(settings, ToggleFields), val5, val6, modResetButton, modCloseButton, rows, keybindCapture); } public bool IsHost(UISettings settings) { return (Object)(object)_settings == (Object)(object)settings; } public void Show() { SaveNativeState(); HideNative(); if ((Object)(object)_tabScrollObject != (Object)null) { _tabScrollObject.SetActive(true); } _panel.SetActive(true); BuildTabs(); SetupButtons(); SelectMod(_selectedGuid); } public void CaptureInput() { if (_panel.activeSelf && _keybindCapture.IsActive) { _keybindCapture.CaptureInput(); } } public void RepairTabLabels() { if ((Object)(object)_panel == (Object)null || !_panel.activeSelf) { return; } for (int i = 0; i < _tabs.Count && i < _mods.Count && i < _tabLabels.Count && i < _tabNames.Count; i++) { GameObject val = _tabs[i]; if ((Object)(object)val == (Object)null) { continue; } string text = _tabNames[i]; TMP_Text[] array = _tabLabels[i]; string gUID = _mods[i].Info.Metadata.GUID; PrepareTabFont(array, text, gUID, logDiagnostics: false); TMP_Text component = val.GetComponent<TMP_Text>(); foreach (TMP_Text val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if (!string.Equals(val2.text, text, StringComparison.Ordinal)) { val2.text = text; } if ((Object)(object)val2 == (Object)(object)component) { ((Behaviour)val2).enabled = true; } } } if (i < _tabDiagnosticFrames.Count && _tabDiagnosticFrames[i] >= 0) { int num = _tabDiagnosticFrames[i] + 1; _tabDiagnosticFrames[i] = (LogTabMesh(array, text, gUID, num) ? (-1) : num); } } } public void Refresh() { if (_panel.activeSelf) { BuildTabs(); SetupButtons(); SelectMod(_selectedGuid); } } public void CancelKeybind() { _keybindCapture.Cancel(); } public void Close() { _keybindCapture.Cancel(); if ((Object)(object)_panel != (Object)null) { _panel.SetActive(false); } if ((Object)(object)_tabScrollObject != (Object)null) { _tabScrollObject.SetActive(false); } ClearTabs(); RestoreNative(); } public void Destroy() { Close(); if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); } if ((Object)(object)_tabScrollObject != (Object)null) { Object.Destroy((Object)(object)_tabScrollObject); } if ((Object)(object)_modResetButton != (Object)null) { Object.Destroy((Object)(object)((Component)_modResetButton).gameObject); } if ((Object)(object)_modCloseButton != (Object)null) { Object.Destroy((Object)(object)((Component)_modCloseButton).gameObject); } } private void BuildTabs() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown ClearTabs(); _mods = ModConfigs.Load(); if (!_mods.Any((ModConfig mod) => string.Equals(mod.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase))) { ModConfig? modConfig = _mods.FirstOrDefault(); _selectedGuid = ((modConfig != null) ? modConfig.Info.Metadata.GUID : null); } for (int num = 0; num < _mods.Count; num++) { ModConfig modConfig2 = _mods[num]; GameObject val = Object.Instantiate<GameObject>(_tabTemplate, (Transform)(object)_tabContent); ((Object)val).name = "Mod Settings Tab - " + modConfig2.Info.Metadata.GUID; val.SetActive(false); NativeUi.DisableLocalization(val); Toggle tab = val.GetComponent<Toggle>(); if ((Object)(object)tab == (Object)null) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("Cloned mod settings tab is missing Toggle."); } CopyTabLayout(val, num); tab.group = null; string guid = modConfig2.Info.Metadata.GUID; string modName = GetModName(modConfig2); TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); val.SetActive(true); PrepareTabFont(componentsInChildren, modName, guid, logDiagnostics: true); NativeUi.SetText(val, modName); tab.onValueChanged = new ToggleEvent(); ((UnityEvent<bool>)(object)tab.onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn) { if (isOn) { SelectMod(guid); } else if (string.Equals(_selectedGuid, guid, StringComparison.OrdinalIgnoreCase)) { SetTabVisual(tab, isOn: true); } }); SetTabVisual(tab, isOn: false); _tabs.Add(val); _tabLabels.Add(componentsInChildren); _tabNames.Add(modName); _tabDiagnosticFrames.Add(0); } ResizeTabContent(); } private void SelectMod(string guid) { _selectedGuid = guid; for (int i = 0; i < _tabs.Count; i++) { Toggle component = _tabs[i].GetComponent<Toggle>(); if ((Object)(object)component != (Object)null) { SetTabVisual(component, string.Equals(_mods[i].Info.Metadata.GUID, guid, StringComparison.OrdinalIgnoreCase)); } } ModConfig modConfig = _mods.FirstOrDefault((ModConfig mod) => string.Equals(mod.Info.Metadata.GUID, guid, StringComparison.OrdinalIgnoreCase)); _rows.Build(modConfig); if ((Object)(object)_modResetButton != (Object)null) { ((Selectable)_modResetButton).interactable = modConfig != null; } for (int num = 0; num < _mods.Count; num++) { if (_mods[num] == modConfig) { ScrollToTab(num); break; } } } private void SaveNativeState() { if (!_savedNativeState) { _contentState = (Object)(object)_nativeContent != (Object)null && _nativeContent.activeSelf; _tabStates = _nativeTabs.Select((GameObject tab) => (Object)(object)tab != (Object)null && tab.activeSelf).ToList(); _resetState = (Object)(object)_resetButton != (Object)null && ((Component)_resetButton).gameObject.activeSelf; _closeState = (Object)(object)_closeButton != (Object)null && ((Component)_closeButton).gameObject.activeSelf; _savedNativeState = true; } } private void HideNative() { if ((Object)(object)_nativeContent != (Object)null) { _nativeContent.SetActive(false); } foreach (GameObject nativeTab in _nativeTabs) { if ((Object)(object)nativeTab != (Object)null) { nativeTab.SetActive(false); } } if ((Object)(object)_resetButton != (Object)null) { ((Component)_resetButton).gameObject.SetActive(false); } if ((Object)(object)_closeButton != (Object)null) { ((Component)_closeButton).gameObject.SetActive(false); } } private void RestoreNative() { if (!_savedNativeState) { return; } if ((Object)(object)_nativeContent != (Object)null) { _nativeContent.SetActive(_contentState); } for (int i = 0; i < _nativeTabs.Count; i++) { if ((Object)(object)_nativeTabs[i] != (Object)null) { _nativeTabs[i].SetActive(_tabStates[i]); } } if ((Object)(object)_resetButton != (Object)null) { ((Component)_resetButton).gameObject.SetActive(_resetState); } if ((Object)(object)_closeButton != (Object)null) { ((Component)_closeButton).gameObject.SetActive(_closeState); } if ((Object)(object)_modResetButton != (Object)null) { ((Component)_modResetButton).gameObject.SetActive(false); } if ((Object)(object)_modCloseButton != (Object)null) { ((Component)_modCloseButton).gameObject.SetActive(false); } _savedNativeState = false; } private void SetupButtons() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown if ((Object)(object)_modResetButton != (Object)null) { ((Component)_modResetButton).gameObject.SetActive(true); ((Component)_modResetButton).transform.SetAsLastSibling(); _modResetButton.onClick = new ButtonClickedEvent(); ((UnityEvent)_modResetButton.onClick).AddListener(new UnityAction(ResetSelectedMod)); } if ((Object)(object)_modCloseButton != (Object)null) { ((Component)_modCloseButton).gameObject.SetActive(true); ((Component)_modCloseButton).transform.SetAsLastSibling(); _modCloseButton.onClick = new ButtonClickedEvent(); ((UnityEvent)_modCloseButton.onClick).AddListener(new UnityAction(_settings.Close)); } } private void ResetSelectedMod() { ModConfig mod = _mods.FirstOrDefault((ModConfig modConfig) => string.Equals(modConfig.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase)); _rows.Reset(mod); } private void ClearTabs() { foreach (GameObject tab in _tabs) { if ((Object)(object)tab != (Object)null) { Object.Destroy((Object)(object)tab); } } _tabs.Clear(); _tabLabels.Clear(); _tabNames.Clear(); _tabDiagnosticFrames.Clear(); } private void CopyTabLayout(GameObject tabObject, int index) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) RectTransform component = _nativeTabs[Mathf.Min(index, _nativeTabs.Count - 1)].GetComponent<RectTransform>(); RectTransform component2 = tabObject.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { CopyRectTransform(component, component2); if (index >= _nativeTabs.Count) { float tabStep = GetTabStep(component); component2.anchoredPosition += new Vector2(tabStep * (float)(index - _nativeTabs.Count + 1), 0f); } } } private void ResizeTabContent() { //IL_004f: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_tabContent == (Object)null) && !((Object)(object)_tabScroll == (Object)null) && !((Object)(object)_tabScroll.viewport == (Object)null)) { RectTransform component = _tabTemplate.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float tabStep = GetTabStep(component); float num = component.anchoredPosition.x + tabStep * (float)Mathf.Max(0, _tabs.Count - 1); Rect rect = component.rect; float num2 = num + ((Rect)(ref rect)).width * (1f - component.pivot.x) + 20f; RectTransform tabContent = _tabContent; rect = _tabScroll.viewport.rect; tabContent.sizeDelta = new Vector2(Mathf.Max(((Rect)(ref rect)).width, num2), 0f); _tabScroll.horizontalNormalizedPosition = 0f; } } } private void ScrollToTab(int index) { //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (index < 0 || index >= _tabs.Count || (Object)(object)_tabScroll == (Object)null || (Object)(object)_tabScroll.viewport == (Object)null || (Object)(object)_tabContent == (Object)null) { return; } Rect rect = _tabScroll.viewport.rect; float width = ((Rect)(ref rect)).width; rect = _tabContent.rect; float num = ((Rect)(ref rect)).width - width; if (num <= 0f) { _tabScroll.horizontalNormalizedPosition = 0f; return; } RectTransform component = _tabs[index].GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float num2 = component.anchoredPosition.x - width * 0.5f; _tabScroll.horizontalNormalizedPosition = Mathf.Clamp01(num2 / num); } } private float GetTabStep(RectTransform source) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (_nativeTabs.Count > 1) { GameObject obj = _nativeTabs[0]; RectTransform val = ((obj != null) ? obj.GetComponent<RectTransform>() : null); GameObject obj2 = _nativeTabs[1]; RectTransform val2 = ((obj2 != null) ? obj2.GetComponent<RectTransform>() : null); float num = (((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) ? 0f : (val2.anchoredPosition.x - val.anchoredPosition.x)); if (num > 0f) { return num; } } Rect rect = source.rect; return ((Rect)(ref rect)).width; } private static void SetTabVisual(Toggle tab, bool isOn) { tab.SetIsOnWithoutNotify(isOn); TMP_Text component = ((Component)tab).GetComponent<TMP_Text>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; } } private static void PrepareTabFont(TMP_Text[] labels, string text, string guid, bool logDiagnostics) { //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Invalid comparison between Unknown and I4 string fontName; switch (LocalizationApi.CurrentLanguage) { case "zh-Hans": fontName = "NotoSansSC-Regular SDF"; break; case "ja": fontName = "NotoSansJP-Regular SDF"; break; case "ko": fontName = "NotoSansKR-Regular SDF"; break; default: if (logDiagnostics) { ManualLogSource log = ModSettingsMenu.Log; if (log != null) { log.LogInfo((object)("[TabFont] skip guid=" + guid + " text=\"" + EscapeLogText(text) + "\" language=" + LocalizationApi.CurrentLanguage)); } } return; } if (labels == null) { if (logDiagnostics) { ManualLogSource log2 = ModSettingsMenu.Log; if (log2 != null) { log2.LogWarning((object)("[TabFont] no labels guid=" + guid + " text=\"" + EscapeLogText(text) + "\"")); } } return; } TMP_FontAsset val = null; string text2 = null; foreach (TMP_Text val2 in labels) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.font == (Object)null) { continue; } val = FindFont(val2.font, fontName); if ((Object)(object)val != (Object)null) { text2 = "label:" + ((Object)((Component)val2).gameObject).name; break; } List<TMP_FontAsset> fallbackFontAssetTable = val2.font.fallbackFontAssetTable; if (fallbackFontAssetTable == null) { continue; } for (int j = 0; j < fallbackFontAssetTable.Count; j++) { val = FindFont(fallbackFontAssetTable[j], fontName); if ((Object)(object)val != (Object)null) { text2 = "fallback:" + ((Object)((Component)val2).gameObject).name + "[" + j + "]"; break; } } if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset item) => (Object)(object)FindFont(item, fontName) != (Object)null)); if ((Object)(object)val != (Object)null) { text2 = "resources"; } } if ((Object)(object)val == (Object)null) { if (logDiagnostics) { ManualLogSource log3 = ModSettingsMenu.Log; if (log3 != null) { log3.LogWarning((object)("[TabFont] font not found guid=" + guid + " text=\"" + EscapeLogText(text) + "\" language=" + LocalizationApi.CurrentLanguage + " requested=" + fontName + " labels=" + DescribeLabels(labels))); } } return; } if ((int)val.atlasPopulationMode != 1 || (Object)(object)val.sourceFontFile == (Object)null) { if (logDiagnostics) { ManualLogSource log4 = ModSettingsMenu.Log; if (log4 != null) { log4.LogWarning((object)("[TabFont] unusable font guid=" + guid + " text=\"" + EscapeLogText(text) + "\" match=" + text2 + " " + DescribeFont(val) + " labels=" + DescribeLabels(labels))); } } return; } int num = ((val.characterTable == null) ? (-1) : val.characterTable.Count); int num2 = ((val.glyphTable == null) ? (-1) : val.glyphTable.Count); string text3 = default(string); bool flag = val.TryAddCharacters(text, ref text3, false); uint[] codes = default(uint[]); bool flag2 = val.HasCharacters(text, ref codes, false, false); if (logDiagnostics) { ManualLogSource log5 = ModSettingsMenu.Log; if (log5 != null) { log5.LogInfo((object)("[TabFont] prepare guid=" + guid + " text=\"" + EscapeLogText(text) + "\" codes=" + FormatTextCodes(text) + " language=" + LocalizationApi.CurrentLanguage + " " + $"match={text2} added={flag} reportedMissing={FormatTextCodes(text3)} " + $"hasAll={flag2} actualMissing={FormatCodes(codes)} " + $"characters={num}->{GetCharacterCount(val)} " + $"glyphs={num2}->{GetGlyphCount(val)} {DescribeFont(val)} " + "labelsBefore=" + DescribeLabels(labels))); } } foreach (TMP_Text val3 in labels) { if ((Object)(object)val3 != (Object)null && (Object)(object)val3.font != (Object)(object)val) { val3.font = val; } } if (logDiagnostics) { ManualLogSource log6 = ModSettingsMenu.Log; if (log6 != null) { log6.LogInfo((object)("[TabFont] bound guid=" + guid + " text=\"" + EscapeLogText(text) + "\" labelsAfter=" + DescribeLabels(labels))); } } } private static bool LogTabMesh(TMP_Text[] labels, string text, string guid, int frame) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) bool flag = labels?.Any((TMP_Text label) => (Object)(object)label != (Object)null && label.textInfo != null && label.textInfo.characterCount >= text.Length) ?? false; if (!flag && frame < 120) { return false; } if (!flag) { ManualLogSource log = ModSettingsMenu.Log; if (log != null) { log.LogWarning((object)("[TabFont] mesh not ready guid=" + guid + " text=\"" + EscapeLogText(text) + "\" " + $"frames={frame} labels={DescribeLabels(labels)}")); } return true; } foreach (TMP_Text val in labels) { if (!((Object)(object)val == (Object)null)) { Rect rect = val.rectTransform.rect; TMP_TextInfo textInfo = val.textInfo; List<string> list = new List<string>(); for (int num2 = 0; num2 < textInfo.characterCount; num2++) { TMP_CharacterInfo val2 = textInfo.characterInfo[num2]; uint code = ((val2.textElement != null) ? val2.textElement.unicode : 0u); uint num3 = ((val2.textElement != null) ? val2.textElement.glyphIndex : 0u); TMP_TextElement textElement = val2.textElement; int num4 = ((((textElement != null) ? textElement.glyph : null) == null) ? (-1) : val2.textElement.glyph.atlasIndex); list.Add(FormatCode(val2.character) + "=>" + FormatCode(code) + $"/glyph={num3}/atlas={num4}" + "/font=" + DescribeFontName(val2.fontAsset) + $"/visible={val2.isVisible}/material={val2.materialReferenceIndex}"); } ManualLogSource log2 = ModSettingsMenu.Log; if (log2 != null) { log2.LogInfo((object)("[TabFont] mesh guid=" + guid + " text=\"" + EscapeLogText(text) + "\" " + $"label={((Object)((Component)val).gameObject).name}#{((Object)val).GetInstanceID()} " + $"active={((Component)val).gameObject.activeInHierarchy} enabled={((Behaviour)val).enabled} " + $"rect={((Rect)(ref rect)).width:0.##}x{((Rect)(ref rect)).height:0.##} overflow={val.overflowMode} " + $"font={DescribeFontName(val.font)} characters={textInfo.characterCount} " + string.Format("materials={0} data=[{1}]", textInfo.materialCount, string.Join(", ", list)))); } } } return true; } private static string DescribeLabels(TMP_Text[] labels) { if (labels == null) { return "null"; } return "[" + string.Join(", ", labels.Select((TMP_Text label) => (!((Object)(object)label == (Object)null)) ? (((Object)((Component)label).gameObject).name + "#" + ((Object)label).GetInstanceID() + "=" + DescribeFontName(label.font)) : "null")) + "]"; } private static string DescribeFont(TMP_FontAsset font) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)font == (Object)null) { return "font=null"; } string arg = (((Object)(object)font.sourceFontFile == (Object)null) ? "null" : (((Object)font.sourceFontFile).name + "#" + ((Object)font.sourceFontFile).GetInstanceID())); Texture2D[] atlasTextures = font.atlasTextures; string text = ((atlasTextures == null) ? "null" : ("[" + string.Join(", ", atlasTextures.Select((Texture2D texture, int index) => (!((Object)(object)texture == (Object)null)) ? (index + ":" + ((Texture)texture).width + "x" + ((Texture)texture).height + "#" + ((Object)texture).GetInstanceID()) : (index + ":null"))) + "]")); return $"font={DescribeFontName(font)} mode={font.atlasPopulationMode} " + $"source={arg} atlasSize={font.atlasWidth}x{font.atlasHeight} " + $"atlasCount={font.atlasTextureCount} multiAtlas={font.isMultiAtlasTexturesEnabled} " + "atlasTextures=" + text; } private static string DescribeFontName(TMP_FontAsset font) { if (!((Object)(object)font == (Object)null)) { return ((Object)font).name + "#" + ((Object)font).GetInstanceID(); } return "null"; } private static int GetCharacterCount(TMP_FontAsset font) { if (font.characterTable != null) { return font.characterTable.Count; } return -1; } private static int GetGlyphCount(TMP_FontAsset font) { if (font.glyphTable != null) { return font.glyphTable.Count; } return -1; } private static string FormatTextCodes(string text) { if (!string.IsNullOrEmpty(text)) { return "[" + string.Join(" ", text.Select((char character) => FormatCode(character))) + "]"; } return "[]"; } private static string FormatCodes(uint[] codes) { if (codes != null && codes.Length != 0) { return "[" + string.Join(" ", codes.Select(FormatCode)) + "]"; } return "[]"; } private static string FormatCode(uint code) { return "U+" + code.ToString((code > 65535) ? "X8" : "X4"); } private static string EscapeLogText(string text) { if (text != null) { return text.Replace("\r", "\\r").Replace("\n", "\\n"); } return "null"; } private static TMP_FontAsset FindFont(TMP_FontAsset font, string fontName) { if ((Object)(object)font == (Object)null) { return null; } if (!string.Equals(((Object)font).name, fontName, StringComparison.Ordinal) && !((Object)font).name.StartsWith(fontName + "(", StringComparison.OrdinalIgnoreCase) && !((Object)font).name.StartsWith(fontName + " ", StringComparison.OrdinalIgnoreCase)) { return null; } return font; } private static void CopyRectTransform(RectTransform source, RectTransform target) { //IL_0015: 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_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.anchorMin = source.anchorMin; target.anchorMax = source.anchorMax; target.pivot = source.pivot; target.sizeDelta = source.sizeDelta; target.anchoredPosition = source.anchoredPosition; ((Transform)target).localScale = ((Transform)source).localScale; ((Transform)target).localRotation = ((Transform)source).localRotation; } } private static void StretchWidth(RectTransform rect) { //IL_0011: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = new Vector2(0f, rect.anchorMin.y); rect.anchorMax = new Vector2(1f, rect.anchorMax.y); rect.offsetMin = new Vector2(0f, rect.offsetMin.y); rect.offsetMax = new Vector2(0f, rect.offsetMax.y); ((Transform)rect).localScale = Vector3.one; } } private static void BalanceScrollMargins(RectTransform rect) { //IL_0010: 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_002e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { float num = Mathf.Max(0f, 0f - rect.offsetMax.x); rect.offsetMin = new Vector2(num, rect.offsetMin.y); } } private static GameObject CreateTabScroll(Transform tabGroup, Scrollbar scrollbarTemplate, out ScrollRect scroll, out RectTransform content) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tabGroup == (Object)null || (Object)(object)tabGroup.parent == (Object)null) { throw new InvalidOperationException("Native tab group is missing its parent."); } GameObject val = new GameObject("Mod Settings Tab Scroll", new Type[3] { typeof(RectTransform), typeof(Image), typeof(ScrollRect) }); val.transform.SetParent(tabGroup.parent, false); CopyRectTransform(((Component)tabGroup).GetComponent<RectTransform>(), val.GetComponent<RectTransform>()); val.transform.SetSiblingIndex(tabGroup.GetSiblingIndex() + 1); Image component = val.GetComponent<Image>(); ((Graphic)component).color = Color.clear; ((Graphic)component).raycastTarget = true; GameObject val2 = new GameObject("Viewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); NativeUi.Stretch(component2); component2.offsetMin = new Vector2(0f, 20f); GameObject val3 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val2.transform, false); content = val3.GetComponent<RectTransform>(); content.anchorMin = new Vector2(0f, 0f); content.anchorMax = new Vector2(0f, 1f); content.pivot = new Vector2(0f, 0.5f); content.anchoredPosition = Vector2.zero; content.sizeDelta = Vector2.zero; scroll = val.GetComponent<ScrollRect>(); scroll.content = content; scroll.viewport = component2; scroll.horizontal = true; scroll.vertical = false; scroll.movementType = (MovementType)2; scroll.inertia = true; scroll.scrollSensitivity = 30f; Scrollbar horizontalScrollbar = CloneHorizontalScrollbar(scrollbarTemplate, val.transform); scroll.horizontalScrollbar = horizontalScrollbar; scroll.horizontalScrollbarVisibility = (ScrollbarVisibility)0; scroll.horizontalScrollbarSpacing = 0f; val.SetActive(false); return val; } private static Scrollbar CloneHorizontalScrollbar(Scrollbar source, Transform parent) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_005c: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent); ((Object)val).name = "Horizontal Scrollbar"; Scrollbar component = val.GetComponent<Scrollbar>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("Cloned native scrollbar is missing Scrollbar."); } component.onValueChanged = new ScrollEvent(); component.SetDirection((Direction)0, true); RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(1f, 0f); component2.pivot = new Vector2(0.5f, 0f); component2.sizeDelta = new Vector2(-40f, 14f); component2.anchoredPosition = new Vector2(0f, 3f); return component; } private static Button CloneButton(Button source, Transform parent, string name) { GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent); ((Object)val).name = name; CopyRectTransform(((Component)source).GetComponent<RectTransform>(), val.GetComponent<RectTransform>()); val.SetActive(false); Button component = val.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("Cloned native settings button is missing Button."); } return component; } private static Transform FindRow(Slider slider) { Transform val = ((Component)slider).transform; while ((Object)(object)val != (Object)null) { if ((Object)(object)val.Find("ValueBackground") != (Object)null) { return val; } val = val.parent; } throw new InvalidOperationException("Native slider row is missing ValueBackground."); } private static GameObject FindTemplate(Transform root, string path) { Transform obj = (((Object)(object)root == (Object)null) ? null : root.Find(path)); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Native settings resource path is missing: " + path); } return ((Component)obj).gameObject; } private static GameObject FindGroupHeading(Transform row) { Transform parent = row.parent; if ((Object)(object)parent != (Object)null) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child != (Object)(object)row && (Object)(object)((Component)child).GetComponent<TMP_Text>() != (Object)null) { return ((Component)child).gameObject; } } } throw new InvalidOperationException("Native settings group is missing its heading."); } private static List<GameObject> GetPrivateToggleGameObjects(UISettings settings, IEnumerable<string> names) { return names.Select(delegate(string name) { Toggle obj = GetPrivate<Toggle>(settings, name); return (obj == null) ? null : ((Component)obj).gameObject; }).ToList(); } private static T GetPrivate<T>(UISettings settings, string name) where T : class { FieldInfo fieldInfo = AccessTools.Field(typeof(UISettings), name); if (!(fieldInfo == null)) { return fieldInfo.GetValue(settings) as T; } return null; } private static string GetModName(ModConfig mod) { string text = mod.Registration?.GetName(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return mod.Info.Metadata.Name; } } internal static class NativeUi { public static void DisableLocalization(GameObject root) { if ((Object)(object)root == (Object)null) { return; } MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.StartsWith("Localize", StringComparison.Ordinal)) { ((Behaviour)val).ena